diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fcfad7738..45207b077 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,14 +1,12 @@ { "name": "TypeScriptToLua", - "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14", - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:18", "extensions": [ "typescript-to-lua.vscode-typescript-to-lua", "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "esbenp.prettier-vscode" ], - "postCreateCommand": "npm ci" + "postCreateCommand": "npm ci", + "remoteUser": "node" } diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 492195f96..000000000 --- a/.eslintignore +++ /dev/null @@ -1,7 +0,0 @@ -/dist -/test/translation/transformation -/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 deleted file mode 100644 index 5b8fe5f4a..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,238 +0,0 @@ -module.exports = { - extends: ["plugin:jest/recommended", "plugin:jest/style"], - parserOptions: { - sourceType: "module", - project: [ - "test/tsconfig.json", - "src/lualib/tsconfig.json", - "benchmark/tsconfig.json", - "language-extensions/tsconfig.json", - ], - }, - env: { es6: true, node: true }, - plugins: ["import"], - rules: { - "arrow-body-style": "error", - curly: ["error", "multi-line"], - eqeqeq: ["error", "always", { null: "ignore" }], - "no-caller": "error", - "no-cond-assign": "error", - "no-debugger": "error", - "no-duplicate-case": "error", - "no-new-wrappers": "error", - "no-restricted-globals": ["error", "parseInt", "parseFloat"], - "no-unused-labels": "error", - "no-var": "error", - "object-shorthand": "error", - "prefer-const": ["error", { destructuring: "all" }], - radix: "error", - "use-isnan": "error", - "object-shorthand": [ - "error", - "always", - { avoidQuotes: true, ignoreConstructors: false, avoidExplicitReturnArrows: true }, - ], - "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "SequenceExpression"], - "spaced-comment": [ - "error", - "always", - { - line: { exceptions: ["-", "+"], markers: ["=", "!", "/"] }, - block: { exceptions: ["-", "+"], markers: ["=", "!", ":", "::"], balanced: true }, - }, - ], - "no-delete-var": ["error"], - "no-label-var": ["error"], - yoda: ["error"], - "prefer-numeric-literals": ["error"], - "prefer-rest-params": ["error"], - "prefer-spread": ["error"], - "no-useless-computed-key": ["error"], - "for-direction": ["error"], - "no-compare-neg-zero": ["error"], - "no-dupe-else-if": ["error"], - "no-empty": ["error", { allowEmptyCatch: true }], - "no-implicit-coercion": ["error", { boolean: true, number: true, string: true }], - "operator-assignment": ["error"], - "no-path-concat": ["error"], - "no-compare-neg-zero": ["error"], - "no-control-regex": ["error"], - "no-unneeded-ternary": ["error", { defaultAssignment: false }], - "one-var": ["error", "never"], - "prefer-exponentiation-operator": ["error"], - "prefer-object-spread": ["error"], - "no-useless-call": ["off"], - "no-useless-catch": ["error"], - "no-useless-concat": ["error"], - "no-useless-escape": ["error"], - "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" }], - "jest/no-disabled-tests": "error", - "jest/no-identical-title": "off", - "jest/no-test-return-statement": "error", - "jest/prefer-spy-on": "error", - "jest/prefer-todo": "error", - "jest/valid-title": "error", - // TODO: - // "jest/lowercase-name": "error", - }, - overrides: [ - { - files: "**/*.ts", - extends: ["plugin:@typescript-eslint/base"], - rules: { - // 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", - "@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", - - "@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, - }, - }, - { - /* Ignore properties that require quotes */ - selector: "objectLiteralProperty", - modifiers: ["requiresQuotes"], - format: null, - }, - ], - }, - }, - { - files: "src/lualib/**/*.ts", - rules: { - "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", - }, - }, - { - files: "benchmark/src/*_benchmarks/**/*.ts", - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65a3c2637..8353ca6d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,16 +5,19 @@ on: branches: master pull_request: +env: + NODE_VERSION: 20.17.0 + jobs: lint: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} - run: npm ci - run: npm run lint env: @@ -28,18 +31,18 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js 16.14.0 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} - run: npm ci - run: npm run build - run: npx jest --maxWorkers 2 --coverage env: CI: true - if: matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v4 benchmark: name: Benchmark @@ -47,22 +50,24 @@ jobs: steps: - name: Lua Install run: sudo apt-get install lua5.3 luajit + - name: Add Brew to Path (Required since Nov 2022) + run: echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH - name: Glow Install run: brew install glow # Checkout master & commit - name: Checkout master - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: master path: master - name: Checkout commit - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: commit - name: Use Node.js 16.14.0 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} # NPM # install and build master - name: npm ci master @@ -122,7 +127,7 @@ jobs: working-directory: commit/benchmark/dist - name: Combine benchmark results id: script-combine-results - uses: actions/github-script@v3 + uses: actions/github-script@v7 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 diff --git a/.gitignore b/.gitignore index e9fe7f092..fc3920330 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ node_modules /dist /coverage +/test/transpile/module-resolution/**/dist +/test/transpile/module-resolution/**/tsconfig.tsbuildinfo yarn.lock .vscode diff --git a/.prettierignore b/.prettierignore index 23b85e3bd..fb6d91319 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,7 @@ /dist /coverage /test/translation/transformation/characterEscapeSequence.ts +/test/translation/transformation/exportStatement.ts /benchmark/dist +/test/transpile/module-resolution/**/node_modules +/test/transpile/module-resolution/**/dist diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ffd37a4c..b96eb944c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,155 @@ # Changelog +## 1.31.0 + +- Upgraded TypeScript to 5.8.2 +- Changed `currentIndent` from private to protected in the `LuaPrinter` to allow custom printers with alternate indentation +- Added `bit` and `bit32` as reserved Lua keywords to avoid accidental naming clashes. + +## 1.30.0 + +- Allow passing in-memory plugins when using the tstl API, for more flexible integration into scripts +- Changed how stacktraces are handled for `Error` in Lua 5.1 and LuaJIT + +## 1.29.0 + +- Added support for the `Luau` luaTarget. This will use Luau's `continue` statement and ternary conditional expression `if ... then ... else ...` where appropriate. +- Added support for `new Array()` syntax to construct arrays (constructing with a length argument is not allowed). +- Fixed a bug causing arrays to sometimes be indexed with a wrong index. + +## 1.28.0 + +- Upgraded TypeScript to 5.7.2 +- Support `String(x)` transforming it to `tostring(x)`. +- Fixed statements before class super call +- Fixed some bugs with `LuaMultiReturn` used in iterables + +## 1.27.0 + +- Upgraded TypeScript to 5.6.2 +- Added support for `Math.trunc` (see [Math.trunc()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc)) +- Fixed a runtime error when disposing a disposable class +- Fixed the wrong `this` value being passed when using `?.` to call a `super` method +- Fixed a bug causing exported `/** @compileMembersOnly */` enums to break +- Fixed a bug in `Array.from` when calling it with a non-array iterable +- Fixed an incorrect diagnostic being shown for `await using` code +- Fixed a bug causing not all getters/setters to be transpiled + +## 1.26.0 + +- Upgraded TypeScript to 5.5.2 +- Added support for the new proposed ECMAScript Set methods in ESNext: `intersection`, `union`, `difference`, `symmetricDifference`, `isSubsetOf`, `isSupersetOf`, `isDisjointFrom`. For more info see [the TypeScript release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#support-for-new-ecmascript-set-methods). +- Fixed a bug causing bundled code to be executed twice in some edge cases. +- Fixed a bug causing errors when using lualib in an environment without coroutines. + +## 1.25.0 + +- Upgraded TypeScript to 5.4.2 +- Added support for new TypeScript 5.4 features `Map.groupBy` and `Object.groupBy` +- Fixed a bug causing files to not be emitted at the correct output path +- Fixed a bug causing `@customname` to not work together with `@noSelf` +- Fixed a bug causing extended tsconfigs to not be correctly read when using watch mode + +## 1.24.0 + +- Optimized promises and async/await to better handle long chains of promises, like for example using await in a loop +- Fixed a bug causing errors when accessing `super` properties + +## 1.23.0 + +- Upgraded TypeScript to 5.3.3 + +## 1.22.0 + +- Added support for `Number.isInteger(n)` +- Added support for `afterEmit` plugin hook that can be used to post-process lua files after (possibly incremental) builds +- Fixed a bug causing `@noSelfInFile` sometimes to be ignored + +## 1.21.0 + +- Added support for `continue` for Lua 5.0, 5.1 and universal targets. +- Added support for the new `/** @customName myCustomName **/` decorator, which allows renaming of variables and identifiers. + - This is useful to get around names that are reserved keywords in TypeScript, but are used in Lua API +- Fixed a bug that caused super calls in static methods to throw an error + +## 1.20.0 + +- Added support for `Number.parseInt` and `Number.parseFloat` (mapped to same implementation as global `parseInt` and `parseFloat`) +- Added implementation for multiple `Number` constants like `Number.EPSILON` +- Added support for `Array.at` +- Fixed a bug when throwing an error object in a Lua environment without `debug` module +- Fixed a bug causing files not to be found when returning an absolute path from a `moduleResolution` plugin + +## 1.19.0 + +- Added support for the new TypeScript 5.2 `using` keyword for explicit resource management. See the [TypeScript release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management) for more information. +- Added support for the newly introduced 'copying array methods' `toReversed`, `toSorted`, `toSpliced` and `with`. These were also introduced in TypeScript 5.2, see [their release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#copying-array-methods) for more information. + +## 1.18.0 + +- Upgraded TypeScript to 5.2.2 +- The `noResolvePaths` option now accepts glob paths (for example, 'mydir/hello\*' to not resolve any files in mydir starting with hello). + - This also allows disabling module resolution completely by providing a '\*\*' pattern in your tsconfig.json `noResolvePaths`. + +## 1.17.0 + +- Added the `moduleResolution` plugin, allowing you to provide custom module resolution logic. See [the docs](https://typescripttolua.github.io/docs/api/plugins#moduleresolution) for more info. +- Added `isEmpty` to `LuaTable`, `LuaMap` and `LuaSet` (and their read-only counterparts). This simply to `next(tbl) == nil`, allowing for a simple check to see if a table is empty or not. +- Fixed a bug with synthetic nodes (e.g. created by custom TypeScript transformers) throwing an exception. +- Fixed unnecessary extra unpacking of tables +- Fixed some bugs with new decorators + +## 1.16.0 + +- Upgraded TypeScript to 5.1.3. +- Added support for [TypeScript 5.0 decorators](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#decorators). + - Old-style decorators will still work as long as you have `experimentalDecorators` configured, otherwise the new standard is used. +- Added support for [class static initialization blocks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks). +- Fixed a bug causing the `tstl` object in tsconfig.json not to be properly extended when extending a tsconfig from node_modules. + +## 1.15.0 + +- Using `extends` in tsconfig.json now also correctly merges settings in the `tstl` block (shallow merge). +- Now avoiding assigning default parameter values if the default value is `nil` (`null` or `undefined`). +- Fixed a bug where indexing a `LuaMultiReturn` value with [0] would still return everything. +- Fixed a bug with nested namespaces causing unexpected nil indexing errors. + +## 1.14.0 + +- **[Breaking]** Upgraded TypeScript to 5.0. +- Added support for `Number.toFixed`. +- Added support for spread expressions with `LuaPairsIterable` and `LuaPairsKeysIterable`. +- Fixed a bug breaking module resolution when using a custom file extension. +- Fixed various exceptions that could happen when trying to translate invalid TS. + +## 1.13.0 + +- Fixed alternate file extensions (other than .lua, if configured) breaking module resolution and emitted require statements. +- Added experimental support for `"luaLibImport": "require-minimal"` configuration option. This will output a lualib bundle containing only the lualib functions used by your code. This might not work if you are including external tstl-generated Lua, for example from a npm package. +- Added support for the "exports" field in package.json. +- Fixed some exceptions resulting from invalid language-extensions use. +- Fixed an exception when using compound assignment (like `+=`) with array length. + +## 1.12.0 + +- Reworked how tstl detects and rewrites `require` statements during dependency resolution. This should reduce the amount of false-positive matches of require statements: require statements in string literals or comments should no longer be detected by tstl. This means require statements in string literals or comments can survive the transpiler without causing a 'could not resolve lua sources' error or getting rewritten into nonsense. +- Now using `math.mod` for Lua 5.0 modulo operations. + +## 1.11.0 + +- **[Breaking]** Upgraded TypeScript to 4.9. +- `--tstlVerbose` now prints more resolver output when failing to resolve Lua sources. +- Fixed a bug breaking default exported classes with unicode names +- Relaxed conditions for the always-true warning to false positives. + +## 1.10.0 + +- **[Breaking]** Upgraded TypeScript to 4.8. +- **[Breaking]** Changed how language-extensions are distributed, you should now put `"types": ["@typescript-to-lua/language-extensions"]` in your tsconfig.json (instead of "typescript-to-lua/..."). +- Added support for **Lua 5.0**, thanks for the effort @YoRyan! +- Added support for TypeScript 4.7 [instantiation expressions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#instantiation-expressions). +- Fixed a bug causing some `require` uses not being recognized my module resolution, leading to missing files in the output. + ## 1.9.0 - Added a warning when trying to use a type in a condition that can never be false in Lua, such as numbers or strings. (Only when `strictNullChecks` is enabled.) diff --git a/benchmark/tsconfig.53.json b/benchmark/tsconfig.53.json index 0a7096234..6dbbe3bca 100644 --- a/benchmark/tsconfig.53.json +++ b/benchmark/tsconfig.53.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "types": ["lua-types/5.3"] + "types": ["lua-types/5.3", "@typescript-to-lua/language-extensions"] }, "tstl": { "luaTarget": "5.3" diff --git a/benchmark/tsconfig.jit.json b/benchmark/tsconfig.jit.json index 1fe18fa2c..0c6912d31 100644 --- a/benchmark/tsconfig.jit.json +++ b/benchmark/tsconfig.jit.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "types": ["lua-types/jit"] + "types": ["lua-types/jit", "@typescript-to-lua/language-extensions"] }, "tstl": { "luaTarget": "JIT" diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json index aefc13ae9..e1c9c2941 100644 --- a/benchmark/tsconfig.json +++ b/benchmark/tsconfig.json @@ -3,7 +3,7 @@ "target": "esnext", "lib": ["esnext"], // Dev types are JIT - "types": ["lua-types/jit"], + "types": ["lua-types/jit", "@typescript-to-lua/language-extensions"], "moduleResolution": "node", "outDir": "dist", "rootDir": "src", diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..0ea4d78ca --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,230 @@ +// @ts-check + +import tseslint from "typescript-eslint"; +import eslintPluginJest from "eslint-plugin-jest"; + +export default tseslint.config( + // Enable linting on TypeScript file extensions. + { + files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"], + }, + + // Base ESLint rules + { + rules: { + "arrow-body-style": "error", + curly: ["error", "multi-line"], + eqeqeq: ["error", "always", { null: "ignore" }], + "no-caller": "error", + "no-cond-assign": "error", + "no-debugger": "error", + "no-duplicate-case": "error", + "no-new-wrappers": "error", + "no-restricted-globals": ["error", "parseInt", "parseFloat"], + "no-unused-labels": "error", + "no-var": "error", + "prefer-const": ["error", { destructuring: "all" }], + radix: "error", + "use-isnan": "error", + "object-shorthand": [ + "error", + "always", + { avoidQuotes: true, ignoreConstructors: false, avoidExplicitReturnArrows: true }, + ], + "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "SequenceExpression"], + "spaced-comment": [ + "error", + "always", + { + line: { exceptions: ["-", "+"], markers: ["=", "!", "/"] }, + block: { exceptions: ["-", "+"], markers: ["=", "!", ":", "::"], balanced: true }, + }, + ], + "no-delete-var": ["error"], + "no-label-var": ["error"], + yoda: ["error"], + "prefer-numeric-literals": ["error"], + "prefer-rest-params": ["error"], + "prefer-spread": ["error"], + "no-useless-computed-key": ["error"], + "for-direction": ["error"], + "no-compare-neg-zero": ["error"], + "no-dupe-else-if": ["error"], + "no-empty": ["error", { allowEmptyCatch: true }], + "no-implicit-coercion": ["error", { boolean: true, number: true, string: true }], + "operator-assignment": ["error"], + "no-path-concat": ["error"], + "no-control-regex": ["error"], + "no-unneeded-ternary": ["error", { defaultAssignment: false }], + "one-var": ["error", "never"], + "prefer-exponentiation-operator": ["error"], + "prefer-object-spread": ["error"], + "no-useless-catch": ["error"], + "no-useless-concat": ["error"], + "no-useless-escape": ["error"], + "no-useless-return": ["error"], + }, + }, + + // typescript-eslint + { + plugins: { + "@typescript-eslint": tseslint.plugin, + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: [ + "test/tsconfig.json", + "src/lualib/tsconfig.json", + "src/lualib/tsconfig.lua50.json", + "benchmark/tsconfig.json", + "language-extensions/tsconfig.json", + "tsconfig.eslint.json", + ], + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + rules: { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": ["error", { default: "array-simple" }], + "@typescript-eslint/await-thenable": "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/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, + }, + }, + { + // Ignore properties that require quotes + selector: "objectLiteralProperty", + modifiers: ["requiresQuotes"], + format: null, + }, + ], + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-empty-object-type": "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", { allowDeclarations: true }], + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unsafe-function-type": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-wrapper-object-types": "error", + "no-throw-literal": "off", + "@typescript-eslint/only-throw-error": "error", // "no-throw-literal" was renamed to "only-throw-error". + "@typescript-eslint/prefer-for-of": "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-nullish-coalescing": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { skipCompoundAssignments: false }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", + }, + }, + + // eslint-plugin-jest + eslintPluginJest.configs["flat/recommended"], + eslintPluginJest.configs["flat/style"], + { + rules: { + "jest/expect-expect": "off", + "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], + "jest/no-disabled-tests": "error", + "jest/no-identical-title": "off", + "jest/no-test-return-statement": "error", + "jest/prefer-spy-on": "error", + "jest/prefer-todo": "error", + "jest/valid-title": "error", + // TODO: + // "jest/lowercase-name": "error", + }, + }, + + // Exceptions for specific files/directories + { + files: ["src/lualib/**/*.ts"], + rules: { + "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], + "@typescript-eslint/only-throw-error": "off", + "@typescript-eslint/prefer-optional-chain": "off", + "@typescript-eslint/naming-convention": "off", + }, + }, + + // Ignore some specific files and directories + { + ignores: [ + ".github/scripts/create_benchmark_check.js", + "dist/", + "eslint.config.mjs", + "jest.config.js", + "test/cli/errors/", + "test/cli/watch/", + "test/translation/transformation/", + "test/transpile/directories/", + "test/transpile/module-resolution/**/node_modules/", + "test/transpile/module-resolution/**/dist/", + "test/transpile/outFile/", + "test/transpile/resolve-plugin/", + ], + } +); diff --git a/jest.config.js b/jest.config.js index 2d390c93d..26b60c1cf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ -const isCI = require("is-ci"); +const isCI = process.env.GITHUB_ACTIONS !== undefined; /** @type {Partial} */ module.exports = { @@ -15,10 +15,13 @@ module.exports = { testEnvironment: "node", testRunner: "jest-circus/runner", preset: "ts-jest", - globals: { - "ts-jest": { - tsconfig: "/test/tsconfig.json", - diagnostics: { warnOnly: !isCI }, - }, + transform: { + "^.+\\.ts?$": [ + "ts-jest", + { + tsconfig: "/test/tsconfig.json", + diagnostics: { warnOnly: !isCI }, + }, + ], }, }; diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 1d80f0856..6d805f189 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + type AnyTable = Record; -// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/consistent-type-definitions +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions,@typescript-eslint/no-empty-object-type type AnyNotNil = {}; /** @@ -562,6 +564,20 @@ declare type LuaTableDelete = ( declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & LuaExtension<"TableDeleteMethod">; +/** + * Calls to functions with this type are translated to `next(myTable) == nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + */ +declare type LuaTableIsEmpty = ((table: TTable) => boolean) & LuaExtension<"TableIsEmpty">; + +/** + * Calls to methods with this type are translated to `next(myTable) == nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + */ +declare type LuaTableIsEmptyMethod = (() => boolean) & LuaExtension<"TableIsEmptyMethod">; + /** * A convenience type for working directly with a Lua table. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -575,6 +591,7 @@ declare interface LuaTable ext set: LuaTableSetMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -612,6 +629,7 @@ declare interface LuaMap extends LuaPa set: LuaTableSetMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -633,6 +651,7 @@ declare const LuaMap: (new () => LuaMa declare interface ReadonlyLuaMap extends LuaPairsIterable { get: LuaTableGetMethod; has: LuaTableHasMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -645,6 +664,7 @@ declare interface LuaSet extends LuaPairsKeyIte add: LuaTableAddKeyMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -662,15 +682,16 @@ declare const LuaSet: (new () => LuaSet) & L */ declare interface ReadonlyLuaSet extends LuaPairsKeyIterable { has: LuaTableHasMethod; + isEmpty: LuaTableIsEmptyMethod; } interface ObjectConstructor { /** Returns an array of keys of an object, when iterated with `pairs`. */ - keys(o: LuaPairsIterable | LuaPairsKeyIterable): K[]; + keys(o: LuaPairsIterable | LuaPairsKeyIterable): K[]; /** Returns an array of values of an object, when iterated with `pairs`. */ values(o: LuaPairsIterable): V[]; /** Returns an array of key/values of an object, when iterated with `pairs`. */ - entries(o: LuaPairsIterable): Array<[K, V]>; + entries(o: LuaPairsIterable): Array<[K, V]>; } diff --git a/language-extensions/package.json b/language-extensions/package.json new file mode 100644 index 000000000..194ab1212 --- /dev/null +++ b/language-extensions/package.json @@ -0,0 +1,23 @@ +{ + "name": "@typescript-to-lua/language-extensions", + "version": "1.19.0", + "description": "Language extensions used by typescript-to-lua", + "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "homepage": "https://typescripttolua.github.io/", + "bugs": { + "url": "https://github.com/TypeScriptToLua/TypeScriptToLua/issues" + }, + "license": "MIT", + "keywords": [ + "typescript", + "lua", + "tstl", + "transpiler", + "language extensions" + ], + "files": [ + "**.d.ts" + ], + "main": "", + "types": "index.d.ts" +} diff --git a/package-lock.json b/package-lock.json index cedb3f0c8..48f4978dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,17 @@ { "name": "typescript-to-lua", - "version": "1.9.0", - "lockfileVersion": 2, + "version": "1.31.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.9.0", + "version": "1.31.0", "license": "MIT", "dependencies": { - "enhanced-resolve": "^5.8.2", + "@typescript-to-lua/language-extensions": "1.19.0", + "enhanced-resolve": "5.8.2", + "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" }, @@ -18,334 +20,266 @@ }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/glob": "^7.1.1", + "@types/glob": "^7.2.0", "@types/jest": "^27.5.2", - "@types/node": "^13.7.7", + "@types/node": "^22.10.0", + "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.27.0", - "@typescript-eslint/parser": "^5.27.0", - "eslint": "^8.17.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.4.6", + "eslint": "^9.22.0", + "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^27.3.0", - "jest-circus": "^27.3.0", - "lua-types": "^2.11.0", - "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.3.2", - "ts-jest": "^27.1.3", - "ts-node": "^10.3.0", - "typescript": "~4.7.3" + "jest": "^29.5.0", + "jest-circus": "^29.7.0", + "lua-types": "^2.13.0", + "lua-wasm-bindings": "^0.3.1", + "prettier": "^2.8.8", + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.0" }, "engines": { - "node": ">=12.13.0" + "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.7.3" + "typescript": "^5.8.2" } }, - "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.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", - "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" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/highlight": "^7.14.5" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">=6.9.0" - } - }, - "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, - "bin": { - "semver": "bin/semver.js" - } - }, - "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, - "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "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=", + "node_modules/@babel/compat-data": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "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==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "node_modules/@babel/generator": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "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, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "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==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -356,6 +290,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -368,6 +303,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -382,6 +318,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -389,14 +326,16 @@ "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 + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" }, "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=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -404,8 +343,9 @@ "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=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -415,6 +355,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -423,10 +364,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -439,6 +384,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -451,6 +397,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -463,6 +410,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -470,11 +418,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -487,6 +468,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -494,11 +476,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -511,6 +510,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -523,6 +523,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -535,6 +536,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -547,6 +549,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -559,6 +562,7 @@ "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -566,11 +570,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-syntax-private-property-in-object": { "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==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -581,11 +586,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-typescript": { + "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "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, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -596,59 +602,51 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" @@ -659,17 +657,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -680,121 +681,283 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", "dev": true, - "engines": { - "node": ">= 12" - } + "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "dependencies": { - "argparse": "^2.0.1" + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, "engines": { - "node": ">=10.10.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "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==", + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "dev": true, "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" + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "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==", + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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, + "license": "ISC", + "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" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "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, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -807,6 +970,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -822,6 +986,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -829,29 +994,12 @@ "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -861,64 +1009,67 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", - "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.3.0", - "jest-util": "^27.3.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", - "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^27.3.0", - "@jest/reporters": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "ci-info": "^3.2.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-resolve-dependencies": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "jest-watcher": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "rimraf": "^3.0.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -929,86 +1080,152 @@ } } }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/@jest/environment": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", - "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^27.3.0" + "jest-mock": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", - "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", - "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/types": "^27.2.5", - "expect": "^27.3.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", - "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", - "source-map": "^0.6.0", "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -1019,259 +1236,320 @@ } } }, - "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==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "graceful-fs": "^4.2.9" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "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": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", - "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", - "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-runtime": "^27.3.0" + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/transform": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", - "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^4.0.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "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": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "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==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">= 8" + "node": ">=6.0.0" } }, - "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==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=6.0.0" } }, - "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==", + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=6.0.0" } }, - "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==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { - "type-detect": "4.0.8" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "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": { - "@sinonjs/commons": "^1.7.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "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==", + "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": ">= 6" + "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/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, "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 + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, "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 + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" }, "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 + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" }, "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 + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@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==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, + "license": "MIT", "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==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "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==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, "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==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", "dev": true, + "license": "MIT", "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==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "dependencies": { "@types/minimatch": "*", @@ -1279,34 +1557,38 @@ } }, "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==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "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 + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" }, "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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "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==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -1322,136 +1604,140 @@ } }, "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/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "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 + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" }, "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 + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } }, - "node_modules/@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", - "dev": true + "node_modules/@types/picomatch": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.4.tgz", + "integrity": "sha512-0so8lU8O5zatZS/2Fi4zrwks+vZv7e0dygrgEZXljODXBig97l4cPQD+9LabXfGJOWwoRkTVz6Q4edZvD12UOA==", + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" + }, "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 + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "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 + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", - "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/type-utils": "5.27.0", - "@typescript-eslint/utils": "5.27.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", + "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/type-utils": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", - "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", + "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", - "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", + "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0" + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1459,38 +1745,35 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", - "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", + "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.27.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/utils": "8.26.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", - "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", + "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1498,92 +1781,105 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", - "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", + "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", - "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", + "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", - "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", + "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.27.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.26.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "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/@typescript-to-lua/language-extensions": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", + "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==", + "license": "MIT" }, "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1592,16 +1888,6 @@ "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", @@ -1612,24 +1898,16 @@ } }, "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==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "4" + "acorn": "^8.11.0" }, "engines": { - "node": ">= 6.0.0" + "node": ">=0.4.0" } }, "node_modules/ajv": { @@ -1653,6 +1931,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1663,23 +1942,12 @@ "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.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1689,6 +1957,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1700,10 +1969,11 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1716,85 +1986,39 @@ "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/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, - "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/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "license": "MIT" }, "node_modules/babel-jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", - "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" @@ -1805,6 +2029,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -1817,15 +2042,16 @@ } }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", - "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { @@ -1833,63 +2059,70 @@ } }, "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, + "license": "MIT", "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-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -1899,57 +2132,64 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.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/browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "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": { @@ -1957,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -1969,6 +2210,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -1977,26 +2219,15 @@ "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/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" - } + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=6" } @@ -2006,25 +2237,38 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, "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, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2041,54 +2285,73 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, + "license": "MIT" }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "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 + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2100,45 +2363,56 @@ "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/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" - } + "license": "MIT" }, "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 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, "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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.1" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "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 + "dev": true, + "license": "MIT" }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -2149,51 +2423,14 @@ "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/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.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2204,59 +2441,44 @@ } } }, - "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/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "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/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -2266,68 +2488,52 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, - "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==", + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "esutils": "^2.0.2" + "jake": "^10.8.5" }, - "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" + "bin": { + "ejs": "bin/cli.js" }, "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": ">=0.10.0" } }, "node_modules/electron-to-chromium": { - "version": "1.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", - "dev": true + "version": "1.5.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", + "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sindresorhus/emittery?sponsor=1" @@ -2337,12 +2543,14 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -2351,62 +2559,22 @@ "node": ">=10.13.0" } }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "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==", + "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, + "license": "MIT", "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" + "is-arrayish": "^0.2.1" } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2416,6 +2584,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2423,403 +2592,135 @@ "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", + "node_modules/eslint": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" }, "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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" + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "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=", + "node_modules/eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", "dev": true, + "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "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" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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=", + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "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": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "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": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.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.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.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.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "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": "26.4.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", - "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.10.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "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/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -2827,6 +2728,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2836,10 +2738,11 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2847,15 +2750,6 @@ "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", @@ -2868,20 +2762,12 @@ "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==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2891,6 +2777,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2900,6 +2787,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -2921,27 +2809,27 @@ "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", - "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/ansi-styles": { @@ -2949,6 +2837,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2956,15 +2845,70 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/expect/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/expect/node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/expect/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2972,68 +2916,118 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "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" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" } }, - "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-glob/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/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, + "license": "MIT" }, "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 + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "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==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { - "flat-cache": "^3.0.4" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" } }, "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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3042,55 +3036,49 @@ } }, "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "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/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } + "license": "ISC" }, "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, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -3103,15 +3091,17 @@ "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 + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3121,21 +3111,20 @@ } }, "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 + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "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, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3145,29 +3134,17 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "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, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -3177,6 +3154,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3184,32 +3162,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -3221,192 +3185,96 @@ } }, "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==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "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/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" - } + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, - "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==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "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, + "license": "MIT", "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, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/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" - } + "license": "MIT" }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.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": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "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==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "dependencies": { "parent-module": "^1.0.0", @@ -3420,10 +3288,11 @@ } }, "node_modules/import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -3433,221 +3302,78 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.8.19" } }, - "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==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "once": "^1.3.0", + "wrappy": "1" } }, - "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==", + "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, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "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/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-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": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.1.1" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-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==", + "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -3657,6 +3383,7 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3666,6 +3393,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3673,78 +3401,22 @@ "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, + "license": "MIT", "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-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-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true, - "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, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3752,105 +3424,53 @@ "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-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "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 + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "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==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "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": ">=10" } }, "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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -3858,6 +3478,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -3872,15 +3493,17 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -3889,27 +3512,49 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "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 + "dev": true, + "license": "MIT" }, "node_modules/jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", - "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^27.3.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^27.3.0" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -3921,379 +3566,540 @@ } }, "node_modules/jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", "execa": "^5.0.0", - "throat": "^6.0.1" + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", - "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.3.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-cli": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", - "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@jest/core": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "node-notifier": { + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { "optional": true } } }, "node_modules/jest-config": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", - "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.0", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.0", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.3.0", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^27.3.0" + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { + "@types/node": "*", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, "ts-node": { "optional": true } } }, - "node_modules/jest-config/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", - "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-environment-jsdom": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", - "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0", - "jsdom": "^16.6.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/jest-environment-node": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", - "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", - "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, - "node_modules/jest-jasmine2": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", - "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-leak-detector": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", - "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-matcher-utils": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", - "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } + "license": "MIT" }, - "node_modules/jest-matcher-utils/node_modules/jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", - "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.3.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.14.5" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", - "@types/node": "*" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "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==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -4307,285 +4113,344 @@ } }, "node_modules/jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", - "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", - "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", - "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-leak-detector": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runtime": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", - "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/globals": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "strip-bom": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", - "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.7.2", + "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.0", - "semver": "^7.3.2" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/jest-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", - "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", - "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^27.3.0" + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "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_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/jest-watcher": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", - "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", - "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker/node_modules/supports-color": { @@ -4593,6 +4458,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4607,84 +4473,27 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, - "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.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -4692,6 +4501,20 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4701,17 +4524,16 @@ "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 + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" }, "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==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4722,17 +4544,29 @@ "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "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, + "license": "MIT", "engines": { "node": ">=6" } @@ -4742,6 +4576,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4751,6 +4586,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -4759,108 +4595,110 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "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==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/lua-types": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", - "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", "dev": true, - "peerDependencies": { - "typescript-to-lua": "^1.0.0" - } + "license": "MIT" }, "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 + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", + "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/semver": "^7.3.9", + "semver": "^7.3.7" + } }, "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "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 + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "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 + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", @@ -4872,44 +4710,25 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "dependencies": { - "mime-db": "1.50.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, + "license": "MIT", "engines": { "node": ">=6" } @@ -4919,6 +4738,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4926,50 +4746,40 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, "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 + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "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 + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" }, "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=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4979,6 +4789,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -4986,70 +4797,12 @@ "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/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.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.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "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=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -5059,6 +4812,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -5070,53 +4824,63 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "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" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, "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==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "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=", + "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, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/parent-module": { @@ -5131,26 +4895,41 @@ "node": ">=6" } }, - "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/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, + "license": "MIT", + "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/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "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, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "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=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5160,6 +4939,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5167,28 +4947,21 @@ "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" - } + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true, + "license": "ISC" }, "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, + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5197,36 +4970,108 @@ } }, "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "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, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/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, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pretty-format": { @@ -5234,6 +5079,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -5248,6 +5094,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5260,6 +5107,7 @@ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -5268,21 +5116,32 @@ "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/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5307,35 +5166,26 @@ "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/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" - } + "license": "MIT" }, "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=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5351,6 +5201,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -5363,6 +5214,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5377,39 +5229,25 @@ } }, "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "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/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5433,38 +5271,12 @@ "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/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/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.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5477,6 +5289,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5489,58 +5302,50 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "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==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -5551,6 +5356,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5558,14 +5364,16 @@ "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 + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -5578,6 +5386,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5587,6 +5396,7 @@ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -5600,6 +5410,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5609,37 +5420,12 @@ "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.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5652,6 +5438,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5661,6 +5448,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5670,6 +5458,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5682,6 +5471,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5689,23 +5479,11 @@ "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/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5713,41 +5491,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", "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, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -5757,29 +5515,19 @@ "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": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "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=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5789,6 +5537,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5796,66 +5545,56 @@ "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==", + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "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" + "node": ">=18.12" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "typescript": ">=4.8.4" } }, "node_modules/ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "version": "29.2.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", + "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", "dev": true, "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" + "bs-logger": "^0.2.6", + "ejs": "^3.1.10", + "fast-json-stable-stringify": "^2.1.0", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.6.3", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "esbuild": "~0.14.0", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" + "@jest/transform": "^29.0.0", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { "@babel/core": { "optional": true }, - "@types/jest": { + "@jest/transform": { + "optional": true + }, + "@jest/types": { "optional": true }, "babel-jest": { @@ -5867,12 +5606,12 @@ } }, "node_modules/ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -5883,11 +5622,13 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" @@ -5907,179 +5648,122 @@ } } }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "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, - "bin": { - "acorn": "bin/acorn" + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=0.4.0" + "node": ">= 0.8.0" } }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "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, + "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "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, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { - "json5": "lib/cli.js" - } - }, - "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" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "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": ">=14.17" } }, - "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==", + "node_modules/typescript-eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", + "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "@typescript-eslint/eslint-plugin": "8.26.0", + "@typescript-eslint/parser": "8.26.0", + "@typescript-eslint/utils": "8.26.0" }, "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" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, - "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/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true }, - "node_modules/typescript": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", + "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, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "license": "MIT", "engines": { - "node": ">=4.2.0" + "node": ">= 4.0.0" } }, - "node_modules/typescript-to-lua": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", - "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, - "peer": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "enhanced-resolve": "^5.8.2", - "resolve": "^1.15.1", - "source-map": "^0.7.3" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "tstl": "dist/tstl.js" - }, - "engines": { - "node": ">=12.13.0" + "update-browserslist-db": "cli.js" }, "peerDependencies": { - "typescript": "~4.7.3" - } - }, - "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/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" + "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { @@ -6091,92 +5775,36 @@ "punycode": "^2.1.0" } }, - "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-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.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==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" + "makeerror": "1.0.12" } }, "node_modules/which": { @@ -6184,6 +5812,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6194,27 +5823,12 @@ "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/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==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6224,6 +5838,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6239,94 +5854,68 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" }, "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==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "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.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "signal-exit": "^3.0.7" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "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": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "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 + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "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==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yn": { @@ -6334,4751 +5923,23 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } - } - }, - "dependencies": { - "@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.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", - "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": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "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.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", - "dev": true, - "requires": { - "@babel/types": "^7.15.6", - "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 - } - } }, - "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" + "license": "MIT", + "engines": { + "node": ">=10" }, - "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 - } - } - }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@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.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/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.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", - "dev": true, - "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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 - }, - "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 - }, - "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" - } - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } - }, - "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - } - } - }, - "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "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 - } - } - }, - "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", - "dev": true, - "requires": { - "@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 - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "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": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@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": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", - "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.3.0", - "jest-util": "^27.3.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", - "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/reporters": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-resolve-dependencies": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "jest-watcher": "^27.3.0", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", - "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0" - } - }, - "@jest/fake-timers": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", - "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" - } - }, - "@jest/globals": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", - "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/types": "^27.2.5", - "expect": "^27.3.0" - } - }, - "@jest/reporters": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", - "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", - "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", - "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-runtime": "^27.3.0" - } - }, - "@jest/transform": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", - "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@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 - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@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, - "requires": { - "@types/node": "*" - } - }, - "@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, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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 - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@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 - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@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 - }, - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", - "dev": true - }, - "@types/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, - "requires": { - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", - "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/type-utils": "5.27.0", - "@typescript-eslint/utils": "5.27.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", - "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", - "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", - "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "5.27.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", - "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", - "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", - "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", - "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.27.0", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } - } - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "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, - "requires": {} - }, - "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 - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "babel-jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", - "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", - "dev": true, - "requires": { - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", - "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "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, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "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 - }, - "browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "call-bind": { - "version": "1.0.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", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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 - }, - "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "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, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "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 - }, - "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, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "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 - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "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", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "electron-to-chromium": { - "version": "1.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", - "dev": true - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "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" - } - }, - "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, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "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": "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": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "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": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "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": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "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": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.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": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.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" - } - }, - "doctrine": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-jest": { - "version": "26.4.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", - "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.10.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "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, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "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 - }, - "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } - } - }, - "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 - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "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.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": "^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": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expect": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", - "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "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 - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "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", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "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 - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "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, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "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" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "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==" - }, - "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 - }, - "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 - }, - "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 - }, - "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", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "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", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "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 - }, - "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" - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "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, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "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": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "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-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 - }, - "is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", - "dev": true, - "requires": { - "ci-info": "^3.1.1" - } - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "requires": { - "has": "^1.0.3" - } - }, - "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, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "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-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-regex": { - "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": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "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 - }, - "is-string": { - "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.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.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "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, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "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 - } - } - }, - "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, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "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 - } - } - }, - "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "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 - }, - "jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", - "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", - "dev": true, - "requires": { - "@jest/core": "^27.3.0", - "import-local": "^3.0.2", - "jest-cli": "^27.3.0" - } - }, - "jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", - "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", - "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", - "dev": true, - "requires": { - "@jest/core": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "jest-config": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", - "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.0", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.0", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.3.0", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "micromatch": "^4.0.4", - "pretty-format": "^27.3.0" - }, - "dependencies": { - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", - "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0" - }, - "dependencies": { - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-environment-jsdom": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", - "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", - "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" - } - }, - "jest-haste-map": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", - "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", - "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", - "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", - "dev": true, - "requires": { - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - }, - "dependencies": { - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-matcher-utils": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", - "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - }, - "dependencies": { - "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", - "dev": true - }, - "jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - } - }, - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-message-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", - "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - } - } - }, - "jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", - "dev": true - }, - "jest-resolve": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", - "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", - "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.0" - } - }, - "jest-runner": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", - "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-leak-detector": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", - "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/globals": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" - } - }, - "jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", - "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", - "natural-compare": "^1.4.0", - "pretty-format": "^27.3.0", - "semver": "^7.3.2" - }, - "dependencies": { - "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", - "dev": true - }, - "jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - } - }, - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", - "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", - "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "leven": "^3.1.0", - "pretty-format": "^27.3.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", - "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.3.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", - "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "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=", - "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 - }, - "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.11.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", - "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", - "dev": true, - "requires": {} - }, - "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": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "requires": { - "mime-db": "1.50.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "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 - }, - "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 - }, - "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, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "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" - } - }, - "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=", - "dev": true, - "requires": { - "p-limit": "^1.1.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 - }, - "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, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "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 - }, - "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 - }, - "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==" - }, - "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 - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "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 - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "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 - }, - "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "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 - }, - "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": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "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 - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "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, - "requires": { - "shebang-regex": "^3.0.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 - }, - "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.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "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": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "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": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "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 - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "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 - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "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 - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "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, - "requires": { - "is-number": "^7.0.0" - } - }, - "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, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } - } - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "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, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "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 - }, - "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 - }, - "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, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", - "dev": true - }, - "typescript-to-lua": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", - "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", - "dev": true, - "peer": true, - "requires": { - "enhanced-resolve": "^5.8.2", - "resolve": "^1.15.1", - "source-map": "^0.7.3" - } - }, - "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" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "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 - }, - "v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "requires": { - "makeerror": "1.0.x" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "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" - } - }, - "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 - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "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, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true, - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "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 - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true } } } diff --git a/package.json b/package.json index 0a6cbbc48..411987781 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.9.0", + "version": "1.31.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/", @@ -18,21 +18,20 @@ "dist/**/*.js", "dist/**/*.lua", "dist/**/*.ts", - "dist/lualib/*.json", - "language-extensions/**/*.ts" + "dist/lualib/**/*.json" ], "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc && npm run build-lualib", - "build-lualib": "node dist/tstl.js -p src/lualib/tsconfig.json", + "build-lualib": "node dist/tstl.js -p src/lualib/tsconfig.json && node dist/tstl.js -p src/lualib/tsconfig.lua50.json", "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", + "lint:eslint": "eslint .", "fix:prettier": "prettier --write .", - "check:language-extensions": "tsc language-extensions/index.d.ts", + "check:language-extensions": "tsc --strict language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, @@ -40,36 +39,37 @@ "tstl": "dist/tstl.js" }, "engines": { - "node": ">=12.13.0" + "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.7.3" + "typescript": "5.8.2" }, "dependencies": { - "enhanced-resolve": "^5.8.2", + "@typescript-to-lua/language-extensions": "1.19.0", + "enhanced-resolve": "5.8.2", + "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/glob": "^7.1.1", + "@types/glob": "^7.2.0", "@types/jest": "^27.5.2", - "@types/node": "^13.7.7", + "@types/node": "^22.10.0", + "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.27.0", - "@typescript-eslint/parser": "^5.27.0", - "eslint": "^8.17.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.4.6", + "eslint": "^9.22.0", + "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^27.3.0", - "jest-circus": "^27.3.0", - "lua-types": "^2.11.0", - "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.3.2", - "ts-jest": "^27.1.3", - "ts-node": "^10.3.0", - "typescript": "~4.7.3" + "jest": "^29.5.0", + "jest-circus": "^29.7.0", + "lua-types": "^2.13.0", + "lua-wasm-bindings": "^0.3.1", + "prettier": "^2.8.8", + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", + "typescript": "5.8.2", + "typescript-eslint": "^8.26.0" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index deee41b70..7f5562c07 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; +import { Plugin } from "./transpilation/plugins"; type OmitIndexSignature = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; @@ -12,12 +13,19 @@ export interface TransformerImport { after?: boolean; afterDeclarations?: boolean; type?: "program" | "config" | "checker" | "raw" | "compilerOptions"; + [option: string]: any; } export interface LuaPluginImport { name: string; import?: string; + + [option: string]: any; +} + +export interface InMemoryLuaPlugin { + plugin: Plugin | ((options: Record) => Plugin); [option: string]: any; } @@ -28,7 +36,7 @@ export interface TypeScriptToLuaOptions { luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; - luaPlugins?: LuaPluginImport[]; + luaPlugins?: Array; noImplicitGlobalVariables?: boolean; noImplicitSelf?: boolean; noHeader?: boolean; @@ -49,15 +57,18 @@ export enum LuaLibImportKind { None = "none", Inline = "inline", Require = "require", + RequireMinimal = "require-minimal", } export enum LuaTarget { Universal = "universal", + Lua50 = "5.0", Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", Lua54 = "5.4", LuaJIT = "JIT", + Luau = "Luau", } export enum BuildMode { diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 472831451..ad4a7e06b 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,7 +5,7 @@ // because we don't create the AST from text import * as ts from "typescript"; -import { LuaLibFeature } from "./transformation/utils/lualib"; +import { LuaLibFeature } from "./LuaLib"; import { castArray } from "./utils"; export enum SyntaxKind { @@ -25,6 +25,7 @@ export enum SyntaxKind { LabelStatement, ReturnStatement, BreakStatement, + ContinueStatement, // Luau only. ExpressionStatement, // Expression @@ -32,6 +33,7 @@ export enum SyntaxKind { NumericLiteral, NilKeyword, DotsKeyword, + ArgKeyword, TrueKeyword, FalseKeyword, FunctionExpression, @@ -43,6 +45,8 @@ export enum SyntaxKind { MethodCallExpression, Identifier, TableIndexExpression, + ParenthesizedExpression, + ConditionalExpression, // Luau only // Operators @@ -486,6 +490,18 @@ export function createBreakStatement(tsOriginal?: ts.Node): BreakStatement { return createNode(SyntaxKind.BreakStatement, tsOriginal) as BreakStatement; } +export interface ContinueStatement extends Statement { + kind: SyntaxKind.ContinueStatement; +} + +export function isContinueStatement(node: Node): node is ContinueStatement { + return node.kind === SyntaxKind.ContinueStatement; +} + +export function createContinueStatement(tsOriginal?: ts.Node): ContinueStatement { + return createNode(SyntaxKind.ContinueStatement, tsOriginal) as ContinueStatement; +} + export interface ExpressionStatement extends Statement { kind: SyntaxKind.ExpressionStatement; expression: Expression; @@ -544,6 +560,18 @@ export function createDotsLiteral(tsOriginal?: ts.Node): DotsLiteral { return createNode(SyntaxKind.DotsKeyword, tsOriginal) as DotsLiteral; } +export interface ArgLiteral extends Expression { + kind: SyntaxKind.ArgKeyword; +} + +export function isArgLiteral(node: Node): node is ArgLiteral { + return node.kind === SyntaxKind.ArgKeyword; +} + +export function createArgLiteral(tsOriginal?: ts.Node): ArgLiteral { + return createNode(SyntaxKind.ArgKeyword, tsOriginal) as ArgLiteral; +} + // StringLiteral / NumberLiteral // TODO TS uses the export interface "LiteralLikeNode" with a "text: string" member // but since we don't parse from text I think we can simplify by just having a value member @@ -581,10 +609,11 @@ export function createStringLiteral(value: string, tsOriginal?: ts.Node): String export function isLiteral( node: Node -): node is NilLiteral | DotsLiteral | BooleanLiteral | NumericLiteral | StringLiteral { +): node is NilLiteral | DotsLiteral | ArgLiteral | BooleanLiteral | NumericLiteral | StringLiteral { return ( isNilLiteral(node) || isDotsLiteral(node) || + isArgLiteral(node) || isBooleanLiteral(node) || isNumericLiteral(node) || isStringLiteral(node) @@ -802,6 +831,7 @@ export function createTableIndexExpression( } export type AssignmentLeftHandSideExpression = Identifier | TableIndexExpression; + export function isAssignmentLeftHandSideExpression(node: Node): node is AssignmentLeftHandSideExpression { return isIdentifier(node) || isTableIndexExpression(node); } @@ -828,3 +858,43 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr (expression.flags & NodeFlags.Inline) !== 0 ); } + +export type ParenthesizedExpression = Expression & { + expression: Expression; +}; + +export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { + return node.kind === SyntaxKind.ParenthesizedExpression; +} + +export function createParenthesizedExpression(expression: Expression, tsOriginal?: ts.Node): ParenthesizedExpression { + const parenthesizedExpression = createNode( + SyntaxKind.ParenthesizedExpression, + tsOriginal + ) as ParenthesizedExpression; + parenthesizedExpression.expression = expression; + return parenthesizedExpression; +} + +export type ConditionalExpression = Expression & { + condition: Expression; + whenTrue: Expression; + whenFalse: Expression; +}; + +export function isConditionalExpression(node: Node): node is ConditionalExpression { + return node.kind === SyntaxKind.ConditionalExpression; +} + +export function createConditionalExpression( + condition: Expression, + whenTrue: Expression, + whenFalse: Expression, + tsOriginal?: ts.Node +): ConditionalExpression { + const conditionalExpression = createNode(SyntaxKind.ConditionalExpression, tsOriginal) as ConditionalExpression; + conditionalExpression.condition = condition; + conditionalExpression.whenTrue = whenTrue; + conditionalExpression.whenFalse = whenFalse; + return conditionalExpression; +} diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7780a35eb..6320bc99c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,11 +1,15 @@ import * as path from "path"; import { EmitHost } from "./transpilation"; import * as lua from "./LuaAST"; +import { LuaTarget } from "./CompilerOptions"; +import { getOrUpdate } from "./utils"; export enum LuaLibFeature { + ArrayAt = "ArrayAt", ArrayConcat = "ArrayConcat", ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", + ArrayFill = "ArrayFill", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", ArrayFind = "ArrayFind", @@ -30,14 +34,22 @@ export enum LuaLibFeature { ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", + ArrayToReversed = "ArrayToReversed", + ArrayToSorted = "ArrayToSorted", + ArrayToSpliced = "ArrayToSpliced", + ArrayWith = "ArrayWith", Await = "Await", Class = "Class", ClassExtends = "ClassExtends", CloneDescriptor = "CloneDescriptor", + CountVarargs = "CountVarargs", Decorate = "Decorate", + DecorateLegacy = "DecorateLegacy", DecorateParam = "DecorateParam", Delete = "Delete", DelegatedYield = "DelegatedYield", + DescriptorGet = "DescriptorGet", + DescriptorSet = "DescriptorSet", Error = "Error", FunctionBind = "FunctionBind", Generator = "Generator", @@ -46,19 +58,28 @@ export enum LuaLibFeature { Iterator = "Iterator", LuaIteratorSpread = "LuaIteratorSpread", Map = "Map", + MapGroupBy = "MapGroupBy", + Match = "Match", MathAtan2 = "MathAtan2", + MathModf = "MathModf", MathSign = "MathSign", + MathTrunc = "MathTrunc", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", + NumberIsInteger = "NumberIsInteger", NumberIsNaN = "NumberIsNaN", + NumberParseInt = "ParseInt", + NumberParseFloat = "ParseFloat", NumberToString = "NumberToString", + NumberToFixed = "NumberToFixed", ObjectAssign = "ObjectAssign", ObjectDefineProperty = "ObjectDefineProperty", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors", + ObjectGroupBy = "ObjectGroupBy", ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", @@ -99,42 +120,79 @@ export enum LuaLibFeature { SymbolRegistry = "SymbolRegistry", TypeOf = "TypeOf", Unpack = "Unpack", + Using = "Using", + UsingAsync = "UsingAsync", } export interface LuaLibFeatureInfo { dependencies?: LuaLibFeature[]; exports: string[]; } + export type LuaLibModulesInfo = Record; +export function resolveLuaLibDir(luaTarget: LuaTarget) { + const luaLibDir = luaTarget === LuaTarget.Lua50 ? "5.0" : "universal"; + return path.resolve(__dirname, path.join("..", "dist", "lualib", luaLibDir)); +} + export const luaLibModulesInfoFileName = "lualib_module_info.json"; -let luaLibModulesInfo: LuaLibModulesInfo | undefined; -export function getLuaLibModulesInfo(emitHost: EmitHost): LuaLibModulesInfo { - if (luaLibModulesInfo === undefined) { - const lualibPath = path.resolve(__dirname, `../dist/lualib/${luaLibModulesInfoFileName}`); +const luaLibModulesInfo = new Map(); + +export function getLuaLibModulesInfo(luaTarget: LuaTarget, emitHost: EmitHost): LuaLibModulesInfo { + if (!luaLibModulesInfo.has(luaTarget)) { + const lualibPath = path.join(resolveLuaLibDir(luaTarget), luaLibModulesInfoFileName); const result = emitHost.readFile(lualibPath); if (result !== undefined) { - luaLibModulesInfo = JSON.parse(result) as LuaLibModulesInfo; + luaLibModulesInfo.set(luaTarget, JSON.parse(result) as LuaLibModulesInfo); } else { throw new Error(`Could not load lualib dependencies from '${lualibPath}'`); } } - return luaLibModulesInfo; + return luaLibModulesInfo.get(luaTarget)!; } -export function readLuaLibFeature(feature: LuaLibFeature, emitHost: EmitHost): string { - const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - const luaLibFeature = emitHost.readFile(featurePath); - if (luaLibFeature === undefined) { - throw new Error(`Could not load lualib feature from '${featurePath}'`); +// This caches the names of lualib exports to their LuaLibFeature, avoiding a linear search for every lookup +const lualibExportToFeature = new Map>(); + +export function getLuaLibExportToFeatureMap( + luaTarget: LuaTarget, + emitHost: EmitHost +): ReadonlyMap { + if (!lualibExportToFeature.has(luaTarget)) { + const luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost); + const map = new Map(); + for (const [feature, info] of Object.entries(luaLibModulesInfo)) { + for (const exportName of info.exports) { + map.set(exportName, feature as LuaLibFeature); + } + } + lualibExportToFeature.set(luaTarget, map); } - return luaLibFeature; + + return lualibExportToFeature.get(luaTarget)!; +} + +const lualibFeatureCache = new Map>(); + +export function readLuaLibFeature(feature: LuaLibFeature, luaTarget: LuaTarget, emitHost: EmitHost): string { + const featureMap = getOrUpdate(lualibFeatureCache, luaTarget, () => new Map()); + if (!featureMap.has(feature)) { + const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`); + const luaLibFeature = emitHost.readFile(featurePath); + if (luaLibFeature === undefined) { + throw new Error(`Could not load lualib feature from '${featurePath}'`); + } + featureMap.set(feature, luaLibFeature); + } + return featureMap.get(feature)!; } export function resolveRecursiveLualibFeatures( features: Iterable, + luaTarget: LuaTarget, emitHost: EmitHost, - luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModulesInfo(emitHost) + luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost) ): LuaLibFeature[] { const loadedFeatures = new Set(); const result: LuaLibFeature[] = []; @@ -158,28 +216,31 @@ export function resolveRecursiveLualibFeatures( return result; } -export function loadInlineLualibFeatures(features: Iterable, emitHost: EmitHost): string { - let result = ""; - - for (const feature of resolveRecursiveLualibFeatures(features, emitHost)) { - const luaLibFeature = readLuaLibFeature(feature, emitHost); - result += luaLibFeature + "\n"; - } - - return result; +export function loadInlineLualibFeatures( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): string { + return resolveRecursiveLualibFeatures(features, luaTarget, emitHost) + .map(feature => readLuaLibFeature(feature, luaTarget, emitHost)) + .join("\n"); } -export function loadImportedLualibFeatures(features: Iterable, emitHost: EmitHost): lua.Statement[] { - const luaLibModuleInfo = getLuaLibModulesInfo(emitHost); +export function loadImportedLualibFeatures( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): lua.Statement[] { + const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost); const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports); + if (imports.length === 0) { + return []; + } const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [ lua.createStringLiteral("lualib_bundle"), ]); - if (imports.length === 0) { - return []; - } const luaLibId = lua.createIdentifier("____lualib"); const importStatement = lua.createVariableDeclarationStatement(luaLibId, requireCall); @@ -196,17 +257,57 @@ export function loadImportedLualibFeatures(features: Iterable, em return statements; } -let luaLibBundleContent: string; -export function getLuaLibBundle(emitHost: EmitHost): string { - if (luaLibBundleContent === undefined) { - const lualibPath = path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"); +const luaLibBundleContent = new Map(); + +export function getLuaLibBundle(luaTarget: LuaTarget, emitHost: EmitHost): string { + const lualibPath = path.join(resolveLuaLibDir(luaTarget), "lualib_bundle.lua"); + if (!luaLibBundleContent.has(lualibPath)) { const result = emitHost.readFile(lualibPath); if (result !== undefined) { - luaLibBundleContent = result; + luaLibBundleContent.set(lualibPath, result); } else { throw new Error(`Could not load lualib bundle from '${lualibPath}'`); } } - return luaLibBundleContent; + return luaLibBundleContent.get(lualibPath) as string; +} + +export function getLualibBundleReturn(exportedValues: string[]): string { + return `\nreturn {\n${exportedValues.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; +} + +export function buildMinimalLualibBundle( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): string { + const code = loadInlineLualibFeatures(features, luaTarget, emitHost); + const moduleInfo = getLuaLibModulesInfo(luaTarget, emitHost); + const exports = Array.from(features).flatMap(feature => moduleInfo[feature].exports); + + return code + getLualibBundleReturn(exports); +} + +export function findUsedLualibFeatures( + luaTarget: LuaTarget, + emitHost: EmitHost, + luaContents: string[] +): Set { + const features = new Set(); + const exportToFeatureMap = getLuaLibExportToFeatureMap(luaTarget, emitHost); + + for (const lua of luaContents) { + const regex = /^local (\w+) = ____lualib\.(\w+)$/gm; + while (true) { + const match = regex.exec(lua); + if (!match) break; + const [, localName, exportName] = match; + if (localName !== exportName) continue; + const feature = exportToFeatureMap.get(exportName); + if (feature) features.add(feature); + } + } + + return features; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 62fda173a..b0a02dfaf 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,9 +1,9 @@ import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; +import { CompilerOptions, isBundleEnabled, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; import * as lua from "./LuaAST"; -import { loadInlineLualibFeatures, LuaLibFeature, loadImportedLualibFeatures } from "./LuaLib"; +import { loadImportedLualibFeatures, loadInlineLualibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier, shouldAllowUnicode } from "./transformation/utils/safe-names"; import { EmitHost, getEmitPath } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; @@ -157,7 +157,7 @@ export class LuaPrinter { }; private static rightAssociativeOperators = new Set([lua.SyntaxKind.ConcatOperator, lua.SyntaxKind.PowerOperator]); - private currentIndent = ""; + protected currentIndent = ""; protected luaFile: string; protected relativeSourcePath: string; protected options: CompilerOptions; @@ -233,14 +233,20 @@ export class LuaPrinter { sourceChunks.push(tstlHeader); } + const luaTarget = this.options.luaTarget ?? LuaTarget.Universal; const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; - if (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) { + if ( + (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.RequireMinimal) && + file.luaLibFeatures.size > 0 + ) { // Import lualib features - sourceChunks = this.printStatementArray(loadImportedLualibFeatures(file.luaLibFeatures, this.emitHost)); + sourceChunks = this.printStatementArray( + loadImportedLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost) + ); } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features sourceChunks.push("-- Lua Library inline imports\n"); - sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost)); + sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost)); sourceChunks.push("-- End of Lua Library inline imports\n"); } @@ -390,6 +396,8 @@ export class LuaPrinter { return this.printReturnStatement(statement as lua.ReturnStatement); case lua.SyntaxKind.BreakStatement: return this.printBreakStatement(statement as lua.BreakStatement); + case lua.SyntaxKind.ContinueStatement: + return this.printContinueStatement(statement as lua.ContinueStatement); case lua.SyntaxKind.ExpressionStatement: return this.printExpressionStatement(statement as lua.ExpressionStatement); default: @@ -568,6 +576,10 @@ export class LuaPrinter { return this.createSourceNode(statement, this.indent("break")); } + public printContinueStatement(statement: lua.ContinueStatement): SourceNode { + return this.createSourceNode(statement, this.indent("continue")); + } + public printExpressionStatement(statement: lua.ExpressionStatement): SourceNode { return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]); } @@ -583,6 +595,8 @@ export class LuaPrinter { return this.printNilLiteral(expression as lua.NilLiteral); case lua.SyntaxKind.DotsKeyword: return this.printDotsLiteral(expression as lua.DotsLiteral); + case lua.SyntaxKind.ArgKeyword: + return this.printArgLiteral(expression as lua.ArgLiteral); case lua.SyntaxKind.TrueKeyword: case lua.SyntaxKind.FalseKeyword: return this.printBooleanLiteral(expression as lua.BooleanLiteral); @@ -604,6 +618,10 @@ export class LuaPrinter { return this.printIdentifier(expression as lua.Identifier); case lua.SyntaxKind.TableIndexExpression: return this.printTableIndexExpression(expression as lua.TableIndexExpression); + case lua.SyntaxKind.ParenthesizedExpression: + return this.printParenthesizedExpression(expression as lua.ParenthesizedExpression); + case lua.SyntaxKind.ConditionalExpression: + return this.printConditionalExpression(expression as lua.ConditionalExpression); default: throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`); } @@ -625,6 +643,10 @@ export class LuaPrinter { return this.createSourceNode(expression, "..."); } + public printArgLiteral(expression: lua.ArgLiteral): SourceNode { + return this.createSourceNode(expression, "arg"); + } + public printBooleanLiteral(expression: lua.BooleanLiteral): SourceNode { return this.createSourceNode(expression, expression.kind === lua.SyntaxKind.TrueKeyword ? "true" : "false"); } @@ -810,6 +832,21 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } + public printParenthesizedExpression(expression: lua.ParenthesizedExpression) { + return this.createSourceNode(expression, ["(", this.printExpression(expression.expression), ")"]); + } + + public printConditionalExpression(expression: lua.ConditionalExpression): SourceNode { + return this.createSourceNode(expression, [ + "if ", + this.printExpression(expression.condition), + " then ", + this.printExpression(expression.whenTrue), + " else ", + this.printExpression(expression.whenFalse), + ]); + } + public printOperator(kind: lua.Operator): SourceNode { return new SourceNode(null, null, this.relativeSourcePath, LuaPrinter.operatorMap[kind]); } @@ -890,9 +927,9 @@ export class LuaPrinter { map.addMapping(currentMapping); } - for (const chunk of sourceNode.children) { + for (const chunk of sourceNode.children as SourceChunk[]) { if (typeof chunk === "string") { - const lines = (chunk as string).split("\n"); + const lines = chunk.split("\n"); if (lines.length > 1) { generatedLine += lines.length - 1; generatedColumn = 0; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index a49510780..ca4f039ad 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -147,7 +147,7 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: if (!args[i].startsWith("-")) continue; const isShorthand = !args[i].startsWith("--"); - const argumentName = args[i].substr(isShorthand ? 1 : 2); + const argumentName = args[i].substring(isShorthand ? 1 : 2); const option = optionDeclarations.find(option => { if (option.name.toLowerCase() === argumentName.toLowerCase()) return true; if (isShorthand && option.aliases) { diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index bc6fb5ae9..33e469368 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions } from "../CompilerOptions"; +import { CompilerOptions, TypeScriptToLuaOptions } from "../CompilerOptions"; import { normalizeSlashes } from "../utils"; import * as cliDiagnostics from "./diagnostics"; import { ParsedCommandLine, updateParsedConfigFile } from "./parse"; @@ -41,17 +41,93 @@ export function parseConfigFileWithSystem( commandLineOptions?: CompilerOptions, system = ts.sys ): ParsedCommandLine { + const configRootDir = path.dirname(configFileName); const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent( ts.readJsonConfigFile(configFileName, system.readFile), system, - path.dirname(configFileName), + configRootDir, commandLineOptions, configFileName ); + const cycleCache = new Set(); + const extendedTstlOptions = getExtendedTstlOptions(configFileName, configRootDir, cycleCache, system); + + parsedConfigFile.raw.tstl = Object.assign(extendedTstlOptions, parsedConfigFile.raw.tstl ?? {}); + return updateParsedConfigFile(parsedConfigFile); } +function resolveNpmModuleConfig( + moduleName: string, + configRootDir: string, + host: ts.ModuleResolutionHost +): string | undefined { + const resolved = ts.nodeNextJsonConfigResolver(moduleName, path.join(configRootDir, "tsconfig.json"), host); + if (resolved.resolvedModule) { + return resolved.resolvedModule.resolvedFileName; + } +} + +function getExtendedTstlOptions( + configFilePath: string, + configRootDir: string, + cycleCache: Set, + system: ts.System +): TypeScriptToLuaOptions { + const absolutePath = ts.pathIsAbsolute(configFilePath) + ? configFilePath + : ts.pathIsRelative(configFilePath) + ? path.resolve(configRootDir, configFilePath) + : resolveNpmModuleConfig(configFilePath, configRootDir, system); // if a path is neither relative nor absolute, it is probably a npm module + + if (!absolutePath) { + return {}; + } + + const newConfigRoot = path.dirname(absolutePath); + + if (cycleCache.has(absolutePath)) { + return {}; + } + + cycleCache.add(absolutePath); + const fileContent = system.readFile(absolutePath); + const options = {}; + + if (fileContent) { + const { config: parsedConfig } = ts.parseConfigFileTextToJson(configFilePath, fileContent) as { + config?: { + extends?: string | string[]; + tstl?: TypeScriptToLuaOptions; + }; + }; + + if (!parsedConfig) { + return {}; + } + + if (parsedConfig.extends) { + if (Array.isArray(parsedConfig.extends)) { + for (const extendedConfigFile of parsedConfig.extends) { + Object.assign( + options, + getExtendedTstlOptions(extendedConfigFile, newConfigRoot, cycleCache, system) + ); + } + } else { + Object.assign(options, getExtendedTstlOptions(parsedConfig.extends, newConfigRoot, cycleCache, system)); + } + } + + if (parsedConfig.tstl) { + Object.assign(options, parsedConfig.tstl); + } + } + + return options; +} + export function createConfigFileUpdater( optionsToExtend: CompilerOptions ): (options: ts.CompilerOptions) => ts.Diagnostic[] { @@ -61,16 +137,7 @@ export function createConfigFileUpdater( if (!configFile || !configFilePath) return []; if (!configFileMap.has(configFile)) { - const parsedConfigFile = updateParsedConfigFile( - ts.parseJsonSourceFileConfigFileContent( - configFile, - ts.sys, - path.dirname(configFilePath), - optionsToExtend, - configFilePath - ) - ); - + const parsedConfigFile = parseConfigFileWithSystem(configFilePath, optionsToExtend, ts.sys); configFileMap.set(configFile, parsedConfigFile); } diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index 76b7e5008..79233f3df 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -2,7 +2,13 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import * as tstl from ".."; import * as path from "path"; -import { LuaLibFeature, LuaLibModulesInfo, luaLibModulesInfoFileName, resolveRecursiveLualibFeatures } from "../LuaLib"; +import { + getLualibBundleReturn, + LuaLibFeature, + LuaLibModulesInfo, + luaLibModulesInfoFileName, + resolveRecursiveLualibFeatures, +} from "../LuaLib"; import { EmitHost, ProcessedFile } from "../transpilation/utils"; import { isExportAlias, @@ -42,17 +48,28 @@ class LuaLibPlugin implements tstl.Plugin { emitBOM ); + // Flatten the output folder structure; we do not want to keep the target-specific directories + for (const file of result) { + let outPath = file.fileName; + while (outPath.includes("lualib") && path.basename(path.dirname(outPath)) !== "lualib") { + const upOne = path.join(path.dirname(outPath), "..", path.basename(outPath)); + outPath = path.normalize(upOne); + } + file.fileName = outPath; + } + // Create map of result files keyed by their 'lualib name' const exportedLualibFeatures = new Map(result.map(f => [path.basename(f.fileName).split(".")[0], f.code])); // Figure out the order required in the bundle by recursively resolving all dependency features const allFeatures = Object.values(LuaLibFeature) as LuaLibFeature[]; - const orderedFeatures = resolveRecursiveLualibFeatures(allFeatures, emitHost, luaLibModuleInfo); + const luaTarget = options.luaTarget ?? tstl.LuaTarget.Universal; + const orderedFeatures = resolveRecursiveLualibFeatures(allFeatures, luaTarget, emitHost, luaLibModuleInfo); // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLibFeature[f])).join("\n"); const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports); - lualibBundle += `\nreturn {\n${exports.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; + lualibBundle += getLualibBundleReturn(exports); result.push({ fileName: "lualib_bundle.lua", code: lualibBundle }); return diagnostics; @@ -104,7 +121,7 @@ class LuaLibPlugin implements tstl.Plugin { } return statement; }) - .filter(statement => statement !== undefined) as tstl.Statement[]; + .filter(statement => statement !== undefined); const exportNames = filteredStatements.filter(isExportAssignment).map(s => s.left[0].index.value); if (!filteredStatements.every(isExportAssignment)) { @@ -168,5 +185,4 @@ class LuaLibPrinter extends tstl.LuaPrinter { } const pluginInstance = new LuaLibPlugin(); -// eslint-disable-next-line import/no-default-export export default pluginInstance; diff --git a/src/lualib/5.0/CountVarargs.ts b/src/lualib/5.0/CountVarargs.ts new file mode 100644 index 000000000..34467ebd4 --- /dev/null +++ b/src/lualib/5.0/CountVarargs.ts @@ -0,0 +1,7 @@ +/** @noSelfInFile */ + +export function __TS__CountVarargs(...args: T[]): number { + // select() is not available in Lua 5.0. In this version, the arg table + // includes trailing nils. + return args.length; +} diff --git a/src/lualib/5.0/Match.ts b/src/lualib/5.0/Match.ts new file mode 100644 index 000000000..3b1705939 --- /dev/null +++ b/src/lualib/5.0/Match.ts @@ -0,0 +1,12 @@ +/** @noSelfInFile */ + +export function __TS__Match(s: string, pattern: string, init?: number): LuaMultiReturn { + const [start, end, ...captures] = string.find(s, pattern, init); + if (start === undefined || end === undefined) { + return $multi(); + } else if (captures.length <= 0) { + return $multi(s.slice(start - 1, end)); + } else { + return $multi(...(captures as string[])); + } +} diff --git a/src/lualib/5.0/MathModf.ts b/src/lualib/5.0/MathModf.ts new file mode 100644 index 000000000..ec816ebe0 --- /dev/null +++ b/src/lualib/5.0/MathModf.ts @@ -0,0 +1,6 @@ +/** @noSelfInFile */ + +export function __TS__MathModf(x: number): LuaMultiReturn<[number, number]> { + const integral = x > 0 ? Math.floor(x) : Math.ceil(x); + return $multi(integral, x - integral); +} diff --git a/src/lualib/5.0/SparseArraySpread.ts b/src/lualib/5.0/SparseArraySpread.ts new file mode 100644 index 000000000..9a11f3cc9 --- /dev/null +++ b/src/lualib/5.0/SparseArraySpread.ts @@ -0,0 +1,6 @@ +import { __TS__SparseArray } from "./SparseArray"; +import { __TS__Unpack } from "./Unpack"; + +export function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { + return __TS__Unpack(sparseArray, 1, sparseArray.sparseLength); +} diff --git a/src/lualib/5.0/Unpack.ts b/src/lualib/5.0/Unpack.ts new file mode 100644 index 000000000..a84416233 --- /dev/null +++ b/src/lualib/5.0/Unpack.ts @@ -0,0 +1,16 @@ +/** @noSelfInFile */ + +// We're not interested in emulating all of the behaviors of unpack() from Lua +// 5.1, just the ones needed by other parts of lualib. +export function __TS__Unpack(list: T[], i: number, j?: number): LuaMultiReturn { + if (i === 1 && j === undefined) { + return unpack(list); + } else { + j ??= list.length; + const slice: T[] = []; + for (let n = i; n <= j; n++) { + slice[n - i] = list[n - 1]; // We don't want to add 1 to the index into list. + } + return $multi(...slice); + } +} diff --git a/src/lualib/ArrayAt.ts b/src/lualib/ArrayAt.ts new file mode 100644 index 000000000..32e4ea2b4 --- /dev/null +++ b/src/lualib/ArrayAt.ts @@ -0,0 +1,13 @@ +// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.at +// Technically the specs also allow non-numeric types to be passed as index. +// However, TypeScript types the `Array.at` index param as number so we also expect only numbers +// This behaviour also matches the implementation of other Array functions in lualib. +export function __TS__ArrayAt(this: T[], relativeIndex: number): T | undefined { + const absoluteIndex = relativeIndex < 0 ? this.length + relativeIndex : relativeIndex; + + if (absoluteIndex >= 0 && absoluteIndex < this.length) { + return this[absoluteIndex]; + } + + return undefined; +} diff --git a/src/lualib/ArrayFill.ts b/src/lualib/ArrayFill.ts new file mode 100644 index 000000000..a1654114a --- /dev/null +++ b/src/lualib/ArrayFill.ts @@ -0,0 +1,19 @@ +// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.fill +export function __TS__ArrayFill(this: T[], value: T, start?: number, end?: number): T[] { + let relativeStart = start ?? 0; + let relativeEnd = end ?? this.length; + + if (relativeStart < 0) { + relativeStart += this.length; + } + + if (relativeEnd < 0) { + relativeEnd += this.length; + } + + for (let i = relativeStart; i < relativeEnd; i++) { + this[i] = value; + } + + return this; +} diff --git a/src/lualib/ArrayFrom.ts b/src/lualib/ArrayFrom.ts index fda55580f..3742d7949 100644 --- a/src/lualib/ArrayFrom.ts +++ b/src/lualib/ArrayFrom.ts @@ -11,7 +11,7 @@ function arrayLikeStep(this: ArrayLike, index: number): LuaMultiReturn< const arrayLikeIterator: ( this: void, arr: ArrayLike | Iterable -) => LuaIterable> = (arr => { +) => LuaIterable> = ((arr: any) => { if (typeof arr.length === "number") return $multi(arrayLikeStep, arr, 0); return __TS__Iterator(arr); }) as any; @@ -28,8 +28,9 @@ export function __TS__ArrayFrom( result.push(v); } } else { - for (const [i, v] of arrayLikeIterator(arrayLike)) { - result.push(mapFn.call(thisArg, v, i - 1)); + let i = 0; + for (const [, v] of arrayLikeIterator(arrayLike)) { + result.push(mapFn.call(thisArg, v, i++)); } } return result; diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index eb26a9731..cc569409a 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,3 +1,5 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduce( this: TElement[], @@ -7,10 +9,10 @@ export function __TS__ArrayReduce( const len = this.length; let k = 0; - let accumulator: TAccumulator = undefined; + let accumulator: TAccumulator = undefined!; // Check if initial value is present in function call - if (select("#", ...initial) !== 0) { + if (__TS__CountVarargs(...initial) !== 0) { [accumulator] = [...initial]; } else if (len > 0) { accumulator = this[0] as unknown as TAccumulator; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index e32e87e79..2316fa048 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,3 +1,5 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduceRight( this: TElement[], @@ -7,10 +9,10 @@ export function __TS__ArrayReduceRight( const len = this.length; let k = len - 1; - let accumulator: TAccumulator = undefined; + let accumulator: TAccumulator = undefined!; // Check if initial value is present in function call - if (select("#", ...initial) !== 0) { + if (__TS__CountVarargs(...initial) !== 0) { [accumulator] = [...initial]; } else if (len > 0) { accumulator = this[k] as unknown as TAccumulator; diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 4ec78715d..6f4de4b18 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -9,7 +9,7 @@ export function __TS__ArraySetLength(this: T[], length: number): number { throw `invalid array length: ${length}`; } for (const i of $range(length + 1, this.length)) { - this[i - 1] = undefined; + this[i - 1] = undefined!; } return length; } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index dc69e16fb..24b5264b2 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,8 +1,10 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { const len = this.length; - const actualArgumentCount = select("#", ...args); + const actualArgumentCount = __TS__CountVarargs(...args); let start = args[0] as number; const deleteCount = args[1] as number; @@ -56,11 +58,11 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { if (this[from - 1]) { this[to - 1] = this[from - 1]; } else { - this[to - 1] = undefined; + this[to - 1] = undefined!; } } for (const k of $range(len - actualDeleteCount + itemCount + 1, len)) { - this[k - 1] = undefined; + this[k - 1] = undefined!; } } else if (itemCount > actualDeleteCount) { for (const k of $range(len - actualDeleteCount, start + 1, -1)) { @@ -70,7 +72,7 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { if (this[from - 1]) { this[to - 1] = this[from - 1]; } else { - this[to - 1] = undefined; + this[to - 1] = undefined!; } } } @@ -82,7 +84,7 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { } for (const k of $range(this.length, len - actualDeleteCount + itemCount + 1, -1)) { - this[k - 1] = undefined; + this[k - 1] = undefined!; } return out; diff --git a/src/lualib/ArrayToReversed.ts b/src/lualib/ArrayToReversed.ts new file mode 100644 index 000000000..50b58855f --- /dev/null +++ b/src/lualib/ArrayToReversed.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToReversed(this: T[]): T[] { + const copy = [...this]; + copy.reverse(); + return copy; +} diff --git a/src/lualib/ArrayToSorted.ts b/src/lualib/ArrayToSorted.ts new file mode 100644 index 000000000..47c033d2d --- /dev/null +++ b/src/lualib/ArrayToSorted.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToSorted(this: T[], compareFn?: (a: T, b: T) => number): T[] { + const copy = [...this]; + copy.sort(compareFn); + return copy; +} diff --git a/src/lualib/ArrayToSpliced.ts b/src/lualib/ArrayToSpliced.ts new file mode 100644 index 000000000..298ed8035 --- /dev/null +++ b/src/lualib/ArrayToSpliced.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToSpliced(this: T[], start: number, deleteCount: number, ...items: T[]): T[] { + const copy = [...this]; + copy.splice(start, deleteCount, ...items); + return copy; +} diff --git a/src/lualib/ArrayWith.ts b/src/lualib/ArrayWith.ts new file mode 100644 index 000000000..90d818a5a --- /dev/null +++ b/src/lualib/ArrayWith.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayWith(this: T[], index: number, value: T): T[] { + const copy = [...this]; + copy[index] = value; + return copy; +} diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index 7093a617f..7f6a345ee 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -16,44 +16,54 @@ import { __TS__Promise } from "./Promise"; +const coroutine = _G.coroutine ?? {}; +const cocreate = coroutine.create; +const coresume = coroutine.resume; +const costatus = coroutine.status; +const coyield = coroutine.yield; + +// Be extremely careful editing this function. A single non-tail function call may ruin chained awaits performance // eslint-disable-next-line @typescript-eslint/promise-function-async export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { return new Promise((resolve, reject) => { let resolved = false; - const asyncCoroutine = coroutine.create(generator); + const asyncCoroutine = cocreate(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: unknown) { - const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); + function fulfilled(value: unknown): void { + const [success, resultOrError] = coresume(asyncCoroutine, value); if (success) { - step(resultOrError); - } else { - reject(resultOrError); + // `step` never throws. Tail call return is important! + return step(resultOrError); } + // `reject` should never throw. Tail call return is important! + return reject(resultOrError); } - function step(result: unknown) { - if (resolved) return; - if (coroutine.status(asyncCoroutine) === "dead") { - resolve(result); - } else { - adopt(result).then(fulfilled, reject); + + function step(this: void, result: unknown): void { + if (resolved) { + return; } + if (costatus(asyncCoroutine) === "dead") { + // `resolve` never throws. Tail call return is important! + return resolve(result); + } + // We cannot use `then` because we need to avoid calling `coroutine.resume` from inside `pcall` + // `fulfilled` and `reject` should never throw. Tail call return is important! + return __TS__Promise.resolve(result).addCallbacks(fulfilled, reject); } - const [success, resultOrError] = coroutine.resume(asyncCoroutine, (v: unknown) => { + + const [success, resultOrError] = coresume(asyncCoroutine, (v: unknown) => { resolved = true; - adopt(v).then(resolve, reject); + return __TS__Promise.resolve(v).addCallbacks(resolve, reject); }); if (success) { - step(resultOrError); + return step(resultOrError); } else { - reject(resultOrError); + return reject(resultOrError); } }); } export function __TS__Await(this: void, thing: unknown) { - return coroutine.yield(thing); + return coyield(thing); } diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 50510f12c..fd65f44e8 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,47 +1,20 @@ /** - * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 + * TypeScript 5.0 decorators */ -import { __TS__ObjectGetOwnPropertyDescriptor } from "./ObjectGetOwnPropertyDescriptor"; -import { __TS__SetDescriptor } from "./SetDescriptor"; import { Decorator } from "./Decorator"; -export function __TS__Decorate( - this: void, - decorators: Array>, - target: TTarget, - key?: TKey, - desc?: any +export function __TS__Decorate( + this: TClass, + originalValue: TTarget, + decorators: Array>, + context: DecoratorContext ): TTarget { - let result = target; + let result = originalValue; for (let i = decorators.length; i >= 0; i--) { const decorator = decorators[i]; - if (decorator) { - const oldResult = result; - - if (key === undefined) { - result = decorator(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); - } - - result = result || oldResult; + if (decorator !== undefined) { + result = decorator.call(this, result, context) ?? result; } } diff --git a/src/lualib/DecorateLegacy.ts b/src/lualib/DecorateLegacy.ts new file mode 100644 index 000000000..0369623d3 --- /dev/null +++ b/src/lualib/DecorateLegacy.ts @@ -0,0 +1,54 @@ +/** + * Old-style decorators, activated by enabling the experimentalDecorators flag + */ +import { __TS__ObjectGetOwnPropertyDescriptor } from "./ObjectGetOwnPropertyDescriptor"; +import { __TS__SetDescriptor } from "./SetDescriptor"; + +export type LegacyDecorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; + +export function __TS__DecorateLegacy( + this: void, + decorators: Array>, + target: TTarget, + key?: TKey, + desc?: any +): TTarget { + let result = target; + + for (let i = decorators.length; i >= 0; i--) { + const decorator = decorators[i]; + if (decorator !== undefined) { + const oldResult = result; + + if (key === undefined) { + result = decorator(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); + } + + result = result || oldResult; + } + } + + return result; +} diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index f6c405015..0165294b2 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -1,14 +1,14 @@ -import { Decorator } from "./Decorator"; +import type { LegacyDecorator } from "./DecorateLegacy"; type ParamDecorator = ( target: TTarget, - key: TKey, + key: TKey | undefined, index: number ) => TTarget; export function __TS__DecorateParam( this: void, paramIndex: number, decorator: ParamDecorator -): Decorator { +): LegacyDecorator { return (target: TTarget, key?: TKey) => decorator(target, key, paramIndex); } diff --git a/src/lualib/Decorator.d.ts b/src/lualib/Decorator.d.ts index 338b11b3f..d8f84febf 100644 --- a/src/lualib/Decorator.d.ts +++ b/src/lualib/Decorator.d.ts @@ -1,5 +1 @@ -export type Decorator = ( - target: TTarget, - key?: TKey, - descriptor?: PropertyDescriptor -) => TTarget; +export type Decorator = (target: TTarget, context: DecoratorContext) => TTarget; diff --git a/src/lualib/DescriptorGet.ts b/src/lualib/DescriptorGet.ts new file mode 100644 index 000000000..034a5825a --- /dev/null +++ b/src/lualib/DescriptorGet.ts @@ -0,0 +1,25 @@ +const getmetatable = _G.getmetatable; +const rawget = _G.rawget; + +export function __TS__DescriptorGet(this: any, metatable: any, key: string): void { + while (metatable) { + const rawResult = rawget(metatable, key as any); + if (rawResult !== undefined) { + return rawResult; + } + + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor !== undefined) { + if (descriptor.get) { + return descriptor.get.call(this); + } + + return descriptor.value; + } + } + + metatable = getmetatable(metatable); + } +} diff --git a/src/lualib/DescriptorSet.ts b/src/lualib/DescriptorSet.ts new file mode 100644 index 000000000..bb50ca4d3 --- /dev/null +++ b/src/lualib/DescriptorSet.ts @@ -0,0 +1,28 @@ +const getmetatable = _G.getmetatable; +const rawget = _G.rawget; +const rawset = _G.rawset; + +export function __TS__DescriptorSet(this: any, metatable: any, key: string, value: any): void { + while (metatable) { + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor !== undefined) { + 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; + } + } + + metatable = getmetatable(metatable); + } + + rawset(this, key, value); +} diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index 2ebb2aaaa..ae5deb05b 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -1,9 +1,14 @@ +import { __TS__New } from "./New"; + interface ErrorType { name: string; new (...args: any[]): Error; } -function getErrorStack(constructor: () => any): string { +function getErrorStack(constructor: () => any): string | undefined { + // If debug module is not available in this environment, don't bother trying to get stack trace + if (debug === undefined) return undefined; + let level = 1; while (true) { const info = debug.getinfo(level, "f"); @@ -17,14 +22,26 @@ function getErrorStack(constructor: () => any): string { } } - return debug.traceback(undefined, level); + if (_VERSION.includes("Lua 5.0")) { + return debug.traceback(`[Level ${level}]`); + // @ts-ignore Fails when compiled with Lua 5.0 types + } else if (_VERSION === "Lua 5.1") { + // Lua 5.1 and LuaJIT have a bug where it's not possible to specify the level without a message. + // @ts-ignore Fails when compiled with Lua 5.0 types + return string.sub(debug.traceback("", level), 2); + } else { + // @ts-ignore Fails when compiled with Lua 5.0 types + return debug.traceback(undefined, level); + } } function wrapErrorToString(getDescription: (this: T) => string): (this: T) => string { return function (this: Error): string { - const description = getDescription.call(this); + const description = getDescription.call(this as T); const caller = debug.getinfo(3, "f"); - if (_VERSION === "Lua 5.1" || (caller && caller.func !== error)) { + // @ts-ignore Fails when compiled with Lua 5.0 types + const isClassicLua = _VERSION.includes("Lua 5.0"); + if (isClassicLua || (caller && caller.func !== error)) { return description; } else { return `${description}\n${this.stack}`; @@ -42,12 +59,12 @@ function initErrorClass(Type: ErrorType, name: string): any { export const Error: ErrorConstructor = initErrorClass( class implements Error { public name = "Error"; - public stack: string; + public stack?: string; constructor(public message = "") { - this.stack = getErrorStack((this.constructor as any).new); + this.stack = getErrorStack(__TS__New as any); const metatable = getmetatable(this); - if (!metatable.__errorToStringPatched) { + if (metatable && !metatable.__errorToStringPatched) { metatable.__errorToStringPatched = true; metatable.__tostring = wrapErrorToString(metatable.__tostring); } diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index 0122602a2..c17aab8c7 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -1,4 +1,6 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { GeneratorIterator } from "./GeneratorIterator"; +import { __TS__Unpack } from "./Unpack"; function generatorIterator(this: GeneratorIterator) { return this; @@ -16,10 +18,10 @@ function generatorNext(this: GeneratorIterator, ...args: any[]) { export function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { return function (this: void, ...args: any[]): GeneratorIterator { - const argsLength = select("#", ...args); + const argsLength = __TS__CountVarargs(...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(...__TS__Unpack(args, 1, argsLength))), [Symbol.iterator]: generatorIterator, next: generatorNext, }; diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index a469cc35f..317c0b794 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -5,7 +5,7 @@ export function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: Lu if (classTbl[Symbol.hasInstance] !== undefined) { // eslint-disable-next-line no-implicit-coercion - return !!classTbl[Symbol.hasInstance](obj); + return !!classTbl[Symbol.hasInstance]!(obj); } if (typeof obj === "object") { @@ -14,7 +14,7 @@ export function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: Lu if (luaClass === classTbl) { return true; } - luaClass = luaClass.____super; + luaClass = luaClass.____super!; } } return false; diff --git a/src/lualib/LuaIteratorSpread.ts b/src/lualib/LuaIteratorSpread.ts index abe18e454..b846bc535 100644 --- a/src/lualib/LuaIteratorSpread.ts +++ b/src/lualib/LuaIteratorSpread.ts @@ -9,5 +9,5 @@ export function __TS__LuaIteratorSpread( results.push([key, value]); [key, value] = this(state, key); } - return $multi(...results); + return $multi(...results) as LuaMultiReturn>; } diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index fb1382fc3..16fa7e453 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -1,4 +1,4 @@ -export class Map { +export class Map { public static [Symbol.species] = Map; public [Symbol.toStringTag] = "Map"; @@ -52,24 +52,24 @@ export class Map { // Do order bookkeeping const next = this.nextKey.get(key); const previous = this.previousKey.get(key); - if (next && previous) { + if (next !== undefined && previous !== undefined) { this.nextKey.set(previous, next); this.previousKey.set(next, previous); - } else if (next) { + } else if (next !== undefined) { this.firstKey = next; - this.previousKey.set(next, undefined); - } else if (previous) { + this.previousKey.set(next, undefined!); + } else if (previous !== undefined) { this.lastKey = previous; - this.nextKey.set(previous, undefined); + this.nextKey.set(previous, undefined!); } else { this.firstKey = undefined; this.lastKey = undefined; } - this.nextKey.set(key, undefined); - this.previousKey.set(key, undefined); + this.nextKey.set(key, undefined!); + this.previousKey.set(key, undefined!); } - this.items.set(key, undefined); + this.items.set(key, undefined!); return contains; } @@ -100,8 +100,8 @@ export class Map { this.firstKey = key; this.lastKey = key; } else if (isNewValue) { - this.nextKey.set(this.lastKey, key); - this.previousKey.set(key, this.lastKey); + this.nextKey.set(this.lastKey!, key); + this.previousKey.set(key, this.lastKey!); this.lastKey = key; } @@ -120,8 +120,8 @@ export class Map { return this; }, next(): IteratorResult<[K, V]> { - const result = { done: !key, value: [key, items.get(key)] as [K, V] }; - key = nextKey.get(key); + const result = { done: !key, value: [key, items.get(key!)] as [K, V] }; + key = nextKey.get(key!); return result; }, }; @@ -136,8 +136,8 @@ export class Map { }, next(): IteratorResult { const result = { done: !key, value: key }; - key = nextKey.get(key); - return result; + key = nextKey.get(key!); + return result as IteratorResult; }, }; } @@ -150,8 +150,8 @@ export class Map { return this; }, next(): IteratorResult { - const result = { done: !key, value: items.get(key) }; - key = nextKey.get(key); + const result = { done: !key, value: items.get(key!) }; + key = nextKey.get(key!); return result; }, }; diff --git a/src/lualib/MapGroupBy.ts b/src/lualib/MapGroupBy.ts new file mode 100644 index 000000000..d3e079192 --- /dev/null +++ b/src/lualib/MapGroupBy.ts @@ -0,0 +1,22 @@ +export function __TS__MapGroupBy( + this: void, + items: Iterable, + keySelector: (item: T, index: number) => K +): Map { + const result = new Map(); + + let i = 0; + for (const item of items) { + const key = keySelector(item, i); + + if (result.has(key)) { + result.get(key)!.push(item); + } else { + result.set(key, [item]); + } + + i++; + } + + return result; +} diff --git a/src/lualib/MathSign.ts b/src/lualib/MathSign.ts index f3be69e8d..629895a11 100644 --- a/src/lualib/MathSign.ts +++ b/src/lualib/MathSign.ts @@ -1,9 +1,15 @@ +// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.sign + +import { __TS__NumberIsNaN } from "./NumberIsNaN"; + export function __TS__MathSign(this: void, val: number) { - if (val > 0) { - return 1; - } else if (val < 0) { + if (__TS__NumberIsNaN(val) || val === 0) { + return val; + } + + if (val < 0) { return -1; } - return 0; + return 1; } diff --git a/src/lualib/MathTrunc.ts b/src/lualib/MathTrunc.ts new file mode 100644 index 000000000..f244c2147 --- /dev/null +++ b/src/lualib/MathTrunc.ts @@ -0,0 +1,10 @@ +// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.trunc + +import { __TS__NumberIsFinite } from "./NumberIsFinite"; +export function __TS__MathTrunc(this: void, val: number) { + if (!__TS__NumberIsFinite(val) || val === 0) { + return val; + } + + return val > 0 ? math.floor(val) : math.ceil(val); +} diff --git a/src/lualib/NumberIsInteger.ts b/src/lualib/NumberIsInteger.ts new file mode 100644 index 000000000..275fcae03 --- /dev/null +++ b/src/lualib/NumberIsInteger.ts @@ -0,0 +1,6 @@ +import { __TS__NumberIsFinite } from "./NumberIsFinite"; + +/// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.isinteger +export function __TS__NumberIsInteger(this: void, value: unknown): boolean { + return __TS__NumberIsFinite(value) && math.floor(value as number) === (value as number); +} diff --git a/src/lualib/NumberToFixed.ts b/src/lualib/NumberToFixed.ts new file mode 100644 index 000000000..355da13f0 --- /dev/null +++ b/src/lualib/NumberToFixed.ts @@ -0,0 +1,14 @@ +/// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tofixed +export function __TS__NumberToFixed(this: number, fractionDigits?: number): string { + if (Math.abs(this) >= 1e21 || this !== this) { + return this.toString(); + } + const f = Math.floor(fractionDigits ?? 0); + // reduced to 99 as string.format only supports 2-digit numbers + if (f < 0 || f > 99) { + throw "toFixed() digits argument must be between 0 and 99"; + } + // throws "invalid format (width or precision too long)" if strlen > 99 + // if (f < 80) return fmt; else try {return fmt} catch(_) { throw "toFixed() digits argument..." } + return string.format(`%.${f}f`, this); +} diff --git a/src/lualib/NumberToString.ts b/src/lualib/NumberToString.ts index 1e1a1ad03..6cdbaadc3 100644 --- a/src/lualib/NumberToString.ts +++ b/src/lualib/NumberToString.ts @@ -1,3 +1,5 @@ +import { __TS__MathModf } from "./MathModf"; + const radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tostring @@ -11,7 +13,7 @@ export function __TS__NumberToString(this: number, radix?: number): string { throw "toString() radix argument must be between 2 and 36"; } - let [integer, fraction] = math.modf(Math.abs(this)); + let [integer, fraction] = __TS__MathModf(Math.abs(this)); let result = ""; if (radix === 8) { diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index 4fd4aff0d..a7f691433 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,5 +1,4 @@ // https://tc39.github.io/ecma262/#sec-object.assign -// eslint-disable-next-line @typescript-eslint/ban-types export function __TS__ObjectAssign(this: void, target: T, ...sources: T[]): T { for (const i of $range(1, sources.length)) { const source = sources[i - 1]; diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index 6b275bfa0..c0dc40a1f 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,6 +1,5 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -// eslint-disable-next-line @typescript-eslint/ban-types import { __TS__SetDescriptor } from "./SetDescriptor"; export function __TS__ObjectDefineProperty( @@ -26,9 +25,9 @@ export function __TS__ObjectDefineProperty( 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, + configurable: desc.configurable ?? valueExists, + enumerable: desc.enumerable ?? valueExists, + writable: desc.writable ?? valueExists, value: desc.value !== undefined ? desc.value : value, }; } diff --git a/src/lualib/ObjectEntries.ts b/src/lualib/ObjectEntries.ts index 5daeee1e0..20fde96ad 100644 --- a/src/lualib/ObjectEntries.ts +++ b/src/lualib/ObjectEntries.ts @@ -1,5 +1,8 @@ -export function __TS__ObjectEntries(this: void, obj: any): Array { - const result = []; +export function __TS__ObjectEntries( + this: void, + obj: Record +): Array<[TKey, TValue]> { + const result: Array<[TKey, TValue]> = []; let len = 0; for (const key in obj) { len++; diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts index 1f7e660bf..975de6712 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptor.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -6,5 +6,5 @@ export function __TS__ObjectGetOwnPropertyDescriptor( const metatable = getmetatable(object); if (!metatable) return; if (!rawget(metatable, "_descriptors")) return; - return rawget(metatable, "_descriptors")[key]; + return rawget(metatable, "_descriptors")![key]; } diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts index 41d92ddfc..69d23af06 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptors.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -4,5 +4,5 @@ export function __TS__ObjectGetOwnPropertyDescriptors( ): Record { const metatable = getmetatable(object); if (!metatable) return {}; - return rawget(metatable, "_descriptors") || {}; + return rawget(metatable, "_descriptors") ?? {}; } diff --git a/src/lualib/ObjectGroupBy.ts b/src/lualib/ObjectGroupBy.ts new file mode 100644 index 000000000..6328ad2aa --- /dev/null +++ b/src/lualib/ObjectGroupBy.ts @@ -0,0 +1,22 @@ +export function __TS__ObjectGroupBy( + this: void, + items: Iterable, + keySelector: (item: T, index: number) => K +): Partial> { + const result: Partial> = {}; + + let i = 0; + for (const item of items) { + const key = keySelector(item, i); + + if (key in result) { + result[key]!.push(item); + } else { + result[key] = [item]; + } + + i++; + } + + return result; +} diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts index 94ca97429..7720acb6b 100644 --- a/src/lualib/ParseFloat.ts +++ b/src/lualib/ParseFloat.ts @@ -1,11 +1,13 @@ +import { __TS__Match } from "./Match"; + export function __TS__ParseFloat(this: void, numberString: string): number { // Check if string is infinity - const [infinityMatch] = string.match(numberString, "^%s*(-?Infinity)"); - if (infinityMatch) { + const [infinityMatch] = __TS__Match(numberString, "^%s*(-?Infinity)"); + if (infinityMatch !== undefined) { // 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]); + const number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)")[0]); return number ?? NaN; } diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index 208d84e44..c27d62662 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -1,15 +1,17 @@ +import { __TS__Match } from "./Match"; + const parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; export 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) { + const [hexMatch] = __TS__Match(numberString, "^%s*-?0[xX]"); + if (hexMatch !== undefined) { base = 16; - numberString = string.match(hexMatch, "-")[0] - ? "-" + numberString.substr(hexMatch.length) - : numberString.substr(hexMatch.length); + numberString = __TS__Match(hexMatch, "-")[0] + ? "-" + numberString.substring(hexMatch.length) + : numberString.substring(hexMatch.length); } } @@ -20,11 +22,11 @@ export function __TS__ParseInt(this: void, numberString: string, base?: number): // Calculate string match pattern to use const allowedDigits = - base <= 10 ? parseIntBasePattern.substring(0, base) : parseIntBasePattern.substr(0, 10 + 2 * (base - 10)); + base <= 10 ? parseIntBasePattern.substring(0, base) : parseIntBasePattern.substring(0, 10 + 2 * (base - 10)); const pattern = `^%s*(-?[${allowedDigits}]*)`; // Try to parse with Lua tonumber - const number = tonumber(string.match(numberString, pattern)[0], base); + const number = tonumber(__TS__Match(numberString, pattern)[0], base); if (number === undefined) { return NaN; diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index b55330713..c5b6aa2a5 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -9,109 +9,113 @@ export const enum PromiseState { Rejected, } -type FulfillCallback = (value: TData) => TResult | PromiseLike; -type RejectCallback = (reason: any) => TResult | PromiseLike; - -function promiseDeferred() { - let resolve: FulfillCallback; - let reject: RejectCallback; - const promise = new Promise((res, rej) => { +type PromiseExecutor = ConstructorParameters>[0]; +type PromiseResolve = Parameters>[0]; +type PromiseReject = Parameters>[1]; +type PromiseResolveCallback = (value: TValue) => TResult | PromiseLike; +type PromiseRejectCallback = (reason: any) => TResult | PromiseLike; + +function makeDeferredPromiseFactory(this: void) { + let resolve: PromiseResolve; + let reject: PromiseReject; + const executor: PromiseExecutor = (res, rej) => { resolve = res; reject = rej; - }); - - return { promise, resolve, reject }; + }; + return function (this: void) { + const promise = new Promise(executor); + return $multi(promise, resolve, reject); + }; } -function isPromiseLike(thing: unknown): thing is PromiseLike { - return thing instanceof __TS__Promise; +const makeDeferredPromise = makeDeferredPromiseFactory(); + +function isPromiseLike(this: void, value: unknown): value is PromiseLike { + return value instanceof __TS__Promise; } +function doNothing(): void {} + +const pcall = _G.pcall; + export class __TS__Promise implements Promise { public state = PromiseState.Pending; public value?: T; public rejectionReason?: any; - private fulfilledCallbacks: Array> = []; - private rejectedCallbacks: Array> = []; + private fulfilledCallbacks: Array> = []; + private rejectedCallbacks: PromiseReject[] = []; private finallyCallbacks: Array<() => void> = []; + // @ts-ignore 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 { + public static resolve(this: void, value: T | PromiseLike): __TS__Promise> { + if (value instanceof __TS__Promise) { + return value; + } // Create and return a promise instance that is already resolved - const promise = new __TS__Promise(() => {}); + const promise = new __TS__Promise>(doNothing); promise.state = PromiseState.Fulfilled; - promise.value = data; + promise.value = value as Awaited; return promise; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject - public static reject(this: void, reason: any): Promise { + public static reject(this: void, reason?: any): __TS__Promise { // Create and return a promise instance that is already rejected - const promise = new __TS__Promise(() => {}); + const promise = new __TS__Promise(doNothing); promise.state = 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) { + constructor(executor: PromiseExecutor) { + // Avoid unnecessary local functions allocations by using `pcall` explicitly + const [success, error] = pcall( + executor, + undefined, + v => this.resolve(v), + err => this.reject(err) + ); + if (!success) { // When a promise executor throws, the promise should be rejected with the thrown object as reason - this.reject(e); + this.reject(error); } } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then public then( - onFulfilled?: FulfillCallback, - onRejected?: RejectCallback + onFulfilled?: PromiseResolveCallback, + onRejected?: PromiseRejectCallback ): Promise { - const { promise, resolve, reject } = promiseDeferred(); - - const isFulfilled = this.state === PromiseState.Fulfilled; - const isRejected = this.state === PromiseState.Rejected; - - if (onFulfilled) { - const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); - this.fulfilledCallbacks.push(internalCallback); + const [promise, resolve, reject] = makeDeferredPromise(); - if (isFulfilled) { - // If promise already resolved, immediately call callback - internalCallback(this.value); - } - } else { + this.addCallbacks( // We always want to resolve our child promise if this promise is resolved, even if we have no handler - this.fulfilledCallbacks.push(v => resolve(v)); - } - - if (onRejected) { - const internalCallback = this.createPromiseResolvingCallback(onRejected, resolve, reject); - this.rejectedCallbacks.push(internalCallback); - - if (isRejected) { - // If promise already rejected, immediately call callback - internalCallback(this.rejectionReason); - } - } else { + onFulfilled ? this.createPromiseResolvingCallback(onFulfilled, resolve, reject) : resolve, // We always want to reject our child promise if this promise is rejected, even if we have no handler - this.rejectedCallbacks.push(err => reject(err)); - } + onRejected ? this.createPromiseResolvingCallback(onRejected, resolve, reject) : reject + ); - if (isFulfilled) { - // If promise already resolved, also resolve returned promise - resolve(this.value); - } + return promise as Promise; + } - if (isRejected) { - // If promise already rejected, also reject returned promise - reject(this.rejectionReason); + // Both callbacks should never throw! + public addCallbacks(fulfilledCallback: (value: T) => void, rejectedCallback: (rejectionReason: any) => void): void { + if (this.state === PromiseState.Fulfilled) { + // If promise already resolved, immediately call callback. We don't even need to store rejected callback + // Tail call return is important! + return fulfilledCallback(this.value!); + } + if (this.state === PromiseState.Rejected) { + // Similar thing + return rejectedCallback(this.rejectionReason); } - return promise as Promise; + this.fulfilledCallbacks.push(fulfilledCallback as any); + this.rejectedCallbacks.push(rejectedCallback); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch @@ -132,26 +136,22 @@ export class __TS__Promise implements Promise { return this; } - private resolve(data: T): void { - if (data instanceof __TS__Promise) { - data.then( + private resolve(value: T | PromiseLike): void { + if (isPromiseLike(value)) { + // Tail call return is important! + return (value as __TS__Promise).addCallbacks( v => this.resolve(v), err => this.reject(err) ); - return; } // Resolve this promise, if it is still pending. This function is passed to the constructor function. if (this.state === PromiseState.Pending) { this.state = PromiseState.Fulfilled; - this.value = data; + this.value = value; - for (const callback of this.fulfilledCallbacks) { - callback(data); - } - for (const callback of this.finallyCallbacks) { - callback(); - } + // Tail call return is important! + return this.invokeCallbacks(this.fulfilledCallbacks, value); } } @@ -161,55 +161,85 @@ export class __TS__Promise implements Promise { this.state = PromiseState.Rejected; this.rejectionReason = reason; - for (const callback of this.rejectedCallbacks) { - callback(reason); + // Tail call return is important! + return this.invokeCallbacks(this.rejectedCallbacks, reason); + } + } + + private invokeCallbacks(callbacks: ReadonlyArray<(value: T) => void>, value: T): void { + const callbacksLength = callbacks.length; + const finallyCallbacks = this.finallyCallbacks; + const finallyCallbacksLength = finallyCallbacks.length; + + if (callbacksLength !== 0) { + for (const i of $range(1, callbacksLength - 1)) { + callbacks[i - 1](value); } - for (const callback of this.finallyCallbacks) { - callback(); + // Tail call optimization for a common case. + if (finallyCallbacksLength === 0) { + return callbacks[callbacksLength - 1](value); } + callbacks[callbacksLength - 1](value); + } + + if (finallyCallbacksLength !== 0) { + for (const i of $range(1, finallyCallbacksLength - 1)) { + finallyCallbacks[i - 1](); + } + return finallyCallbacks[finallyCallbacksLength - 1](); } } private createPromiseResolvingCallback( - f: FulfillCallback | RejectCallback, - resolve: FulfillCallback, - reject: RejectCallback + f: PromiseResolveCallback | PromiseRejectCallback, + resolve: (data: TResult1 | TResult2) => void, + reject: (reason: any) => void ) { - 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); + return (value: T): void => { + const [success, resultOrError] = pcall< + undefined, + [T], + TResult1 | PromiseLike | TResult2 | PromiseLike + >(f, undefined, value); + if (!success) { + // Tail call return is important! + return reject(resultOrError); } + // Tail call return is important! + return this.handleCallbackValue(resultOrError, resolve, reject); }; } - private handleCallbackData( - data: TResult | PromiseLike, - resolve: FulfillCallback, - reject: RejectCallback - ) { - if (isPromiseLike(data)) { - const nextpromise = data as __TS__Promise; + private handleCallbackValue( + value: TResult | PromiseLike, + resolve: (data: TResult1 | TResult2) => void, + reject: (reason: any) => void + ): void { + if (isPromiseLike(value)) { + const nextpromise = value as __TS__Promise; if (nextpromise.state === 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); + // the promise returned by then gets fulfilled with that promise's value. + // Tail call return is important! + return resolve(nextpromise.value!); } else if (nextpromise.state === 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); + // the promise returned by then gets fulfilled with that promise's value. + // Tail call return is important! + return 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); + // We cannot use `then` because we need to do tail call, and `then` returns a Promise. + // `resolve` and `reject` should never throw. + return nextpromise.addCallbacks(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); + // Tail call return is important! + return resolve(value); } } } diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index e4ac5e1cb..b46555edf 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -1,4 +1,4 @@ -export class Set { +export class Set { public static [Symbol.species] = Set; public [Symbol.toStringTag] = "Set"; @@ -42,8 +42,8 @@ export class Set { this.firstKey = value; this.lastKey = value; } else if (isNewValue) { - this.nextKey.set(this.lastKey, value); - this.previousKey.set(value, this.lastKey); + this.nextKey.set(this.lastKey!, value); + this.previousKey.set(value, this.lastKey!); this.lastKey = value; } @@ -66,22 +66,22 @@ export class Set { // Do order bookkeeping const next = this.nextKey.get(value); const previous = this.previousKey.get(value); - if (next && previous) { + if (next !== undefined && previous !== undefined) { this.nextKey.set(previous, next); this.previousKey.set(next, previous); - } else if (next) { + } else if (next !== undefined) { this.firstKey = next; - this.previousKey.set(next, undefined); - } else if (previous) { + this.previousKey.set(next, undefined!); + } else if (previous !== undefined) { this.lastKey = previous; - this.nextKey.set(previous, undefined); + this.nextKey.set(previous, undefined!); } else { this.firstKey = undefined; this.lastKey = undefined; } - this.nextKey.set(value, undefined); - this.previousKey.set(value, undefined); + this.nextKey.set(value, undefined!); + this.previousKey.set(value, undefined!); } return contains; @@ -103,7 +103,7 @@ export class Set { public entries(): IterableIterator<[T, T]> { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator<[T, T]> { return this; @@ -118,7 +118,7 @@ export class Set { public keys(): IterableIterator { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator { return this; @@ -133,7 +133,7 @@ export class Set { public values(): IterableIterator { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator { return this; @@ -145,4 +145,90 @@ export class Set { }, }; } + + /** + * @returns a new Set containing all the elements in this Set and also all the elements in the argument. + */ + public union(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + result.add(item); + } + return result; + } + + /** + * @returns a new Set containing all the elements which are both in this Set and in the argument. + */ + public intersection(other: ReadonlySet) { + const result = new Set(); + for (const item of this) { + if (other.has(item)) { + result.add(item); + } + } + return result; + } + + /** + * @returns a new Set containing all the elements in this Set which are not also in the argument. + */ + public difference(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + result.delete(item); + } + return result; + } + + /** + * @returns a new Set containing all the elements which are in either this Set or in the argument, but not in both. + */ + public symmetricDifference(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + if (this.has(item)) { + result.delete(item); + } else { + result.add(item); + } + } + return result; + } + + /** + * @returns a boolean indicating whether all the elements in this Set are also in the argument. + */ + public isSubsetOf(other: ReadonlySet): boolean { + for (const item of this) { + if (!other.has(item)) { + return false; + } + } + return true; + } + + /** + * @returns a boolean indicating whether all the elements in the argument are also in this Set. + */ + public isSupersetOf(other: ReadonlySet): boolean { + for (const item of other) { + if (!this.has(item as T)) { + return false; + } + } + return true; + } + + /** + * @returns a boolean indicating whether this Set has no elements in common with the argument. + */ + public isDisjointFrom(other: ReadonlySetLike): boolean { + for (const item of this) { + if (other.has(item)) { + return false; + } + } + return true; + } } diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 11c435162..4339c8cc1 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -1,58 +1,15 @@ import { __TS__CloneDescriptor } from "./CloneDescriptor"; +import { __TS__DescriptorGet } from "./DescriptorGet"; +import { __TS__DescriptorSet } from "./DescriptorSet"; -function descriptorIndex(this: any, key: string): void { - const value = rawget(this, key); - if (value !== null) { - return value; - } - - let metatable = getmetatable(this); - while (metatable) { - const rawResult = rawget(metatable, key as any); - if (rawResult !== undefined) { - return rawResult; - } +const getmetatable = _G.getmetatable; - const descriptors = rawget(metatable, "_descriptors"); - if (descriptors) { - const descriptor: PropertyDescriptor = descriptors[key]; - if (descriptor) { - if (descriptor.get) { - return descriptor.get.call(this); - } - - return descriptor.value; - } - } - - metatable = getmetatable(metatable); - } +function descriptorIndex(this: any, key: string): void { + return __TS__DescriptorGet.call(this, getmetatable(this), key); } function descriptorNewIndex(this: any, key: string, value: any): void { - let metatable = getmetatable(this); - while (metatable) { - const descriptors = rawget(metatable, "_descriptors"); - if (descriptors) { - const descriptor: PropertyDescriptor = descriptors[key]; - 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; - } - } - - metatable = getmetatable(metatable); - } - - rawset(this, key, value); + return __TS__DescriptorSet.call(this, getmetatable(this), key, value); } // It's also used directly in class transform to add descriptors to the prototype @@ -73,8 +30,7 @@ export function __TS__SetDescriptor( if (value !== undefined) rawset(target, key, undefined); if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; - const descriptor = __TS__CloneDescriptor(desc); - metatable._descriptors[key] = descriptor; + metatable._descriptors[key] = __TS__CloneDescriptor(desc); metatable.__index = descriptorIndex; metatable.__newindex = descriptorNewIndex; } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index fe1714f1f..47c2c8739 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,11 +1,17 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. +import { __TS__Match } from "./Match"; + interface SourceMap { - [line: number]: number | { line: number; file: string }; + [line: string]: number | { line: number; file: string }; } -declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); +declare global { + function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number): void; + // eslint-disable-next-line no-var + var __TS__sourcemap: Record; +} export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; @@ -13,12 +19,15 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap if (globalThis.__TS__originalTraceback === undefined) { const originalTraceback = debug.traceback; - globalThis.__TS__originalTraceback = originalTraceback; - debug.traceback = ((thread, message, level) => { + globalThis.__TS__originalTraceback = originalTraceback as typeof __TS__originalTraceback; + debug.traceback = ((thread?: LuaThread, message?: string, level?: number) => { let trace: string; if (thread === undefined && message === undefined && level === undefined) { trace = originalTraceback(); + } else if (_VERSION.includes("Lua 5.0")) { + trace = originalTraceback(`[Level ${level}] ${message}`); } else { + // @ts-ignore Fails when compiled with Lua 5.0 types trace = originalTraceback(thread, message, level); } @@ -28,7 +37,7 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap const replacer = (file: string, srcFile: string, line: string) => { const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; - if (fileSourceMap && fileSourceMap[line]) { + if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) { const data = fileSourceMap[line]; if (typeof data === "number") { return `${srcFile}:${data}`; @@ -46,8 +55,8 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap const stringReplacer = (file: string, line: string) => { const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; - if (fileSourceMap && fileSourceMap[line]) { - const chunkName = string.match(file, '%[string "([^"]+)"%]')[0]; + if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) { + const chunkName = __TS__Match(file, '%[string "([^"]+)"%]')[0]; const [sourceName] = string.gsub(chunkName, ".lua$", ".ts"); const data = fileSourceMap[line]; if (typeof data === "number") { diff --git a/src/lualib/SparseArrayNew.ts b/src/lualib/SparseArrayNew.ts index 07bfae13e..c6877b9c2 100644 --- a/src/lualib/SparseArrayNew.ts +++ b/src/lualib/SparseArrayNew.ts @@ -1,9 +1,9 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { __TS__SparseArray } from "./SparseArray"; export function __TS__SparseArrayNew(this: void, ...args: T[]): __TS__SparseArray { const sparseArray = [...args] as __TS__SparseArray; - // select("#", ...) counts the number of args passed, including nils. // Note that we're depending on vararg optimization to occur here. - sparseArray.sparseLength = select("#", ...args); + sparseArray.sparseLength = __TS__CountVarargs(...args); return sparseArray; } diff --git a/src/lualib/SparseArrayPush.ts b/src/lualib/SparseArrayPush.ts index 8a089a192..253d6e223 100644 --- a/src/lualib/SparseArrayPush.ts +++ b/src/lualib/SparseArrayPush.ts @@ -1,7 +1,8 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { __TS__SparseArray } from "./SparseArray"; export function __TS__SparseArrayPush(this: void, sparseArray: __TS__SparseArray, ...args: T[]): void { - const argsLen = select("#", ...args); + const argsLen = __TS__CountVarargs(...args); const listLen = sparseArray.sparseLength; for (const i of $range(1, argsLen)) { sparseArray[listLen + i - 1] = args[i - 1]; diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index ffe745b6d..3c736060d 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,9 +1,8 @@ export function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { - const arr = []; + const arr: T[] = []; if (typeof iterable === "string") { - // eslint-disable-next-line @typescript-eslint/prefer-for-of for (const i of $range(0, iterable.length - 1)) { - arr[i] = iterable[i]; + arr[i] = iterable[i] as T; } } else { let len = 0; diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index d06eec37e..5c1d7076b 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,6 +1,6 @@ const symbolMetatable = { __tostring(this: symbol): string { - return `Symbol(${this.description || ""})`; + return `Symbol(${this.description ?? ""})`; }, }; @@ -9,6 +9,8 @@ export function __TS__Symbol(this: void, description?: string | number): symbol } export const Symbol = { + asyncDispose: __TS__Symbol("Symbol.asyncDispose"), + dispose: __TS__Symbol("Symbol.dispose"), iterator: __TS__Symbol("Symbol.iterator"), hasInstance: __TS__Symbol("Symbol.hasInstance"), diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index d8e68e3dd..4deaa0993 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -9,8 +9,10 @@ export function __TS__SymbolRegistryFor(this: void, key: string): symbol { return symbolRegistry[key]; } -export function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string { +export function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string | undefined { for (const key in symbolRegistry) { if (symbolRegistry[key] === sym) return key; } + + return undefined; } diff --git a/src/lualib/Using.ts b/src/lualib/Using.ts new file mode 100644 index 000000000..a720f6e60 --- /dev/null +++ b/src/lualib/Using.ts @@ -0,0 +1,22 @@ +export function __TS__Using( + this: undefined, + cb: (this: void, ...args: TArgs) => TReturn, + ...args: TArgs +): TReturn { + let thrownError; + const [ok, result] = xpcall( + () => cb(...args), + err => (thrownError = err) + ); + + const argArray = [...args]; + for (let i = argArray.length - 1; i >= 0; i--) { + argArray[i][Symbol.dispose](); + } + + if (!ok) { + throw thrownError; + } + + return result; +} diff --git a/src/lualib/UsingAsync.ts b/src/lualib/UsingAsync.ts new file mode 100644 index 000000000..e4b7593f9 --- /dev/null +++ b/src/lualib/UsingAsync.ts @@ -0,0 +1,27 @@ +export async function __TS__UsingAsync, TReturn>( + this: undefined, + cb: (...args: TArgs) => TReturn, + ...args: TArgs +): Promise { + let thrownError; + const [ok, result] = xpcall( + () => cb(...args), + err => (thrownError = err) + ); + + const argArray = [...args]; + for (let i = argArray.length - 1; i >= 0; i--) { + if (Symbol.dispose in argArray[i]) { + (argArray[i] as Disposable)[Symbol.dispose](); + } + if (Symbol.asyncDispose in argArray[i]) { + await (argArray[i] as AsyncDisposable)[Symbol.asyncDispose](); + } + } + + if (!ok) { + throw thrownError; + } + + return result; +} diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index e5f333293..65d1ae4da 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -export class WeakMap { +export class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; @@ -30,7 +30,7 @@ export class WeakMap { public delete(key: K): boolean { const contains = this.has(key); - this.items.set(key, undefined); + this.items.set(key, undefined!); return contains; } diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index 0873861ab..b921efc17 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -export class WeakSet { +export class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; @@ -33,7 +33,7 @@ export class WeakSet { public delete(value: T): boolean { const contains = this.has(value); - this.items.set(value, undefined); + this.items.set(value, undefined!); return contains; } diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 90a3283ef..9de44be80 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -18,9 +18,6 @@ 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/declarations/universal/unpack.d.ts b/src/lualib/declarations/universal/unpack.d.ts new file mode 100644 index 000000000..c199c09df --- /dev/null +++ b/src/lualib/declarations/universal/unpack.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ + +// Declare unpack for versions that have it instead of table.unpack +declare const unpack: typeof table.unpack | undefined; diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index 246e46b90..0f0874d0d 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -1,18 +1,18 @@ { "compilerOptions": { - "outDir": "../../dist/lualib", + "outDir": "../../dist/lualib/universal", "target": "esnext", "lib": ["esnext"], "types": ["lua-types/5.4"], "skipLibCheck": true, + "rootDirs": [".", "universal"], - "noUnusedLocals": true, - "noUnusedParameters": true + "strict": true }, "tstl": { "luaLibImport": "none", "noHeader": true, "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] }, - "include": [".", "../../language-extensions/index.d.ts"] + "include": ["*.ts", "universal/**/*.ts", "declarations/**/*.ts", "../../language-extensions/index.d.ts"] } diff --git a/src/lualib/tsconfig.lua50.json b/src/lualib/tsconfig.lua50.json new file mode 100644 index 000000000..a0b5aee4b --- /dev/null +++ b/src/lualib/tsconfig.lua50.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "outDir": "../../dist/lualib/5.0", + "target": "esnext", + "lib": ["esnext"], + "types": ["lua-types/5.0"], + "skipLibCheck": true, + "rootDirs": [".", "5.0"], + + "strict": true + }, + "tstl": { + "luaLibImport": "none", + "noHeader": true, + "luaTarget": "5.0", + "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] + }, + "include": ["*.ts", "5.0/**/*.ts", "declarations/**/*.ts", "../../language-extensions/index.d.ts"] +} diff --git a/src/lualib/universal/CountVarargs.ts b/src/lualib/universal/CountVarargs.ts new file mode 100644 index 000000000..dc6107bb5 --- /dev/null +++ b/src/lualib/universal/CountVarargs.ts @@ -0,0 +1,6 @@ +/** @noSelfInFile */ + +export function __TS__CountVarargs(...args: T[]): number { + // Note that we need vararg optimization for this call. + return select("#", ...args); +} diff --git a/src/lualib/universal/Match.ts b/src/lualib/universal/Match.ts new file mode 100644 index 000000000..de9420b59 --- /dev/null +++ b/src/lualib/universal/Match.ts @@ -0,0 +1 @@ +export const __TS__Match = string.match; diff --git a/src/lualib/universal/MathModf.ts b/src/lualib/universal/MathModf.ts new file mode 100644 index 000000000..139ae8f6a --- /dev/null +++ b/src/lualib/universal/MathModf.ts @@ -0,0 +1 @@ +export const __TS__MathModf = math.modf; diff --git a/src/lualib/SparseArraySpread.ts b/src/lualib/universal/SparseArraySpread.ts similarity index 100% rename from src/lualib/SparseArraySpread.ts rename to src/lualib/universal/SparseArraySpread.ts diff --git a/src/lualib/Unpack.ts b/src/lualib/universal/Unpack.ts similarity index 100% rename from src/lualib/Unpack.ts rename to src/lualib/universal/Unpack.ts diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 9eeca1a1c..b22bff01d 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -1,10 +1,11 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../visitors/call"; -import { findFirstNonOuterParent, typeAlwaysHasSomeOfFlags } from "../utils/typescript"; +import { expressionResultIsUsed, typeAlwaysHasSomeOfFlags } from "../utils/typescript"; import { moveToPrecedingTemp } from "../visitors/expression-list"; import { isUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -29,6 +30,18 @@ export function transformArrayConstructorCall( } } +function createTableLengthExpression(context: TransformationContext, expression: lua.Expression, node?: ts.Expression) { + if (context.luaTarget === LuaTarget.Lua50) { + const tableGetn = lua.createTableIndexExpression( + lua.createIdentifier("table"), + lua.createStringLiteral("getn") + ); + return lua.createCallExpression(tableGetn, [expression], node); + } else { + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + } +} + /** * Optimized single element Array.push * @@ -41,17 +54,16 @@ function transformSingleElementArrayPush( caller: lua.Expression, param: lua.Expression ): lua.Expression { - const expressionIsUsed = !ts.isExpressionStatement(findFirstNonOuterParent(node)); - const arrayIdentifier = lua.isIdentifier(caller) ? caller : moveToPrecedingTemp(context, caller); // #array + 1 let lengthExpression: lua.Expression = lua.createBinaryExpression( - lua.createUnaryExpression(arrayIdentifier, lua.SyntaxKind.LengthOperator), + createTableLengthExpression(context, arrayIdentifier), lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator ); + const expressionIsUsed = expressionResultIsUsed(node); if (expressionIsUsed) { // store length in a temp lengthExpression = moveToPrecedingTemp(context, lengthExpression); @@ -76,20 +88,24 @@ export function transformArrayPrototypeCall( const expressionName = calledMethod.name.text; switch (expressionName) { + case "at": + return transformLuaLibFunction(context, LuaLibFeature.ArrayAt, node, caller, ...params); case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); case "entries": return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); + case "fill": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFill, node, caller, ...params); case "push": if (node.arguments.length === 1) { - const param = params[0]; + const param = params[0] ?? lua.createNilLiteral(); if (isUnpackCall(param)) { return transformLuaLibFunction( context, LuaLibFeature.ArrayPushArray, node, caller, - (param as lua.CallExpression).params[0] + (param as lua.CallExpression).params[0] ?? lua.createNilLiteral() ); } if (!lua.isDotsLiteral(param)) { @@ -150,7 +166,7 @@ export function transformArrayPrototypeCall( typeAlwaysHasSomeOfFlags(context, elementType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike) ) { const defaultSeparatorLiteral = lua.createStringLiteral(","); - const param = params[0]; + const param = params[0] ?? lua.createNilLiteral(); const parameters = [ caller, node.arguments.length === 0 @@ -172,6 +188,14 @@ export function transformArrayPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.ArrayFlat, node, caller, ...params); case "flatMap": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); + case "toReversed": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToReversed, node, caller, ...params); + case "toSorted": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToSorted, node, caller, ...params); + case "toSpliced": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToSpliced, node, caller, ...params); + case "with": + return transformLuaLibFunction(context, LuaLibFeature.ArrayWith, node, caller, ...params); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "array", expressionName)); } @@ -180,11 +204,11 @@ export function transformArrayPrototypeCall( export function transformArrayProperty( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.UnaryExpression | undefined { +): lua.Expression | undefined { switch (node.name.text) { case "length": const expression = context.transformExpression(node.expression); - return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + return createTableLengthExpression(context, expression, node); default: return undefined; } diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index f2ee043c9..8b219b6ba 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -40,8 +40,12 @@ export function transformFunctionProperty( ): lua.Expression | undefined { switch (node.name.text) { case "length": - if (context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Universal) { - context.diagnostics.push(unsupportedForTarget(node, "function.length", LuaTarget.Lua51)); + if ( + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Universal + ) { + context.diagnostics.push(unsupportedForTarget(node, "function.length", context.luaTarget)); } // debug.getinfo(fn) diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 4d882b293..288414a60 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -4,6 +4,7 @@ import { TransformationContext } from "../context"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isNumberType } from "../utils/typescript"; import { transformArguments } from "../visitors/call"; +import { transformStringConstructorCall } from "./string"; export function tryTransformBuiltinGlobalCall( context: TransformationContext, @@ -21,6 +22,8 @@ export function tryTransformBuiltinGlobalCall( return transformLuaLibFunction(context, LuaLibFeature.Symbol, node, ...getParameters()); case "NumberConstructor": return transformLuaLibFunction(context, LuaLibFeature.Number, node, ...getParameters()); + case "StringConstructor": + return transformStringConstructorCall(node, ...getParameters()); case "isNaN": case "isFinite": const numberParameters = isNumberType(context, expressionType) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 711015b5f..3eefd64c9 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -11,12 +11,14 @@ import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { tryTransformBuiltinGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; -import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; +import { transformNumberConstructorCall, transformNumberPrototypeCall, transformNumberProperty } from "./number"; import { transformObjectConstructorCall, tryTransformObjectPrototypeCall } from "./object"; import { transformPromiseConstructorCall } from "./promise"; -import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; +import { transformStringConstructorMethodCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; +import { LuaTarget } from "../../CompilerOptions"; +import { transformMapConstructorCall } from "./map"; export function transformBuiltinPropertyAccessExpression( context: TransformationContext, @@ -26,6 +28,8 @@ export function transformBuiltinPropertyAccessExpression( if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { switch (ownerType.symbol.name) { + case "NumberConstructor": + return transformNumberProperty(context, node); case "Math": return transformMathProperty(context, node); case "SymbolConstructor": @@ -90,11 +94,14 @@ function tryTransformBuiltinGlobalMethodCall( case "Console": result = transformConsoleCall(context, node, calledMethod); break; + case "MapConstructor": + result = transformMapConstructorCall(context, node, calledMethod); + break; case "Math": result = transformMathCall(context, node, calledMethod); break; case "StringConstructor": - result = transformStringConstructorCall(context, node, calledMethod); + result = transformStringConstructorMethodCall(context, node, calledMethod); break; case "ObjectConstructor": result = transformObjectConstructorCall(context, node, calledMethod); @@ -152,10 +159,15 @@ export function transformBuiltinIdentifierExpression( return createNaN(node); case "Infinity": - const math = lua.createIdentifier("math"); - const huge = lua.createStringLiteral("huge"); - return lua.createTableIndexExpression(math, huge, node); - + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, node); + } case "globalThis": return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node, symbol), "globalThis"); } @@ -209,7 +221,10 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type } } -function tryGetStandardLibrarySymbolOfType(context: TransformationContext, type: ts.Type): ts.Symbol | undefined { +export function tryGetStandardLibrarySymbolOfType( + context: TransformationContext, + type: ts.Type +): ts.Symbol | undefined { if (type.isUnionOrIntersection()) { for (const subType of type.types) { const symbol = tryGetStandardLibrarySymbolOfType(context, subType); diff --git a/src/transformation/builtins/map.ts b/src/transformation/builtins/map.ts new file mode 100644 index 000000000..556578591 --- /dev/null +++ b/src/transformation/builtins/map.ts @@ -0,0 +1,22 @@ +import * as lua from "../../LuaAST"; +import * as ts from "typescript"; +import { TransformationContext } from "../context"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { transformArguments } from "../visitors/call"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; + +export function transformMapConstructorCall( + context: TransformationContext, + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression +): lua.Expression | undefined { + const args = transformArguments(context, node.arguments); + const methodName = calledMethod.name.text; + + switch (methodName) { + case "groupBy": + return transformLuaLibFunction(context, LuaLibFeature.MapGroupBy, node, ...args); + default: + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Map", methodName)); + } +} diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 630f33646..ab831d52f 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -66,20 +66,33 @@ export function transformMathCall( case "log1p": { const log = lua.createStringLiteral("log"); const one = lua.createNumericLiteral(1); - const add = lua.createBinaryExpression(one, params[0], lua.SyntaxKind.AdditionOperator); + const add = lua.createBinaryExpression( + one, + params[0] ?? lua.createNilLiteral(), + lua.SyntaxKind.AdditionOperator + ); return lua.createCallExpression(lua.createTableIndexExpression(math, log), [add], node); } case "pow": { // Translate to base ^ power - return lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.PowerOperator, node); + return lua.createBinaryExpression( + params[0] ?? lua.createNilLiteral(), + params[1] ?? lua.createNilLiteral(), + lua.SyntaxKind.PowerOperator, + node + ); } // math.floor(x + 0.5) case "round": { const floor = lua.createStringLiteral("floor"); const half = lua.createNumericLiteral(0.5); - const add = lua.createBinaryExpression(params[0], half, lua.SyntaxKind.AdditionOperator); + const add = lua.createBinaryExpression( + params[0] ?? lua.createNilLiteral(), + half, + lua.SyntaxKind.AdditionOperator + ); return lua.createCallExpression(lua.createTableIndexExpression(math, floor), [add], node); } @@ -87,6 +100,10 @@ export function transformMathCall( return transformLuaLibFunction(context, LuaLibFeature.MathSign, node, ...params); } + case "trunc": { + return transformLuaLibFunction(context, LuaLibFeature.MathTrunc, node, ...params); + } + case "abs": case "acos": case "asin": diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index 3376c0db3..17c44b6fd 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -1,9 +1,11 @@ import ts = require("typescript"); import * as lua from "../../LuaAST"; +import { createNaN } from "../utils/lua-ast"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformArguments } from "../visitors/call"; +import { LuaTarget } from "../../CompilerOptions"; export function transformNumberPrototypeCall( context: TransformationContext, @@ -20,11 +22,94 @@ export function transformNumberPrototypeCall( return params.length === 0 ? lua.createCallExpression(lua.createIdentifier("tostring"), [caller], node) : transformLuaLibFunction(context, LuaLibFeature.NumberToString, node, caller, ...params); + case "toFixed": + return transformLuaLibFunction(context, LuaLibFeature.NumberToFixed, node, caller, ...params); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "number", expressionName)); } } +export function transformNumberProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { + const name = node.name.text; + + /* + Read the docs on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number for further info about what these numbers entail. + Most of them should be fairly straight forward base on their name(s) though. + */ + + switch (name) { + case "POSITIVE_INFINITY": + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, node); + } + case "NEGATIVE_INFINITY": + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createUnaryExpression( + lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator), + lua.SyntaxKind.NegationOperator + ); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createUnaryExpression( + lua.createTableIndexExpression(math, huge, node), + lua.SyntaxKind.NegationOperator + ); + } + case "NaN": + return createNaN(node); + case "EPSILON": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(-52), + lua.SyntaxKind.PowerOperator, + node + ); + case "MIN_VALUE": + return lua.createBinaryExpression( + lua.createNumericLiteral(-2), + lua.createNumericLiteral(1074), + lua.SyntaxKind.PowerOperator, + node + ); + case "MIN_SAFE_INTEGER": + return lua.createBinaryExpression( + lua.createNumericLiteral(-2), + lua.createNumericLiteral(1074), + lua.SyntaxKind.PowerOperator, + node + ); + case "MAX_SAFE_INTEGER": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(1024), + lua.SyntaxKind.PowerOperator, + node + ); + case "MAX_VALUE": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(1024), + lua.SyntaxKind.PowerOperator, + node + ); + + default: + context.diagnostics.push(unsupportedProperty(node.name, "Number", name)); + } +} + export function transformNumberConstructorCall( context: TransformationContext, node: ts.CallExpression, @@ -33,10 +118,16 @@ export function transformNumberConstructorCall( const parameters = transformArguments(context, node.arguments); const methodName = calledMethod.name.text; switch (methodName) { + case "isInteger": + return transformLuaLibFunction(context, LuaLibFeature.NumberIsInteger, node, ...parameters); case "isNaN": return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, node, ...parameters); case "isFinite": return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, node, ...parameters); + case "parseInt": + return transformLuaLibFunction(context, LuaLibFeature.NumberParseInt, node, ...parameters); + case "parseFloat": + return transformLuaLibFunction(context, LuaLibFeature.NumberParseFloat, node, ...parameters); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "Number", methodName)); } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index cd386ce19..43dd8a165 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -26,6 +26,8 @@ export function transformObjectConstructorCall( return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, node, ...args); case "getOwnPropertyDescriptors": return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, node, ...args); + case "groupBy": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGroupBy, node, ...args); case "keys": return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, node, ...args); case "values": diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 711f59230..98bd62303 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; @@ -41,7 +42,7 @@ export function transformStringPrototypeCall( "find", node, caller, - params[0], + params[0] ?? lua.createNilLiteral(), params[1] ? // string.find handles negative indexes by making it relative to string end, but for indexOf it's the same as 0 lua.createCallExpression( @@ -109,7 +110,7 @@ export function transformStringPrototypeCall( const literalValue = getNumberLiteralValue(params[0]); // Inline string.sub call if we know that parameter is pure and isn't negative if (literalValue !== undefined && literalValue >= 0) { - const firstParamPlusOne = addToNumericExpression(params[0], 1); + const firstParamPlusOne = addToNumericExpression(params[0] ?? lua.createNilLiteral(), 1); return createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); } @@ -121,7 +122,12 @@ export function transformStringPrototypeCall( // Inline string.sub call if we know that parameter is pure and isn't negative if (literalValue !== undefined && literalValue >= 0) { return lua.createBinaryExpression( - createStringCall("byte", node, caller, addToNumericExpression(params[0], 1)), + createStringCall( + "byte", + node, + caller, + addToNumericExpression(params[0] ?? lua.createNilLiteral(), 1) + ), createNaN(), lua.SyntaxKind.OrOperator ); @@ -139,7 +145,9 @@ export function transformStringPrototypeCall( case "repeat": const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); - const parameter = lua.createCallExpression(lua.createTableIndexExpression(math, floor), [params[0]]); + const parameter = lua.createCallExpression(lua.createTableIndexExpression(math, floor), [ + params[0] ?? lua.createNilLiteral(), + ]); return createStringCall("rep", node, caller, parameter); case "padStart": return transformLuaLibFunction(context, LuaLibFeature.StringPadStart, node, caller, ...params); @@ -152,7 +160,7 @@ export function transformStringPrototypeCall( } } -export function transformStringConstructorCall( +export function transformStringConstructorMethodCall( context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression @@ -177,12 +185,28 @@ export function transformStringConstructorCall( export function transformStringProperty( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.UnaryExpression | undefined { +): lua.Expression | undefined { switch (node.name.text) { case "length": const expression = context.transformExpression(node.expression); - return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + if (context.luaTarget === LuaTarget.Lua50) { + const stringLen = lua.createTableIndexExpression( + lua.createIdentifier("string"), + lua.createStringLiteral("len") + ); + return lua.createCallExpression(stringLen, [expression], node); + } else { + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + } default: context.diagnostics.push(unsupportedProperty(node.name, "string", node.name.text)); } } + +export function transformStringConstructorCall( + originalNode: ts.CallExpression, + ...args: lua.Expression[] +): lua.Expression | undefined { + const tostring = lua.createIdentifier("tostring", originalNode.expression); + return lua.createCallExpression(tostring, args, originalNode); +} diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 8fda0bc23..79e385b2b 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -15,7 +15,6 @@ export const tempSymbolId = -1 as lua.SymbolId; export interface AllAccessorDeclarations { firstAccessor: ts.AccessorDeclaration; - secondAccessor: ts.AccessorDeclaration | undefined; getAccessor: ts.GetAccessorDeclaration | undefined; setAccessor: ts.SetAccessorDeclaration | undefined; } @@ -24,8 +23,6 @@ export interface EmitResolver { isValueAliasDeclaration(node: ts.Node): boolean; isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; - moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; - getAllAccessorDeclarations(declaration: ts.AccessorDeclaration): AllAccessorDeclarations; } export interface TypeCheckerWithEmitResolver extends ts.TypeChecker { @@ -42,6 +39,7 @@ export class TransformationContext { public readonly luaTarget = this.options.luaTarget ?? LuaTarget.Universal; public readonly isModule = ts.isExternalModule(this.sourceFile); public readonly isStrict = + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (this.options.alwaysStrict ?? this.options.strict) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); @@ -65,7 +63,10 @@ export class TransformationContext { /** @internal */ public transformNodeRaw(node: ts.Node, isExpression?: boolean) { // TODO: Move to visitors? - if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { + if ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword) + ) { return []; } diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index fff7441e5..429cce1b4 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -61,6 +61,7 @@ interface NodesBySyntaxKind { [ts.SyntaxKind.AsExpression]: ts.AsExpression; [ts.SyntaxKind.NonNullExpression]: ts.NonNullExpression; [ts.SyntaxKind.MetaProperty]: ts.MetaProperty; + [ts.SyntaxKind.SatisfiesExpression]: ts.SatisfiesExpression; [ts.SyntaxKind.TemplateSpan]: ts.TemplateSpan; [ts.SyntaxKind.SemicolonClassElement]: ts.SemicolonClassElement; [ts.SyntaxKind.Block]: ts.Block; @@ -148,6 +149,7 @@ export type VisitorResult = T extends ExpressionLikeNode export type Visitor = FunctionVisitor | ObjectVisitor; export type FunctionVisitor = (node: T, context: TransformationContext) => VisitorResult; + export interface ObjectVisitor { transform: FunctionVisitor; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 4580a3b80..b9e1f6241 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -3,6 +3,7 @@ import * as lua from "../LuaAST"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; import { standardVisitors } from "./visitors"; +import { usingTransformer } from "./pre-transformers/using-transformer"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { const objectVisitorMap: Map>> = new Map(); @@ -32,7 +33,13 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { const context = new TransformationContext(program, sourceFile, visitorMap); - const [file] = context.transformNode(sourceFile) as [lua.File]; + + // TS -> TS pre-transformation + const preTransformers = [usingTransformer(context)]; + const result = ts.transform(sourceFile, preTransformers); + + // TS -> Lua transformation + const [file] = context.transformNode(result.transformed[0]) as [lua.File]; return { file, diagnostics: context.diagnostics }; } diff --git a/src/transformation/pre-transformers/using-transformer.ts b/src/transformation/pre-transformers/using-transformer.ts new file mode 100644 index 000000000..d78f6206a --- /dev/null +++ b/src/transformation/pre-transformers/using-transformer.ts @@ -0,0 +1,129 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../context"; +import { LuaLibFeature, importLuaLibFeature } from "../utils/lualib"; + +export function usingTransformer(context: TransformationContext): ts.TransformerFactory { + return ctx => sourceFile => { + function visit(node: ts.Node): ts.Node { + if (ts.isBlock(node)) { + const [hasUsings, newStatements] = transformBlockWithUsing(context, node.statements, node); + if (hasUsings) { + // Recurse visitor into updated block to find further usings + const updatedBlock = ts.factory.updateBlock(node, newStatements); + const result = ts.visitEachChild(updatedBlock, visit, ctx); + + // Set all the synthetic node parents to something that makes sense + const parent: ts.Node[] = [updatedBlock]; + function setParent(node2: ts.Node): ts.Node { + ts.setParent(node2, parent[parent.length - 1]); + parent.push(node2); + ts.visitEachChild(node2, setParent, ctx); + parent.pop(); + return node2; + } + ts.visitEachChild(updatedBlock, setParent, ctx); + ts.setParent(updatedBlock, node.parent); + + return result; + } + } + return ts.visitEachChild(node, visit, ctx); + } + return ts.visitEachChild(sourceFile, visit, ctx); + }; +} + +function isUsingDeclarationList(node: ts.Node): node is ts.VariableStatement { + return ts.isVariableStatement(node) && (node.declarationList.flags & ts.NodeFlags.Using) !== 0; +} + +function transformBlockWithUsing( + context: TransformationContext, + statements: ts.NodeArray | ts.Statement[], + block: ts.Block +): [true, ts.Statement[]] | [false] { + const newStatements: ts.Statement[] = []; + + for (let i = 0; i < statements.length; i++) { + const statement = statements[i]; + if (isUsingDeclarationList(statement)) { + const isAwaitUsing = (statement.declarationList.flags & ts.NodeFlags.AwaitContext) !== 0; + + if (isAwaitUsing) { + importLuaLibFeature(context, LuaLibFeature.UsingAsync); + } else { + importLuaLibFeature(context, LuaLibFeature.Using); + } + + // Make declared using variables callback function parameters + const variableNames = statement.declarationList.declarations.map(d => + ts.factory.createParameterDeclaration(undefined, undefined, d.name) + ); + // Add this: void as first parameter + variableNames.unshift(createThisVoidParameter(context.checker)); + + // Put all following statements in the callback body + const followingStatements = statements.slice(i + 1); + const [followingHasUsings, replacedFollowingStatements] = transformBlockWithUsing( + context, + followingStatements, + block + ); + const callbackBody = ts.factory.createBlock( + followingHasUsings ? replacedFollowingStatements : followingStatements + ); + + const callback = ts.factory.createFunctionExpression( + // Put async keyword in front of callback when we are in an async using + isAwaitUsing ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)] : undefined, + undefined, + undefined, + undefined, + variableNames, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), // Required for TS to not freak out trying to infer the type of synthetic nodes + callbackBody + ); + + // Replace using variable list with call to lualib function with callback and followed by all variable initializers + const functionIdentifier = ts.factory.createIdentifier(isAwaitUsing ? "__TS__UsingAsync" : "__TS__Using"); + let call: ts.Expression = ts.factory.createCallExpression( + functionIdentifier, + [], + [ + callback, + ...statement.declarationList.declarations.map( + d => d.initializer ?? ts.factory.createIdentifier("unidentified") + ), + ] + ); + + // If this is an 'await using ...', add an await statement here + if (isAwaitUsing) { + call = ts.factory.createAwaitExpression(call); + } + + if (ts.isBlock(block.parent) && block.parent.statements[block.parent.statements.length - 1] !== block) { + // If this is a free-standing block in a function (not the last statement), dont return the value + newStatements.push(ts.factory.createExpressionStatement(call)); + } else { + newStatements.push(ts.factory.createReturnStatement(call)); + } + + return [true, newStatements]; + } else { + newStatements.push(statement); + } + } + return [false]; +} + +function createThisVoidParameter(checker: ts.TypeChecker) { + const voidType = checker.typeToTypeNode(checker.getVoidType(), undefined, undefined); + return ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier("this"), + undefined, + voidType + ); +} diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 0f25d8769..91ef6d531 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -5,6 +5,7 @@ export enum AnnotationKind { CompileMembersOnly = "compileMembersOnly", NoResolution = "noResolution", NoSelf = "noSelf", + CustomName = "customName", NoSelfInFile = "noSelfInFile", } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 7fc7d814b..5fb1bf15e 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import * as lua from "../../LuaAST"; import { LuaTarget, TypeScriptToLuaOptions } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; @@ -84,16 +85,14 @@ export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); -type NonUniversalTarget = Exclude; - const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export const unsupportedForTarget = createErrorDiagnosticFactory( - (functionality: string, version: NonUniversalTarget) => + (functionality: string, version: LuaTarget) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); export const unsupportedForTargetButOverrideAvailable = createErrorDiagnosticFactory( - (functionality: string, version: NonUniversalTarget, optionName: keyof TypeScriptToLuaOptions) => + (functionality: string, version: LuaTarget, optionName: keyof TypeScriptToLuaOptions) => `As a precaution, ${functionality} is/are not supported for target ${getLuaTargetName( version )} due to language features/limitations. ` + @@ -121,12 +120,6 @@ export const invalidMultiFunctionReturnType = createErrorDiagnosticFactory( "The $multi function cannot be cast to a non-LuaMultiReturn type." ); -export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); - -export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosticFactory( - "There must be one or more elements specified here." -); - export const invalidMultiReturnAccess = createErrorDiagnosticFactory( "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); @@ -134,13 +127,6 @@ export const invalidMultiReturnAccess = createErrorDiagnosticFactory( export const invalidCallExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); - -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 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. ` + @@ -148,7 +134,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory( ); export const truthyOnlyConditionalValue = createWarningDiagnosticFactory( - "Numbers and strings will always evaluate to true in Lua. Explicitly check the value with ===." + "Only false and nil evaluate to 'false' in Lua, everything else is considered 'true'. Explicitly compare the value with ===." ); export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( @@ -170,3 +156,23 @@ export const unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactor export const undefinedInArrayLiteral = createErrorDiagnosticFactory( "Array literals may not contain undefined or null." ); + +export const invalidMethodCallExtensionUse = createErrorDiagnosticFactory( + "This language extension must be called as a method." +); + +export const invalidSpreadInCallExtension = createErrorDiagnosticFactory( + "Spread elements are not supported in call extensions." +); + +export const cannotAssignToNodeOfKind = createErrorDiagnosticFactory( + (kind: lua.SyntaxKind) => `Cannot create assignment assigning to a node of type ${lua.SyntaxKind[kind]}.` +); + +export const incompleteFieldDecoratorWarning = createWarningDiagnosticFactory( + "You are using a class field decorator, note that tstl ignores returned value initializers!" +); + +export const unsupportedArrayWithLengthConstructor = createErrorDiagnosticFactory( + `Constructing new Array with length is not supported.` +); diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index fafc26d86..fa1c03649 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -1,17 +1,23 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { createModuleLocalNameIdentifier } from "../visitors/namespace"; +import { createModuleLocalName } from "../visitors/namespace"; import { createExportsIdentifier } from "./lua-ast"; import { getSymbolInfo } from "./symbols"; import { findFirstNodeAbove } from "./typescript"; export function hasDefaultExportModifier(node: ts.Node): boolean { - return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); + return ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword) === true + ); } export function hasExportModifier(node: ts.Node): boolean { - return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword); + return ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword) === true + ); } export const createDefaultExportStringLiteral = (original?: ts.Node): lua.StringLiteral => @@ -138,7 +144,7 @@ export function createExportedIdentifier( const exportTable = exportScope && ts.isModuleDeclaration(exportScope) - ? createModuleLocalNameIdentifier(context, exportScope) + ? createModuleLocalName(context, exportScope) : createExportsIdentifier(); return lua.createTableIndexExpression(exportTable, lua.createStringLiteral(identifier.text)); diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 41e70d40f..5b2c0cb4e 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -30,14 +30,42 @@ function hasNoSelfAncestor(declaration: ts.Declaration): boolean { function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined { const param = signatureDeclaration.parameters[0]; - if (param && ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + if (param && ts.isIdentifier(param.name) && ts.identifierToKeywordKind(param.name) === ts.SyntaxKind.ThisKeyword) { return param; } } +const callContextTypes = new WeakMap(); + +export function getCallContextType(context: TransformationContext, callExpression: ts.CallLikeExpression): ContextType { + const known = callContextTypes.get(callExpression); + if (known !== undefined) return known; + + const signature = context.checker.getResolvedSignature(callExpression); + const signatureDeclaration = signature?.getDeclaration(); + + let contextType = ContextType.None; + + if (signatureDeclaration) { + contextType = computeDeclarationContextType(context, signatureDeclaration); + } else { + // No signature declaration could be resolved, so instead try to see if the declaration is in a + // noSelfInFile file + const declarations = findRootDeclarations(context, callExpression); + contextType = declarations.some(d => getFileAnnotations(d.getSourceFile()).has(AnnotationKind.NoSelfInFile)) + ? ContextType.Void + : context.options.noImplicitSelf + ? ContextType.Void + : ContextType.NonVoid; + } + + callContextTypes.set(callExpression, contextType); + return contextType; +} + const signatureDeclarationContextTypes = new WeakMap(); -export function getDeclarationContextType( +function getSignatureContextType( context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration ): ContextType { @@ -48,6 +76,34 @@ export function getDeclarationContextType( return contextType; } +function findRootDeclarations(context: TransformationContext, callExpression: ts.CallLikeExpression): ts.Declaration[] { + const calledExpression = ts.isTaggedTemplateExpression(callExpression) + ? callExpression.tag + : ts.isJsxSelfClosingElement(callExpression) + ? callExpression.tagName + : ts.isJsxOpeningElement(callExpression) + ? callExpression.tagName + : ts.isCallExpression(callExpression) + ? callExpression.expression + : undefined; + + if (!calledExpression) return []; + + const calledSymbol = context.checker.getSymbolAtLocation(calledExpression); + if (calledSymbol === undefined) return []; + + return ( + calledSymbol.getDeclarations()?.flatMap(d => { + if (ts.isImportSpecifier(d)) { + const aliasSymbol = context.checker.getAliasedSymbol(calledSymbol); + return aliasSymbol.getDeclarations() ?? []; + } else { + return [d]; + } + }) ?? [] + ); +} + function computeDeclarationContextType(context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration) { const thisParameter = getExplicitThisParameter(signatureDeclaration); if (thisParameter) { @@ -84,6 +140,10 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.NonVoid; } + if (signatureDeclaration.parent && ts.isTypeParameterDeclaration(signatureDeclaration.parent)) { + return ContextType.NonVoid; + } + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const program = context.program; const options = program.getCompilerOptions() as CompilerOptions; @@ -116,7 +176,15 @@ function reduceContextTypes(contexts: ContextType[]): ContextType { } function getSignatureDeclarations(context: TransformationContext, signature: ts.Signature): ts.SignatureDeclaration[] { + if (signature.compositeSignatures) { + return signature.compositeSignatures.flatMap(s => getSignatureDeclarations(context, s)); + } + const signatureDeclaration = signature.getDeclaration(); + if (signatureDeclaration === undefined) { + return []; + } + let inferredType: ts.Type | undefined; if ( ts.isMethodDeclaration(signatureDeclaration) && @@ -164,6 +232,6 @@ function computeFunctionContextType(context: TransformationContext, type: ts.Typ } return reduceContextTypes( - signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getDeclarationContextType(context, s)) + signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getSignatureContextType(context, s)) ); } diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 881da105b..6da38837a 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; +import { invalidMethodCallExtensionUse, invalidSpreadInCallExtension } from "./diagnostics"; export enum ExtensionKind { MultiFunction = "MultiFunction", @@ -52,7 +53,10 @@ export enum ExtensionKind { TableSetMethodType = "TableSetMethod", TableAddKeyType = "TableAddKey", TableAddKeyMethodType = "TableAddKeyMethod", + TableIsEmptyType = "TableIsEmpty", + TableIsEmptyMethodType = "TableIsEmptyMethod", } + const extensionValues: Set = new Set(Object.values(ExtensionKind)); export function getExtensionKindForType(context: TransformationContext, type: ts.Type): ExtensionKind | undefined { @@ -119,3 +123,56 @@ export function getIterableExtensionKindForNode( const type = context.checker.getTypeAtLocation(node); return getIterableExtensionTypeForType(context, type); } + +export const methodExtensionKinds: ReadonlySet = new Set( + Object.values(ExtensionKind).filter(key => key.endsWith("Method")) +); + +export function getNaryCallExtensionArgs( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind, + numArgs: number +): readonly ts.Expression[] | undefined { + let expressions: readonly ts.Expression[]; + if (node.arguments.some(ts.isSpreadElement)) { + context.diagnostics.push(invalidSpreadInCallExtension(node)); + return undefined; + } + if (methodExtensionKinds.has(kind)) { + if (!(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) { + context.diagnostics.push(invalidMethodCallExtensionUse(node)); + return undefined; + } + if (node.arguments.length < numArgs - 1) { + // assumed to be TS error + return undefined; + } + expressions = [node.expression.expression, ...node.arguments]; + } else { + if (node.arguments.length < numArgs) { + // assumed to be TS error + return undefined; + } + expressions = node.arguments; + } + return expressions; +} + +export function getUnaryCallExtensionArg( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind +): ts.Expression | undefined { + return getNaryCallExtensionArgs(context, node, kind, 1)?.[0]; +} + +export function getBinaryCallExtensionArgs( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind +): readonly [ts.Expression, ts.Expression] | undefined { + const expressions = getNaryCallExtensionArgs(context, node, kind, 2); + if (expressions === undefined) return undefined; + return [expressions[0], expressions[1]]; +} diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 31c101d13..b947e0bf6 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -72,7 +72,9 @@ export function createUnpackCall( } const unpack = - context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.LuaJIT + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.LuaJIT ? lua.createIdentifier("unpack") : lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("unpack")); @@ -303,15 +305,17 @@ function getJSDocCommentFromTSNode( // https://stevedonovan.github.io/ldoc/manual/doc.md.html // LDoc comments require that the first line starts with three hyphens. // Thus, need to add a hyphen to the first line. - const firstLine = lines[0]; - if (firstLine.startsWith(" @")) { - lines.unshift("-"); - } else { - lines.shift(); - lines.unshift("-" + firstLine); - } + if (lines.length > 0) { + const firstLine = lines[0]; + if (firstLine.startsWith(" @")) { + lines.unshift("-"); + } else { + lines.shift(); + lines.unshift("-" + firstLine); + } - return lines; + return lines; + } } export const createNaN = (tsOriginal?: ts.Node) => diff --git a/src/transformation/utils/preceding-statements.ts b/src/transformation/utils/preceding-statements.ts index c64d0b90a..16cefac12 100644 --- a/src/transformation/utils/preceding-statements.ts +++ b/src/transformation/utils/preceding-statements.ts @@ -1,11 +1,18 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; +export interface WithPrecedingStatements< + T extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] +> { + precedingStatements: lua.Statement[]; + result: T; +} + export function transformInPrecedingStatementScope< TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] ->(context: TransformationContext, transformer: () => TReturn): [lua.Statement[], TReturn] { +>(context: TransformationContext, transformer: () => TReturn): WithPrecedingStatements { context.pushPrecedingStatements(); const statementOrStatements = transformer(); const precedingStatements = context.popPrecedingStatements(); - return [precedingStatements, statementOrStatements]; + return { precedingStatements, result: statementOrStatements }; } diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index 538d77a91..0772d71a8 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -16,6 +16,8 @@ export const isValidLuaIdentifier = (name: string, options: CompilerOptions) => export const luaKeywords: ReadonlySet = new Set([ "and", + "bit", + "bit32", "break", "do", "else", diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 9e89d3422..2b0351e4f 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -22,6 +22,12 @@ interface FunctionDefinitionInfo { definition?: lua.VariableDeclarationStatement | lua.AssignmentStatement; } +export enum LoopContinued { + WithGoto, + WithRepeatBreak, + WithContinue, +} + export interface Scope { type: ScopeType; id: number; @@ -30,7 +36,7 @@ export interface Scope { variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; importStatements?: lua.Statement[]; - loopContinued?: boolean; + loopContinued?: LoopContinued; functionReturned?: boolean; } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index cac697064..e5984b08f 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -32,6 +32,10 @@ export function findFirstNonOuterParent(node: ts.Node): ts.Node { return current; } +export function expressionResultIsUsed(node: ts.Expression): boolean { + return !ts.isExpressionStatement(findFirstNonOuterParent(node)); +} + export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { const originalSourceFile = ts.getParseTreeNode(sourceFile) ?? sourceFile; const declarations = (symbol.getDeclarations() ?? []).filter(d => d.getSourceFile() === originalSourceFile); @@ -91,7 +95,7 @@ export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { export function getFunctionTypeForCall(context: TransformationContext, node: ts.CallExpression) { const signature = context.checker.getResolvedSignature(node); - if (!signature || !signature.declaration) { + if (!signature?.declaration) { return; } const typeDeclaration = findFirstNodeAbove(signature.declaration, ts.isTypeAliasDeclaration); @@ -110,7 +114,7 @@ export function isConstIdentifier(context: TransformationContext, node: ts.Node) return false; } const symbol = context.checker.getSymbolAtLocation(identifier); - if (!symbol || !symbol.declarations) { + if (!symbol?.declarations) { return false; } return symbol.declarations.some( diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index ef6cec08f..09e2791c7 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -33,7 +33,11 @@ export function isInAsyncFunction(node: ts.Node): boolean { return false; } - return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; + if (ts.canHaveModifiers(declaration)) { + return ts.getModifiers(declaration)?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; + } else { + return false; + } } export function isInGeneratorFunction(node: ts.Node): boolean { diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index d13a40b38..4a356b972 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -56,6 +56,20 @@ export function isNumberType(context: TransformationContext, type: ts.Type): boo function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { if (context.checker.isArrayType(type) || context.checker.isTupleType(type)) return true; + + if (type.isUnionOrIntersection()) { + if (type.types.some(t => isExplicitArrayType(context, t))) { + return true; + } + } + + const baseTypes = type.getBaseTypes(); + if (baseTypes) { + if (baseTypes.some(t => isExplicitArrayType(context, t))) { + return true; + } + } + if (type.symbol) { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (baseConstraint && baseConstraint !== type) { @@ -63,8 +77,20 @@ function isExplicitArrayType(context: TransformationContext, type: ts.Type): boo } } + return false; +} + +function isAlwaysExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { + if (context.checker.isArrayType(type) || context.checker.isTupleType(type)) return true; + if (type.symbol) { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint && baseConstraint !== type) { + return isAlwaysExplicitArrayType(context, baseConstraint); + } + } + if (type.isUnionOrIntersection()) { - return type.types.some(t => isExplicitArrayType(context, t)); + return type.types.every(t => isAlwaysExplicitArrayType(context, t)); } return false; @@ -95,6 +121,10 @@ export function isArrayType(context: TransformationContext, type: ts.Type): bool return forTypeOrAnySupertype(context, type, t => isExplicitArrayType(context, t)); } +export function isAlwaysArrayType(context: TransformationContext, type: ts.Type): boolean { + return forTypeOrAnySupertype(context, type, t => isAlwaysExplicitArrayType(context, t)); +} + export function isFunctionType(type: ts.Type): boolean { return type.getCallSignatures().length > 0; } @@ -115,8 +145,6 @@ export function canBeFalsy(context: TransformationContext, type: ts.Type): boole } export function canBeFalsyWhenNotNull(context: TransformationContext, type: ts.Type): boolean { - const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; - if (!strictNullChecks && !type.isLiteral()) return true; const falsyFlags = ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral | diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 12e9385ad..c97c0f4c7 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -9,7 +9,7 @@ import { unsupportedOptionalCompileMembersOnly, } from "../utils/diagnostics"; import { getExtensionKindForNode } from "../utils/language-extensions"; -import { addToNumericExpression } from "../utils/lua-ast"; +import { addToNumericExpression, createExportsIdentifier } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; @@ -22,6 +22,9 @@ import { isOptionalContinuation, captureThisValue, } from "./optional-chaining"; +import { SyntaxKind } from "typescript"; +import { getCustomNameFromSymbol } from "./identifier"; +import { getSymbolExportScope, isSymbolExported } from "../utils/export"; function addOneToArrayAccessArgument( context: TransformationContext, @@ -79,13 +82,15 @@ export function transformElementAccessExpressionWithCapture( context.diagnostics.push(invalidMultiReturnAccess(node)); } - // When selecting the first element, we can shortcut - if (ts.isNumericLiteral(node.argumentExpression) && node.argumentExpression.text === "0") { - return { expression: table }; - } else { - const selectIdentifier = lua.createIdentifier("select"); - return { expression: lua.createCallExpression(selectIdentifier, [updatedAccessExpression, table]) }; + const canOmitSelect = ts.isNumericLiteral(node.argumentExpression) && node.argumentExpression.text === "0"; + if (canOmitSelect) { + // wrapping in parenthesis ensures only the first return value is used + // https://www.lua.org/manual/5.1/manual.html#2.5 + return { expression: lua.createParenthesizedExpression(table) }; } + + const selectIdentifier = lua.createIdentifier("select"); + return { expression: lua.createCallExpression(selectIdentifier, [updatedAccessExpression, table]) }; } if (thisValueCapture) { @@ -105,10 +110,16 @@ export function transformPropertyAccessExpressionWithCapture( node: ts.PropertyAccessExpression, thisValueCapture: lua.Identifier | undefined ): ExpressionWithThisValue { - const property = node.name.text; const type = context.checker.getTypeAtLocation(node.expression); const isOptionalLeft = isOptionalContinuation(node.expression); + let property = node.name.text; + const symbol = context.checker.getSymbolAtLocation(node.name); + const customName = getCustomNameFromSymbol(symbol); + if (customName) { + property = customName; + } + const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return { expression: constEnumValue }; @@ -128,6 +139,7 @@ export function transformPropertyAccessExpressionWithCapture( if (isOptionalLeft) { context.diagnostics.push(unsupportedOptionalCompileMembersOnly(node)); } + if (ts.isPropertyAccessExpression(node.expression)) { // in case of ...x.enum.y transform to ...x.y const expression = lua.createTableIndexExpression( @@ -137,7 +149,21 @@ export function transformPropertyAccessExpressionWithCapture( ); return { expression }; } else { - return { expression: lua.createIdentifier(property, node) }; + // Check if we need to account for enum being exported int his file + if ( + isSymbolExported(context, type.symbol) && + getSymbolExportScope(context, type.symbol) === node.expression.getSourceFile() + ) { + return { + expression: lua.createTableIndexExpression( + createExportsIdentifier(), + lua.createStringLiteral(property), + node + ), + }; + } else { + return { expression: lua.createIdentifier(property, node) }; + } } } @@ -171,6 +197,21 @@ export function transformPropertyAccessExpressionWithCapture( thisValue, }; } + if (node.expression.kind === SyntaxKind.SuperKeyword) { + const symbol = context.checker.getSymbolAtLocation(node); + if (symbol && symbol.flags & ts.SymbolFlags.GetAccessor) { + return { + expression: transformLuaLibFunction( + context, + LuaLibFeature.DescriptorGet, + node, + lua.createIdentifier("self"), + table, + lua.createStringLiteral(property) + ), + }; + } + } return { expression: lua.createTableIndexExpression(table, lua.createStringLiteral(property), node) }; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index efd7180cb..3e246c3f8 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; +import { SyntaxKind } from "typescript"; import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; @@ -9,7 +9,7 @@ import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; -import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; +import { cannotAssignToNodeOfKind, notAllowedOptionalAssignment } from "../../utils/diagnostics"; import { transformElementAccessArgument } from "../access"; import { moveToPrecedingTemp, transformExpressionList } from "../expression-list"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; @@ -37,9 +37,16 @@ export function transformAssignmentLeftHandSideExpression( const symbol = context.checker.getSymbolAtLocation(node); const left = context.transformExpression(node); - return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) - ? createExportedIdentifier(context, left) - : cast(left, lua.isAssignmentLeftHandSideExpression); + if (lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol)) { + return createExportedIdentifier(context, left); + } + + if (lua.isAssignmentLeftHandSideExpression(left)) { + return left; + } else { + context.diagnostics.push(cannotAssignToNodeOfKind(node, left.kind)); + return lua.createAnonymousIdentifier(); + } } export function transformAssignment( @@ -69,6 +76,29 @@ export function transformAssignment( return [arrayLengthAssignment]; } + if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { + if (lhs.expression.kind === SyntaxKind.SuperKeyword) { + const symbol = context.checker.getSymbolAtLocation(lhs); + if (symbol && symbol.flags & ts.SymbolFlags.SetAccessor) { + return [ + lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.DescriptorSet, + parent, + lua.createIdentifier("self"), + context.transformExpression(lhs.expression), + ts.isPropertyAccessExpression(lhs) + ? lua.createStringLiteral(lhs.name.text) + : context.transformExpression(lhs.argumentExpression), + right + ) + ), + ]; + } + } + } + const symbol = lhs.parent && ts.isShorthandPropertyAssignment(lhs.parent) ? context.checker.getShorthandAssignmentValueSymbol(lhs.parent) @@ -107,8 +137,9 @@ function transformDestructuredAssignmentExpression( context: TransformationContext, expression: ts.DestructuringAssignment ) { - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expression.right) + let { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(expression.right) ); context.addPrecedingStatements(rightPrecedingStatements); if (isMultiReturnCall(context, expression.right)) { @@ -153,7 +184,7 @@ export function transformAssignmentExpression( } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { - const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: right } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); @@ -233,7 +264,7 @@ export function transformAssignmentStatement( const { statements } = transformDestructuredAssignmentExpression(context, expression); return statements; } else { - const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: right } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); return transformAssignmentWithRightPrecedingStatements(context, expression.left, right, precedingStatements); diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index e284b2ea0..79e9c1f3c 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -49,6 +49,7 @@ function transformBitOperatorToLuaOperator( return lua.SyntaxKind.BitwiseLeftShiftOperator; case ts.SyntaxKind.GreaterThanGreaterThanToken: context.diagnostics.push(unsupportedRightShiftOperator(node)); + return lua.SyntaxKind.BitwiseRightShiftOperator; case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return lua.SyntaxKind.BitwiseRightShiftOperator; } @@ -63,8 +64,10 @@ export function transformBinaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Universal: + case LuaTarget.Lua50: case LuaTarget.Lua51: - context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); + return transformBinaryBitLibOperation(node, left, right, operator, "bit"); case LuaTarget.LuaJIT: return transformBinaryBitLibOperation(node, left, right, operator, "bit"); @@ -107,8 +110,10 @@ export function transformUnaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Universal: + case LuaTarget.Lua50: case LuaTarget.Lua51: - context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); + return transformUnaryBitLibOperation(node, expression, operator, "bit"); case LuaTarget.LuaJIT: return transformUnaryBitLibOperation(node, expression, operator, "bit"); diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 44c492505..4532fe56c 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -1,10 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast, assertNever } from "../../../utils"; +import { assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; -import { transformBinaryOperation } from "../binary-expression"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../../utils/preceding-statements"; +import { transformBinaryOperation } from "./index"; import { transformAssignmentWithRightPrecedingStatements } from "./assignments"; +import { isArrayLength } from "./destructuring-assignments"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { cannotAssignToNodeOfKind } from "../../utils/diagnostics"; function isLuaExpressionWithSideEffect(expression: lua.Expression) { return !(lua.isLiteral(expression) || lua.isIdentifier(expression)); @@ -63,17 +66,35 @@ export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; -export function transformCompoundAssignment( +function transformCompoundAssignment( context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -) { - const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rhs) +): WithPrecedingStatements { + if (isArrayLength(context, lhs)) { + const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter( + context, + expression, + lhs, + rhs, + operator + ); + + return { precedingStatements, result: lengthSetterStatement.expression }; + } + + const left = context.transformExpression(lhs); + if (!lua.isAssignmentLeftHandSideExpression(left)) { + context.diagnostics.push(cannotAssignToNodeOfKind(expression, left.kind)); + return { precedingStatements: [], result: left }; + } + + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) ); if (lua.isTableIndexExpression(left)) { @@ -91,7 +112,7 @@ export function transformCompoundAssignment( // ____obj[____index] = ____tmp ${replacementOperator} ${right}; // return ____tmp const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, tmp, right, @@ -101,13 +122,13 @@ export function transformCompoundAssignment( ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return { - statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], result: tmp, }; } else { if (isSetterSkippingCompoundAssignmentOperator(operator)) { return { - statements: [ + precedingStatements: [ objAndIndexDeclaration, ...transformSetterSkippingCompoundAssignment( accessExpression, @@ -122,7 +143,7 @@ export function transformCompoundAssignment( // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; // return ____tmp - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, accessExpression, right, @@ -133,7 +154,7 @@ export function transformCompoundAssignment( const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); const assignStatement = lua.createAssignmentStatement(accessExpression, tmp); return { - statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], result: tmp, }; } @@ -144,7 +165,7 @@ export function transformCompoundAssignment( // return ____tmp const tmpIdentifier = context.createTempNameForLuaExpression(left); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, tmpIdentifier, right, @@ -158,18 +179,26 @@ export function transformCompoundAssignment( operatorExpression, rightPrecedingStatements ); - return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier }; + return { + precedingStatements: [tmpDeclaration, ...precedingStatements, ...assignStatements], + result: tmpIdentifier, + }; } else { if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) { return { - statements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements), + precedingStatements: transformSetterSkippingCompoundAssignment( + left, + operator, + right, + rightPrecedingStatements + ), result: left, }; } // Simple expressions // ${left} = ${left} ${operator} ${right} - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, left, right, @@ -183,7 +212,7 @@ export function transformCompoundAssignment( operatorExpression, precedingStatements ); - return { statements, result: left }; + return { precedingStatements: statements, result: left }; } } @@ -196,8 +225,15 @@ export function transformCompoundAssignmentExpression( operator: CompoundAssignmentToken, isPostfix: boolean ): lua.Expression { - const { statements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix); - context.addPrecedingStatements(statements); + const { precedingStatements, result } = transformCompoundAssignment( + context, + expression, + lhs, + rhs, + operator, + isPostfix + ); + context.addPrecedingStatements(precedingStatements); return result; } @@ -208,9 +244,27 @@ export function transformCompoundAssignmentStatement( rhs: ts.Expression, operator: CompoundAssignmentToken ): lua.Statement[] { - const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rhs) + if (isArrayLength(context, lhs)) { + const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter( + context, + node, + lhs, + rhs, + operator + ); + + return [...precedingStatements, lengthSetterStatement]; + } + + const left = context.transformExpression(lhs); + if (!lua.isAssignmentLeftHandSideExpression(left)) { + context.diagnostics.push(cannotAssignToNodeOfKind(node, left.kind)); + return []; + } + + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) ); if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { @@ -236,8 +290,7 @@ export function transformCompoundAssignmentStatement( ]; } - let operatorExpression: lua.Expression; - [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = transformBinaryOperation( context, accessExpression, right, @@ -246,7 +299,7 @@ export function transformCompoundAssignmentStatement( node ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); - return [objAndIndexDeclaration, ...rightPrecedingStatements, assignStatement]; + return [objAndIndexDeclaration, ...rightPrecedingStatements2, assignStatement]; } else { if (isSetterSkippingCompoundAssignmentOperator(operator)) { return transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements, node); @@ -254,8 +307,7 @@ export function transformCompoundAssignmentStatement( // Simple statements // ${left} = ${left} ${replacementOperator} ${right} - let operatorExpression: lua.Expression; - [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = transformBinaryOperation( context, left, right, @@ -267,7 +319,7 @@ export function transformCompoundAssignmentStatement( context, lhs, operatorExpression, - rightPrecedingStatements + rightPrecedingStatements2 ); } } @@ -319,3 +371,32 @@ function transformSetterSkippingCompoundAssignment( ), ]; } + +function transformCompoundLengthSetter( + context: TransformationContext, + node: ts.Node, + lhs: ts.PropertyAccessExpression | ts.ElementAccessExpression, + rhs: ts.Expression, + operator: CompoundAssignmentToken +): WithPrecedingStatements { + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) + ); + const table = context.transformExpression(lhs.expression); + const lengthExpression = lua.createUnaryExpression(table, lua.SyntaxKind.LengthOperator, lhs); + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( + context, + lengthExpression, + right, + rightPrecedingStatements, + operator, + node + ); + + const arrayLengthAssignment = lua.createExpressionStatement( + transformLuaLibFunction(context, LuaLibFeature.ArraySetLength, node, table, operatorExpression) + ); + + return { precedingStatements, result: arrayLengthAssignment }; +} diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index d3d0086c0..aa7042727 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -97,15 +97,14 @@ function transformArrayLiteralAssignmentPattern( lua.SyntaxKind.EqualityOperator ); - const [defaultPrecedingStatements, defaultAssignmentStatements] = transformInPrecedingStatementScope( - context, - () => + const { precedingStatements: defaultPrecedingStatements, result: defaultAssignmentStatements } = + transformInPrecedingStatementScope(context, () => transformAssignment( context, (element as ts.BinaryExpression).left, context.transformExpression((element as ts.BinaryExpression).right) ) - ); + ); // Keep preceding statements inside if block defaultAssignmentStatements.unshift(...defaultPrecedingStatements); @@ -126,7 +125,7 @@ function transformArrayLiteralAssignmentPattern( case ts.SyntaxKind.Identifier: case ts.SyntaxKind.PropertyAccessExpression: case ts.SyntaxKind.ElementAccessExpression: - const [precedingStatements, statements] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: statements } = transformInPrecedingStatementScope(context, () => transformAssignment(context, element, indexedRoot, rightHasPrecedingStatements) ); return [...precedingStatements, ...statements]; // Keep preceding statements in order @@ -144,14 +143,15 @@ function transformArrayLiteralAssignmentPattern( lua.createNumericLiteral(index) ); - const [spreadPrecedingStatements, spreadStatements] = transformInPrecedingStatementScope(context, () => - transformAssignment( - context, - (element as ts.SpreadElement).expression, - restElements, - rightHasPrecedingStatements - ) - ); + const { precedingStatements: spreadPrecedingStatements, result: spreadStatements } = + transformInPrecedingStatementScope(context, () => + transformAssignment( + context, + (element as ts.SpreadElement).expression, + restElements, + rightHasPrecedingStatements + ) + ); return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order case ts.SyntaxKind.OmittedExpression: return []; @@ -279,9 +279,8 @@ function transformPropertyAssignment( const left = cast(context.transformExpression(node.initializer.left), lua.isTableIndexExpression); const rightExpression = node.initializer.right; - const [defaultPrecedingStatements, defaultExpression] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rightExpression) - ); + const { precedingStatements: defaultPrecedingStatements, result: defaultExpression } = + transformInPrecedingStatementScope(context, () => context.transformExpression(rightExpression)); const tableTemp = context.createTempNameForLuaExpression(left.table); const indexTemp = context.createTempNameForLuaExpression(left.index); @@ -292,7 +291,7 @@ function transformPropertyAssignment( ); // obj[index] = extractingExpression ?? defaultExpression - const [rightPrecedingStatements, rhs] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements, result: rhs } = transformBinaryOperation( context, extractingExpression, defaultExpression, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index ba292d126..f2b0acb16 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../../CompilerOptions"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { wrapInToStringForConcat } from "../../utils/lua-ast"; @@ -15,7 +16,7 @@ import { } from "./compound"; import { assert } from "../../../utils"; import { transformOrderedExpressions } from "../expression-list"; -import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../../utils/preceding-statements"; type ShortCircuitOperator = | ts.SyntaxKind.AmpersandAmpersandToken @@ -68,6 +69,11 @@ function transformBinaryOperationWithNoPrecedingStatements( return transformNullishCoalescingOperationNoPrecedingStatements(context, node, left, right); } + if (operator === ts.SyntaxKind.PercentToken && context.luaTarget === LuaTarget.Lua50) { + const mathMod = lua.createTableIndexExpression(lua.createIdentifier("math"), lua.createStringLiteral("mod")); + return lua.createCallExpression(mathMod, [left, right], node); + } + let luaOperator = simpleOperatorsToLua[operator]; // Check if we need to use string concat operator @@ -94,7 +100,7 @@ export function createShortCircuitBinaryExpressionPrecedingStatements( rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { const conditionIdentifier = context.createTempNameForLuaExpression(lhs); const assignmentStatement = lua.createVariableDeclarationStatement(conditionIdentifier, lhs, node?.left); @@ -126,19 +132,19 @@ export function createShortCircuitBinaryExpressionPrecedingStatements( undefined, node?.left ); - return [[assignmentStatement, ifStatement], conditionIdentifier]; + return { precedingStatements: [assignmentStatement, ifStatement], result: conditionIdentifier }; } function transformShortCircuitBinaryExpression( context: TransformationContext, node: ts.BinaryExpression, operator: ShortCircuitOperator -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { const lhs = context.transformExpression(node.left); - const [rightPrecedingStatements, rhs] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result } = transformInPrecedingStatementScope(context, () => context.transformExpression(node.right) ); - return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node); + return transformBinaryOperation(context, lhs, result, precedingStatements, operator, node); } export function transformBinaryOperation( @@ -148,7 +154,7 @@ export function transformBinaryOperation( rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) { assert(ts.isBinaryExpression(node)); return createShortCircuitBinaryExpressionPrecedingStatements( @@ -161,10 +167,10 @@ export function transformBinaryOperation( ); } - return [ - rightPrecedingStatements, - transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node), - ]; + return { + precedingStatements: rightPrecedingStatements, + result: transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node), + }; } export const transformBinaryExpression: FunctionVisitor = (node, context) => { @@ -210,7 +216,7 @@ export const transformBinaryExpression: FunctionVisitor = ( case ts.SyntaxKind.CommaToken: { const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left)); - const [precedingStatements, result] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result } = transformInPrecedingStatementScope(context, () => context.transformExpression(node.right) ); statements.push(...precedingStatements); @@ -221,17 +227,27 @@ export const transformBinaryExpression: FunctionVisitor = ( case ts.SyntaxKind.QuestionQuestionToken: case ts.SyntaxKind.AmpersandAmpersandToken: case ts.SyntaxKind.BarBarToken: { - const [precedingStatements, result] = transformShortCircuitBinaryExpression(context, node, operator); + const { precedingStatements, result } = transformShortCircuitBinaryExpression(context, node, operator); context.addPrecedingStatements(precedingStatements); return result; } } - let [precedingStatements, [lhs, rhs]] = transformInPrecedingStatementScope(context, () => + const { + precedingStatements: orderedExpressionPrecedingStatements, + result: [lhs, rhs], + } = transformInPrecedingStatementScope(context, () => transformOrderedExpressions(context, [node.left, node.right]) ); - let result: lua.Expression; - [precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node); + + const { precedingStatements, result } = transformBinaryOperation( + context, + lhs, + rhs, + orderedExpressionPrecedingStatements, + operator, + node + ); context.addPrecedingStatements(precedingStatements); return result; }; @@ -271,7 +287,7 @@ function transformNullishCoalescingOperationNoPrecedingStatements( // Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'. if (canBeFalsyWhenNotNull(context, lhsType)) { // reuse logic from case with preceding statements - const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements( + const { precedingStatements, result } = createShortCircuitBinaryExpressionPrecedingStatements( context, transformedLeft, transformedRight, diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 9e476b17e..87487475d 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -2,8 +2,7 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { unsupportedForTarget } from "../utils/diagnostics"; -import { findScope, ScopeType } from "../utils/scope"; +import { findScope, LoopContinued, ScopeType } from "../utils/scope"; export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { void context; @@ -11,15 +10,36 @@ export const transformBreakStatement: FunctionVisitor = (brea }; export const transformContinueStatement: FunctionVisitor = (statement, context) => { - if (context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua51) { - context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", LuaTarget.Lua51)); - } - const scope = findScope(context, ScopeType.Loop); + const continuedWith = { + [LuaTarget.Universal]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua50]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua51]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua52]: LoopContinued.WithGoto, + [LuaTarget.Lua53]: LoopContinued.WithGoto, + [LuaTarget.Lua54]: LoopContinued.WithGoto, + [LuaTarget.LuaJIT]: LoopContinued.WithGoto, + [LuaTarget.Luau]: LoopContinued.WithContinue, + }[context.luaTarget]; + if (scope) { - scope.loopContinued = true; + scope.loopContinued = continuedWith; } - return lua.createGotoStatement(`__continue${scope?.id ?? ""}`, statement); + const label = `__continue${scope?.id ?? ""}`; + + switch (continuedWith) { + case LoopContinued.WithGoto: + return lua.createGotoStatement(label, statement); + + case LoopContinued.WithContinue: + return lua.createContinueStatement(statement); + + case LoopContinued.WithRepeatBreak: + return [ + lua.createAssignmentStatement(lua.createIdentifier(label), lua.createBooleanLiteral(true), statement), + lua.createBreakStatement(statement), + ]; + } }; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 9fac8aa0f..1f9fb521b 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { validateAssignment } from "../utils/assignment-validation"; -import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { ContextType, getCallContextType } from "../utils/function-context"; import { wrapInTable } from "../utils/lua-ast"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; @@ -15,6 +15,7 @@ import { transformInPrecedingStatementScope } from "../utils/preceding-statement import { getOptionalContinuationData, transformOptionalChain } from "./optional-chaining"; import { transformImportExpression } from "./modules/import"; import { transformLanguageExtensionCallExpression } from "./language-extensions/call-extension"; +import { getCustomNameFromSymbol } from "./identifier"; export function validateArguments( context: TransformationContext, @@ -80,9 +81,8 @@ export function transformCallAndArguments( signature?: ts.Signature, callContext?: ts.Expression ): [lua.Expression, lua.Expression[]] { - const [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => - transformArguments(context, params, signature, callContext) - ); + const { precedingStatements: argPrecedingStatements, result: transformedArguments } = + transformInPrecedingStatementScope(context, () => transformArguments(context, params, signature, callContext)); return transformCallWithArguments(context, callExpression, transformedArguments, argPrecedingStatements); } @@ -117,17 +117,15 @@ function transformElementAccessCall( export function transformContextualCallExpression( context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, - args: ts.Expression[] | ts.NodeArray, - signature?: ts.Signature + args: ts.Expression[] | ts.NodeArray ): lua.Expression { if (ts.isOptionalChain(node)) { return transformOptionalChain(context, node); } const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag; - let [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => - transformArguments(context, args, signature) - ); + let { precedingStatements: argPrecedingStatements, result: transformedArguments } = + transformInPrecedingStatementScope(context, () => transformArguments(context, args)); if ( ts.isPropertyAccessExpression(left) && @@ -137,12 +135,16 @@ export function transformContextualCallExpression( ) { // table:name() const table = context.transformExpression(left.expression); - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformedArguments, - node - ); + let name = left.name.text; + + const symbol = context.checker.getSymbolAtLocation(left); + const customName = getCustomNameFromSymbol(symbol); + + if (customName) { + name = customName; + } + + return lua.createMethodCallExpression(table, lua.createIdentifier(name, left.name), transformedArguments, node); } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { return transformElementAccessCall(context, left, transformedArguments, argPrecedingStatements); @@ -186,10 +188,9 @@ function transformPropertyCall( return lua.createCallExpression(context.transformExpression(node.expression), parameters, node); } - const signatureDeclaration = signature?.getDeclaration(); - if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + if (getCallContextType(context, node) !== ContextType.Void) { // table:name() - return transformContextualCallExpression(context, node, node.arguments, signature); + return transformContextualCallExpression(context, node, node.arguments); } else { // table.name() const [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); @@ -199,14 +200,12 @@ function transformPropertyCall( } function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { - const signature = context.checker.getResolvedSignature(node); - const signatureDeclaration = signature?.getDeclaration(); - if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + if (getCallContextType(context, node) !== ContextType.Void) { // A contextual parameter must be given to this call expression - return transformContextualCallExpression(context, node, node.arguments, signature); + return transformContextualCallExpression(context, node, node.arguments); } else { // No context - const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); + const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments); return lua.createCallExpression(expression, parameters, node); } } @@ -264,7 +263,9 @@ export const transformCallExpression: FunctionVisitor = (node let callPath: lua.Expression; let parameters: lua.Expression[]; - const isContextualCall = isContextualCallExpression(context, signature); + + const isContextualCall = getCallContextType(context, node) !== ContextType.Void; + if (!isContextualCall) { [callPath, parameters] = transformCallAndArguments(context, calledExpression, node.arguments, signature); } else { @@ -287,14 +288,6 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResultInTable ? wrapInTable(callExpression) : callExpression; }; -function isContextualCallExpression(context: TransformationContext, signature: ts.Signature | undefined): boolean { - const declaration = signature?.getDeclaration(); - if (!declaration) { - return !context.options.noImplicitSelf; - } - return getDeclarationContextType(context, declaration) !== ContextType.Void; -} - export function getCalledExpression(node: ts.CallExpression): ts.Expression { return ts.skipOuterExpressions(node.expression); } diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 4b913485c..11e4b75c7 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -1,9 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import { decoratorInvalidContext } from "../../utils/diagnostics"; +import { decoratorInvalidContext, incompleteFieldDecoratorWarning } from "../../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isNonNull } from "../../../utils"; +import { transformMemberExpressionOwnerName, transformMethodName } from "./members/method"; +import { transformPropertyName } from "../literal"; +import { isPrivateNode, isStaticNode } from "./utils"; export function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression { const expression = decorator.expression; @@ -16,7 +20,161 @@ export function transformDecoratorExpression(context: TransformationContext, dec return context.transformExpression(expression); } -export function createDecoratingExpression( +export function createClassDecoratingExpression( + context: TransformationContext, + classDeclaration: ts.ClassDeclaration | ts.ClassExpression, + className: lua.Expression +): lua.Expression { + const classDecorators = + ts.getDecorators(classDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? []; + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + return createLegacyDecoratingExpression(context, classDeclaration.kind, classDecorators, className); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, className, classDecorators, { + kind: lua.createStringLiteral("class"), + name: lua.createStringLiteral(classDeclaration.name?.getText() ?? ""), + }); +} + +export function createClassMethodDecoratingExpression( + context: TransformationContext, + methodDeclaration: ts.MethodDeclaration, + originalMethod: lua.Expression, + className: lua.Identifier +): lua.Expression { + const parameterDecorators = getParameterDecorators(context, methodDeclaration); + const methodDecorators = + ts.getDecorators(methodDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? []; + + const methodName = transformMethodName(context, methodDeclaration); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const methodTable = transformMemberExpressionOwnerName(methodDeclaration, className); + return createLegacyDecoratingExpression( + context, + methodDeclaration.kind, + [...methodDecorators, ...parameterDecorators], + methodTable, + methodName + ); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, originalMethod, methodDecorators, { + kind: lua.createStringLiteral("method"), + name: methodName, + private: lua.createBooleanLiteral(isPrivateNode(methodDeclaration)), + static: lua.createBooleanLiteral(isStaticNode(methodDeclaration)), + }); +} + +export function createClassAccessorDecoratingExpression( + context: TransformationContext, + accessor: ts.AccessorDeclaration, + originalAccessor: lua.Expression, + className: lua.Identifier +): lua.Expression { + const accessorDecorators = ts.getDecorators(accessor)?.map(d => transformDecoratorExpression(context, d)) ?? []; + const propertyName = transformPropertyName(context, accessor.name); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const propertyOwnerTable = transformMemberExpressionOwnerName(accessor, className); + + return createLegacyDecoratingExpression( + context, + accessor.kind, + accessorDecorators, + propertyOwnerTable, + propertyName + ); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, originalAccessor, accessorDecorators, { + kind: lua.createStringLiteral(accessor.kind === ts.SyntaxKind.SetAccessor ? "setter" : "getter"), + name: propertyName, + private: lua.createBooleanLiteral(isPrivateNode(accessor)), + static: lua.createBooleanLiteral(isStaticNode(accessor)), + }); +} + +export function createClassPropertyDecoratingExpression( + context: TransformationContext, + property: ts.PropertyDeclaration, + className: lua.Identifier +): lua.Expression { + const decorators = ts.getDecorators(property) ?? []; + const propertyDecorators = decorators.map(d => transformDecoratorExpression(context, d)); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const propertyName = transformPropertyName(context, property.name); + const propertyOwnerTable = transformMemberExpressionOwnerName(property, className); + + return createLegacyDecoratingExpression( + context, + property.kind, + propertyDecorators, + propertyOwnerTable, + propertyName + ); + } + + // Else: TypeScript 5.0 decorator + + // Add a diagnostic when something is returned from a field decorator + for (const decorator of decorators) { + const signature = context.checker.getResolvedSignature(decorator); + const decoratorReturnType = signature?.getReturnType(); + // If return type of decorator is NOT void + if (decoratorReturnType && (decoratorReturnType.flags & ts.TypeFlags.Void) === 0) { + context.diagnostics.push(incompleteFieldDecoratorWarning(property)); + } + } + + return createDecoratingExpression(context, className, lua.createNilLiteral(), propertyDecorators, { + kind: lua.createStringLiteral("field"), + name: lua.createStringLiteral(property.name.getText()), + private: lua.createBooleanLiteral(isPrivateNode(property)), + static: lua.createBooleanLiteral(isStaticNode(property)), + }); +} + +function createDecoratingExpression( + context: TransformationContext, + className: lua.Expression, + originalValue: TValue, + decorators: lua.Expression[], + decoratorContext: Record +): lua.Expression { + const decoratorTable = lua.createTableExpression(decorators.map(d => lua.createTableFieldExpression(d))); + const decoratorContextTable = objectToLuaTableLiteral(decoratorContext); + + return transformLuaLibFunction( + context, + LuaLibFeature.Decorate, + undefined, + className, + originalValue, + decoratorTable, + decoratorContextTable + ); +} + +function objectToLuaTableLiteral(obj: Record): lua.Expression { + return lua.createTableExpression( + Object.entries(obj).map(([key, value]) => lua.createTableFieldExpression(value, lua.createStringLiteral(key))) + ); +} + +// Legacy decorators: +function createLegacyDecoratingExpression( context: TransformationContext, kind: ts.SyntaxKind, decorators: lua.Expression[], @@ -35,5 +193,39 @@ export function createDecoratingExpression( trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral()); } - return transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, ...trailingExpressions); + return transformLuaLibFunction(context, LuaLibFeature.DecorateLegacy, undefined, ...trailingExpressions); +} + +function getParameterDecorators( + context: TransformationContext, + node: ts.FunctionLikeDeclarationBase +): lua.CallExpression[] { + return node.parameters + .flatMap((parameter, index) => + ts + .getDecorators(parameter) + ?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) + ) + ) + .filter(isNonNull); +} + +export function createConstructorDecoratingExpression( + context: TransformationContext, + node: ts.ConstructorDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + const parameterDecorators = getParameterDecorators(context, node); + + if (parameterDecorators.length > 0) { + const decorateMethod = createLegacyDecoratingExpression(context, node.kind, parameterDecorators, className); + return lua.createExpressionStatement(decorateMethod); + } } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 3aee65a36..0edfce050 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { FunctionVisitor, TransformationContext } from "../../context"; +import { AllAccessorDeclarations, FunctionVisitor, TransformationContext } from "../../context"; import { createDefaultExportExpression, createExportedIdentifier, @@ -11,24 +11,27 @@ import { import { createSelfIdentifier } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { transformIdentifier } from "../identifier"; -import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; +import { createClassDecoratingExpression, createConstructorDecoratingExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; -import { - createPropertyDecoratingExpression, - transformClassInstanceFields, - transformStaticPropertyDeclaration, -} from "./members/fields"; -import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; +import { transformClassInstanceFields, transformStaticPropertyDeclaration } from "./members/fields"; +import { transformMethodDeclaration } from "./members/method"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; +import { LuaTarget } from "../../../CompilerOptions"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { createClassPropertyDecoratingExpression } from "./decorators"; +import { findFirstNodeAbove } from "../../utils/typescript"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { - const left = createDefaultExportExpression(declaration); - const right = transformClassAsExpression(declaration, context); - return [lua.createAssignmentStatement(left, right, declaration)]; + // Class declaration including assignment to ____exports.default are in preceding statements + const { precedingStatements } = transformInPrecedingStatementScope(context, () => { + transformClassAsExpression(declaration, context); + return []; + }); + return precedingStatements; } const { statements } = transformClassLikeDeclaration(declaration, context); @@ -111,11 +114,15 @@ function transformClassLikeDeclaration( ); if (constructorResult) result.push(constructorResult); + + // Legacy constructor decorator + const decoratingExpression = createConstructorDecoratingExpression(context, constructor, localClassName); + if (decoratingExpression) result.push(decoratingExpression); } 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)), + ts.factory.createConstructorDeclaration([], [], ts.factory.createBlock([], true)), localClassName, instanceFields, classDeclaration @@ -125,16 +132,20 @@ function transformClassLikeDeclaration( } 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, ...) + // baseClassName.prototype.____constructor(self, ...) // or unpack(arg) for Lua 5.0 // ... const constructorBody = transformClassInstanceFields(context, instanceFields); + const argsExpression = + context.luaTarget === LuaTarget.Lua50 + ? lua.createCallExpression(lua.createIdentifier("unpack"), [lua.createArgLiteral()]) + : lua.createDotsLiteral(); const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), - [createSelfIdentifier(), lua.createDotsLiteral()] + [createSelfIdentifier(), argsExpression] ) ); constructorBody.unshift(superCall); @@ -149,51 +160,57 @@ function transformClassLikeDeclaration( ); } - // Transform accessors - for (const member of classDeclaration.members) { - if (!ts.isAccessor(member)) continue; - const accessors = context.resolver.getAllAccessorDeclarations(member); - if (accessors.firstAccessor !== member) continue; + // Transform class members - const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); - if (accessorsResult) { - result.push(accessorsResult); + // First transform the methods, in case the static properties call them + for (const member of classDeclaration.members) { + if (ts.isMethodDeclaration(member)) { + // Methods + const statements = transformMethodDeclaration(context, member, localClassName); + result.push(...statements); } } - const decorationStatements: lua.Statement[] = []; - + // Then transform the rest 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); + // Accessors + const symbol = context.checker.getSymbolAtLocation(member.name); + if (!symbol) continue; + const accessors = getAllAccessorDeclarations(classDeclaration, symbol, context); + if (accessors.firstAccessor !== member) continue; + + const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); + if (accessorsResult) { + result.push(accessorsResult); } } else if (ts.isPropertyDeclaration(member)) { + // Properties if (isStaticNode(member)) { const statement = transformStaticPropertyDeclaration(context, member, localClassName); - if (statement) decorationStatements.push(statement); + if (statement) result.push(statement); + } + + if (ts.getDecorators(member)?.length) { + result.push( + lua.createExpressionStatement(createClassPropertyDecoratingExpression(context, member, className)) + ); + } + } else if (ts.isClassStaticBlockDeclaration(member)) { + if (member.body.statements.length > 0) { + const bodyStatements = context.transformStatements(member.body.statements); + const iif = lua.createFunctionExpression(lua.createBlock(bodyStatements), [ + lua.createIdentifier("self"), + ]); + const iife = lua.createCallExpression(iif, [className]); + result.push(lua.createExpressionStatement(iife, member)); } - const expression = createPropertyDecoratingExpression(context, member, localClassName); - if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } } - result.push(...decorationStatements); - // Decorate the class - if (classDeclaration.decorators) { - const decoratingExpression = createDecoratingExpression( - context, - classDeclaration.kind, - classDeclaration.decorators.map(d => transformDecoratorExpression(context, d)), - localClassName - ); + if (ts.canHaveDecorators(classDeclaration) && ts.getDecorators(classDeclaration)) { + const decoratingExpression = createClassDecoratingExpression(context, classDeclaration, localClassName); const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); result.push(decoratingStatement); @@ -212,6 +229,31 @@ function transformClassLikeDeclaration( return { statements: result, name: className }; } +function getAllAccessorDeclarations( + classDeclaration: ts.ClassLikeDeclaration, + symbol: ts.Symbol, + context: TransformationContext +): AllAccessorDeclarations { + const getAccessor = classDeclaration.members.find( + (m): m is ts.GetAccessorDeclaration => + ts.isGetAccessor(m) && context.checker.getSymbolAtLocation(m.name) === symbol + ); + const setAccessor = classDeclaration.members.find( + (m): m is ts.SetAccessorDeclaration => + ts.isSetAccessor(m) && context.checker.getSymbolAtLocation(m.name) === symbol + ); + + // Get the first of the two (that is not undefined) + const firstAccessor = + getAccessor && (!setAccessor || getAccessor.pos < setAccessor.pos) ? getAccessor : setAccessor!; + + return { + firstAccessor, + setAccessor, + getAccessor, + }; +} + export const transformSuperExpression: FunctionVisitor = (expression, context) => { const superInfos = context.classSuperInfos; const superInfo = superInfos[superInfos.length - 1]; @@ -235,5 +277,11 @@ export const transformSuperExpression: FunctionVisitor = (ex baseClassName = lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression); } - return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); + const f = findFirstNodeAbove(expression, ts.isFunctionLike); + if (f && ts.canHaveModifiers(f) && isStaticNode(f)) { + // In static method, don't add prototype to super call + return baseClassName; + } else { + return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); + } }; diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index fe34a3d8a..165d3fa88 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -7,11 +7,27 @@ import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; import { createPrototypeName } from "./constructor"; +import { createClassAccessorDecoratingExpression } from "../decorators"; -function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { +function transformAccessor( + context: TransformationContext, + node: ts.AccessorDeclaration, + className: lua.Identifier +): lua.Expression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; - return lua.createFunctionExpression(lua.createBlock(body), params, dot, lua.NodeFlags.Declaration); + const accessorFunction = lua.createFunctionExpression( + lua.createBlock(body), + params, + dot, + lua.NodeFlags.Declaration + ); + + if (ts.getDecorators(node)?.length) { + return createClassAccessorDecoratingExpression(context, node, accessorFunction, className); + } else { + return accessorFunction; + } } export function transformAccessorDeclarations( @@ -23,12 +39,12 @@ export function transformAccessorDeclarations( const descriptor = lua.createTableExpression([]); if (getAccessor) { - const getterFunction = transformAccessor(context, getAccessor); + const getterFunction = transformAccessor(context, getAccessor, className); descriptor.fields.push(lua.createTableFieldExpression(getterFunction, lua.createStringLiteral("get"))); } if (setAccessor) { - const setterFunction = transformAccessor(context, setAccessor); + const setterFunction = transformAccessor(context, setAccessor, className); descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); } diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 73aad20a8..039e705f7 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -45,23 +45,22 @@ export function transformConstructorDeclaration( 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 + // If there are field initializers and there is a super call somewhere, + // move super call and everything before it to between default assignments and initializers if ( (constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) && statement.body && statement.body.statements.length > 0 ) { - const firstStatement = statement.body.statements[0]; - if ( - ts.isExpressionStatement(firstStatement) && - ts.isCallExpression(firstStatement.expression) && - firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword - ) { - const superCall = body.shift(); - if (superCall) { - bodyWithFieldInitializers.push(superCall); - } + const superIndex = statement.body.statements.findIndex( + s => + ts.isExpressionStatement(s) && + ts.isCallExpression(s.expression) && + s.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ); + + if (superIndex !== -1) { + bodyWithFieldInitializers.push(...body.splice(0, superIndex + 1)); } } diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 49edacdb3..2308eaac8 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -4,25 +4,6 @@ import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements"; import { transformPropertyName } from "../../literal"; -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, @@ -31,7 +12,7 @@ export function transformClassInstanceFields( const statements: lua.Statement[] = []; for (const f of instanceFields) { - const [precedingStatements, statement] = transformInPrecedingStatementScope(context, () => { + const { precedingStatements, result: statement } = transformInPrecedingStatementScope(context, () => { // Get identifier const fieldName = transformPropertyName(context, f.name); @@ -61,5 +42,6 @@ export function transformStaticPropertyDeclaration( 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 c902ea8de..adfe2c352 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -4,10 +4,8 @@ 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"; +import { createClassMethodDecoratingExpression } from "../decorators"; export function transformMemberExpressionOwnerName( node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, @@ -28,53 +26,45 @@ export function transformMethodDeclaration( context: TransformationContext, node: ts.MethodDeclaration, className: lua.Identifier -): lua.Statement | undefined { +): lua.Statement[] { // Don't transform methods without body (overload declarations) - if (!node.body) return; + if (!node.body) return []; const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); - return lua.createAssignmentStatement( - lua.createTableIndexExpression(methodTable, methodName), - functionExpression, - 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)) ?? []; + const methodHasDecorators = (ts.getDecorators(node)?.length ?? 0) > 0; + const methodHasParameterDecorators = node.parameters.some(p => (ts.getDecorators(p)?.length ?? 0) > 0); // Legacy decorators - if (methodDecorators.length > 0 || parameterDecorators.length > 0) { - const decorateMethod = createDecoratingExpression( - context, - node.kind, - [...methodDecorators, ...parameterDecorators], - methodTable, - methodName - ); - return lua.createExpressionStatement(decorateMethod); + if (methodHasDecorators || methodHasParameterDecorators) { + if (context.options.experimentalDecorators) { + // Legacy decorator statement + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression + ), + lua.createExpressionStatement( + createClassMethodDecoratingExpression(context, node, functionExpression, className) + ), + ]; + } else { + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + createClassMethodDecoratingExpression(context, node, functionExpression, className), + node + ), + ]; + } + } else { + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression, + node + ), + ]; } } diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 9fcdc3c94..0c5733451 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,23 +2,44 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount, unsupportedArrayWithLengthConstructor } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; +import { tryGetStandardLibrarySymbolOfType } from "../../builtins"; export const transformNewExpression: FunctionVisitor = (node, context) => { if (isTableNewCall(context, node)) { return lua.createTableExpression(undefined, node); } + const constructorType = context.checker.getTypeAtLocation(node.expression); + if (tryGetStandardLibrarySymbolOfType(context, constructorType)?.name === "ArrayConstructor") { + if (node.arguments === undefined || node.arguments.length === 0) { + // turn new Array<>() into a simple {} + return lua.createTableExpression([], node); + } else { + // More than one argument, check if items constructor + const signature = context.checker.getResolvedSignature(node); + const signatureDeclaration = signature?.getDeclaration(); + if ( + signatureDeclaration?.parameters.length === 1 && + signatureDeclaration.parameters[0].dotDotDotToken === undefined + ) { + context.diagnostics.push(unsupportedArrayWithLengthConstructor(node)); + return lua.createTableExpression([], node); + } else { + const callArguments = transformArguments(context, node.arguments, signature); + return lua.createTableExpression( + callArguments.map(e => lua.createTableFieldExpression(e)), + node + ); + } + } + } + const signature = context.checker.getResolvedSignature(node); - const [name, params] = transformCallAndArguments( - context, - node.expression, - node.arguments ?? [ts.factory.createTrue()], - signature - ); + const [name, params] = transformCallAndArguments(context, node.expression, node.arguments ?? [], signature); const type = context.checker.getTypeAtLocation(node); const annotations = getTypeAnnotations(type); diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 8708a54fb..0cd4384bb 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,12 +1,16 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; -export function isStaticNode(node: ts.Node): boolean { - return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); +export function isPrivateNode(node: ts.HasModifiers): boolean { + return node.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword) === true; +} + +export function isStaticNode(node: ts.HasModifiers): boolean { + return node.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) === true; } export function getExtendsClause(node: ts.ClassLikeDeclarationBase): ts.HeritageClause | undefined { - return (node.heritageClauses ?? []).find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); + return node.heritageClauses?.find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); } export function getExtendedNode(node: ts.ClassLikeDeclarationBase): ts.ExpressionWithTypeArguments | undefined { diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 82d214cdd..b90c7e2db 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -1,36 +1,35 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../utils/preceding-statements"; import { performHoisting, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; import { truthyOnlyConditionalValue } from "../utils/diagnostics"; - -type EvaluatedExpression = [precedingStatemens: lua.Statement[], value: lua.Expression]; +import { LuaTarget } from "../../CompilerOptions"; function transformProtectedConditionalExpression( context: TransformationContext, expression: ts.ConditionalExpression, - condition: EvaluatedExpression, - whenTrue: EvaluatedExpression, - whenFalse: EvaluatedExpression + condition: WithPrecedingStatements, + whenTrue: WithPrecedingStatements, + whenFalse: WithPrecedingStatements ): lua.Expression { const tempVar = context.createTempNameForNode(expression.condition); - const trueStatements = whenTrue[0].concat( - lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue[1], expression.whenTrue) + const trueStatements = whenTrue.precedingStatements.concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue.result, expression.whenTrue) ); - const falseStatements = whenFalse[0].concat( - lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse[1], expression.whenFalse) + const falseStatements = whenFalse.precedingStatements.concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse.result, expression.whenFalse) ); context.addPrecedingStatements([ lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition), - ...condition[0], + ...condition.precedingStatements, lua.createIfStatement( - condition[1], + condition.result, lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression @@ -40,6 +39,16 @@ function transformProtectedConditionalExpression( } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { + if (context.luaTarget === LuaTarget.Luau) { + // Luau's ternary operator doesn't have these issues + return lua.createConditionalExpression( + context.transformExpression(expression.condition), + context.transformExpression(expression.whenTrue), + context.transformExpression(expression.whenFalse), + expression + ); + } + // Check if we need to add diagnostic about Lua truthiness checkOnlyTruthyCondition(expression.condition, context); @@ -53,17 +62,17 @@ export const transformConditionalExpression: FunctionVisitor 0 || - whenFalse[0].length > 0 || + whenTrue.precedingStatements.length > 0 || + whenFalse.precedingStatements.length > 0 || canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue)) ) { return transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse); } // condition and v1 or v2 - context.addPrecedingStatements(condition[0]); - const conditionAnd = lua.createBinaryExpression(condition[1], whenTrue[1], lua.SyntaxKind.AndOperator); - return lua.createBinaryExpression(conditionAnd, whenFalse[1], lua.SyntaxKind.OrOperator, expression); + context.addPrecedingStatements(condition.precedingStatements); + const conditionAnd = lua.createBinaryExpression(condition.result, whenTrue.result, lua.SyntaxKind.AndOperator); + return lua.createBinaryExpression(conditionAnd, whenFalse.result, lua.SyntaxKind.OrOperator, expression); }; export function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): lua.IfStatement { @@ -80,7 +89,7 @@ export function transformIfStatement(statement: ts.IfStatement, context: Transfo if (statement.elseStatement) { if (ts.isIfStatement(statement.elseStatement)) { const tsElseStatement = statement.elseStatement; - const [precedingStatements, elseStatement] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: elseStatement } = transformInPrecedingStatementScope(context, () => transformIfStatement(tsElseStatement, context) ); // If else-if condition generates preceding statements, we can't use elseif, we have to break it down: @@ -113,6 +122,9 @@ export function transformIfStatement(statement: ts.IfStatement, context: Transfo } export function checkOnlyTruthyCondition(condition: ts.Expression, context: TransformationContext) { + if (context.options.strictNullChecks === false) return; // This check is not valid if everything could implicitly be nil + if (ts.isElementAccessExpression(condition)) return; // Array index could always implicitly return nil + if (!canBeFalsy(context, context.checker.getTypeAtLocation(condition))) { context.diagnostics.push(truthyOnlyConditionalValue(condition)); } diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 783a340e5..f81519e4c 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -16,7 +16,10 @@ import { createReturnStatement } from "./return"; const transformAsyncTry: FunctionVisitor = (statement, context) => { const [tryBlock] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if (context.options.luaTarget === LuaTarget.Lua51 && !context.options.lua51AllowTryCatchInAsyncAwait) { + if ( + (context.options.luaTarget === LuaTarget.Lua50 || context.options.luaTarget === LuaTarget.Lua51) && + !context.options.lua51AllowTryCatchInAsyncAwait + ) { context.diagnostics.push( unsupportedForTargetButOverrideAvailable( statement, @@ -79,7 +82,10 @@ export const transformTryStatement: FunctionVisitor = (statemen const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if (context.options.luaTarget === LuaTarget.Lua51 && isInGeneratorFunction(statement)) { + if ( + (context.options.luaTarget === LuaTarget.Lua50 || context.options.luaTarget === LuaTarget.Lua51) && + isInGeneratorFunction(statement) + ) { context.diagnostics.push( unsupportedForTarget(statement, "try/catch inside generator functions", LuaTarget.Lua51) ); diff --git a/src/transformation/visitors/expression-list.ts b/src/transformation/visitors/expression-list.ts index 475108922..617d09d4a 100644 --- a/src/transformation/visitors/expression-list.ts +++ b/src/transformation/visitors/expression-list.ts @@ -47,9 +47,8 @@ function transformExpressions( const transformedExpressions: lua.Expression[] = []; let lastPrecedingStatementsIndex = -1; for (let i = 0; i < expressions.length; ++i) { - const [expressionPrecedingStatements, expression] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expressions[i]) - ); + const { precedingStatements: expressionPrecedingStatements, result: expression } = + transformInPrecedingStatementScope(context, () => context.transformExpression(expressions[i])); transformedExpressions.push(expression); if (expressionPrecedingStatements.length > 0) { lastPrecedingStatementsIndex = i; diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index ebc0b1600..a247fd29b 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor, tempSymbolId, TransformationContext } from "../context"; +import { FunctionVisitor, tempSymbolId } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -15,15 +15,10 @@ export const transformExpressionStatement: FunctionVisitor context.transformExpression(value) + ); + if (!lua.isNilLiteral(parameterValue)) { + statements.push(lua.createAssignmentStatement(parameterName, parameterValue)); + } + if (statements.length === 0) return undefined; const nilCondition = lua.createBinaryExpression( parameterName, @@ -35,7 +42,7 @@ function transformParameterDefaultValueDeclaration( lua.SyntaxKind.EqualityOperator ); - const ifBlock = lua.createBlock([assignment]); + const ifBlock = lua.createBlock(statements, tsOriginal); return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); } @@ -89,7 +96,7 @@ export function isFunctionTypeWithProperties(context: TransformationContext, fun export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { - const [precedingStatements, returnStatement] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: returnStatement } = transformInPrecedingStatementScope(context, () => transformExpressionBodyToReturnStatement(context, body) ); return [...precedingStatements, returnStatement]; @@ -105,7 +112,7 @@ export function transformFunctionBodyHeader( parameters: ts.NodeArray, spreadIdentifier?: lua.Identifier ): lua.Statement[] { - const headerStatements = []; + const headerStatements: lua.Statement[] = []; // Add default parameters and object binding patterns const bindingPatternDeclarations: lua.Statement[] = []; @@ -115,32 +122,35 @@ export function transformFunctionBodyHeader( const identifier = lua.createIdentifier(`____bindingPattern${bindPatternIndex++}`); if (declaration.initializer !== undefined) { // Default binding parameter - headerStatements.push( - transformParameterDefaultValueDeclaration(context, identifier, declaration.initializer) + const initializer = transformParameterDefaultValueDeclaration( + context, + identifier, + declaration.initializer ); + if (initializer) headerStatements.push(initializer); } // Binding pattern const name = declaration.name; - const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: bindings } = transformInPrecedingStatementScope(context, () => transformBindingPattern(context, name, identifier) ); bindingPatternDeclarations.push(...precedingStatements, ...bindings); } else if (declaration.initializer !== undefined) { // Default parameter - headerStatements.push( - transformParameterDefaultValueDeclaration( - context, - transformIdentifier(context, declaration.name), - declaration.initializer - ) + const initializer = transformParameterDefaultValueDeclaration( + context, + transformIdentifier(context, declaration.name), + declaration.initializer ); + if (initializer) headerStatements.push(initializer); } } // Push spread operator here if (spreadIdentifier && isRestParameterReferenced(spreadIdentifier, bodyScope)) { - const spreadTable = wrapInTable(lua.createDotsLiteral()); + const spreadTable = + context.luaTarget === LuaTarget.Lua50 ? lua.createArgLiteral() : wrapInTable(lua.createDotsLiteral()); headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -185,7 +195,7 @@ export function transformParameters( // Only push parameter name to paramName array if it isn't a spread parameter for (const param of parameters) { - if (ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + if (ts.isIdentifier(param.name) && ts.identifierToKeywordKind(param.name) === ts.SyntaxKind.ThisKeyword) { continue; } @@ -217,7 +227,15 @@ export function transformFunctionToExpression( const type = context.checker.getTypeAtLocation(node); let functionContext: lua.Identifier | undefined; - if (getFunctionContextType(context, type) !== ContextType.Void) { + + const firstParam = node.parameters[0]; + const hasThisVoidParameter = + firstParam && + ts.isIdentifier(firstParam.name) && + ts.identifierToKeywordKind(firstParam.name) === ts.SyntaxKind.ThisKeyword && + firstParam.type?.kind === ts.SyntaxKind.VoidKeyword; + + if (!hasThisVoidParameter && getFunctionContextType(context, type) !== ContextType.Void) { if (ts.isArrowFunction(node)) { // dummy context for arrow functions with parameters if (node.parameters.length > 0) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 78f2bb8c2..e5dd90e01 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -7,22 +7,52 @@ import { invalidCallExtensionUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; -import { isOptionalContinuation } from "./optional-chaining"; +import { getOptionalContinuationData, isOptionalContinuation } from "./optional-chaining"; import { isStandardLibraryType } from "../utils/typescript"; import { getExtensionKindForNode, getExtensionKindForSymbol } from "../utils/language-extensions"; import { callExtensions } from "./language-extensions/call-extension"; import { isIdentifierExtensionValue, reportInvalidExtensionValue } from "./language-extensions/identifier"; +import { Annotation, AnnotationKind, getNodeAnnotations } from "../utils/annotations"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { return transformNonValueIdentifier(context, identifier, context.checker.getSymbolAtLocation(identifier)); } + +export function getCustomNameFromSymbol(symbol?: ts.Symbol): undefined | string { + let retVal: undefined | string; + + if (symbol) { + const declarations = symbol.getDeclarations(); + if (declarations) { + let customNameAnnotation: undefined | Annotation = undefined; + for (const declaration of declarations) { + const nodeAnnotations = getNodeAnnotations(declaration); + const foundAnnotation = nodeAnnotations.get(AnnotationKind.CustomName); + + if (foundAnnotation) { + customNameAnnotation = foundAnnotation; + break; + } + } + + if (customNameAnnotation) { + retVal = customNameAnnotation.args[0]; + } + } + } + + return retVal; +} + function transformNonValueIdentifier( context: TransformationContext, identifier: ts.Identifier, symbol: ts.Symbol | undefined ) { if (isOptionalContinuation(identifier)) { - return lua.createIdentifier(identifier.text, undefined, tempSymbolId); + const result = lua.createIdentifier(identifier.text, undefined, tempSymbolId); + getOptionalContinuationData(identifier)!.usedIdentifiers.push(result); + return result; } const extensionKind = symbol @@ -50,9 +80,10 @@ function transformNonValueIdentifier( } } - const text = hasUnsafeIdentifierName(context, identifier, symbol) - ? createSafeName(identifier.text) - : identifier.text; + let text = hasUnsafeIdentifierName(context, identifier, symbol) ? createSafeName(identifier.text) : identifier.text; + + const customName = getCustomNameFromSymbol(symbol); + if (customName) text = customName; const symbolId = getIdentifierSymbolId(context, identifier, symbol); return lua.createIdentifier(text, identifier, symbolId, identifier.text); @@ -82,7 +113,7 @@ export function transformIdentifierWithSymbol( } export const transformIdentifierExpression: FunctionVisitor = (node, context) => { - if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + if (ts.identifierToKeywordKind(node) === ts.SyntaxKind.UndefinedKeyword) { return lua.createNilLiteral(node); } diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts index 5d96f409e..ee1ded7be 100644 --- a/src/transformation/visitors/language-extensions/iterable.ts +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -62,8 +62,13 @@ export function transformForOfIterableStatement( statement: ts.ForOfStatement, block: lua.Block ): lua.Statement { - const type = context.checker.getTypeAtLocation(statement.expression); - if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { + const iteratedExpressionType = context.checker.getTypeAtLocation(statement.expression); + const iterableType = + iteratedExpressionType.isIntersection() && + iteratedExpressionType.types.find(t => t.symbol.escapedName === "Iterable"); + const iterableTypeArguments = (iterableType as ts.TypeReference)?.typeArguments; + + if (iterableTypeArguments && iterableTypeArguments.length > 0 && isMultiReturnType(iterableTypeArguments[0])) { const luaIterator = context.transformExpression(statement.expression); return transformForOfMultiIterableStatement( context, diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 73dec6d9c..d9d7cbc02 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -6,7 +6,7 @@ import { IterableExtensionKind, } from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { findFirstNodeAbove } from "../../utils/typescript"; +import { findFirstNodeAbove, findFirstNonOuterParent } from "../../utils/typescript"; const multiReturnExtensionName = "__tstlMultiReturn"; export function isMultiReturnType(type: ts.Type): boolean { @@ -58,46 +58,48 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n return false; } + const parent = findFirstNonOuterParent(node); + // Variable declaration with destructuring - if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + if (ts.isVariableDeclaration(parent) && ts.isArrayBindingPattern(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) + ts.isBinaryExpression(parent) && + parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(parent.left) ) { return false; } // Spread operator - if (ts.isSpreadElement(node.parent)) { + if (ts.isSpreadElement(parent)) { return false; } // Stand-alone expression - if (ts.isExpressionStatement(node.parent)) { + if (ts.isExpressionStatement(parent)) { return false; } // Forwarded multi-return call if ( - (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + (ts.isReturnStatement(parent) || ts.isArrowFunction(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)) { + if (ts.isElementAccessExpression(parent)) { return false; } // LuaIterable in for...of if ( - ts.isForOfStatement(node.parent) && + ts.isForOfStatement(parent) && getIterableExtensionKindForNode(context, node) === IterableExtensionKind.Iterable ) { return false; diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index 2281712b8..4cb08abc2 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -4,8 +4,9 @@ import { TransformationContext } from "../../context"; import { assert } from "../../../utils"; import { LuaTarget } from "../../../CompilerOptions"; import { unsupportedForTarget } from "../../utils/diagnostics"; -import { ExtensionKind } from "../../utils/language-extensions"; +import { ExtensionKind, getBinaryCallExtensionArgs, getUnaryCallExtensionArg } from "../../utils/language-extensions"; import { LanguageExtensionCallTransformerMap } from "./call-extension"; +import { transformOrderedExpressions } from "../expression-list"; const binaryOperatorMappings = new Map([ [ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], @@ -81,35 +82,21 @@ for (const kind of unaryOperatorMappings.keys()) { function transformBinaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); - let args: readonly ts.Expression[] = node.arguments; - if ( - args.length === 1 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - args = [node.expression.expression, ...args]; - } + const args = getBinaryCallExtensionArgs(context, node, kind); + if (!args) return lua.createNilLiteral(); + + const [left, right] = transformOrderedExpressions(context, args); const luaOperator = binaryOperatorMappings.get(kind); assert(luaOperator); - return lua.createBinaryExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - luaOperator - ); + return lua.createBinaryExpression(left, right, luaOperator); } function transformUnaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); - let arg: ts.Expression; - if ( - node.arguments.length === 0 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - arg = node.expression.expression; - } else { - arg = node.arguments[0]; - } + const arg = getUnaryCallExtensionArg(context, node, kind); + if (!arg) return lua.createNilLiteral(); const luaOperator = unaryOperatorMappings.get(kind); assert(luaOperator); @@ -118,6 +105,7 @@ function transformUnaryOperator(context: TransformationContext, node: ts.CallExp function checkHasLua53(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { const isBefore53 = + context.luaTarget === LuaTarget.Lua50 || context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Lua52 || context.luaTarget === LuaTarget.LuaJIT || diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index 2d22adf15..e42e3f8c7 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -1,16 +1,23 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import { ExtensionKind, getExtensionKindForNode } from "../../utils/language-extensions"; -import { transformExpressionList } from "../expression-list"; -import { LanguageExtensionCallTransformer } from "./call-extension"; +import { + ExtensionKind, + getBinaryCallExtensionArgs, + getExtensionKindForNode, + getNaryCallExtensionArgs, + getUnaryCallExtensionArg, +} from "../../utils/language-extensions"; +import { transformOrderedExpressions } from "../expression-list"; +import { LanguageExtensionCallTransformerMap } from "./call-extension"; export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { return getExtensionKindForNode(context, node.expression) === ExtensionKind.TableNewType; } + export const tableNewExtensions = [ExtensionKind.TableNewType]; -export const tableExtensionTransformers: { [P in ExtensionKind]?: LanguageExtensionCallTransformer } = { +export const tableExtensionTransformers: LanguageExtensionCallTransformerMap = { [ExtensionKind.TableDeleteType]: transformTableDeleteExpression, [ExtensionKind.TableDeleteMethodType]: transformTableDeleteExpression, [ExtensionKind.TableGetType]: transformTableGetExpression, @@ -19,8 +26,10 @@ export const tableExtensionTransformers: { [P in ExtensionKind]?: LanguageExtens [ExtensionKind.TableHasMethodType]: transformTableHasExpression, [ExtensionKind.TableSetType]: transformTableSetExpression, [ExtensionKind.TableSetMethodType]: transformTableSetExpression, - [ExtensionKind.TableAddKeyType]: transformTableAddExpression, - [ExtensionKind.TableAddKeyMethodType]: transformTableAddExpression, + [ExtensionKind.TableAddKeyType]: transformTableAddKeyExpression, + [ExtensionKind.TableAddKeyMethodType]: transformTableAddKeyExpression, + [ExtensionKind.TableIsEmptyType]: transformTableIsEmptyExpression, + [ExtensionKind.TableIsEmptyMethodType]: transformTableIsEmptyExpression, }; function transformTableDeleteExpression( @@ -28,48 +37,32 @@ function transformTableDeleteExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === ExtensionKind.TableDeleteMethodType && - (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); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); } - const [table, accessExpression] = transformExpressionList(context, args); + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] = nil context.addPrecedingStatements( - lua.createAssignmentStatement( - lua.createTableIndexExpression(table, accessExpression), - lua.createNilLiteral(), - node - ) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createNilLiteral(), node) ); return lua.createBooleanLiteral(true); } -function transformWithTableArgument(context: TransformationContext, node: ts.CallExpression): lua.Expression[] { - if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { - return transformExpressionList(context, [node.expression.expression, ...node.arguments]); - } - // todo: report diagnostic? - return [lua.createNilLiteral(), ...transformExpressionList(context, node.arguments)]; -} - function transformTableGetExpression( context: TransformationContext, node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableGetMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] - return lua.createTableIndexExpression(table, accessExpression, node); + return lua.createTableIndexExpression(table, key, node); } function transformTableHasExpression( @@ -77,14 +70,14 @@ function transformTableHasExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableHasMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] - const tableIndexExpression = lua.createTableIndexExpression(table, accessExpression); + const tableIndexExpression = lua.createTableIndexExpression(table, key); // arg0[arg1] ~= nil return lua.createBinaryExpression( @@ -100,37 +93,53 @@ function transformTableSetExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableSetMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getNaryCallExtensionArgs(context, node, extensionKind, 3); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression, value] = args; + const [table, key, value] = transformOrderedExpressions(context, args); // arg0[arg1] = arg2 context.addPrecedingStatements( - lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), value, node) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), value, node) ); return lua.createNilLiteral(); } -function transformTableAddExpression( +function transformTableAddKeyExpression( context: TransformationContext, node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableAddKeyMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getNaryCallExtensionArgs(context, node, extensionKind, 2); + if (!args) { + return lua.createNilLiteral(); + } - const [table, value] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] = true context.addPrecedingStatements( - lua.createAssignmentStatement( - lua.createTableIndexExpression(table, value), - lua.createBooleanLiteral(true), - node - ) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createBooleanLiteral(true), node) ); return lua.createNilLiteral(); } + +function transformTableIsEmptyExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: ExtensionKind +): lua.Expression { + const args = getUnaryCallExtensionArg(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } + + const table = context.transformExpression(args); + // next(arg0) == nil + return lua.createBinaryExpression( + lua.createCallExpression(lua.createIdentifier("next"), [table], node), + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator, + node + ); +} diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 838b8d5c2..1d91c89d9 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -9,6 +9,7 @@ import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { transformIdentifierWithSymbol } from "./identifier"; +import { LuaTarget } from "../../CompilerOptions"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -31,11 +32,17 @@ export function createShorthandIdentifier( return transformIdentifierWithSymbol(context, propertyIdentifier, valueSymbol); } -const transformNumericLiteralExpression: FunctionVisitor = expression => { +const transformNumericLiteralExpression: FunctionVisitor = (expression, context) => { if (expression.text === "Infinity") { - const math = lua.createIdentifier("math"); - const huge = lua.createStringLiteral("huge"); - return lua.createTableIndexExpression(math, huge, expression); + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, expression); + } } return lua.createNumericLiteral(Number(expression.text), expression); diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index 806876631..f4c714c71 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -11,8 +11,9 @@ export const transformWhileStatement: FunctionVisitor = (stat const body = transformLoopBody(context, statement); - let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - context.transformExpression(statement.expression) + let { precedingStatements: conditionPrecedingStatements, result: condition } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(statement.expression) ); // If condition has preceding statements, ensure they are executed every iteration by using the form: @@ -46,8 +47,9 @@ export const transformDoStatement: FunctionVisitor = (statement, const body = lua.createDoStatement(transformLoopBody(context, statement)); - let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - invertCondition(context.transformExpression(statement.expression)) + let { precedingStatements: conditionPrecedingStatements, result: condition } = transformInPrecedingStatementScope( + context, + () => invertCondition(context.transformExpression(statement.expression)) ); // If condition has preceding statements, ensure they are executed every iteration by using the form: diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 3fbbb6353..3a82b5a24 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -22,11 +22,12 @@ export const transformForStatement: FunctionVisitor = (statemen let condition: lua.Expression; if (statement.condition) { - let conditionPrecedingStatements: lua.Statement[]; const tsCondition = statement.condition; - [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - context.transformExpression(tsCondition) + const { precedingStatements: conditionPrecedingStatements, result } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(tsCondition) ); + condition = result; // If condition has preceding statements, ensure they are executed every iteration by using the form: // diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index e24a92269..01466b450 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; -import { performHoisting, ScopeType } from "../../utils/scope"; +import { LoopContinued, performHoisting, ScopeType } from "../../utils/scope"; import { isAssignmentPattern } from "../../utils/typescript"; import { transformAssignment } from "../binary-expression/assignments"; import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; @@ -19,15 +19,32 @@ export function transformLoopBody( const scope = context.popScope(); const scopeId = scope.id; - if (!scope.loopContinued) { - return body; - } + switch (scope.loopContinued) { + case undefined: + case LoopContinued.WithContinue: + return body; + + case LoopContinued.WithGoto: + return [lua.createDoStatement(body), lua.createLabelStatement(`__continue${scopeId}`)]; - const baseResult: lua.Statement[] = [lua.createDoStatement(body)]; - const continueLabel = lua.createLabelStatement(`__continue${scopeId}`); - baseResult.push(continueLabel); + case LoopContinued.WithRepeatBreak: + const identifier = lua.createIdentifier(`__continue${scopeId}`); + const literalTrue = lua.createBooleanLiteral(true); - return baseResult; + return [ + lua.createDoStatement([ + lua.createVariableDeclarationStatement(identifier), + lua.createRepeatStatement( + lua.createBlock([...body, lua.createAssignmentStatement(identifier, literalTrue)]), + literalTrue + ), + lua.createIfStatement( + lua.createUnaryExpression(identifier, lua.SyntaxKind.NotOperator), + lua.createBlock([lua.createBreakStatement()]) + ), + ]), + ]; + } } export function getVariableDeclarationBinding( @@ -57,7 +74,7 @@ export function transformForInitializer( const binding = getVariableDeclarationBinding(context, initializer); if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { - const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: bindings } = transformInPrecedingStatementScope(context, () => transformBindingPattern(context, binding, valueVariable) ); block.statements.unshift(...precedingStatements, ...bindings); diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 219e99eee..c814b8257 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -2,17 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { assert } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { - createDefaultExportExpression, - createDefaultExportStringLiteral, - createExportedIdentifier, -} from "../../utils/export"; +import { createDefaultExportExpression, createDefaultExportStringLiteral } from "../../utils/export"; import { createExportsIdentifier } from "../../utils/lua-ast"; -import { ScopeType } from "../../utils/scope"; -import { transformScopeBlock } from "../block"; -import { transformIdentifier } from "../identifier"; -import { createShorthandIdentifier } from "../literal"; +import { createShorthandIdentifier, transformPropertyName } from "../literal"; import { createModuleRequire } from "./import"; +import { createSafeName } from "../../utils/safe-names"; +import * as path from "path"; export const transformExportAssignment: FunctionVisitor = (node, context) => { if (!context.resolver.isValueAliasDeclaration(node)) { @@ -39,10 +34,6 @@ export const transformExportAssignment: FunctionVisitor = ( function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { assert(node.moduleSpecifier); - if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { - return undefined; - } - const moduleRequire = createModuleRequire(context, node.moduleSpecifier); // export * as ns from "..."; @@ -105,20 +96,37 @@ function transformExportAll(context: TransformationContext, node: ts.ExportDecla } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => - (node.name && node.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || - (node.propertyName && node.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword); + (node.name && + ts.isIdentifier(node.name) && + ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) || + (node.propertyName && + ts.isIdentifier(node.propertyName) && + ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword); function transformExportSpecifier(context: TransformationContext, node: ts.ExportSpecifier): lua.AssignmentStatement { - const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); - const exportedIdentifier = node.propertyName ? node.propertyName : node.name; - const exportedExpression = createShorthandIdentifier(context, exportedSymbol, exportedIdentifier); + const exportedName = node.name; + const exportedValue = node.propertyName ?? node.name; + let rhs: lua.Expression; + if (ts.isIdentifier(exportedValue)) { + const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); + rhs = createShorthandIdentifier(context, exportedSymbol, exportedValue); + } else { + rhs = lua.createStringLiteral(exportedName.text, exportedValue); + } - const isDefault = isDefaultExportSpecifier(node); - const exportAssignmentLeftHandSide = isDefault - ? createDefaultExportExpression(node) - : createExportedIdentifier(context, transformIdentifier(context, node.name)); + if (isDefaultExportSpecifier(node)) { + const lhs = createDefaultExportExpression(node); + return lua.createAssignmentStatement(lhs, rhs, node); + } else { + const exportsTable = createExportsIdentifier(); + const lhs = lua.createTableIndexExpression( + exportsTable, + lua.createStringLiteral(exportedName.text), + exportedName + ); - return lua.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); + return lua.createAssignmentStatement(lhs, rhs, node); + } } function transformExportSpecifiersFrom( @@ -127,37 +135,32 @@ function transformExportSpecifiersFrom( moduleSpecifier: ts.Expression, exportSpecifiers: ts.ExportSpecifier[] ): lua.Statement { - // First transpile as import clause - const importClause = ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports( - exportSpecifiers.map(s => ts.factory.createImportSpecifier(statement.isTypeOnly, s.propertyName, s.name)) - ) - ); + const result: lua.Statement[] = []; - const importDeclaration = ts.factory.createImportDeclaration( - statement.decorators, - statement.modifiers, - importClause, - moduleSpecifier - ); + const importPath = ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text.replace(/"/g, "") : "module"; - // Wrap in block to prevent imports from hoisting out of `do` statement - const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); - const result = block.statements; + // Create the require statement to extract values. + // local ____module = require("module") + const importUniqueName = lua.createIdentifier(createSafeName(path.basename(importPath))); + const requireCall = createModuleRequire(context, moduleSpecifier); + result.push(lua.createVariableDeclarationStatement(importUniqueName, requireCall, statement)); - // Now the module is imported, add the imports to the export table for (const specifier of exportSpecifiers) { - result.push( - lua.createAssignmentStatement( - createExportedIdentifier(context, transformIdentifier(context, specifier.name)), - transformIdentifier(context, specifier.name) - ) + // Assign to exports table + const exportsTable = createExportsIdentifier(); + const exportedName = specifier.name; + const exportedNameTransformed = transformPropertyName(context, exportedName); + const lhs = lua.createTableIndexExpression(exportsTable, exportedNameTransformed, exportedName); + + const exportedValue = specifier.propertyName ?? specifier.name; + const rhs = lua.createTableIndexExpression( + lua.cloneIdentifier(importUniqueName), + transformPropertyName(context, exportedValue), + specifier ); + result.push(lua.createAssignmentStatement(lhs, rhs, specifier)); } - // Wrap this in a DoStatement to prevent polluting the scope. return lua.createDoStatement(result, statement); } diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 66432fb44..b3a1d74a2 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -47,10 +47,7 @@ function transformImportSpecifier( moduleTableName: lua.Identifier ): lua.VariableDeclarationStatement { const leftIdentifier = transformIdentifier(context, importSpecifier.name); - const propertyName = transformPropertyName( - context, - importSpecifier.propertyName ? importSpecifier.propertyName : importSpecifier.name - ); + const propertyName = transformPropertyName(context, importSpecifier.propertyName ?? importSpecifier.name); return lua.createVariableDeclarationStatement( leftIdentifier, diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 4e0727753..743b52b62 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -11,6 +11,16 @@ import { performHoisting, ScopeType } from "../utils/scope"; import { getSymbolIdOfSymbol } from "../utils/symbols"; import { transformIdentifier } from "./identifier"; +export function createModuleLocalName(context: TransformationContext, module: ts.ModuleDeclaration): lua.Expression { + if (!ts.isSourceFile(module.parent) && ts.isModuleDeclaration(module.parent)) { + const parentDeclaration = createModuleLocalName(context, module.parent); + const name = createModuleLocalNameIdentifier(context, module); + return lua.createTableIndexExpression(parentDeclaration, lua.createStringLiteral(name.text), module.name); + } + + return createModuleLocalNameIdentifier(context, module); +} + export function createModuleLocalNameIdentifier( context: TransformationContext, declaration: ts.ModuleDeclaration @@ -25,7 +35,6 @@ export function createModuleLocalNameIdentifier( ); } - // TODO: Should synthetic name nodes be escaped as well? return transformIdentifier(context, declaration.name as ts.Identifier); } diff --git a/src/transformation/visitors/optional-chaining.ts b/src/transformation/visitors/optional-chaining.ts index 7c6d457eb..6d6deeb8d 100644 --- a/src/transformation/visitors/optional-chaining.ts +++ b/src/transformation/visitors/optional-chaining.ts @@ -1,10 +1,12 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { TransformationContext, tempSymbolId } from "../context"; +import { tempSymbolId, TransformationContext } from "../context"; import { assert, assertNever } from "../../utils"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; -import { transformPropertyAccessExpressionWithCapture, transformElementAccessExpressionWithCapture } from "./access"; +import { transformElementAccessExpressionWithCapture, transformPropertyAccessExpressionWithCapture } from "./access"; import { shouldMoveToTemp } from "./expression-list"; +import { canBeFalsyWhenNotNull, expressionResultIsUsed } from "../utils/typescript"; +import { wrapInStatement } from "./expression-statement"; type NormalOptionalChain = ts.PropertyAccessChain | ts.ElementAccessChain | ts.CallChain; @@ -56,7 +58,7 @@ export function captureThisValue( thisValueCapture: lua.Identifier, tsOriginal: ts.Node ): lua.Expression { - if (!shouldMoveToTemp(context, expression, tsOriginal) && !isOptionalContinuation(tsOriginal)) { + if (!shouldMoveToTemp(context, expression, tsOriginal)) { return expression; } const tempAssignment = lua.createAssignmentStatement(thisValueCapture, expression, tsOriginal); @@ -66,6 +68,7 @@ export function captureThisValue( export interface OptionalContinuation { contextualCall?: lua.CallExpression; + usedIdentifiers: lua.Identifier[]; } const optionalContinuations = new WeakMap(); @@ -74,12 +77,16 @@ const optionalContinuations = new WeakMap() function createOptionalContinuationIdentifier(text: string, tsOriginal: ts.Expression): ts.Identifier { const identifier = ts.factory.createIdentifier(text); ts.setOriginalNode(identifier, tsOriginal); - optionalContinuations.set(identifier, {}); + optionalContinuations.set(identifier, { + usedIdentifiers: [], + }); return identifier; } + export function isOptionalContinuation(node: ts.Node): boolean { return ts.isIdentifier(node) && optionalContinuations.has(node); } + export function getOptionalContinuationData(identifier: ts.Identifier): OptionalContinuation | undefined { return optionalContinuations.get(identifier); } @@ -90,16 +97,16 @@ export function transformOptionalChain(context: TransformationContext, node: ts. export function transformOptionalChainWithCapture( context: TransformationContext, - node: ts.OptionalChain, + tsNode: ts.OptionalChain, thisValueCapture: lua.Identifier | undefined, isDelete?: ts.DeleteExpression ): ExpressionWithThisValue { - const luaTemp = context.createTempNameForNode(node); + const luaTempName = context.createTempName("opt"); - const { expression: tsLeftExpression, chain } = flattenChain(node); + const { expression: tsLeftExpression, chain } = flattenChain(tsNode); // build temp.b.c.d - const tsTemp = createOptionalContinuationIdentifier(luaTemp.text, tsLeftExpression); + const tsTemp = createOptionalContinuationIdentifier(luaTempName, tsLeftExpression); let tsRightExpression: ts.Expression = tsTemp; for (const link of chain) { if (ts.isPropertyAccessExpression(link)) { @@ -121,39 +128,57 @@ export function transformOptionalChainWithCapture( // transform right expression first to check if thisValue capture is needed // capture and return thisValue if requested from outside let returnThisValue: lua.Expression | undefined; - const [rightPrecedingStatements, rightAssignment] = transformInPrecedingStatementScope(context, () => { - let result: lua.Expression; - if (thisValueCapture) { - ({ expression: result, thisValue: returnThisValue } = transformExpressionWithThisValueCapture( + const { precedingStatements: rightPrecedingStatements, result: rightExpression } = + transformInPrecedingStatementScope(context, () => { + if (!thisValueCapture) { + return context.transformExpression(tsRightExpression); + } + + const { expression: result, thisValue } = transformExpressionWithThisValueCapture( context, tsRightExpression, thisValueCapture - )); - } else { - result = context.transformExpression(tsRightExpression); - } - return lua.createAssignmentStatement(luaTemp, result); - }); + ); + returnThisValue = thisValue; + return result; + }); // transform left expression, handle thisValue if needed by rightExpression const thisValueCaptureName = context.createTempName("this"); const leftThisValueTemp = lua.createIdentifier(thisValueCaptureName, undefined, tempSymbolId); let capturedThisValue: lua.Expression | undefined; - const rightContextualCall = getOptionalContinuationData(tsTemp)?.contextualCall; - const [leftPrecedingStatements, leftExpression] = transformInPrecedingStatementScope(context, () => { - let result: lua.Expression; - if (rightContextualCall) { - ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture( - context, - tsLeftExpression, - leftThisValueTemp - )); + const optionalContinuationData = getOptionalContinuationData(tsTemp); + const rightContextualCall = optionalContinuationData?.contextualCall; + const { precedingStatements: leftPrecedingStatements, result: leftExpression } = transformInPrecedingStatementScope( + context, + () => { + let result: lua.Expression; + if (rightContextualCall) { + ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture( + context, + tsLeftExpression, + leftThisValueTemp + )); + } else { + result = context.transformExpression(tsLeftExpression); + } + return result; + } + ); + + // handle super calls by passing self as context + function getLeftMostChainItem(node: ts.Node): ts.Node { + if (ts.isPropertyAccessExpression(node)) { + return getLeftMostChainItem(node.expression); } else { - result = context.transformExpression(tsLeftExpression); + return node; } - return result; - }); + } + if (getLeftMostChainItem(tsLeftExpression).kind === ts.SyntaxKind.SuperKeyword) { + capturedThisValue = lua.createIdentifier("self"); + } + // handle context if (rightContextualCall) { if (capturedThisValue) { @@ -177,26 +202,78 @@ export function transformOptionalChainWithCapture( } } - // - // local temp = - // if temp ~= nil then - // - // temp = temp.b.c.d - // end - // return temp - - context.addPrecedingStatements([ - ...leftPrecedingStatements, - lua.createVariableDeclarationStatement(luaTemp, leftExpression), - lua.createIfStatement( - lua.createBinaryExpression(luaTemp, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), - lua.createBlock([...rightPrecedingStatements, rightAssignment]) - ), - ]); - return { - expression: luaTemp, - thisValue: returnThisValue, - }; + // evaluate optional chain + context.addPrecedingStatements(leftPrecedingStatements); + + // try use existing variable instead of creating new one, if possible + let leftIdentifier: lua.Identifier | undefined; + const usedLuaIdentifiers = optionalContinuationData?.usedIdentifiers; + const reuseLeftIdentifier = + usedLuaIdentifiers && + usedLuaIdentifiers.length > 0 && + lua.isIdentifier(leftExpression) && + (rightPrecedingStatements.length === 0 || !shouldMoveToTemp(context, leftExpression, tsLeftExpression)); + if (reuseLeftIdentifier) { + leftIdentifier = leftExpression; + for (const usedIdentifier of usedLuaIdentifiers) { + usedIdentifier.text = leftIdentifier.text; + } + } else { + leftIdentifier = lua.createIdentifier(luaTempName, undefined, tempSymbolId); + context.addPrecedingStatements(lua.createVariableDeclarationStatement(leftIdentifier, leftExpression)); + } + + if (!expressionResultIsUsed(tsNode) || isDelete) { + // if left ~= nil then + // + // + // end + + const innerExpression = wrapInStatement(rightExpression); + const innerStatements = rightPrecedingStatements; + if (innerExpression) innerStatements.push(innerExpression); + + context.addPrecedingStatements( + lua.createIfStatement( + lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), + lua.createBlock(innerStatements) + ) + ); + return { expression: lua.createNilLiteral(), thisValue: returnThisValue }; + } else if ( + rightPrecedingStatements.length === 0 && + !canBeFalsyWhenNotNull(context, context.checker.getTypeAtLocation(tsLeftExpression)) + ) { + // return a && a.b + return { + expression: lua.createBinaryExpression(leftIdentifier, rightExpression, lua.SyntaxKind.AndOperator, tsNode), + thisValue: returnThisValue, + }; + } else { + let resultIdentifier: lua.Identifier; + if (!reuseLeftIdentifier) { + // reuse temp variable for output + resultIdentifier = leftIdentifier; + } else { + resultIdentifier = lua.createIdentifier(context.createTempName("opt_result"), undefined, tempSymbolId); + context.addPrecedingStatements(lua.createVariableDeclarationStatement(resultIdentifier)); + } + // if left ~= nil then + // + // result = + // end + // return result + context.addPrecedingStatements( + lua.createIfStatement( + lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), + lua.createBlock([ + ...rightPrecedingStatements, + lua.createAssignmentStatement(resultIdentifier, rightExpression), + ]) + ) + ); + return { expression: resultIdentifier, thisValue: returnThisValue }; + } } export function transformOptionalDeleteExpression( diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 6870d292b..4a0c62c6d 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -13,7 +13,7 @@ export const transformSourceFileNode: FunctionVisitor = (node, co const [statement] = node.statements; if (statement) { assert(ts.isExpressionStatement(statement)); - const [precedingStatements, expression] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: expression } = transformInPrecedingStatementScope(context, () => context.transformExpression(statement.expression) ); statements.push(...precedingStatements); diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 84a13f0fd..9c8cb6feb 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,7 +1,9 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; +import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isLuaIterable } from "../utils/language-extensions"; +import { getIterableExtensionKindForNode, IterableExtensionKind } from "../utils/language-extensions"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { @@ -11,7 +13,7 @@ import { isFunctionScopeWithDefinition, ScopeType, } from "../utils/scope"; -import { isArrayType, findFirstNonOuterParent } from "../utils/typescript"; +import { findFirstNonOuterParent, isAlwaysArrayType } from "../utils/typescript"; import { isMultiReturnCall } from "./language-extensions/multi"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; @@ -37,7 +39,10 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: } // Scope cannot be an async function - if (scope.node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) { + if ( + ts.canHaveModifiers(scope.node) && + ts.getModifiers(scope.node)?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) + ) { return false; } @@ -66,19 +71,33 @@ export const transformSpreadElement: FunctionVisitor = (node, if (ts.isIdentifier(tsInnerExpression)) { const symbol = context.checker.getSymbolAtLocation(tsInnerExpression); if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) { - return lua.createDotsLiteral(node); + return context.luaTarget === LuaTarget.Lua50 + ? createUnpackCall(context, lua.createArgLiteral(), node) + : lua.createDotsLiteral(node); } } const innerExpression = context.transformExpression(node.expression); if (isMultiReturnCall(context, tsInnerExpression)) return innerExpression; - const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts - if (isLuaIterable(context, type)) { - return transformLuaLibFunction(context, LuaLibFeature.LuaIteratorSpread, node, innerExpression); + const iterableExtensionType = getIterableExtensionKindForNode(context, node.expression); + if (iterableExtensionType) { + if (iterableExtensionType === IterableExtensionKind.Iterable) { + return transformLuaLibFunction(context, LuaLibFeature.LuaIteratorSpread, node, innerExpression); + } else if (iterableExtensionType === IterableExtensionKind.Pairs) { + const objectEntries = transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, node, innerExpression); + return createUnpackCall(context, objectEntries, node); + } else if (iterableExtensionType === IterableExtensionKind.PairsKey) { + const objectKeys = transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, node, innerExpression); + return createUnpackCall(context, objectKeys, node); + } else { + assertNever(iterableExtensionType); + } } - if (isArrayType(context, type)) { + const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts + if (isAlwaysArrayType(context, type)) { + // All union members must be arrays to be able to shortcut to unpack call return createUnpackCall(context, innerExpression, node); } diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 913e6ce71..2ceaedb39 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../utils/preceding-statements"; import { ScopeType, separateHoistedStatements } from "../utils/scope"; import { createShortCircuitBinaryExpressionPrecedingStatements } from "./binary-expression"; @@ -9,10 +9,16 @@ const containsBreakOrReturn = (nodes: Iterable): boolean => { for (const s of nodes) { if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) { return true; - } else if (ts.isBlock(s) && containsBreakOrReturn(s.getChildren())) { - return true; - } else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) { + } else if (ts.isBlock(s) && containsBreakOrReturn(s.statements)) { return true; + } else if (s.kind === ts.SyntaxKind.SyntaxList) { + // We cannot use getChildren() because that breaks when using synthetic nodes from transformers + // So get children the long way + const children: ts.Node[] = []; + ts.forEachChild(s, c => children.push(c)); + if (containsBreakOrReturn(children)) { + return true; + } } } @@ -24,7 +30,7 @@ const createOrExpression = ( left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[] -): [lua.Statement[], lua.Expression] => { +): WithPrecedingStatements => { if (rightPrecedingStatements.length > 0) { return createShortCircuitBinaryExpressionPrecedingStatements( context, @@ -34,7 +40,10 @@ const createOrExpression = ( ts.SyntaxKind.BarBarToken ); } else { - return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)]; + return { + precedingStatements: rightPrecedingStatements, + result: lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator), + }; } }; @@ -44,8 +53,8 @@ const coalesceCondition = ( switchVariable: lua.Identifier, expression: ts.Expression, context: TransformationContext -): [lua.Statement[], lua.Expression] => { - const [precedingStatements, transformedExpression] = transformInPrecedingStatementScope(context, () => +): WithPrecedingStatements => { + const { precedingStatements, result: transformedExpression } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression) ); @@ -60,7 +69,7 @@ const coalesceCondition = ( } // Next condition - return [[...conditionPrecedingStatements, ...precedingStatements], comparison]; + return { precedingStatements: [...conditionPrecedingStatements, ...precedingStatements], result: comparison }; }; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { @@ -108,13 +117,15 @@ export const transformSwitchStatement: FunctionVisitor = (st // Compute the condition for the if statement if (!ts.isDefaultClause(clause)) { - [conditionPrecedingStatements, condition] = coalesceCondition( + const { precedingStatements, result } = coalesceCondition( condition, conditionPrecedingStatements, switchVariable, clause.expression, context ); + conditionPrecedingStatements = precedingStatements; + condition = result; // Skip empty clauses unless final clause (i.e side-effects) if (i !== clauses.length - 1 && clause.statements.length === 0) continue; @@ -126,12 +137,15 @@ export const transformSwitchStatement: FunctionVisitor = (st lua.createVariableDeclarationStatement(conditionVariable, condition) ); } else { - [conditionPrecedingStatements, condition] = createOrExpression( + const { precedingStatements, result } = createOrExpression( context, conditionVariable, condition, conditionPrecedingStatements ); + conditionPrecedingStatements = precedingStatements; + condition = result; + statements.push( ...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition) @@ -159,12 +173,14 @@ export const transformSwitchStatement: FunctionVisitor = (st if (i === clauses.length - 1) { // Evaluate the final condition that we may be skipping if (condition) { - [conditionPrecedingStatements, condition] = createOrExpression( + const { precedingStatements, result } = createOrExpression( context, conditionVariable, condition, conditionPrecedingStatements ); + conditionPrecedingStatements = precedingStatements; + condition = result; statements.push( ...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition) diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 5f949adb1..291c703d5 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -1,9 +1,9 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { ContextType, getCallContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; -import { isStringType } from "../utils/typescript/types"; +import { isStringType } from "../utils/typescript"; import { transformArguments, transformContextualCallExpression } from "./call"; import { transformOrderedExpressions } from "./expression-list"; @@ -88,17 +88,14 @@ export const transformTaggedTemplateExpression: FunctionVisitor undefined, [ts.SyntaxKind.NonNullExpression]: (node, context) => context.transformExpression(node.expression), + [ts.SyntaxKind.ExpressionWithTypeArguments]: (node, context) => context.transformExpression(node.expression), + [ts.SyntaxKind.SatisfiesExpression]: (node, context) => context.transformExpression(node.expression), [ts.SyntaxKind.AsExpression]: transformAssertionExpression, [ts.SyntaxKind.TypeAssertionExpression]: transformAssertionExpression, [ts.SyntaxKind.NotEmittedStatement]: () => undefined, diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 58dc8a76a..082ef9a6b 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -71,7 +71,7 @@ export function transformBindingPattern( const variableName = transformIdentifier(context, element.name); // The field to extract const elementName = element.propertyName ?? element.name; - const [precedingStatements, propertyName] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: propertyName } = transformInPrecedingStatementScope(context, () => transformPropertyName(context, elementName) ); result.push(...precedingStatements); // Keep property's preceding statements in order @@ -135,9 +135,8 @@ export function transformBindingPattern( if (element.initializer) { const identifier = addExportToIdentifier(context, variableName); const tsInitializer = element.initializer; - const [initializerPrecedingStatements, initializer] = transformInPrecedingStatementScope(context, () => - context.transformExpression(tsInitializer) - ); + const { precedingStatements: initializerPrecedingStatements, result: initializer } = + transformInPrecedingStatementScope(context, () => context.transformExpression(tsInitializer)); result.push( lua.createIfStatement( lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), @@ -173,8 +172,9 @@ export function transformBindingVariableDeclaration( if (isMultiReturnCall(context, initializer)) { expression = wrapInTable(expression); } - const [moveStatements, movedExpr] = transformInPrecedingStatementScope(context, () => - moveToPrecedingTemp(context, expression, initializer) + const { precedingStatements: moveStatements, result: movedExpr } = transformInPrecedingStatementScope( + context, + () => moveToPrecedingTemp(context, expression, initializer) ); statements.push(...moveStatements); table = movedExpr; @@ -282,8 +282,8 @@ export function transformVariableDeclaration( } export function checkVariableDeclarationList(context: TransformationContext, node: ts.VariableDeclarationList): void { - if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) === 0) { - const token = node.getFirstToken(); + if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const | ts.NodeFlags.Using | ts.NodeFlags.AwaitUsing)) === 0) { + const token = ts.getOriginalNode(node).getFirstToken(); assert(token); context.diagnostics.push(unsupportedVarDeclaration(token)); } diff --git a/src/transformation/visitors/void.ts b/src/transformation/visitors/void.ts index ab5286db5..c942e859c 100644 --- a/src/transformation/visitors/void.ts +++ b/src/transformation/visitors/void.ts @@ -1,13 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { transformExpressionToStatement } from "./expression-statement"; +import { wrapInStatement } from "./expression-statement"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void export const transformVoidExpression: FunctionVisitor = (node, context) => { // If content is a literal it is safe to replace the entire expression with nil if (!ts.isLiteralExpression(node.expression)) { - const statements = transformExpressionToStatement(context, node.expression); + const statements = wrapInStatement(context.transformExpression(node.expression)); if (statements) context.addPrecedingStatements(statements); } diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 547c3b110..1e0436c35 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -1,7 +1,7 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions } from "../CompilerOptions"; +import { CompilerOptions, LuaTarget } from "../CompilerOptions"; import { escapeString, tstlHeader } from "../LuaPrinter"; import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; @@ -12,7 +12,12 @@ const createModulePath = (pathToResolve: string, program: ts.Program) => escapeString(formatPathToLuaPath(trimExtension(getEmitPathRelativeToOutDir(pathToResolve, program)))); // Override `require` to read from ____modules table. -const requireOverride = ` +function requireOverride(options: CompilerOptions) { + const runModule = + options.luaTarget === LuaTarget.Lua50 + ? "if (table.getn(arg) > 0) then value = module(unpack(arg)) else value = module(file) end" + : 'if (select("#", ...) > 0) then value = module(...) else value = module(file) end'; + return ` local ____modules = {} local ____moduleCache = {} local ____originalRequire = require @@ -22,8 +27,10 @@ local function require(file, ...) end if ____modules[file] then local module = ____modules[file] - ____moduleCache[file] = { value = (select("#", ...) > 0) and module(...) or module(file) } - return ____moduleCache[file].value + local value = nil + ${runModule} + ____moduleCache[file] = { value = value } + return value else if ____originalRequire then return ____originalRequire(file) @@ -33,6 +40,7 @@ local function require(file, ...) end end `; +} export const sourceMapTracebackBundlePlaceholder = "{#SourceMapTracebackBundle}"; @@ -101,7 +109,8 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ...)\n`; + const args = options.luaTarget === LuaTarget.Lua50 ? "unpack(arg == nil and {} or arg)" : "..."; + const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ${args})\n`; const footers: string[] = []; if (options.sourceMapTraceback) { @@ -110,7 +119,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t footers.push(`${sourceMapTracebackBundlePlaceholder}\n`); } - const sourceChunks = [requireOverride, moduleTable, ...footers, entryPoint]; + const sourceChunks = [requireOverride(options), moduleTable, ...footers, entryPoint]; if (!options.noHeader) { sourceChunks.unshift(tstlHeader); diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 1f37f3260..348542ac5 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -51,7 +51,7 @@ export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDi export const cannotBundleLibrary = createDiagnosticFactory( () => - 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' + 'Cannot bundle projects 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/find-lua-requires.ts b/src/transpilation/find-lua-requires.ts new file mode 100644 index 000000000..90be465e6 --- /dev/null +++ b/src/transpilation/find-lua-requires.ts @@ -0,0 +1,168 @@ +export interface LuaRequire { + from: number; + to: number; + requirePath: string; +} + +export function findLuaRequires(lua: string): LuaRequire[] { + return findRequire(lua, 0); +} + +function findRequire(lua: string, offset: number): LuaRequire[] { + const result = []; + + while (offset < lua.length) { + const c = lua[offset]; + if ( + c === "r" && + (offset === 0 || + isWhitespace(lua[offset - 1]) || + lua[offset - 1] === "]" || + lua[offset - 1] === "(" || + lua[offset - 1] === "[") + ) { + const m = matchRequire(lua, offset); + if (m.matched) { + offset = m.match.to + 1; + result.push(m.match); + } else { + offset = m.end; + } + } else if (c === '"' || c === "'") { + offset = readString(lua, offset, c).offset; // Skip string and surrounding quotes + } else if (c === "-" && offset + 1 < lua.length && lua[offset + 1] === "-") { + offset = skipComment(lua, offset); + } else { + offset++; + } + } + + return result; +} + +type MatchResult = { matched: true; match: T } | { matched: false; end: number }; + +function matchRequire(lua: string, offset: number): MatchResult { + const start = offset; + for (const c of "require") { + if (offset > lua.length) { + return { matched: false, end: offset }; + } + + if (lua[offset] !== c) { + return { matched: false, end: offset }; + } + offset++; + } + + offset = skipWhitespace(lua, offset); + + let hasParentheses = false; + + if (offset > lua.length) { + return { matched: false, end: offset }; + } else { + if (lua[offset] === "(") { + hasParentheses = true; + offset++; + offset = skipWhitespace(lua, offset); + } else if (lua[offset] === '"' || lua[offset] === "'") { + // require without parentheses + } else { + // otherwise fail match + return { matched: false, end: offset }; + } + } + + if (offset > lua.length || (lua[offset] !== '"' && lua[offset] !== "'")) { + return { matched: false, end: offset }; + } + + const { value: requireString, offset: offsetAfterString } = readString(lua, offset, lua[offset]); + offset = offsetAfterString; // Skip string and surrounding quotes + + if (hasParentheses) { + offset = skipWhitespace(lua, offset); + + if (offset > lua.length || lua[offset] !== ")") { + return { matched: false, end: offset }; + } + + offset++; + } + + return { matched: true, match: { from: start, to: offset - 1, requirePath: requireString } }; +} + +function readString(lua: string, offset: number, delimiter: string): { value: string; offset: number } { + expect(lua, offset, delimiter); + offset++; + + let start = offset; + let result = ""; + + let escaped = false; + while (offset < lua.length && (lua[offset] !== delimiter || escaped)) { + if (lua[offset] === "\\" && !escaped) { + escaped = true; + } else { + if (lua[offset] === delimiter) { + result += lua.slice(start, offset - 1); + start = offset; + } + escaped = false; + } + + offset++; + } + + if (offset < lua.length) { + expect(lua, offset, delimiter); + } + + result += lua.slice(start, offset); + return { value: result, offset: offset + 1 }; +} + +function skipWhitespace(lua: string, offset: number): number { + while (offset < lua.length && isWhitespace(lua[offset])) { + offset++; + } + return offset; +} + +function isWhitespace(c: string): boolean { + return c === " " || c === "\t" || c === "\r" || c === "\n"; +} + +function skipComment(lua: string, offset: number): number { + expect(lua, offset, "-"); + expect(lua, offset + 1, "-"); + offset += 2; + + if (offset + 1 < lua.length && lua[offset] === "[" && lua[offset + 1] === "[") { + return skipMultiLineComment(lua, offset); + } else { + return skipSingleLineComment(lua, offset); + } +} + +function skipMultiLineComment(lua: string, offset: number): number { + while (offset < lua.length && !(lua[offset] === "]" && lua[offset - 1] === "]")) { + offset++; + } + return offset + 1; +} + +function skipSingleLineComment(lua: string, offset: number): number { + while (offset < lua.length && lua[offset] !== "\n") { + offset++; + } + return offset + 1; +} + +function expect(lua: string, offset: number, char: string) { + if (lua[offset] !== char) { + throw new Error(`Expected ${char} at position ${offset} but found ${lua[offset]}`); + } +} diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts index 866c1f79a..1458b2403 100644 --- a/src/transpilation/output-collector.ts +++ b/src/transpilation/output-collector.ts @@ -14,7 +14,7 @@ export interface TranspiledFile { jsSourceMap?: string; } -export function createEmitOutputCollector() { +export function createEmitOutputCollector(luaExtension = ".lua") { const files: TranspiledFile[] = []; const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); @@ -25,9 +25,9 @@ export function createEmitOutputCollector() { file.sourceFiles = union(file.sourceFiles, sourceFiles); } - if (fileName.endsWith(".lua")) { + if (fileName.endsWith(luaExtension)) { file.lua = data; - } else if (fileName.endsWith(".lua.map")) { + } else if (fileName.endsWith(`${luaExtension}.map`)) { file.luaSourceMap = data; } else if (fileName.endsWith(".js")) { file.js = data; diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 13c96be64..f84af2bc9 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -45,6 +45,27 @@ export interface Plugin { emitHost: EmitHost, result: EmitFile[] ) => ts.Diagnostic[] | void; + + /** + * This function is called after translating the input program to Lua, after resolving dependencies, after bundling and writing files to disk. + */ + afterEmit?: ( + program: ts.Program, + options: CompilerOptions, + emitHost: EmitHost, + result: EmitFile[] + ) => ts.Diagnostic[] | void; + + /** + * This function is called when trying to resolve the .lua file corresponding to a Lua require statement. Allows you to provide + * your own module resolution logic. If return value is undefined, regular module resolution is done. + */ + moduleResolution?: ( + moduleIdentifier: string, + requiringFile: string, + options: CompilerOptions, + emitHost: EmitHost + ) => string | undefined; } export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } { @@ -56,15 +77,23 @@ export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; for (const [index, pluginOption] of (options.luaPlugins ?? []).entries()) { const optionName = `tstl.luaPlugins[${index}]`; - const { error: resolveError, result: factory } = resolvePlugin( - "plugin", - `${optionName}.name`, - getConfigDirectory(options), - pluginOption.name, - pluginOption.import - ); + const factory = (() => { + if ("plugin" in pluginOption) { + return pluginOption.plugin; + } else { + const { error: resolveError, result: factory } = resolvePlugin( + "plugin", + `${optionName}.name`, + getConfigDirectory(options), + pluginOption.name, + pluginOption.import + ); + + if (resolveError) diagnostics.push(resolveError); + return factory; + } + })(); - if (resolveError) diagnostics.push(resolveError); if (factory === undefined) continue; const plugin = typeof factory === "function" ? factory(pluginOption) : factory; diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index f0037c249..bd16773e9 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -8,12 +8,16 @@ import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./tra import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; import { BuildMode, CompilerOptions } from "../CompilerOptions"; +import { findLuaRequires, LuaRequire } from "./find-lua-requires"; +import { Plugin } from "./plugins"; +import * as picomatch from "picomatch"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], enforceExtension: true, // Resolved file must be a lua file - fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, + fileSystem: { ...new resolve.CachedInputFileSystem(fs, 0) }, useSyncFileSystemCalls: true, + conditionNames: ["require", "node", "tstl", "default"], symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) }); @@ -23,7 +27,7 @@ interface ResolutionResult { } class ResolutionContext { - private noResolvePaths: Set; + private noResolvePaths: picomatch.Matcher[]; public diagnostics: ts.Diagnostic[] = []; public resolvedFiles = new Map(); @@ -31,23 +35,27 @@ class ResolutionContext { constructor( public readonly program: ts.Program, public readonly options: CompilerOptions, - private readonly emitHost: EmitHost + private readonly emitHost: EmitHost, + private readonly plugins: Plugin[] ) { - this.noResolvePaths = new Set(options.noResolvePaths); + const unique = [...new Set(options.noResolvePaths)]; + const matchers = unique.map(x => picomatch(x)); + this.noResolvePaths = matchers; } public addAndResolveDependencies(file: ProcessedFile): void { if (this.resolvedFiles.has(file.fileName)) return; this.resolvedFiles.set(file.fileName, file); - for (const required of findRequiredPaths(file.code)) { + // Do this backwards so the replacements do not mess with the positions of the previous requires + for (const required of findLuaRequires(file.code).reverse()) { // Do not resolve noResolution paths - if (required.startsWith("@NoResolution:")) { + if (required.requirePath.startsWith("@NoResolution:")) { // Remove @NoResolution prefix if not building in library mode if (!isBuildModeLibrary(this.program)) { - const path = required.replace("@NoResolution:", ""); - replaceRequireInCode(file, required, path); - replaceRequireInSourceMap(file, required, path); + const path = required.requirePath.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path, this.options.extension); + replaceRequireInSourceMap(file, required, path, this.options.extension); } // Skip @@ -58,38 +66,105 @@ class ResolutionContext { } } - public resolveImport(file: ProcessedFile, required: string): void { + public resolveImport(file: ProcessedFile, required: LuaRequire): void { // Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages - if (required === "lualib_bundle") { + if (required.requirePath === "lualib_bundle") { this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" }); return; } - if (this.noResolvePaths.has(required)) { + if (this.noResolvePaths.find(isMatch => isMatch(required.requirePath))) { if (this.options.tstlVerbose) { - console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`); + console.log( + `Skipping module resolution of ${required.requirePath} as it is in the tsconfig noResolvePaths.` + ); } return; } - const dependencyPath = this.resolveDependencyPath(file, required); + const dependencyPath = + this.resolveDependencyPathsWithPlugins(file, required.requirePath) ?? + this.resolveDependencyPath(file, required.requirePath); + if (!dependencyPath) return this.couldNotResolveImport(required, file); if (this.options.tstlVerbose) { - console.log(`Resolved ${required} to ${normalizeSlashes(dependencyPath)}`); + console.log(`Resolved ${required.requirePath} to ${normalizeSlashes(dependencyPath)}`); } this.processDependency(dependencyPath); // Figure out resolved require path and dependency output path if (shouldRewriteRequires(dependencyPath, this.program)) { const resolvedRequire = getEmitPathRelativeToOutDir(dependencyPath, this.program); - replaceRequireInCode(file, required, resolvedRequire); - replaceRequireInSourceMap(file, required, resolvedRequire); + replaceRequireInCode(file, required, resolvedRequire, this.options.extension); + replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension); + } + } + + private resolveDependencyPathsWithPlugins(requiringFile: ProcessedFile, dependency: string) { + const requiredFromLuaFile = requiringFile.fileName.endsWith(".lua"); + for (const plugin of this.plugins) { + if (plugin.moduleResolution != null) { + const pluginResolvedPath = plugin.moduleResolution( + dependency, + requiringFile.fileName, + this.options, + this.emitHost + ); + if (pluginResolvedPath !== undefined) { + // If resolved path is absolute no need to further resolve it + if (path.isAbsolute(pluginResolvedPath)) { + return pluginResolvedPath; + } + + // If lua file is in node_module + if (requiredFromLuaFile && isNodeModulesFile(requiringFile.fileName)) { + // If requiring file is in lua module, try to resolve sibling in that file first + const resolvedNodeModulesFile = this.resolveLuaDependencyPathFromNodeModules( + requiringFile, + pluginResolvedPath + ); + if (resolvedNodeModulesFile) { + if (this.options.tstlVerbose) { + console.log( + `Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.` + ); + } + return resolvedNodeModulesFile; + } + } + + const resolvedPath = this.formatPathToFile(pluginResolvedPath, requiringFile); + const fileFromPath = this.getFileFromPath(resolvedPath); + + if (fileFromPath) { + if (this.options.tstlVerbose) { + console.log( + `Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.` + ); + } + return fileFromPath; + } + } + } } } public processedDependencies = new Set(); + private formatPathToFile(targetPath: string, required: ProcessedFile) { + const isRelative = ["/", "./", "../"].some(p => targetPath.startsWith(p)); + + // // If the import is relative, always resolve it relative to the requiring file + // // If the import is not relative, resolve it relative to options.baseUrl if it is set + const fileDirectory = path.dirname(required.fileName); + const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; + + // // Check if file is a file in the project + const resolvedPath = path.join(relativeTo, targetPath); + return resolvedPath; + } + private processDependency(dependencyPath: string): void { if (this.processedDependencies.has(dependencyPath)) return; this.processedDependencies.add(dependencyPath); @@ -110,13 +185,13 @@ class ResolutionContext { this.addAndResolveDependencies(dependency); } - private couldNotResolveImport(required: string, file: ProcessedFile): void { + private couldNotResolveImport(required: LuaRequire, file: ProcessedFile): void { const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); - replaceRequireInCode(file, required, fallbackRequire); - replaceRequireInSourceMap(file, required, fallbackRequire); + replaceRequireInCode(file, required, fallbackRequire, this.options.extension); + replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension); this.diagnostics.push( - couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)) + couldNotResolveRequire(required.requirePath, path.relative(getProjectRoot(this.program), file.fileName)) ); } @@ -135,15 +210,8 @@ class ResolutionContext { if (resolvedNodeModulesFile) return resolvedNodeModulesFile; } - // Check if the import is relative - const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); - - // If the import is relative, always resolve it relative to the requiring file - // If the import is not relative, resolve it relative to options.baseUrl if it is set - const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; - // Check if file is a file in the project - const resolvedPath = path.join(relativeTo, dependencyPath); + const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); const fileFromPath = this.getFileFromPath(resolvedPath); if (fileFromPath) return fileFromPath; @@ -161,8 +229,12 @@ class ResolutionContext { try { const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); if (resolveResult) return resolveResult; - } catch (e) { + } catch (e: any) { // resolveSync errors if it fails to resolve + if (this.options.tstlVerbose && e.details) { + // Output resolver log + console.log(e.details); + } } return undefined; @@ -226,6 +298,7 @@ class ResolutionContext { 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 (this.emitHost.fileExists(possibleFile)) { return possibleFile; @@ -268,10 +341,15 @@ class ResolutionContext { } } -export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { +export function resolveDependencies( + program: ts.Program, + files: ProcessedFile[], + emitHost: EmitHost, + plugins: Plugin[] +): ResolutionResult { const options = program.getCompilerOptions() as CompilerOptions; - const resolutionContext = new ResolutionContext(program, options, emitHost); + const resolutionContext = new ResolutionContext(program, options, emitHost, plugins); // Resolve dependencies for all processed files for (const file of files) { @@ -301,35 +379,44 @@ 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: LuaRequire, + newRequire: string, + extension: string | undefined +): void { + const requirePath = requirePathForFile(newRequire, extension); + file.code = file.code = + file.code.substring(0, originalRequire.from) + + `require("${requirePath}")` + + file.code.substring(originalRequire.to + 1); } -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: LuaRequire, + newRequire: string, + extension?: string | undefined +): void { + const requirePath = requirePathForFile(newRequire, extension); + if (file.sourceMapNode) { + replaceInSourceMap( + file.sourceMapNode, + file.sourceMapNode, + `"${originalRequire.requirePath}"`, + `"${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 requirePathForFile(filePath: string, extension = ".lua"): string { + if (!extension.startsWith(".")) { + extension = `.${extension}`; + } + if (filePath.endsWith(extension)) { + return formatPathToLuaPath(filePath.substring(0, filePath.length - extension.length)); + } else { + return formatPathToLuaPath(filePath); } } @@ -371,10 +458,10 @@ function hasSourceFileInProject(filePath: string, program: ts.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 { +function fallbackResolve(required: LuaRequire, sourceRootDir: string, fileDir: string): string { return formatPathToLuaPath( path - .normalize(path.join(path.relative(sourceRootDir, fileDir), required)) + .normalize(path.join(path.relative(sourceRootDir, fileDir), required.requirePath)) .split(path.sep) .filter(s => s !== "." && s !== "..") .join(path.sep) diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index b06131e8c..0080b6e4e 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -79,7 +79,7 @@ export const stripParenthesisExpressionsTransformer: ts.TransformerFactory f.fileName === "lualib_bundle"); @@ -123,10 +131,10 @@ export class Transpiler { 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) }); + const code = this.getLuaLibBundleContent(options, resolutionResult.resolvedFiles); + resolutionResult.resolvedFiles.unshift({ fileName, code }); } let emitPlan: EmitFile[]; @@ -145,6 +153,20 @@ export class Transpiler { return { emitPlan }; } + + private getLuaLibBundleContent(options: CompilerOptions, resolvedFiles: ProcessedFile[]) { + const luaTarget = options.luaTarget ?? LuaTarget.Universal; + if (options.luaLibImport === LuaLibImportKind.RequireMinimal) { + const usedFeatures = findUsedLualibFeatures( + luaTarget, + this.emitHost, + resolvedFiles.map(f => f.code) + ); + return buildMinimalLualibBundle(usedFeatures, luaTarget, this.emitHost); + } else { + return getLuaLibBundle(luaTarget, this.emitHost); + } + } } export function getEmitPath(file: string, program: ts.Program): string { @@ -181,7 +203,9 @@ export function getSourceDir(program: ts.Program): string { if (rootDir && rootDir.length > 0) { return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir); } - return program.getCommonSourceDirectory(); + + // If no rootDir is given, source is relative to the project root + return getProjectRoot(program); } export function getEmitOutDir(program: ts.Program): string { diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index cef3af310..ce03fd854 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -40,7 +40,7 @@ export function resolvePlugin( kind: string, optionName: string, basedir: string, - query: string, + query: unknown, importName = "default" ): { error?: ts.Diagnostic; result?: unknown } { if (typeof query !== "string") { diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 8d85b9374..5333df95a 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -30,12 +30,12 @@ declare module "typescript" { } interface Symbol { - // false positive - // eslint-disable-next-line @typescript-eslint/ban-types parent?: Symbol; } - function getObjectFlags(type: Type): ObjectFlags; + interface Signature { + compositeSignatures?: Signature[]; + } function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; @@ -48,4 +48,15 @@ declare module "typescript" { function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; export function isOuterExpression(node: Node, kinds?: OuterExpressionKinds): node is OuterExpression; + + export function nodeNextJsonConfigResolver( + moduleName: string, + containingFile: string, + host: ModuleResolutionHost + ): ResolvedModuleWithFailedLookupLocations; + + export function pathIsAbsolute(path: string): boolean; + export function pathIsRelative(path: string): boolean; + + export function setParent(child: T, parent: T["parent"] | undefined): T; } diff --git a/src/utils.ts b/src/utils.ts index 72e6ee168..b1877e368 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,7 @@ import * as path from "path"; export function castArray(value: T | T[]): T[]; export function castArray(value: T | readonly T[]): readonly T[]; export function castArray(value: T | readonly T[]): readonly T[] { - return Array.isArray(value) ? value : [value]; + return Array.isArray(value) ? value : [value as T]; } export const intersperse = (values: readonly T[], separator: T): T[] => @@ -50,7 +50,6 @@ 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 @@ -62,7 +61,6 @@ export function getOrUpdate( return map.get(key)!; } -// eslint-disable-next-line @typescript-eslint/ban-types export function isNonNull(value: T | null | undefined): value is T { return value != null; } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 2def0b45a..e06a8fafd 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -242,11 +242,13 @@ describe("tsconfig", () => { ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], ["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }], + ["luaTarget", "5.0", { luaTarget: tstl.LuaTarget.Lua50 }], ["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 }], + ["luaTarget", "luau", { luaTarget: tstl.LuaTarget.Luau }], ["luaBundle", "foo", { luaBundle: "foo" }], ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], diff --git a/test/cli/run.ts b/test/cli/run.ts index 652e03095..732d71bcb 100644 --- a/test/cli/run.ts +++ b/test/cli/run.ts @@ -26,6 +26,6 @@ export async function runCli(args: string[]): Promise { child.stderr!.on("data", (data: Buffer) => (output += data.toString())); return new Promise(resolve => { - child.on("close", exitCode => resolve({ exitCode, output })); + child.on("close", exitCode => resolve({ exitCode: exitCode ?? 1, output })); }); } diff --git a/test/cli/tsconfig.spec.ts b/test/cli/tsconfig.spec.ts index 1608ac973..e5d1b946c 100644 --- a/test/cli/tsconfig.spec.ts +++ b/test/cli/tsconfig.spec.ts @@ -1,7 +1,7 @@ import * as fs from "fs-extra"; import * as os from "os"; import * as path from "path"; -import { locateConfigFile } from "../../src/cli/tsconfig"; +import { locateConfigFile, parseConfigFileWithSystem } from "../../src/cli/tsconfig"; import { normalizeSlashes } from "../../src/utils"; let temp: string; @@ -20,7 +20,7 @@ afterEach(async () => { const locate = (project: string | undefined, fileNames: string[] = []) => locateConfigFile({ errors: [], fileNames, options: { project } }); -const normalize = (name: string) => normalizeSlashes(path.resolve(temp, name)); +const normalize = (name: string) => normalizeSlashes(fs.realpathSync(path.resolve(temp, name))); describe("specified", () => { for (const separator of process.platform === "win32" ? ["/", "\\"] : ["/"]) { @@ -91,3 +91,25 @@ describe("errors", () => { expect([locate("tsconfig.json", [""])]).toHaveDiagnostics(); }); }); + +describe("tsconfig extends", () => { + test("correctly merges extended tsconfig files", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.3", noHeader: true }); + }); + + test("can handle multiple extends", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.multi-extends.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.4", sourceMapTraceback: true }); + }); + + test("can handle cycles in configs", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig-cycle1.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.4" }); + }); + + test("can handle tsconfig files with comments", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.with-comments.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.3" }); + }); +}); diff --git a/test/cli/tsconfig/tsconfig-cycle1.json b/test/cli/tsconfig/tsconfig-cycle1.json new file mode 100644 index 000000000..6383b5ccf --- /dev/null +++ b/test/cli/tsconfig/tsconfig-cycle1.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig-cycle2.json", + "tstl": { + "luaTarget": "5.4" + } +} diff --git a/test/cli/tsconfig/tsconfig-cycle2.json b/test/cli/tsconfig/tsconfig-cycle2.json new file mode 100644 index 000000000..14c3edcd1 --- /dev/null +++ b/test/cli/tsconfig/tsconfig-cycle2.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig-cycle1.json", + "tstl": { + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig.base.json b/test/cli/tsconfig/tsconfig.base.json new file mode 100644 index 000000000..6b296a8de --- /dev/null +++ b/test/cli/tsconfig/tsconfig.base.json @@ -0,0 +1,6 @@ +{ + "tstl": { + "noHeader": true, + "luaTarget": "jit" + } +} diff --git a/test/cli/tsconfig/tsconfig.json b/test/cli/tsconfig/tsconfig.json new file mode 100644 index 000000000..7e76044a2 --- /dev/null +++ b/test/cli/tsconfig/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.base.json", + "tstl": { + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig.multi-extends.json b/test/cli/tsconfig/tsconfig.multi-extends.json new file mode 100644 index 000000000..7404a6266 --- /dev/null +++ b/test/cli/tsconfig/tsconfig.multi-extends.json @@ -0,0 +1,6 @@ +{ + "extends": ["./tsconfig.json", "./tsconfig2.json"], + "tstl": { + "sourceMapTraceback": true + } +} diff --git a/test/cli/tsconfig/tsconfig.with-comments.json b/test/cli/tsconfig/tsconfig.with-comments.json new file mode 100644 index 000000000..9baf9adda --- /dev/null +++ b/test/cli/tsconfig/tsconfig.with-comments.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "tstl": { + // Can handle comments + /* also of this kind */ + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig2.json b/test/cli/tsconfig/tsconfig2.json new file mode 100644 index 000000000..9cfef77e0 --- /dev/null +++ b/test/cli/tsconfig/tsconfig2.json @@ -0,0 +1,5 @@ +{ + "tstl": { + "luaTarget": "5.4" + } +} diff --git a/test/json.50.lua b/test/json.50.lua new file mode 100644 index 000000000..8e4109c8f --- /dev/null +++ b/test/json.50.lua @@ -0,0 +1,147 @@ +-- +-- json.lua +-- +-- Copyright (c) 2015 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- +-- +-- LICENSE CONTENTS: +-- +-- Copyright (c) 2015 rxi +-- +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. + +local json = { _version = "0.1.0" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\\\", + [ "\"" ] = "\\\"", + [ "\b" ] = "\\b", + [ "\f" ] = "\\f", + [ "\n" ] = "\\n", + [ "\r" ] = "\\r", + [ "\t" ] = "\\t", +} + +local escape_char_map_inv = { [ "\\/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return escape_char_map[c] or string.format("\\u%04x", c:byte()) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if val[1] ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if k ~= "n" then + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + end + if n ~= table.getn(val) then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. string.gsub(val, '[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + if val ~= val then + return "NaN" + elseif val >= 1 / 0 then + return "Infinity" + elseif val <= 0 / 0 then + return "-Infinity" + else + return string.format("%.17g", val) + end +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + +return {stringify = function(val) return ( encode(val) ) end} diff --git a/test/setup.ts b/test/setup.ts index e468c5ab8..e431d8519 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -3,7 +3,6 @@ import * as ts from "typescript"; import * as tstl from "../src"; declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { // eslint-disable-next-line @typescript-eslint/naming-convention interface Matchers { diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 05bb647b8..6753c66b1 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Luau-specific Transformation (luauSpecificTransformations) 1`] = ` +"t = if true then "is true" else "is false" +while false do + continue +end +repeat + do + continue + end +until not false" +`; + exports[`Transformation (blockScopeVariables) 1`] = ` "do local a = 1 @@ -10,44 +22,51 @@ end" `; exports[`Transformation (characterEscapeSequence) 1`] = ` -"quoteInDoubleQuotes = \\"' ' '\\" -quoteInTemplateString = \\"' ' '\\" -doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" -backQuoteInQuotes = \\"\` \` \`\\" -backQuoteInDoubleQuotes = \\"\` \` \`\\" -backQuoteInTemplateString = \\"\` \` \`\\" -escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -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 --\\"" +"quoteInDoubleQuotes = "' ' '" +quoteInTemplateString = "' ' '" +doubleQuoteInQuotes = "\\" \\" \\"" +doubleQuoteInDoubleQuotes = "\\" \\" \\"" +doubleQuoteInTemplateString = "\\" \\" \\"" +backQuoteInQuotes = "\` \` \`" +backQuoteInDoubleQuotes = "\` \` \`" +backQuoteInTemplateString = "\` \` \`" +escapedCharsInQuotes = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" +escapedCharsInDoubleQuotes = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" +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 (customNameWithNoSelf) 1`] = `"TestNamespace.pass()"`; + exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 ____exports.xyz = xyz ____exports.uwv = xyz do - local ____export = require(\\"xyz\\") + local ____export = require("xyz") for ____exportKey, ____exportValue in pairs(____export) do - if ____exportKey ~= \\"default\\" then + if ____exportKey ~= "default" then ____exports[____exportKey] = ____exportValue end end end do - local ____xyz = require(\\"xyz\\") - local abc = ____xyz.abc - local def = ____xyz.def - ____exports.abc = abc - ____exports.def = def + local ____xyz = require("xyz") + ____exports.abc = ____xyz.abc + ____exports.def = ____xyz.def +end +do + local ____xyz = require("xyz") + ____exports.def = ____xyz.abc +end +do + local ____bla = require("bla") + ____exports.bar = ____bla["123"] end do - local ____xyz = require(\\"xyz\\") - local def = ____xyz.abc - ____exports.def = def + local ____bla = require("bla") + ____exports["123"] = ____bla.foo end return ____exports" `; @@ -58,10 +77,10 @@ return ____exports" `; exports[`Transformation (methodRestArguments) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class MyClass = __TS__Class() -MyClass.name = \\"MyClass\\" +MyClass.name = "MyClass" function MyClass.prototype.____constructor(self) end function MyClass.prototype.varargsFunction(self, a, ...) @@ -75,24 +94,24 @@ return ____exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass -TestClass.name = \\"TestClass\\" +TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end return ____exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass -TestClass.name = \\"TestClass\\" +TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end function TestClass.prototype.memberFunc(self) @@ -114,14 +133,14 @@ end" exports[`Transformation (modulesImportAll) 1`] = ` "local ____exports = {} -local Test = require(\\"test\\") +local Test = require("test") local ____ = Test return ____exports" `; exports[`Transformation (modulesImportNamed) 1`] = ` "local ____exports = {} -local ____test = require(\\"test\\") +local ____test = require("test") local TestClass = ____test.TestClass local ____ = TestClass return ____exports" @@ -129,15 +148,15 @@ return ____exports" exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` "local ____exports = {} -local ____kebab_2Dmodule = require(\\"kebab-module\\") +local ____kebab_2Dmodule = require("kebab-module") local TestClass1 = ____kebab_2Dmodule.TestClass1 -local ____dollar_24module = require(\\"dollar$module\\") +local ____dollar_24module = require("dollar$module") local TestClass2 = ____dollar_24module.TestClass2 -local ____singlequote_27module = require(\\"singlequote'module\\") +local ____singlequote_27module = require("singlequote'module") local TestClass3 = ____singlequote_27module.TestClass3 -local ____hash_23module = require(\\"hash#module\\") +local ____hash_23module = require("hash#module") local TestClass4 = ____hash_23module.TestClass4 -local ____space_20module = require(\\"space module\\") +local ____space_20module = require("space module") local TestClass5 = ____space_20module.TestClass5 local ____ = TestClass1 local ____ = TestClass2 @@ -149,7 +168,7 @@ return ____exports" exports[`Transformation (modulesImportRenamed) 1`] = ` "local ____exports = {} -local ____test = require(\\"test\\") +local ____test = require("test") local RenamedClass = ____test.TestClass local ____ = RenamedClass return ____exports" @@ -157,15 +176,15 @@ return ____exports" exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` "local ____exports = {} -local ____kebab_2Dmodule = require(\\"kebab-module\\") +local ____kebab_2Dmodule = require("kebab-module") local RenamedClass1 = ____kebab_2Dmodule.TestClass -local ____dollar_24module = require(\\"dollar$module\\") +local ____dollar_24module = require("dollar$module") local RenamedClass2 = ____dollar_24module.TestClass -local ____singlequote_27module = require(\\"singlequote'module\\") +local ____singlequote_27module = require("singlequote'module") local RenamedClass3 = ____singlequote_27module.TestClass -local ____hash_23module = require(\\"hash#module\\") +local ____hash_23module = require("hash#module") local RenamedClass4 = ____hash_23module.TestClass -local ____space_20module = require(\\"space module\\") +local ____space_20module = require("space module") local RenamedClass5 = ____space_20module.TestClass local ____ = RenamedClass1 local ____ = RenamedClass2 @@ -177,7 +196,7 @@ return ____exports" exports[`Transformation (modulesImportWithoutFromClause) 1`] = ` "local ____exports = {} -require(\\"test\\") +require("test") return ____exports" `; @@ -227,19 +246,19 @@ return ____exports" exports[`Transformation (modulesVariableExport) 1`] = ` "local ____exports = {} -____exports.foo = \\"bar\\" +____exports.foo = "bar" return ____exports" `; -exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; +exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = "bar""`; exports[`Transformation (printFormat) 1`] = ` -"stringConcat = ((\\"a\\" .. \\"b\\" .. \\"c\\") .. \\"d\\") .. \\"e\\" +"stringConcat = (("a" .. "b" .. "c") .. "d") .. "e" numbers = 2 * 2 + 3 + 4 * (5 + 6) ~= 7 function func(...) end func(function() - local b = \\"A function\\" + local b = "A function" end) func(func()) array = {func()} @@ -252,8 +271,8 @@ bigObject = { a = 1, b = 2, c = 3, - d = \\"value1\\", - e = \\"value2\\" + d = "value1", + e = "value2" }" `; @@ -279,7 +298,7 @@ end" exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` "local ____exports = {} -local x = require(\\"module\\") +local x = require("module") local ____ = x return ____exports" `; diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 42a4b4355..5f9df58fe 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -19,3 +19,18 @@ test.each(fixtures)("Transformation (%s)", (_name, content) => { .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); + +const luauFixturesPath = path.join(fixturesPath, "luau"); +const luauFixtures = fs + .readdirSync(luauFixturesPath) + .filter(f => path.extname(f) === ".ts") + .sort() + .map(f => [path.parse(f).name, fs.readFileSync(path.join(luauFixturesPath, f), "utf8")]); + +test.each(luauFixtures)("Luau-specific Transformation (%s)", (_name, content) => { + util.testModule(content) + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require, luaTarget: tstl.LuaTarget.Luau }) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); diff --git a/test/translation/transformation/customNameWithNoSelf.ts b/test/translation/transformation/customNameWithNoSelf.ts new file mode 100644 index 000000000..73175ccdc --- /dev/null +++ b/test/translation/transformation/customNameWithNoSelf.ts @@ -0,0 +1,7 @@ +/** @noSelf */ +declare namespace TestNamespace { + /** @customName pass */ + function fail(): void; +} + +TestNamespace.fail(); diff --git a/test/translation/transformation/exportStatement.ts b/test/translation/transformation/exportStatement.ts index 7aa965422..cf227da3d 100644 --- a/test/translation/transformation/exportStatement.ts +++ b/test/translation/transformation/exportStatement.ts @@ -4,3 +4,5 @@ export { xyz as uwv }; export * from "xyz"; export { abc, def } from "xyz"; export { abc as def } from "xyz"; +export { "123" as bar } from "bla"; +export { foo as "123" } from "bla"; diff --git a/test/translation/transformation/luau/luauSpecificTransformations.ts b/test/translation/transformation/luau/luauSpecificTransformations.ts new file mode 100644 index 000000000..b4c9fdec4 --- /dev/null +++ b/test/translation/transformation/luau/luauSpecificTransformations.ts @@ -0,0 +1,9 @@ +const t = true ? "is true" : "is false"; + +while (false) { + continue; +} + +do { + continue; +} while (false); diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index a76619460..d214dbba7 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -1,28 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` -Array [ +[ "directories/basic/src/lib/file.lua", "directories/basic/src/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 2`] = ` -Array [ +[ "directories/basic/out/lib/file.lua", "directories/basic/out/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 3`] = ` -Array [ +[ "directories/basic/src/lib/file.lua", "directories/basic/src/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 4`] = ` -Array [ +[ "directories/basic/out/lib/file.lua", "directories/basic/out/main.lua", ] diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap index 2e4d888cb..c9f0be298 100644 --- a/test/transpile/__snapshots__/module-resolution.spec.ts.snap +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`supports complicated paths configuration 1`] = ` -Array [ +[ "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/bar.lua", "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/index.lua", "/paths-base-tsconfig/dist/packages/tstl-program/packages/myprogram/src/main.lua", @@ -9,9 +9,9 @@ Array [ `; exports[`supports paths configuration 1`] = ` -Array [ +[ + "/paths-simple/myprogram/dist/main.lua", "/paths-simple/myprogram/dist/mypackage/bar.lua", "/paths-simple/myprogram/dist/mypackage/index.lua", - "/paths-simple/myprogram/dist/myprogram/main.lua", ] `; diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index c2f66a1e7..227e004f8 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should give verbose output 1`] = ` -Array [ +[ "Loaded 0 plugins", "Parsing project settings", "Transforming /test/transpile/project/otherFile.ts", @@ -11,7 +11,7 @@ Array [ "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/index.ts", + "Resolving "./otherFile" from /test/transpile/project/index.ts", "Resolved ./otherFile to /test/transpile/project/otherFile.ts", "Emitting output", "Emitting /test/transpile/project/otherFile.lua", @@ -21,8 +21,8 @@ Array [ `; exports[`should transpile 1`] = ` -Array [ - Object { +[ + { "filePath": "otherFile.lua", "lua": "local ____exports = {} function ____exports.getNumber(self) @@ -31,10 +31,10 @@ end return ____exports ", }, - Object { + { "filePath": "index.lua", "lua": "local ____exports = {} -local ____otherFile = require(\\"otherFile\\") +local ____otherFile = require("otherFile") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) setAPIValue(myNumber * 5) diff --git a/test/transpile/lualib.spec.ts b/test/transpile/lualib.spec.ts index b35ab996b..20288bd8a 100644 --- a/test/transpile/lualib.spec.ts +++ b/test/transpile/lualib.spec.ts @@ -1,10 +1,10 @@ import * as ts from "typescript"; -import { LuaLibFeature } from "../../src"; +import { LuaLibFeature, LuaTarget } from "../../src"; import { readLuaLibFeature } from "../../src/LuaLib"; import * as util from "../util"; test.each(Object.entries(LuaLibFeature))("Lualib does not use ____exports (%p)", (_, feature) => { - const lualibCode = readLuaLibFeature(feature, ts.sys); + const lualibCode = readLuaLibFeature(feature, LuaTarget.Lua54, ts.sys); const exportsOccurrences = lualibCode.match(/____exports/g); expect(exportsOccurrences).toBeNull(); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 4e8f3d49b..ff29ac9b5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -174,6 +174,22 @@ describe("module resolution with sourceDir", () => { .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) .expectToEqual(expectedResult); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1394 + test("can resolve files with non-standard extension (#1394)", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out", extension: ".script" }) + .expectToEqual(expectedResult); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1394 + test("can resolve files with non-standard extension without separator (#1394)", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out", extension: "script" }) + .expectToEqual(expectedResult); + }); }); describe("module resolution project with lua sources", () => { @@ -272,6 +288,51 @@ describe("module resolution project with dependencies built by tstl library mode }); }); +describe("module resolution project with dependencies built by tstl library mode and has exports field", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-has-exports-field"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + const dependency1Path = path.join(projectPath, "node_modules", "dependency1"); + tstl.transpileProject(path.join(dependency1Path, "tsconfig.json")); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + }; + + test("can resolve lua dependencies", () => { + const transpileResult = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ + outDir: "tstl-out", + moduleResolution: ts.ModuleResolutionKind.Node16, + module: ts.ModuleKind.Node16, + }) + .expectToEqual(expectedResult) + .getLuaResult(); + + // Assert node_modules file requires the correct lualib_bundle + const requiringLuaFile = path.join("lua_modules", "dependency1", "dist", "index.lua"); + const lualibRequiringFile = transpileResult.transpiledFiles.find(f => f.outPath.endsWith(requiringLuaFile)); + expect(lualibRequiringFile).toBeDefined(); + expect(lualibRequiringFile?.lua).toContain('require("lualib_bundle")'); + }); + + 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, + moduleResolution: ts.ModuleResolutionKind.Node16, + module: ts.ModuleKind.Node16, + }) + .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"); @@ -385,6 +446,65 @@ describe("module resolution should not try to resolve modules in noResolvePaths" .setOptions({ noResolvePaths: ["a.b.c.foo", "somethingExtra", "dontResolveThis"] }) .expectToHaveNoDiagnostics(); }); + + test("can ignore specific files with glob pattern", () => { + util.testModule` + // Pre-Load as to not error out at runtime + import "preload"; + + import "ignoreme"; + import * as b from "./actualfile"; + + export const result = b.foo(); + ` + .addExtraFile("preload.lua", 'package.preload["ignoreme"] = function() return nil end') + .addExtraFile( + "actualfile.ts", + `export function foo() + { + return 'foo'; + }` + ) + .addExtraFile( + "ignoreme.d.ts", + `declare module "ignoreme" { + export function foo(): void; + }` + ) + .setOptions({ noResolvePaths: ["ignore*"] }) + .expectToHaveNoDiagnostics() + .expectToEqual({ result: "foo" }); + }); + + test("can ignore all files with glob pattern in require", () => { + util.testModule` + declare function require(this: void, module: string): any; + + const a = require("a") + const b = require("b/b") + const c = require("c/c/c") + const d = require("!:?somefile") + ` + .setOptions({ noResolvePaths: ["**"] }) + .expectToHaveNoDiagnostics(); + }); + + test("can ignore all files with glob pattern as used in imported lua sources", () => { + util.testModule` + import * as lua from "./luasource"; + lua.foo(); + ` + .addExtraFile("luasource.d.ts", "export function foo(): void;") + .addExtraFile( + "luasource.lua", + ` + require("ignoreme!") + require("i.g.n.o.r.e") + ` + ) + .setOptions({ noResolvePaths: ["**"] }) + .expectToHaveNoDiagnostics(); + }); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 @@ -411,7 +531,7 @@ test("module resolution should not rewrite @NoResolution requires in library mod }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 -test("module resolution should not try to resolve resolve-like functions", () => { +test("module resolution should not try to resolve require-like functions", () => { util.testModule` function custom_require(this: void, value: string) { return value; @@ -591,6 +711,30 @@ test("paths without baseUrl is error", () => { util.testFunction``.setOptions({ paths: {} }).expectToHaveDiagnostics([pathsWithoutBaseUrl.code]); }); +test("module resolution using plugin", () => { + const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); + const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); + const mainFile = path.join(baseProjectPath, "main.ts"); + + const testBuilder = util + .testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ + luaPlugins: [ + { + name: path.join(__dirname, "./plugins/moduleResolution.ts"), + }, + ], + }) + .expectToHaveNoDiagnostics(); + + const luaResult = testBuilder.getLuaResult(); + + expect(luaResult.transpiledFiles).toHaveLength(3); + + testBuilder.expectToEqual({ result: ["foo", "absolutefoo"] }); +}); + function snapshotPaths(files: tstl.TranspiledFile[]) { return files.map(f => normalizeSlashes(f.outPath).split("module-resolution")[1]).sort(); } diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua new file mode 100644 index 000000000..35718ddea --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua @@ -0,0 +1,5 @@ +local ____exports = {} +function ____exports.absolutefoo(self) + return "absolutefoo" +end +return ____exports \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts new file mode 100644 index 000000000..9df109b2e --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts @@ -0,0 +1 @@ +export declare function absolutefoo(): string; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua new file mode 100644 index 000000000..b821a15b5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua @@ -0,0 +1,5 @@ +local ____exports = {} +function ____exports.foo(self) + return "foo" +end +return ____exports \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts new file mode 100644 index 000000000..27e069e94 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts @@ -0,0 +1 @@ +export declare function foo(): string; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts new file mode 100644 index 000000000..e3e6bc616 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts @@ -0,0 +1,3 @@ +import { foo } from "./lua_sources/foo"; +import { absolutefoo } from "./lua_sources/absolutefoo"; +export const result = [foo(), absolutefoo()]; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json new file mode 100644 index 000000000..06ed18c9f --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "lib": ["esnext"], + "types": [] + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/main.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/main.ts new file mode 100644 index 000000000..3421911f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/main.ts @@ -0,0 +1,5 @@ +import { dependency1IndexFunc } from "dependency1/sub"; +import { dependency1OtherFileFunc } from "dependency1/sub/d1otherfile"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/package.json new file mode 100644 index 000000000..c74b862a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/package.json @@ -0,0 +1,14 @@ +{ + "name": "dependency1", + "version": "0.0.1", + "exports": { + "./sub": { + "require": "./dist/index", + "types": "./dist/index.d.ts" + }, + "./sub/*": { + "require": "./dist/*", + "types": "./dist/*.d.ts" + } + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/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-has-exports-field/node_modules/dependency1/src/index.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/index.ts new file mode 100644 index 000000000..03cff47c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/index.ts @@ -0,0 +1,10 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} + +export function squares(nums: number[]) { + // Require lualib functionality + return nums.map(n => n * n); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/tsconfig.json new file mode 100644 index 000000000..d6ffcdc0c --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/package.json new file mode 100644 index 000000000..b88dc4bc0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "version": "0.0.1", + "dependencies": { + "dependency1": "file:../dependency1-ts" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/tsconfig.json new file mode 100644 index 000000000..7b0969155 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "moduleResolution": "node16" + }, + "references": [{ "path": "./node_modules/dependency1" }] +} diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts index 0917307b8..f98b6e635 100644 --- a/test/transpile/paths.spec.ts +++ b/test/transpile/paths.spec.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { getSourceDir } from "../../src"; +import { getEmitPath, getSourceDir } from "../../src"; import * as util from "../util"; const cwd = process.cwd(); @@ -12,31 +12,24 @@ 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); - + // If rootdir is specified, rootDir is the sourceDir 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 + // If rootDir is not specified, root dir is where the config file is 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, - }); + test("without config file in src dir", () => { + const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], {}); // getCommonSourceDirectory does not work right so mock it jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(path.join(cwd, "src")); - // Common sources directory is src + // If there is no config file, return the common source directory expect(normalize(getSourceDir(program))).toBe(path.join(cwd, "src")); }); }); @@ -145,6 +138,21 @@ describe("getEmitPath", () => { expect(fileNames).toHaveLength(1); expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.scar")); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1540 + test("puts files next to their source if no config is given (#1540)", () => { + const file1 = path.join("src", "main.ts"); + const file2 = path.join("src", "otherfile.ts"); + const file3 = path.join("src", "nested", "nestedfile.ts"); + const program = ts.createProgram([file1, file2, file3], { configFilePath }); + + // If rootDir is not specified, root dir is where the config file is + const configRoot = path.dirname(configFilePath); + const replaceExtension = (f: string) => f.replace(/\.ts$/, ".lua"); + expect(getEmitPath(file1, program)).toBe(replaceExtension(path.join(configRoot, file1))); + expect(getEmitPath(file2, program)).toBe(replaceExtension(path.join(configRoot, file2))); + expect(getEmitPath(file3, program)).toBe(replaceExtension(path.join(configRoot, file3))); + }); }); function normalize(path: string) { diff --git a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap index 9902416ab..7e3be754d 100644 --- a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap +++ b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap @@ -5,11 +5,11 @@ exports[`statement comments 1`] = ` function ____exports.__main(self) --This comment on variable declaration was added by a plugin! --- This one too! - local foo = \\"bar\\" + local foo = "bar" -- This trailing comment was also added by a plugin! --- Example luadoc comment ---@param paramName ParamClass - foo = \\"baz\\" + foo = "baz" --[[ This plugin can also (kinda) create multiline comments. -- Line 2 --]] diff --git a/test/transpile/plugins/add-comments.ts b/test/transpile/plugins/add-comments.ts index 9beb01432..2e9c56a5f 100644 --- a/test/transpile/plugins/add-comments.ts +++ b/test/transpile/plugins/add-comments.ts @@ -58,5 +58,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/afterEmit.ts b/test/transpile/plugins/afterEmit.ts new file mode 100644 index 000000000..277258f25 --- /dev/null +++ b/test/transpile/plugins/afterEmit.ts @@ -0,0 +1,23 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + afterEmit(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost, result: tstl.EmitFile[]) { + void program; + void options; + void emitHost; + void result; + + const diagnostic = { + category: ts.DiagnosticCategory.Message, + messageText: "After emit diagnostic message!", + code: 1234, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic; + return [diagnostic]; + }, +}; + +export default plugin; diff --git a/test/transpile/plugins/afterPrint.ts b/test/transpile/plugins/afterPrint.ts index 1c2529361..cb548218b 100644 --- a/test/transpile/plugins/afterPrint.ts +++ b/test/transpile/plugins/afterPrint.ts @@ -18,5 +18,4 @@ const plugin: tstl.Plugin = { }, }; -// 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 index f6aa2ba6e..e90afae3b 100644 --- a/test/transpile/plugins/arguments.ts +++ b/test/transpile/plugins/arguments.ts @@ -6,7 +6,6 @@ interface Options { option: boolean; } -// eslint-disable-next-line import/no-default-export export default function plugin(options: Options): tstl.Plugin { return { visitors: { diff --git a/test/transpile/plugins/beforeEmit.ts b/test/transpile/plugins/beforeEmit.ts index 973024ba4..2deb029e4 100644 --- a/test/transpile/plugins/beforeEmit.ts +++ b/test/transpile/plugins/beforeEmit.ts @@ -13,5 +13,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/beforeTransform.ts b/test/transpile/plugins/beforeTransform.ts index 947358fa2..c93c20f91 100644 --- a/test/transpile/plugins/beforeTransform.ts +++ b/test/transpile/plugins/beforeTransform.ts @@ -11,5 +11,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/moduleResolution.ts b/test/transpile/plugins/moduleResolution.ts new file mode 100644 index 000000000..705345a5b --- /dev/null +++ b/test/transpile/plugins/moduleResolution.ts @@ -0,0 +1,22 @@ +import path = require("path"); +import type * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + moduleResolution(moduleIdentifier) { + if (moduleIdentifier.includes("absolutefoo")) { + return path.join( + path.dirname(__dirname), + "module-resolution", + "project-with-module-resolution-plugin", + "lua_sources", + "absolutebar.lua" + ); + } + + if (moduleIdentifier.includes("foo")) { + return moduleIdentifier.replace("foo", "bar"); + } + }, +}; + +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 3fc4b63cf..ed25ae748 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -1,5 +1,7 @@ import * as path from "path"; import * as util from "../../util"; +import { Plugin } from "../../../src/transpilation/plugins"; +import * as ts from "typescript"; test("printer", () => { util.testModule`` @@ -160,3 +162,82 @@ test("beforeEmit plugin bundle", () => { expect(f.lua).toContain("-- Comment added by beforeEmit plugin"); } }); + +test("afterEmit plugin", () => { + const { diagnostics } = util.testModule` + console.log("Hello, World!"); + [].push(1,2,3); // Use lualib code + ` + .addExtraFile( + "extrafile.ts", + ` + console.log("Hello, Mars!"); + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "afterEmit.ts") }] }) + .getLuaResult(); + + // Expect to see the diagnostic returned by the plugin in the output + const diagnostic = diagnostics.find(d => d.code === 1234); + expect(diagnostic).toBeDefined(); + expect(diagnostic?.category).toBe(ts.DiagnosticCategory.Message); + expect(diagnostic?.messageText).toContain("After emit"); +}); + +test("in memory plugin", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + plugin: { + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: 1234, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin, + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +}); + +test("in memory plugin with factory", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + code: 1234, + plugin: options => + ({ + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: options.code, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin), + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +}); diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts index 47627e5b5..37b6d84f7 100644 --- a/test/transpile/plugins/printer.ts +++ b/test/transpile/plugins/printer.ts @@ -20,5 +20,4 @@ const plugin: tstl.Plugin = { printer: (program, emitHost, fileName, file) => new CustomPrinter(emitHost, program, fileName).print(file), }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor-super.ts b/test/transpile/plugins/visitor-super.ts index 9a8bee5f1..3ece9458b 100644 --- a/test/transpile/plugins/visitor-super.ts +++ b/test/transpile/plugins/visitor-super.ts @@ -15,5 +15,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor.ts b/test/transpile/plugins/visitor.ts index 507b9fa3d..15da18ded 100644 --- a/test/transpile/plugins/visitor.ts +++ b/test/transpile/plugins/visitor.ts @@ -7,5 +7,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/resolve-plugin/ts.ts b/test/transpile/resolve-plugin/ts.ts index 60757f0a4..ff3177bab 100644 --- a/test/transpile/resolve-plugin/ts.ts +++ b/test/transpile/resolve-plugin/ts.ts @@ -1,2 +1 @@ -// eslint-disable-next-line import/no-default-export export default true; diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts index 02290d9d1..34dd9dc15 100644 --- a/test/transpile/transformers/transformers.spec.ts +++ b/test/transpile/transformers/transformers.spec.ts @@ -35,3 +35,22 @@ describe("factory types", () => { .expectToEqual(true); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1464 +test("transformer with switch does not break (#1464)", () => { + util.testFunction` + const foo: number = 3; + switch (foo) { + case 2: { + return 10; + } + case 3: { + return false; + } + } + ` + .setOptions({ + plugins: [{ transform: path.join(__dirname, "fixtures.ts"), import: "program", value: true }], + }) + .expectToEqual(true); +}); diff --git a/test/transpile/transformers/utils.ts b/test/transpile/transformers/utils.ts index 3e1503ba0..819454530 100644 --- a/test/transpile/transformers/utils.ts +++ b/test/transpile/transformers/utils.ts @@ -2,5 +2,5 @@ import * as ts from "typescript"; export function visitAndReplace(context: ts.TransformationContext, node: T, visitor: ts.Visitor): T { const visit: ts.Visitor = node => visitor(node) ?? ts.visitEachChild(node, visit, context); - return ts.visitNode(node, visit); + return ts.visitEachChild(node, visit, context); } diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 20d4ec657..852b6a668 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -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[`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[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle projects 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."`; diff --git a/test/unit/__snapshots__/comments.spec.ts.snap b/test/unit/__snapshots__/comments.spec.ts.snap index 23b89dcb7..55052f60e 100644 --- a/test/unit/__snapshots__/comments.spec.ts.snap +++ b/test/unit/__snapshots__/comments.spec.ts.snap @@ -8,7 +8,7 @@ exports[`JSDoc is copied on a function with tags: code 1`] = ` -- @param arg2 This is the second argument. -- @returns A very powerful string. function foo(self, arg1, arg2) - return \\"bar\\" + return "bar" end" `; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 5f58cde14..1e71d2976 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -36,6 +36,116 @@ ____exports.__result = 10 - (4 + 5) return ____exports" `; +exports[`Bitop [5.0] ("~a"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bnot(a) +return ____exports" +`; + +exports[`Bitop [5.0] ("~a"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a&=b"): code 1`] = ` +"local ____exports = {} +a = bit.band(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a&=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a&b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.band(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a&b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a<<=b"): code 1`] = ` +"local ____exports = {} +a = bit.lshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a<<=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a<>=b"): code 1`] = ` +"local ____exports = {} +a = bit.arshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>>=b"): code 1`] = ` +"local ____exports = {} +a = bit.rshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.rshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.arshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a^=b"): code 1`] = ` +"local ____exports = {} +a = bit.bxor(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a^=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a^b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bxor(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a^b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a|=b"): code 1`] = ` +"local ____exports = {} +a = bit.bor(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a|=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a|b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bor(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a|b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + exports[`Bitop [5.1] ("~a"): code 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) @@ -503,21 +613,21 @@ return ____exports" `; exports[`Unary expressions basic ("delete tbl.test") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - __TS__Delete(tbl, \\"test\\") + __TS__Delete(tbl, "test") end return ____exports" `; exports[`Unary expressions basic ("delete tbl['test']") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - __TS__Delete(tbl, \\"test\\") + __TS__Delete(tbl, "test") end return ____exports" `; @@ -539,21 +649,21 @@ return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl.test") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - local a = __TS__Delete(tbl, \\"test\\") + local a = __TS__Delete(tbl, "test") end return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl['test']") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - local a = __TS__Delete(tbl, \\"test\\") + local a = __TS__Delete(tbl, "test") end return ____exports" `; diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 8af819bc0..4a8ddc751 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -72,59 +72,59 @@ exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): cod exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {["$$$"] = _____24_24_24}"`; 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[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {["_̀ः٠‿"] = ______300_903_660_203F}"`; 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[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {["and"] = ____and}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {["elseif"] = ____elseif}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {["end"] = ____end}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {["goto"] = ____goto}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {["local"] = ____local}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {["nil"] = ____nil}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {["not"] = ____not}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {["or"] = ____or}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {["repeat"] = ____repeat}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {["then"] = ____then}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {["until"] = ____until}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {["ɥɣɎɌͼƛಠ"] = _____265_263_24E_24C_37C_19B_CA0}"`; 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."`; @@ -192,66 +192,66 @@ exports[`undeclared identifier must be a valid lua identifier ("ɥɣɎɌͼƛಠ" 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."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {["$$$"] = _____24_24_24}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {["_̀ः٠‿"] = ______300_903_660_203F}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {["and"] = ____and}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {["elseif"] = ____elseif}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {["end"] = ____end}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {["goto"] = ____goto}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {["local"] = ____local}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {["nil"] = ____nil}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {["not"] = ____not}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {["or"] = ____or}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {["repeat"] = ____repeat}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {["then"] = ____then}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {["until"] = ____until}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {["ɥɣɎɌͼƛಠ"] = _____265_263_24E_24C_37C_19B_CA0}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local _̀ः٠‿ = ____temp_0.foo return _̀ः٠‿ end @@ -261,7 +261,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local ɥɣɎɌͼƛಠ = ____temp_0.foo return ɥɣɎɌͼƛಠ end @@ -271,7 +271,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local 𝛼𝛽𝚫 = ____temp_0.foo return 𝛼𝛽𝚫 end @@ -281,7 +281,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {_̀ः٠‿ = \\"foobar\\"} + local ____temp_0 = {_̀ः٠‿ = "foobar"} local _̀ः٠‿ = ____temp_0._̀ः٠‿ return _̀ः٠‿ end @@ -291,7 +291,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + local ____temp_0 = {ɥɣɎɌͼƛಠ = "foobar"} local ɥɣɎɌͼƛಠ = ____temp_0.ɥɣɎɌͼƛಠ return ɥɣɎɌͼƛಠ end @@ -301,7 +301,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {𝛼𝛽𝚫 = \\"foobar\\"} + local ____temp_0 = {𝛼𝛽𝚫 = "foobar"} local 𝛼𝛽𝚫 = ____temp_0.𝛼𝛽𝚫 return 𝛼𝛽𝚫 end @@ -312,9 +312,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("_̀ "local ____exports = {} function ____exports.__main(self) local function _̀ः٠‿(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return _̀ः٠‿(nil, \\"bar\\") + return _̀ः٠‿(nil, "bar") end return ____exports" `; @@ -323,9 +323,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("ɥɣ "local ____exports = {} function ____exports.__main(self) local function ɥɣɎɌͼƛಠ(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return ɥɣɎɌͼƛಠ(nil, \\"bar\\") + return ɥɣɎɌͼƛಠ(nil, "bar") end return ____exports" `; @@ -334,9 +334,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("𝛼 "local ____exports = {} function ____exports.__main(self) local function 𝛼𝛽𝚫(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return 𝛼𝛽𝚫(nil, \\"bar\\") + return 𝛼𝛽𝚫(nil, "bar") end return ____exports" `; @@ -344,7 +344,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local _̀ः٠‿ = \\"foobar\\" + local _̀ः٠‿ = "foobar" return _̀ः٠‿ end return ____exports" @@ -353,7 +353,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ɥɣɎɌͼƛಠ = \\"foobar\\" + local ɥɣɎɌͼƛಠ = "foobar" return ɥɣɎɌͼƛಠ end return ____exports" @@ -362,7 +362,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local 𝛼𝛽𝚫 = \\"foobar\\" + local 𝛼𝛽𝚫 = "foobar" return 𝛼𝛽𝚫 end return ____exports" @@ -372,9 +372,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("_̀ः "local ____exports = {} function ____exports.__main(self) local foo = {_̀ः٠‿ = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:_̀ः٠‿(\\"bar\\") + return foo:_̀ः٠‿("bar") end return ____exports" `; @@ -383,9 +383,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("ɥɣɎ "local ____exports = {} function ____exports.__main(self) local foo = {ɥɣɎɌͼƛಠ = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:ɥɣɎɌͼƛಠ(\\"bar\\") + return foo:ɥɣɎɌͼƛಠ("bar") end return ____exports" `; @@ -394,9 +394,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("𝛼 "local ____exports = {} function ____exports.__main(self) local foo = {𝛼𝛽𝚫 = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:𝛼𝛽𝚫(\\"bar\\") + return foo:𝛼𝛽𝚫("bar") end return ____exports" `; @@ -404,7 +404,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {_̀ः٠‿ = \\"foobar\\"} + local x = {_̀ः٠‿ = "foobar"} return x._̀ः٠‿ end return ____exports" @@ -413,7 +413,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + local x = {ɥɣɎɌͼƛಠ = "foobar"} return x.ɥɣɎɌͼƛಠ end return ____exports" @@ -422,7 +422,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {𝛼𝛽𝚫 = \\"foobar\\"} + local x = {𝛼𝛽𝚫 = "foobar"} return x.𝛼𝛽𝚫 end return ____exports" diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap index e9b6be991..29b609730 100644 --- a/test/unit/__snapshots__/loops.spec.ts.snap +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -11,121 +11,3 @@ return ____exports" `; exports[`forin[Array]: diagnostics 1`] = `"main.ts(3,9): error TSTL: Iterating over arrays with 'for ... in' is not allowed."`; - -exports[`loop continue (do { continue; } while (false)) [5.1]: code 1`] = ` -"repeat - do - do - goto __continue2 - end - ::__continue2:: - end -until not false" -`; - -exports[`loop continue (do { continue; } while (false)) [5.1]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (do { continue; } while (false)) [universal]: code 1`] = ` -"repeat - do - do - goto __continue2 - end - ::__continue2:: - end -until not false" -`; - -exports[`loop continue (do { continue; } while (false)) [universal]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (;;) { continue; }) [5.1]: code 1`] = ` -"do - while true do - do - goto __continue2 - end - ::__continue2:: - end -end" -`; - -exports[`loop continue (for (;;) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (;;) { continue; }) [universal]: code 1`] = ` -"do - while true do - do - goto __continue2 - end - ::__continue2:: - end -end" -`; - -exports[`loop continue (for (;;) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.1]: code 1`] = ` -"for a in pairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a in {}) { continue; }) [universal]: code 1`] = ` -"for a in pairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a in {}) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a of []) { continue; }) [5.1]: code 1`] = ` -"for ____, a in ipairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a of []) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a of []) { continue; }) [universal]: code 1`] = ` -"for ____, a in ipairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a of []) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (while (false) { continue; }) [5.1]: code 1`] = ` -"while false do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (while (false) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (while (false) { continue; }) [universal]: code 1`] = ` -"while false do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (while (false) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 94655ca01..19fa2a309 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -1,31 +1,31 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Unsupported optional chains Builtin global method: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Number = ____lualib.__TS__Number -local ____Number_result_0 = Number -if ____Number_result_0 ~= nil then - ____Number_result_0 = __TS__Number(\\"3\\") +local ____opt_0 = Number +if ____opt_0 ~= nil then + __TS__Number("3") end" `; exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; exports[`Unsupported optional chains Builtin global property: code 1`] = ` -"local ____console_log_result_0 = console -if ____console_log_result_0 ~= nil then - ____console_log_result_0 = print(\\"3\\") +"local ____opt_0 = console +if ____opt_0 ~= nil then + print("3") end" `; exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach -local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach -if ____table_forEach_result_0 ~= nil then - ____table_forEach_result_0 = __TS__ArrayForEach( +local ____opt_0 = ({1, 2, 3, 4}).forEach +if ____opt_0 ~= nil then + __TS__ArrayForEach( {1, 2, 3, 4}, function() end @@ -49,10 +49,10 @@ function ____exports.__main(self) local C = 3 --- -- @compileMembersOnly - local D = \\"D\\" - local ____TestEnum_B_0 = TestEnum - if ____TestEnum_B_0 ~= nil then - ____TestEnum_B_0 = B + local D = "D" + local ____opt_0 = TestEnum + if ____opt_0 ~= nil then + local ____ = B end end return ____exports" @@ -61,10 +61,216 @@ return ____exports" exports[`Unsupported optional chains Compile members only: diagnostics 1`] = `"main.ts(10,17): error TSTL: Optional calls are not supported on enums marked with @compileMembersOnly."`; exports[`Unsupported optional chains Language extensions: code 1`] = ` -"local ____table_has_result_0 = ({}).has -if ____table_has_result_0 ~= nil then - ____table_has_result_0 = nil[3] ~= nil +"local ____opt_0 = ({}).has +if ____opt_0 ~= nil then end" `; -exports[`Unsupported optional chains Language extensions: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; +exports[`Unsupported optional chains Language extensions: diagnostics 1`] = ` +"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions. +main.ts(2,17): error TSTL: This language extension must be called as a method." +`; + +exports[`long optional chain 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local a = {b = {c = {d = {e = {f = "hello!"}}}}} + local ____opt_2 = a.b + local ____opt_0 = ____opt_2 and ____opt_2.c + return ____opt_0 and ____opt_0.d.e.f +end +return ____exports" +`; + +exports[`optional chaining ("{ foo: \\"foo\\" }") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = {foo = "foo"} + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional chaining ("null") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = nil + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional chaining ("undefined") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = nil + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional element function calls 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = { + value = "foobar", + foo = function(v) return v + 10 end + } + local fooKey = "foo" + local barKey = "bar" + local ____opt_0 = obj[barKey] + local ____temp_4 = ____opt_0 and ____opt_0(5) + if ____temp_4 == nil then + local ____opt_2 = obj[fooKey] + ____temp_4 = ____opt_2 and ____opt_2(15) + end + return ____temp_4 +end +return ____exports" +`; + +exports[`unused call 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result + local obj = {foo = function(self) + result = "bar" + end} + if obj ~= nil then + obj:foo() + end + return result +end +return ____exports" +`; + +exports[`unused expression 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = {foo = "bar"} + if obj ~= nil then + local ____ = obj.foo + end +end +return ____exports" +`; + +exports[`unused result with preceding statements on right side 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0_foo_2(obj, ____i_1) + end + return i +end +return ____exports" +`; + +exports[`unused result with preceding statements on right side 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(self, val) + return val + end} + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0_foo_2(obj, ____i_1) + end + return i +end +return ____exports" +`; + +exports[`with preceding statements on right side 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + local ____opt_result_4 + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_result_4 = ____opt_0_foo_2(obj, ____i_1) + end + return {result = ____opt_result_4, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(____, v) return v end} + local ____opt_result_4 + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_result_4 = ____opt_0_foo_2(obj, ____i_1) + end + return {result = ____opt_result_4, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side modifying left 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + local function bar(self) + if obj then + obj.foo = nil + end + obj = nil + return 1 + end + local ____opt_0 = obj + if ____opt_0 ~= nil then + local ____opt_0_foo_3 = ____opt_0.foo + local ____bar_result_2 = bar(nil) + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0 = ____opt_0_foo_3(____opt_0, ____bar_result_2, ____i_1) + end + return {result = ____opt_0, obj = obj, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side modifying left 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(self, v) + return v + end} + local function bar(self) + if obj then + obj.foo = nil + end + obj = nil + return 1 + end + local ____opt_0 = obj + if ____opt_0 ~= nil then + local ____opt_0_foo_3 = ____opt_0.foo + local ____bar_result_2 = bar(nil) + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0 = ____opt_0_foo_3(____opt_0, ____bar_result_2, ____i_1) + end + return {result = ____opt_0, obj = obj, i = i} +end +return ____exports" +`; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index e0ef21233..c1fba08eb 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -12,175 +12,7 @@ function ____exports.__main(self) multi(nil, ...) ) end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization With cast 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 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\\") + return test(nil, "a", "b", "c") end return ____exports" `; diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index ef5504938..a64e3f77d 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -8,7 +8,7 @@ function ____exports.__main(self) local ____switch3 = 0 local ____cond3 = ____switch3 == 1 do - out[#out + 1] = \\"default\\" + out[#out + 1] = "default" end until true return out @@ -24,7 +24,7 @@ function ____exports.__main(self) local ____switch3 = 1 local ____cond3 = ____switch3 == 1 do - out[#out + 1] = \\"default\\" + out[#out + 1] = "default" end until true return out @@ -36,12 +36,12 @@ exports[`switch hoisting hoisting from default clause is not duplicated when fal "local ____exports = {} function ____exports.__main(self) local x = 1 - local result = \\"\\" + local result = "" repeat local ____switch3 = x local hoisted function hoisted(self) - return \\"hoisted\\" + return "hoisted" end local ____cond3 = ____switch3 == 1 if ____cond3 then @@ -50,19 +50,19 @@ function ____exports.__main(self) end ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then - result = \\"2\\" + result = "2" end if ____cond3 then - result = \\"default\\" + result = "default" end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then - result = \\"3\\" + result = "3" break end do - result = \\"default\\" - result = \\"3\\" + result = "default" + result = "3" end until true return result @@ -74,12 +74,12 @@ exports[`switch hoisting hoisting from fallthrough clause after default is not d "local ____exports = {} function ____exports.__main(self) local x = 1 - local result = \\"\\" + local result = "" repeat local ____switch3 = x local hoisted function hoisted(self) - return \\"hoisted\\" + return "hoisted" end local ____cond3 = ____switch3 == 1 if ____cond3 then @@ -88,19 +88,19 @@ function ____exports.__main(self) end ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then - result = \\"2\\" + result = "2" end if ____cond3 then - result = \\"default\\" + result = "default" end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then - result = \\"3\\" + result = "3" break end do - result = \\"default\\" - result = \\"3\\" + result = "default" + result = "3" end until true return result @@ -117,13 +117,13 @@ function ____exports.__main(self) local ____switch3 = 0 local ____cond3 = ____switch3 == 0 or ____switch3 == 1 or ____switch3 == 2 if ____cond3 then - out[#out + 1] = \\"0,1,2\\" + out[#out + 1] = "0,1,2" break end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then do - out[#out + 1] = \\"3\\" + out[#out + 1] = "3" break end end @@ -133,9 +133,9 @@ function ____exports.__main(self) end do x = x + 1 - out[#out + 1] = \\"default = \\" .. tostring(x) + out[#out + 1] = "default = " .. tostring(x) do - out[#out + 1] = \\"3\\" + out[#out + 1] = "3" break end end diff --git a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap index ad79b2eaa..11cab115c 100644 --- a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`IncorrectUsage: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local __TS__New = ____lualib.__TS__New local ____exports = {} @@ -9,7 +9,7 @@ function ____exports.__main(self) --- -- @customConstructor local Point2D = __TS__Class() - Point2D.name = \\"Point2D\\" + Point2D.name = "Point2D" function Point2D.prototype.____constructor(self) end __TS__New(Point2D) diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 398f0513b..53291f50f 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -506,3 +506,13 @@ test.each([ return [obj, objGot]; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1412 +test("invalid assignment to call expression (#1412)", () => { + util.testFunction` + function foo(): number { + return 3; + } + foo() += 4; + `.expectNoTranspileException(); +}); diff --git a/test/unit/builtins/__snapshots__/console.spec.ts.snap b/test/unit/builtins/__snapshots__/console.spec.ts.snap index 2af4f0446..2c9d8578c 100644 --- a/test/unit/builtins/__snapshots__/console.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/console.spec.ts.snap @@ -13,7 +13,7 @@ exports[`console.assert ("console.assert(false, \\"message %%s\\", \\"info\\")") function ____exports.__main(self) assert( false, - string.format(\\"message %%s\\", \\"info\\") + string.format("message %%s", "info") ) end return ____exports" @@ -24,7 +24,7 @@ exports[`console.assert ("console.assert(false, \\"message %s\\", \\"info\\")") function ____exports.__main(self) assert( false, - string.format(\\"message %s\\", \\"info\\") + string.format("message %s", "info") ) end return ____exports" @@ -33,7 +33,7 @@ return ____exports" exports[`console.assert ("console.assert(false, \\"message\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - assert(false, \\"message\\") + assert(false, "message") end return ____exports" `; @@ -41,7 +41,7 @@ return ____exports" exports[`console.assert ("console.assert(false, \\"message\\", \\"more\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - assert(false, \\"message\\", \\"more\\") + assert(false, "message", "more") end return ____exports" `; @@ -57,7 +57,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -65,7 +65,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -73,7 +73,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -81,7 +81,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -97,7 +97,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -105,7 +105,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -113,7 +113,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -121,7 +121,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -137,7 +137,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -145,7 +145,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -153,7 +153,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -161,7 +161,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -177,7 +177,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(string.format(\\"Hello %%s\\", \\"there\\"))) + print(debug.traceback(string.format("Hello %%s", "there"))) end return ____exports" `; @@ -185,7 +185,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(string.format(\\"Hello %s\\", \\"there\\"))) + print(debug.traceback(string.format("Hello %s", "there"))) end return ____exports" `; @@ -193,7 +193,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(\\"Hello\\", \\"there\\")) + print(debug.traceback("Hello", "there")) end return ____exports" `; @@ -201,7 +201,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"message\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(\\"message\\")) + print(debug.traceback("message")) end return ____exports" `; @@ -217,7 +217,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -225,7 +225,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -233,7 +233,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -241,7 +241,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 6c73c1588..dfb6807ec 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -1,4 +1,7 @@ -import { undefinedInArrayLiteral } from "../../../src/transformation/utils/diagnostics"; +import { + undefinedInArrayLiteral, + unsupportedArrayWithLengthConstructor, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("omitted expression", () => { @@ -176,6 +179,23 @@ describe("array.length", () => { `.expectToEqual(new util.ExecutionError(`invalid array length: ${luaSpecialValueString}`)); }); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1395 + test("in compound assignment (#1395)", () => { + util.testFunction` + const arr = [1,2,3,4]; + const returnVal = arr.length -= 2; + return { arr, returnVal }; + `.expectToMatchJsResult(); + }); + + test("as standalone compound assignment (#1395)", () => { + util.testFunction` + const arr = [1,2,3,4]; + arr.length -= 2; + return arr; + `.expectToMatchJsResult(); + }); + test("in array destructuring", () => { util.testFunction` const array = [0, 1, 2]; @@ -255,6 +275,36 @@ test("tuple.forEach", () => { `.expectToMatchJsResult(); }); +describe("at", () => { + test("valid index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(2); + `.expectToMatchJsResult(); + }); + + test("invalid index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(10); + `.expectToMatchJsResult(); + }); + + test("valid negative index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(-2); + `.expectToMatchJsResult(); + }); + + test("invalid negative index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(-10); + `.expectToMatchJsResult(); + }); +}); + test("array.forEach (%p)", () => { util.testFunction` const array = [0, 1, 2, 3]; @@ -706,6 +756,14 @@ test.each([ util.testExpression`Array.from(${valueString})`.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1576 +test("array.from with non-array iterable (#1576)", () => { + util.testFunction` + const map = new Map().set(1, 2); + return Array.from(map, ([v,k]) => ({k,v})); + `.expectToMatchJsResult(); +}); + // Array.of test.each(["1, 2, 3", "", "...[1, 2, 3], 4, 5, 6"])("Array.of(%p)", valueString => { util.testExpression`Array.of(${valueString})`.expectToMatchJsResult(); @@ -741,6 +799,33 @@ test.each([ util.testExpression(literal).expectToHaveNoDiagnostics(); }); +describe("array.fill", () => { + test.each(["[]", "[1]", "[1,2,3,4]"])("Fills full length of array without other parameters (%p)", arr => { + util.testExpression`${arr}.fill(5)`.expectToMatchJsResult(); + }); + + test.each(["[1,2,3]", "[1,2,3,4,5,6]"])("Fills starting from start parameter (%p)", arr => { + util.testExpression`${arr}.fill(5, 3)`.expectToMatchJsResult(); + }); + + test("handles negative start parameter", () => { + util.testExpression`[1,2,3,4,5,6,7].fill(8, -3)`.expectToMatchJsResult(); + }); + + test("handles negative end parameter", () => { + util.testExpression`[1,2,3,4,5,6,7].fill(8, -5, -2)`.expectToMatchJsResult(); + }); + + test("Fills starting from start parameter, up to ending parameter", () => { + util.testExpression`[1,2,3,4,5,6,7,8].fill(5, 2, 6)`.expectToMatchJsResult(); + }); + + // NOTE: This is different from the default ECMAScript specification for the behavior, but for Lua this is much more useful + test("Extends size of the array if ending size is larger than array", () => { + util.testExpression`[1,2,3].fill(5, 0, 6)`.expectToEqual([5, 5, 5, 5, 5, 5]); + }); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", value => { util.testFunction` @@ -752,3 +837,93 @@ test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", v .setOptions({ strictNullChecks: true }) .expectToMatchJsResult(); }); + +describe("copying array methods", () => { + test("toReversed", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const reversed = original.toReversed(); + + return {original, reversed}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + reversed: [5, 4, 3, 2, 1], + }); + }); + + test("toSorted", () => { + util.testFunction` + const original = [5,2,1,4,3]; + const sorted = original.toSorted(); + + return {original, sorted}; + `.expectToEqual({ + original: [5, 2, 1, 4, 3], + sorted: [1, 2, 3, 4, 5], + }); + }); + + test("toSpliced", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const spliced = original.toSpliced(2, 2, 10, 11); + + return {original, spliced}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + spliced: [1, 2, 10, 11, 5], + }); + }); + + test("with", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const updated = original.with(2, 10); + + return {original, updated}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + updated: [1, 2, 10, 4, 5], + }); + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1605 +test("array indexing in optional chain (#1605)", () => { + util.testModule` + interface Foo extends Array {} + const b: {arr?: Foo} = {arr:[1,2]}; + export const t = b.arr?.[1]; + + const c: Foo | undefined = b.arr; + export const u = c?.[1]; + ` + .setOptions({ strict: true }) // crucial to reproducing for some reason + .expectToMatchJsResult(); +}); + +test("new Array()", () => { + util.testFunction` + const arr = new Array(); + arr.push(1,2,3); + return arr; + `.expectToMatchJsResult(); +}); + +test("new Array()", () => { + util.testFunction` + const arr = new Array(); + arr.push(1,2,3); + return arr; + `.expectToMatchJsResult(); +}); + +test("new Array(length)", () => { + util.testFunction` + const arr = new Array(10); + `.expectToHaveDiagnostics([unsupportedArrayWithLengthConstructor.code]); +}); + +test("new Array(...items)", () => { + util.testExpression`new Array(1,2,3,4,5) `.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 8b7e0b5cf..45adb4518 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -24,6 +24,31 @@ function defer() { return { promise, resolve, reject }; }`; +test("high amount of chained awaits doesn't cause stack overflow", () => { + util.testFunction` + let result = "not executed"; + + async function delay() { + return; + } + + async function loop() { + try { + for (let i = 0; i < 500000; ++i) { + await delay(); + } + result = "success"; + } catch (e) { + result = e; + } + } + + loop(); + + return result; + `.expectToEqual("success"); +}); + test("can await already resolved promise", () => { util.testFunction` const result = []; @@ -541,6 +566,8 @@ describe("try/catch in async function", () => { // Cannot execute LuaJIT with test runner { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: 4 })), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } @@ -565,6 +592,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } @@ -593,6 +622,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index ac76de5a1..563870f6d 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -16,21 +16,68 @@ describe("luaLibImport", () => { .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); -}); -test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( - "should not include lualib without code (%p)", - luaLibImport => { - util.testModule``.setOptions({ luaLibImport }).tap(builder => expect(builder.getMainLuaCodeChunk()).toBe("")); + function testLualibOnlyHasArrayIndexOf(builder: util.TestBuilder) { + const lualibBundle = builder.getLuaResult().transpiledFiles.find(f => f.outPath.endsWith("lualib_bundle.lua"))!; + expect(lualibBundle).toBeDefined(); + expect(lualibBundle.lua).toEqual(expect.stringMatching("^local function __TS__ArrayIndexOf")); + expect(lualibBundle.lua).not.toContain("__TS__ArrayConcat"); + expect(lualibBundle.lua).not.toContain("Error"); } -); + + test("require-minimal", () => { + util.testExpression`[0].indexOf(1)` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.RequireMinimal }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) + .tap(testLualibOnlyHasArrayIndexOf) + .expectToMatchJsResult(); + }); + + test("require-minimal with lualib in another file", () => { + util.testModule` + import "./other"; + ` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.RequireMinimal }) + .addExtraFile( + "other.lua", + ` +local ____lualib = require("lualib_bundle") +local __TS__ArrayIndexOf = ____lualib.__TS__ArrayIndexOf +__TS__ArrayIndexOf({}, 1) + ` + ) + // note: indent matters in above code, because searching for lualib checks for start & end of line + .tap(testLualibOnlyHasArrayIndexOf) + .expectNoExecutionError(); + }); +}); + +test.each([ + tstl.LuaLibImportKind.Inline, + tstl.LuaLibImportKind.None, + tstl.LuaLibImportKind.Require, + tstl.LuaLibImportKind.RequireMinimal, +])("should not include lualib without code (%p)", luaLibImport => { + util.testModule``.setOptions({ luaLibImport }).tap(builder => expect(builder.getMainLuaCodeChunk()).toBe("")); +}); test("lualib should not include tstl header", () => { - util.testExpression`[0].push(1)`.tap(builder => + util.testExpression`[0].indexOf(1)`.tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("Generated with") ); }); +test("using lualib does not crash when coroutine is not defined", () => { + util.testModule` + declare const _G: any; + declare function require(this: void, name: string): any + + _G.coroutine = undefined; + require("lualib_bundle"); + export const result = 1 + `.expectToEqual({ result: 1 }); +}); + describe("Unknown builtin property", () => { test("access", () => { util.testExpression`Math.unknownProperty` diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index 7eec8844d..f2e1cbfbe 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -209,3 +209,47 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM `.expectToMatchJsResult(); }); }); + +describe("Map.groupBy", () => { + test("empty", () => { + util.testFunction` + const array = []; + + const map = Map.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual([]); + }); + + test("groupBy", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + const map = Map.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual({ + even: [0, 2, 4], + odd: [1, 3, 5], + }); + }); + + test("groupBy index", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + const map = Map.groupBy(array, (num, index) => { + return index < 3 ? "low": "high"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual({ + low: [0, 1, 2], + high: [3, 4, 5], + }); + }); +}); diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 9e191e1e2..b8f6b2cc3 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -51,6 +51,12 @@ test.each([ // sqrt "Math.sqrt(2)", "Math.sqrt(-2)", + // trunc + "Math.trunc(42.42)", + "Math.trunc(-42.42)", + "Math.trunc(0)", + "Math.trunc(Infinity)", + "Math.trunc(-Infinity)", ])("%s", code => { util.testExpression(code).expectToMatchJsResult(); }); @@ -65,7 +71,14 @@ test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s" }); // LuaLib MathSign -test.each(["Math.sign(-42)", "Math.sign(42)", "Math.sign(-4.2)", "Math.sign(4.2)", "Math.sign(0)"])("%s", code => { +test.each([ + "Math.sign(-42)", + "Math.sign(42)", + "Math.sign(-4.2)", + "Math.sign(4.2)", + "Math.sign(0)", + "Math.sign(-Infinity)", +])("%s", code => { util.testExpression(code).expectToMatchJsResult(); }); @@ -78,10 +91,12 @@ const expectLualibMathAtan2: util.TapCallback = builder => util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibMathAtan2), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectMathAtan2), [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), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectMathAtan2), }); util.testEachVersion( diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index ab7e332a9..0a8e0bf38 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -1,8 +1,6 @@ import * as util from "../../util"; test.each([ - "NaN === NaN", - "NaN !== NaN", "NaN + NaN", "NaN - NaN", "NaN * NaN", @@ -48,6 +46,10 @@ describe("Number", () => { test.each(cases)("isFinite(%p)", value => { util.testExpressionTemplate`Number.isFinite(${value} as any)`.expectToMatchJsResult(); }); + + test.each(cases)("isInteger(%p)", value => { + util.testExpressionTemplate`Number.isInteger(${value} as any)`.expectToMatchJsResult(); + }); }); const toStringRadixes = [undefined, 10, 2, 8, 9, 16, 17, 36, 36.9]; @@ -71,6 +73,26 @@ test.each([ util.testExpressionTemplate`(${value}).toString(2)`.expectToEqual(luaNativeSpecialNumString); }); +const toFixedFractions = [undefined, 0, 1, 2, Math.PI, 5, 99]; +// 1.5, 1.25 and 1.125 fails as rounding differ +const toFixedValues = [-1, 0, 1, Math.PI, -1.1234, -9.99e19, 1e22]; +const toFixedPairs = toFixedValues.flatMap(value => toFixedFractions.map(frac => [value, frac] as const)); +test.each(toFixedPairs)("(%p).toFixed(%p)", (value, frac) => { + util.testExpressionTemplate`(${value}).toFixed(${frac})`.expectToMatchJsResult(); +}); + +test.each([ + [NaN, "(0/0)"], + [Infinity, "(1/0)"], + [-Infinity, "(-(1/0))"], +])("%p.toFixed(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 + util.testExpressionTemplate`(${value}).toFixed(2)`.expectToEqual(luaNativeSpecialNumString); +}); + test.each(cases)("isNaN(%p)", value => { util.testExpressionTemplate`isNaN(${value} as any)`.expectToMatchJsResult(); }); @@ -90,29 +112,32 @@ 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"]; +describe.each(["parseInt", "parseFloat", "Number.parseInt", "Number.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.each(numberStrings)("parses (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); - test("empty string", () => { - util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); - }); + test("empty string", () => { + util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); + }); - test("invalid string", () => { - util.testExpression`${parseFunction}("bla")`.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(["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([" 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(); @@ -144,6 +169,36 @@ test.each([ util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); }); +test.each(["Infinity", "-Infinity", " -Infinity"])("Number.parseFloat handles Infinity", numberString => { + util.testExpression`Number.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 }, +])("Number.parseInt with base (%p)", ({ numberString, base }) => { + util.testExpression`Number.parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + +test.each(["0x4A", "-0x42", "0X42", " 0x391", " -0x8F"])("Number.parseInt detects hexadecimal", numberString => { + util.testExpression`Number.parseInt("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([1, 37, -100])("Number.parseInt with invalid base (%p)", base => { + util.testExpression`Number.parseInt("11111", ${base})`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36px", base: 8 }, + { numberString: "10001010110231", base: 2 }, + { numberString: "3Fcolor", base: 16 }, +])("Number.parseInt with base and trailing text (%p)", ({ numberString, base }) => { + util.testExpression`Number.parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(["42", "undefined"])("prototype call on nullable number (%p)", value => { util.testFunction` @@ -155,3 +210,17 @@ test.each(["42", "undefined"])("prototype call on nullable number (%p)", value = .setOptions({ strictNullChecks: true }) .expectToMatchJsResult(); }); + +test.each([ + "Number.NEGATIVE_INFINITY <= Number.MIN_VALUE", + "Number.MIN_VALUE <= Number.MIN_SAFE_INTEGER", + + "Number.MAX_SAFE_INTEGER <= Number.MAX_VALUE", + "Number.MAX_VALUE <= Number.POSITIVE_INFINITY", + "Number.MIN_SAFE_INTEGER < 0", + + "0 < Number.EPSILON", + "Number.EPSILON < Number.MAX_SAFE_INTEGER", +])("Numer constants have correct relative sizes (%p)", comparison => { + util.testExpression(comparison).expectToEqual(true); +}); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 9cb5f8de3..1edc8a9d6 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -264,3 +264,41 @@ describe("delete from object", () => { .expectToMatchJsResult(); }); }); + +describe("Object.groupBy", () => { + test("empty", () => { + util.testFunction` + const array = []; + + return Object.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + `.expectToEqual([]); + }); + + test("groupBy", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + return Object.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + `.expectToEqual({ + even: [0, 2, 4], + odd: [1, 3, 5], + }); + }); + + test("groupBy index", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + return Object.groupBy(array, (num, index) => { + return index < 3 ? "low": "high"; + }); + `.expectToEqual({ + low: [0, 1, 2], + high: [3, 4, 5], + }); + }); +}); diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index fa6f6cf0f..cb18db994 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -839,6 +839,26 @@ test("resolving promise with pending promise will keep pending until promise2 re .expectToEqual(["promise 2", "rejection", "promise 1", "rejection"]); }); +describe("Promise.resolve", () => { + test("returns the given resolved promise", () => { + util.testFunction` + let result = 0; + Promise.resolve(Promise.resolve(4)) + .then((value) => result = value); + return result; + `.expectToEqual(4); + }); + + test("returns the given rejected promise", () => { + util.testFunction` + let result = 0; + Promise.resolve(Promise.reject(4)) + .catch((value) => result = value); + return result; + `.expectToEqual(4); + }); +}); + describe("Promise.all", () => { test("resolves once all arguments are resolved", () => { util.testFunction` diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index 93e23e98e..a03f27ab2 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -201,3 +201,221 @@ test("instanceof Set without creating set", () => { return myset instanceof Set; `.expectToMatchJsResult(); }); + +describe("new ECMAScript Set methods", () => { + test("union", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); + + test("union with empty sets", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 4, 5, 6]); + + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([4, 5, 6, 7, 8, 9]); + }); + + test("intersection", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([4, 5, 6]); + }); + + test("intersection with empty sets", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([]); + + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([]); + }); + + test("difference", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.difference(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3]); + }); + + test("symmetricDifference", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.symmetricDifference(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 7, 8, 9]); + }); + + test("isSubsetOf", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: false, + }); + }); + + test("isSubsetOf equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: true, + }); + }); + + test("isSubsetOf empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: false, + }); + }); + + test("isSupersetOf", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: false, + set2SupersetOfSet1: true, + }); + }); + + test("isSupersetOf equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: true, + set2SupersetOfSet1: true, + }); + }); + + test("isSupersetOf empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: false, + set2SupersetOfSet1: true, + }); + }); + + test("isDisjointFrom", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([7,8,9]); + const set3 = new Set([1,2,3,4]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + set1DisjointFromSet3: set1.isDisjointFrom(set3), + set3DisjointFromSet1: set3.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: true, + set2DisjointFromSet1: true, + set1DisjointFromSet3: false, + set3DisjointFromSet1: false, + }); + }); + + test("isDisjointFrom equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: false, + set2DisjointFromSet1: false, + }); + }); + + test("isDisjointFrom empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: true, + set2DisjointFromSet1: true, + }); + }); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index db745cb98..977944e55 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -372,6 +372,21 @@ test("string intersected method", () => { `.expectToMatchJsResult(); }); +test("tostring number with String constructor", () => { + util.testFunction` + const n = 123 + return "abc:" + String(n); + `.expectToEqual("abc:123"); +}); + +test("tostring table with String constructor", () => { + const result = util.testFunction` + const t = {} + return "abc:" + String(t); + `.getLuaExecutionResult(); + expect(result).toContain("abc:table: 0x"); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(['"foo"', "undefined"])("prototype call on nullable string (%p)", value => { util.testFunction` @@ -398,3 +413,13 @@ test.each(["string | undefined", "string | null", "null | string", "null | undef .expectToMatchJsResult(); } ); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 +test("string.indexOf without arguments (#1406)", () => { + util.testExpression`"".indexOf()`.expectNoTranspileException(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 +test("string.repeat without arguments (#1406)", () => { + util.testExpression`"".repeat()`.expectNoTranspileException(); +}); diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap index 7822867f5..9154d1911 100644 --- a/test/unit/classes/__snapshots__/classes.spec.ts.snap +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -1,10 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`missing declaration name: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class ____class_0 = __TS__Class() -____class_0.name = \\"\\" +____class_0.name = "" function ____class_0.prototype.____constructor(self) end" `; diff --git a/test/unit/classes/__snapshots__/decorators.spec.ts.snap b/test/unit/classes/__snapshots__/decorators.spec.ts.snap index cef76f35e..681e4fa3d 100644 --- a/test/unit/classes/__snapshots__/decorators.spec.ts.snap +++ b/test/unit/classes/__snapshots__/decorators.spec.ts.snap @@ -1,20 +1,62 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Throws error if decorator function has void context: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local __TS__Decorate = ____lualib.__TS__Decorate local ____exports = {} function ____exports.__main(self) - local function decorator(constructor) + local function decorator(constructor, context) end local TestClass = __TS__Class() - TestClass.name = \\"TestClass\\" + TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end - TestClass = __TS__Decorate({decorator}, TestClass) + TestClass = __TS__Decorate(TestClass, TestClass, {decorator}, {kind = "class", name = "TestClass"}) end return ____exports" `; exports[`Throws error if decorator function has void context: diagnostics 1`] = `"main.ts(4,9): error TSTL: Decorator function cannot have 'this: void'."`; + +exports[`class field decorator warns the return value is ignored: code 1`] = ` +"local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__Decorate = ____lualib.__TS__Decorate +local ____exports = {} +function ____exports.__main(self) + local fieldDecoratorContext + local function fieldDecorator(self, _, context) + fieldDecoratorContext = context + return function(____, initialValue) return initialValue * 12 end + end + local TestClass = __TS__Class() + TestClass.name = "TestClass" + function TestClass.prototype.____constructor(self) + self.value = 22 + end + __TS__Decorate(TestClass, nil, {fieldDecorator}, {kind = "field", name = "value", private = false, static = false}) +end +return ____exports" +`; + +exports[`class field decorator warns the return value is ignored: diagnostics 1`] = `"main.ts(11,13): warning TSTL: You are using a class field decorator, note that tstl ignores returned value initializers!"`; + +exports[`legacy experimentalDecorators Throws error if decorator function has void context: code 1`] = ` +"local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__DecorateLegacy = ____lualib.__TS__DecorateLegacy +local ____exports = {} +function ____exports.__main(self) + local function decorator(constructor) + end + local TestClass = __TS__Class() + TestClass.name = "TestClass" + function TestClass.prototype.____constructor(self) + end + TestClass = __TS__DecorateLegacy({decorator}, TestClass) +end +return ____exports" +`; + +exports[`legacy experimentalDecorators Throws error if decorator function has void context: diagnostics 1`] = `"main.ts(4,13): error TSTL: Decorator function cannot have 'this: void'."`; diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 8a39fb21b..db17fe67d 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -11,6 +11,19 @@ test("get accessor", () => { `.expectToMatchJsResult(); }); +test("multiple get accessors", () => { + util.testFunction` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + _bar = "bar"; + get bar() { return this._bar; } + } + const f = new Foo(); + return f.foo + f.bar; + `.expectToMatchJsResult(); +}); + test("get accessor in base class", () => { util.testFunction` class Foo { @@ -142,6 +155,26 @@ test("get/set accessors", () => { `.expectToMatchJsResult(); }); +test("multiple get/set accessors", () => { + util.testFunction` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + set foo(val: string) { this._foo = val; } + + _bar = "bar"; + get bar() { return this._bar; } + set bar(val: string) { this._bar = val; } + } + const f = new Foo(); + const fooOriginal = f.foo; + f.foo = "fizz"; + const barOriginal = f.bar; + f.bar = "buzz"; + return [fooOriginal, f.foo, barOriginal, f.bar]; + `.expectToMatchJsResult(); +}); + test("get/set accessors in base class", () => { util.testFunction` class Foo { @@ -327,3 +360,44 @@ test("static get/set accessors in base class", () => { return fooOriginal + Bar.foo; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1437 +test("super class get accessor (#1437)", () => { + util.testFunction` + class A { + get foo() { + return "A"; + } + } + + class B extends A { + override get foo() { + return super.foo + "B"; + } + } + + return new B().foo; + `.expectToMatchJsResult(); +}); + +test("super class set accessor", () => { + util.testFunction` + let result = "unset"; + + class A { + set result(value: string) { + result = "foo" + value; + } + } + + class B extends A { + override set result(value: string) { + super.result = "bar" + value; + } + } + + new B().result = "baz"; + + return result; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index f9ab4fe61..40eccc05a 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -181,6 +181,27 @@ test("SubclassConstructor", () => { `.expectToMatchJsResult(); }); +test("SubclassConstructorPropertyInitiailizationSuperOrder", () => { + util.testFunction` + class a { + field: number; + constructor(field: number) { + this.field = field; + } + } + class b extends a { + fieldDouble = this.field * 2; + constructor(field: number) { + const newField = field + 1; + super(newField); + } + } + + const result = new b(10); + return [result.field, result.fieldDouble]; + `.expectToMatchJsResult(); +}); + test("Subclass constructor across merged namespace", () => { util.testModule` namespace NS { @@ -749,9 +770,9 @@ test("default exported anonymous class has 'default' name property", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/584 -test("constructor class name available with constructor", () => { +test("constructor class name available with decorator", () => { util.testModule` - const decorator = any>(constructor: T) => class extends constructor {}; + const decorator = any>(constructor: T, context: ClassDecoratorContext) => class extends constructor {}; @decorator class MyClass {} @@ -799,3 +820,92 @@ test.each(['(this["bar"])', '((((this["bar"]))))'])("methods in parentheses pass export const result = inst.foo(); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1447 +test("static initialization block (#1447)", () => { + util.testModule` + class A { + private static staticProperty1 = 3; + public static staticProperty2; + static { + this.staticProperty2 = this.staticProperty1 + 5; + } + public static staticProperty3; + static { + this.staticProperty3 = this.staticProperty1 + this.staticProperty2; + } + } + export const result1 = A.staticProperty2; + export const result2 = A.staticProperty3; + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1457 +test("static member definition order (#1457)", () => { + util.testFunction` + class A { + static a = A.foo() + + static foo(): number { + return 5 + } + } + + return A.a; + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1504 +test("Calling static inherited functions works (#1504)", () => { + util.testFunction` + class A { + static Get() { + return "A"; + } + } + + class B extends A { + static Get() { + return super.Get() + "B"; + } + } + + return B.Get(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1537 +test("get inherted __index member from super (DotA 2 inheritance) (#1537)", () => { + util.testFunction` + // Inherit 'connected' class + class C extends Connected { + bar() { + return super.foo(); + } + } + + return new C().bar();` + .setTsHeader( + `interface I { + foo(): string; + } + + // Hacky interface/class merging + interface Connected extends I {} + class Connected {} + + declare function setmetatable(this: void, t: any, mt: any); + + const A = { + foo() { + return "foo"; + } + }; + + // Connect class 'Connected' to 'traditional' class A + setmetatable(Connected.prototype, { + __index: A + });` + ) + .expectToEqual("foo"); +}); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index 5b7b6e2ff..1923f8b2b 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -1,27 +1,37 @@ -import { decoratorInvalidContext } from "../../../src/transformation/utils/diagnostics"; +import { + decoratorInvalidContext, + incompleteFieldDecoratorWarning, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("Class decorator with no parameters", () => { util.testFunction` - function setBool {}>(constructor: T) { + let classDecoratorContext; + + function classDecorator {}>(constructor: T, context: ClassDecoratorContext) { + classDecoratorContext = context; + return class extends constructor { decoratorBool = true; } } - @setBool + @classDecorator class TestClass { public decoratorBool = false; } - return new TestClass(); + return { decoratedClass: new TestClass(), context: { + kind: classDecoratorContext.kind, + name: classDecoratorContext.name, + } }; `.expectToMatchJsResult(); }); test("Class decorator with parameters", () => { util.testFunction` function setNum(numArg: number) { - return {}>(constructor: T) => { + return {}>(constructor: T, context: ClassDecoratorContext) => { return class extends constructor { decoratorNum = numArg; }; @@ -39,13 +49,13 @@ test("Class decorator with parameters", () => { test("Multiple class decorators", () => { util.testFunction` - function setTen {}>(constructor: T) { + function setTen {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorTen = 10; } } - function setNum {}>(constructor: T) { + function setNum {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorNum = 410; } @@ -64,7 +74,7 @@ test("Multiple class decorators", () => { test("Class decorator with inheritance", () => { util.testFunction` - function setTen {}>(constructor: T) { + function setTen {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorTen = 10; } @@ -89,7 +99,7 @@ test("Class decorators are applied in order and executed in reverse order", () = function pushOrder(index: number) { order.push("eval " + index); - return (constructor: new (...args: any[]) => {}) => { + return (constructor: new (...args: any[]) => {}, context: ClassDecoratorContext) => { order.push("execute " + index); }; } @@ -105,7 +115,7 @@ test("Class decorators are applied in order and executed in reverse order", () = test("Throws error if decorator function has void context", () => { util.testFunction` - function decorator(this: void, constructor: new (...args: any[]) => {}) {} + function decorator(this: void, constructor: new (...args: any[]) => {}, context: ClassDecoratorContext) {} @decorator class TestClass {} @@ -114,7 +124,7 @@ test("Throws error if decorator function has void context", () => { test("Exported class decorator", () => { util.testModule` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; @@ -127,64 +137,6 @@ test("Exported class decorator", () => { .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(); - } - ); -}); - // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 test("exported class with decorator", () => { util.testModule` @@ -194,7 +146,7 @@ test("exported class with decorator", () => { ` .addExtraFile( "other.ts", - `function myDecorator(target: {new(): any}) { + `function myDecorator(target: {new(): any}, context: ClassDecoratorContext) { return class extends target { foo() { return "overridden"; @@ -220,7 +172,7 @@ test("default exported class with decorator", () => { ` .addExtraFile( "other.ts", - `function myDecorator(target: {new(): any}) { + `function myDecorator(target: {new(): any}, context: ClassDecoratorContext) { return class extends target { foo() { return "overridden"; @@ -237,3 +189,438 @@ test("default exported class with decorator", () => { ) .expectToEqual({ result: "overridden" }); }); + +test("class method decorator", () => { + util.testFunction` + let methodDecoratorContext; + + function methodDecorator(method: (v: number) => number, context: ClassMethodDecoratorContext) { + methodDecoratorContext = context; + + return (v: number) => { + return method(v) + 10; + }; + } + + class TestClass { + @methodDecorator + public myMethod(x: number) { + return x * 23; + } + } + + return { result: new TestClass().myMethod(4), context: { + kind: methodDecoratorContext.kind, + name: methodDecoratorContext.name, + private: methodDecoratorContext.private, + static: methodDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("this in decorator points to class being decorated", () => { + util.testFunction` + function methodDecorator(method: (v: number) => number, context: ClassMethodDecoratorContext) { + return function() { + const thisCallTime = this.myInstanceVariable; + return thisCallTime; + }; + } + + class TestClass { + constructor(protected myInstanceVariable: number) { } + + @methodDecorator + public myMethod() { + return 0; + } + } + + return new TestClass(5).myMethod(); + `.expectToMatchJsResult(); +}); + +test("class getter decorator", () => { + util.testFunction` + let getterDecoratorContext; + + function getterDecorator(getter: () => number, context: ClassGetterDecoratorContext) { + getterDecoratorContext = context; + + return () => { + return getter() + 10; + }; + } + + class TestClass { + @getterDecorator + get getterValue() { return 10; } + } + + return { result: new TestClass().getterValue, context: { + kind: getterDecoratorContext.kind, + name: getterDecoratorContext.name, + private: getterDecoratorContext.private, + static: getterDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("class setter decorator", () => { + util.testFunction` + let setterDecoratorContext; + + function setterDecorator(setter: (v: number) => void, context: ClassSetterDecoratorContext) { + setterDecoratorContext = context; + + return function(v: number) { + setter.call(this, v + 15); + }; + } + + class TestClass { + public value: number; + + @setterDecorator + set valueSetter(v: number) { this.value = v; } + } + + const instance = new TestClass(); + instance.valueSetter = 23; + return { result: instance.value, context: { + kind: setterDecoratorContext.kind, + name: setterDecoratorContext.name, + private: setterDecoratorContext.private, + static: setterDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("class field decorator", () => { + util.testFunction` + let fieldDecoratorContext; + + function fieldDecorator(_: undefined, context: ClassFieldDecoratorContext) { + fieldDecoratorContext = context; + } + + class TestClass { + @fieldDecorator + public value: number = 22; + } + + return { result: new TestClass(), context: { + kind: fieldDecoratorContext.kind, + name: fieldDecoratorContext.name, + private: fieldDecoratorContext.private, + static: fieldDecoratorContext.static, + } }; + `.expectToEqual({ + result: { + value: 22, // Different from JS because we ignore the value initializer + }, + context: { + kind: "field", + name: "value", + private: false, + static: false, + }, + }); +}); + +test("class field decorator warns the return value is ignored", () => { + util.testFunction` + let fieldDecoratorContext; + + function fieldDecorator(_: undefined, context: ClassFieldDecoratorContext) { + fieldDecoratorContext = context; + + return (initialValue: number) => initialValue * 12; + } + + class TestClass { + @fieldDecorator + public value: number = 22; + } + `.expectDiagnosticsToMatchSnapshot([incompleteFieldDecoratorWarning.code]); +}); + +describe("legacy experimentalDecorators", () => { + test("Class decorator with no parameters", () => { + util.testFunction` + function setBool {}>(constructor: T) { + return class extends constructor { + decoratorBool = true; + } + } + + @setBool + class TestClass { + public decoratorBool = false; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorator with parameters", () => { + util.testFunction` + function setNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + @setNum(420) + class TestClass { + public decoratorNum; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Multiple class decorators", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + function setNum {}>(constructor: T) { + return class extends constructor { + decoratorNum = 410; + } + } + + @setTen + @setNum + class TestClass { + public decoratorTen; + public decoratorNum; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorator with inheritance", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + class TestClass { + public decoratorTen = 0; + } + + @setTen + class SubTestClass extends TestClass { + public decoratorTen = 5; + } + + return new SubTestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorators are applied in order and executed in reverse order", () => { + util.testFunction` + const order = []; + + function pushOrder(index: number) { + order.push("eval " + index); + return (constructor: new (...args: any[]) => {}) => { + order.push("execute " + index); + }; + } + + @pushOrder(1) + @pushOrder(2) + @pushOrder(3) + class TestClass {} + + return order; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Throws error if decorator function has void context", () => { + util.testFunction` + function decorator(this: void, constructor: new (...args: any[]) => {}) {} + + @decorator + class TestClass {} + ` + .setOptions({ experimentalDecorators: true }) + .expectDiagnosticsToMatchSnapshot([decoratorInvalidContext.code]); + }); + + test("Exported class decorator", () => { + util.testModule` + function decorator any>(Class: T): T { + return class extends Class { + public bar = "foobar"; + }; + } + + @decorator + export class Foo {} + ` + .setReturnExport("Foo", "bar") + .setOptions({ experimentalDecorators: true }) + .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) {}"], + ["constructor(@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; + ` + .setOptions({ experimentalDecorators: true }) + .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; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test.each(["return { value: true }", "desc.value = true"])( + "Use decorator to override method value %s", + overrideStatement => { + util.testFunction` + const decorator = (target, key, desc): any => { ${overrideStatement} }; + class Foo { @decorator static method() {} } + return Foo.method; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + } + ); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 + test("exported class with decorator", () => { + util.testModule` + import { MyClass } from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export class MyClass { + foo() { + return "foo"; + } + }` + ) + .setOptions({ experimentalDecorators: true }) + .expectToEqual({ result: "overridden" }); + }); + + test("default exported class with decorator", () => { + util.testModule` + import MyClass from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export default class { + foo() { + return "foo"; + } + }` + ) + .setOptions({ experimentalDecorators: true }) + .expectToEqual({ result: "overridden" }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1453 + test("Class methods with legacy decorators can still be called ($1453)", () => { + util.testFunction` + function decorator( + target: Class, + propertyKey: keyof Class, + ): void {} + + class Foo { + @decorator + public method2() { return 4; } + } + + return new Foo().method2(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); +}); diff --git a/test/unit/classes/instanceof.spec.ts b/test/unit/classes/instanceof.spec.ts index 4e4000153..3869bfa1c 100644 --- a/test/unit/classes/instanceof.spec.ts +++ b/test/unit/classes/instanceof.spec.ts @@ -84,7 +84,7 @@ test("instanceof export", () => { test("instanceof Symbol.hasInstance", () => { util.testFunction` class myClass { - static [Symbol.hasInstance]() { + static [Symbol.hasInstance](instance: unknown) { return false; } } diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index ffbff9ab4..f862ca8a3 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -90,7 +90,10 @@ test.each([ { condition: 3, lhs: 4, rhs: 5 }, ])("Ternary Conditional (%p)", ({ condition, lhs, rhs }) => { util.testExpressionTemplate`${condition} ? ${lhs} : ${rhs}` - .ignoreDiagnostics([truthyOnlyConditionalValue.code]) + .ignoreDiagnostics([ + truthyOnlyConditionalValue.code, + 2872 /* TS2872: This kind of expression is always truthy. */, + ]) .expectToMatchJsResult(); }); @@ -154,6 +157,15 @@ test.each(["string", "number", "string | number"])( } ); +test.each(["string", "number", "string | number"])("Warning can be disabled when strict is true (%p)", type => { + util.testFunction` + if (condition) {} + ` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true, strictNullChecks: false }) + .expectToHaveNoDiagnostics(); +}); + test.each(["string", "number", "string | number"])( "Warning when using while statement that cannot evaluate to false undefined or null (%p)", type => { @@ -187,3 +199,10 @@ test.each(["string", "number", "string | number"])( .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); } ); + +test.each(["string", "number", "string | number"])("No warning when using element index in condition (%p)", type => { + util.testExpression`condition[0] ? 1 : 0` + .setTsHeader(`declare var condition: ${type}[];`) + .setOptions({ strict: true }) + .expectToHaveNoDiagnostics(); +}); diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index e44f8f0c3..80d3d482c 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -1,3 +1,4 @@ +import { cannotAssignToNodeOfKind, invalidMultiReturnAccess } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; const allBindings = "x, y, z, rest"; @@ -225,3 +226,14 @@ describe("array destructuring optimization", () => { .expectToMatchJsResult(); }); }); + +test("no exception from semantically invalid TS", () => { + util.testModule` + declare function testFunc(value: number): LuaMultiReturn<[number, number]>; + let [a, b] = testFunc(5) // Missing ; + [a, b] = testFunc(b) // Interpreted as testFunc(5)[a, b] + ` + .withLanguageExtensions() + .disableSemanticCheck() + .expectToHaveDiagnostics([invalidMultiReturnAccess.code, cannotAssignToNodeOfKind.code]); +}); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 705ee77f0..05399d492 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -1,4 +1,5 @@ import * as util from "../util"; +import * as tstl from "../../src"; test("throwString", () => { util.testFunction` @@ -324,3 +325,46 @@ test.each([...builtinErrors, "CustomError"])("get stack from %s", errorType => { expect(stack).toMatch("innerFunction"); expect(stack).toMatch("outerFunction"); }); + +test("still works without debug module", () => { + util.testFunction` + try + { + throw new Error("hello, world"); + } + catch (e) + { + return e; + } + ` + .setLuaHeader("debug = nil") + .expectToEqual({ + message: "hello, world", + name: "Error", + stack: undefined, + }); +}); + +util.testEachVersion( + "error stacktrace omits constructor and __TS_New", + () => util.testFunction` + const e = new Error(); + return e.stack; + `, + { + ...util.expectEachVersionExceptJit(builder => { + builder.expectToHaveNoDiagnostics(); + const luaResult = builder.getLuaExecutionResult(); + // eslint-disable-next-line jest/no-standalone-expect + expect(luaResult.split("\n")).toHaveLength(4); + }), + + // 5.0 debug.traceback doesn't support levels + [tstl.LuaTarget.Lua50](builder) { + builder.expectToHaveNoDiagnostics(); + const luaResult = builder.getLuaExecutionResult(); + // eslint-disable-next-line jest/no-standalone-expect + expect(luaResult).toContain("Level 4"); + }, + } +); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 71c014fda..46ca2f7bd 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -18,9 +18,13 @@ test.each([ util.testFunction(input).disableSemanticCheck().expectLuaToMatchSnapshot(); }); -test.each(["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"])("Binary expressions basic numeric (%p)", input => { - util.testExpression(input).expectToMatchJsResult(); -}); +for (const expression of ["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"]) { + util.testEachVersion( + `Binary expressions basic numeric (${expression})`, + () => util.testExpression(expression), + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); +} test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1", "1||1"])( "Binary expressions basic boolean (%p)", @@ -48,6 +52,14 @@ 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 unsupportedIn53And54 = ["a>>b", "a>>=b"]; const allBinaryOperators = [...supportedInAll, ...unsupportedIn53And54]; +test.each(allBinaryOperators)("Bitop [5.0] (%p)", input => { + // Bit operations not supported in 5.0, expect an exception + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua50, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception util.testExpression(input) @@ -153,6 +165,21 @@ test("Non-null expression", () => { `.expectToMatchJsResult(); }); +test("Typescript 4.7 instantiation expression", () => { + util.testFunction` + function foo(x: T): T { return x; } + const bar = foo; + return bar(3); + `.expectToMatchJsResult(); +}); + +test("Typescript 4.9 satisfies expression", () => { + util.testFunction` + const foo = { a: 1 } satisfies { a: number }; + return foo.a; + `.expectToMatchJsResult(); +}); + test.each([ '"foobar"', "17", diff --git a/test/unit/find-lua-requires.spec.ts b/test/unit/find-lua-requires.spec.ts new file mode 100644 index 000000000..bb879d642 --- /dev/null +++ b/test/unit/find-lua-requires.spec.ts @@ -0,0 +1,159 @@ +import { findLuaRequires, LuaRequire } from "../../src/transpilation/find-lua-requires"; + +test("empty string", () => { + expect(findLuaRequires("")).toEqual([]); +}); + +test("can find requires", () => { + const lua = ` + require("req1") + require('req2') + local r3 = require("req3") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2", "req3"]); +}); + +test("handles requires with spacing", () => { + const lua = 'require \t ( \t "req" )'; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req"]); +}); + +test("handles requires without parentheses", () => { + const lua = 'require "req"'; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req"]); +}); + +test("has correct offsets", () => { + const lua = ` + require("req1") + require('req2') + local r3 = require("req3") + `; + const requires = findLuaRequires(lua); + expect(requires).toHaveLength(3); + expect(lua.substring(requires[0].from, requires[0].to + 1)).toBe('require("req1")'); + expect(lua.substring(requires[1].from, requires[1].to + 1)).toBe("require('req2')"); + expect(lua.substring(requires[2].from, requires[2].to + 1)).toBe('require("req3")'); +}); + +test("has correct offsets for offsets without parentheses", () => { + const lua = ` + require"req1" + require 'req2' + local r3 = require"req3" + `; + const requires = findLuaRequires(lua); + expect(requires).toHaveLength(3); + expect(lua.substring(requires[0].from, requires[0].to + 1)).toBe('require"req1"'); + expect(lua.substring(requires[1].from, requires[1].to + 1)).toBe("require 'req2'"); + expect(lua.substring(requires[2].from, requires[2].to + 1)).toBe('require"req3"'); +}); + +test("ignores requires that should not be included", () => { + const lua = ` + require("req1") + local a = "require('This should not be included')" + require('req2') + local b = 'require("This should not be included")' + require("req3") + -- require("this should not be included") + require("req4") + --[[ require("this should not be included") ]] + require("req5") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2", "req3", "req4", "req5"]); +}); + +test("non-terminated require", () => { + expect(findLuaRequires("require('abc")).toEqual([]); +}); + +describe.each(['"', "'"])("strings with delimiter %p", delimiter => { + test("escaped delimiter", () => { + const lua = ` + require(${delimiter}req1${delimiter}); + local a = ${delimiter}require(excludeThis\\${delimiter})${delimiter} + require(${delimiter}req\\${delimiter}2${delimiter}); + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", `req${delimiter}2`]); + }); + + test("multiple escaped delimiters", () => { + const lua = ` + require(${delimiter}r\\${delimiter}e.- q%\\${delimiter}1${delimiter}) + `; + expect(requirePaths(findLuaRequires(lua))).toEqual([`r${delimiter}e.- q%${delimiter}1`]); + }); + + test("handles other escaped characters", () => { + expect(requirePaths(findLuaRequires(`require(${delimiter}req\\n\\\\${delimiter})`))).toEqual(["req\\n\\\\"]); + }); + + test("handles non-delimiter quote", () => { + const oppositeDelimiter = delimiter === "'" ? '"' : "'"; + const lua = ` + require(${delimiter}req1${delimiter}); + local a = ${delimiter}require(excludeThis${oppositeDelimiter})${delimiter}; + require(${delimiter}req2${oppositeDelimiter}${delimiter}); + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", `req2${oppositeDelimiter}`]); + }); + + test("non-terminated string", () => { + const lua = ` + require(${delimiter}myRequire${delimiter}); + local a = ${delimiter}require("excludeThis") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["myRequire"]); + }); +}); + +describe("single-line comments", () => { + test("comment at end of file", () => { + expect(findLuaRequires("--")).toEqual([]); + }); + + test("require before and after comment", () => { + const lua = ` + require("req1")-- comment\nrequire("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); + + test("require before and after empty comment", () => { + const lua = ` + require("req1")--\nrequire("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); +}); + +describe("multi-line comments", () => { + test("comment at end of file", () => { + expect(findLuaRequires("--[[]]")).toEqual([]); + }); + + test("unterminated comment", () => { + expect(findLuaRequires("--[[")).toEqual([]); + }); + + test("require before and after comment", () => { + const lua = ` + require("req1")--[[ + ml comment require("this should be excluded") + ]]require("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); + + test("require before and after empty comment", () => { + const lua = ` + require("req1")--[[]]require("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); +}); + +function requirePaths(matches: LuaRequire[]): string[] { + return matches.map(m => m.requirePath); +} diff --git a/test/unit/functions/__snapshots__/functions.spec.ts.snap b/test/unit/functions/__snapshots__/functions.spec.ts.snap index 345e31731..83345e13b 100644 --- a/test/unit/functions/__snapshots__/functions.spec.ts.snap +++ b/test/unit/functions/__snapshots__/functions.spec.ts.snap @@ -1,5 +1,39 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Function default parameter with value "null" 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function foo(self, x) + return x + end + return foo(nil) +end +return ____exports" +`; + +exports[`Function default parameter with value "undefined" 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function foo(self, x) + return x + end + return foo(nil) +end +return ____exports" +`; + +exports[`function.length unsupported ("5.0"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function fn(self) + end + return debug.getinfo(fn).nparams - 1 +end +return ____exports" +`; + +exports[`function.length unsupported ("5.0"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua 5.0."`; + exports[`function.length unsupported ("5.1"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -10,7 +44,7 @@ end return ____exports" `; -exports[`function.length unsupported ("5.1"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; +exports[`function.length unsupported ("5.1"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua 5.1."`; exports[`function.length unsupported ("universal"): code 1`] = ` "local ____exports = {} @@ -22,7 +56,7 @@ end return ____exports" `; -exports[`function.length unsupported ("universal"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; +exports[`function.length unsupported ("universal"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua universal."`; exports[`missing declaration name: code 1`] = ` "function ____(self) diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index c44364c9f..7bdf6b040 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -107,6 +107,48 @@ test("Function default binding parameter maintains order", () => { `.expectToMatchJsResult(); }); +test.each(["undefined", "null"])("Function default parameter with value %p", defaultValue => { + util.testFunction` + function foo(x = ${defaultValue}) { + return x; + } + return foo(); + ` + .expectToMatchJsResult() + .tap(builder => { + const lua = builder.getMainLuaCodeChunk(); + expect(lua).not.toMatch("if x == nil then"); + }) + .expectLuaToMatchSnapshot(); +}); + +test("Function default parameter with preceding statements", () => { + util.testFunction` + let i = 1 + function foo(x = i++) { + return x; + } + return [i, foo(), i]; + `.expectToMatchJsResult(); +}); + +test("Function default parameter with nil value and preceding statements", () => { + util.testFunction` + const a = new LuaTable() + a.set("foo", "bar") + function foo(x: any = a.set("foo", "baz")) { + return x ?? "nil"; + } + return [a.get("foo"), foo(), a.get("foo")]; + ` + .withLanguageExtensions() + .tap(builder => { + const lua = builder.getMainLuaCodeChunk(); + expect(lua).not.toMatch(" x = nil"); + }) + .expectToEqual(["bar", "nil", "baz"]); +}); + test("Class method call", () => { util.testFunction` class TestClass { @@ -224,14 +266,17 @@ test.each([ `.expectToMatchJsResult(); }); -test.each([tstl.LuaTarget.Lua51, tstl.LuaTarget.Universal])("function.length unsupported (%p)", luaTarget => { - util.testFunction` - function fn() {} - return fn.length; - ` - .setOptions({ luaTarget }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); -}); +test.each([tstl.LuaTarget.Lua50, tstl.LuaTarget.Lua51, tstl.LuaTarget.Universal])( + "function.length unsupported (%p)", + luaTarget => { + util.testFunction` + function fn() {} + return fn.length; + ` + .setOptions({ luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + } +); test("Recursive function definition", () => { util.testFunction` diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 03b7f3bfd..aa62d719d 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -165,6 +165,7 @@ util.testEachVersion( // Cannot execute LuaJIT with test runner { ...util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()), + [LuaTarget.Lua50]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), } ); diff --git a/test/unit/functions/noSelfAnnotation.spec.ts b/test/unit/functions/noSelfAnnotation.spec.ts index 1125f9cda..b25742a11 100644 --- a/test/unit/functions/noSelfAnnotation.spec.ts +++ b/test/unit/functions/noSelfAnnotation.spec.ts @@ -62,3 +62,58 @@ test("explicit this parameter respected over @noSelf", () => { export const result = foo(1); `.expectToMatchJsResult(); }); + +test("respect noSelfInFile over noImplicitSelf", () => { + const result = util.testModule` + /** @noSelfInFile **/ + const func: Function = () => 1; + export const result = func(1); + ` + .expectToMatchJsResult() + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("func(1)"); +}); + +test("respect noSelfInFile over noImplicitSelf (func declared in other file)", () => { + const result = util.testModule` + import { func, result } from "./functions"; + + export const result1 = result; + export const result2 = func(1); + ` + .addExtraFile( + "functions.ts", + ` + /** @noSelfInFile **/ + export const func: Function = () => 1; + export const result = func(2); + ` + ) + .expectToMatchJsResult() + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath.includes("main.lua")); + expect(mainFile).toBeDefined(); + const functionFile = result.transpiledFiles.find(f => f.outPath.includes("functions.lua")); + expect(functionFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile || !functionFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("func(1)"); + expect(mainFile.lua).toBeDefined(); + expect(functionFile.lua).toContain("func(2)"); +}); diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index caf3576a7..95b26b7d0 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -226,3 +226,18 @@ test.each([ let f: ${assignType} = o; `.expectDiagnosticsToMatchSnapshot([unsupportedOverloadAssignment.code], true); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/896 +test("Does not fail on union type signatures (#896)", () => { + util.testExpression`foo<'a'>(() => {});` + .setTsHeader( + ` + declare interface Events { + a(): void; + [key: string]: (this: void) => void; + } + declare function foo(callback: Events[T]): void; + ` + ) + .expectToHaveDiagnostics([unsupportedOverloadAssignment.code]); +}); diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 8c98196d9..525b95929 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -233,3 +233,35 @@ test.each([ return f(${args.map(a => '"' + a + '"').join(", ")}); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/896 +test("Does not fail on union type signatures (#896)", () => { + util.testExpression`foo<'a'>(() => {});` + .setTsHeader( + ` + declare interface Events { + a(): void; + [key: string]: Function; + } + declare function foo(callback: Events[T]): void; + ` + ) + .expectToHaveNoDiagnostics(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1568 +test("No false positives when using generic functions (#1568)", () => { + util.testModule` + /** @noSelf */ + declare namespace Test { + export function testCallback void>( + callback: T, + ): void; + } + + Test.testCallback(() => {}); + + const f = () => {}; + Test.testCallback(f); + `.expectToHaveNoDiagnostics(); +}); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index b5b627b4d..4ef550c4e 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -196,7 +196,7 @@ test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name => { util.testFunction` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; @@ -210,7 +210,7 @@ test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua name", name => { util.testModule` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; @@ -285,6 +285,38 @@ describe("unicode identifiers in supporting environments (luajit)", () => { }); }); +test("unicode export class", () => { + util.testModule` + import { 你好 } from "./utfclass"; + export const result = new 你好().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); +}); + +test("unicode export default class", () => { + util.testModule` + import c from "./utfclass"; + export const result = new c().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export default class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { util.testFunction` @@ -545,6 +577,15 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { expect(luaResult).toBe("foobar"); }); + test("variable (bit32)", () => { + util.testFunction` + const bit32 = 1; + return bit32 << 1; + ` + .setOptions({ luaTarget: LuaTarget.Lua52 }) + .expectToMatchJsResult(); + }); + test("variable (_G)", () => { util.testFunction` const _G = "bar"; @@ -813,3 +854,129 @@ test("lua built-in as in constructor assignment", () => { export const result = new A("42").error; `.expectToMatchJsResult(); }); + +test("customName rename function", () => { + const result = util.testModule` + /** @customName test2 **/ + function test(this: void): number { return 3; } + export const result: number = test(); + ` + .expectToEqual({ result: 3 }) + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("function test2()"); + expect(mainFile.lua).not.toContain("test()"); +}); + +test("customName rename variable", () => { + const result = util.testModule` + /** @customName result2 **/ + export const result: number = 3; + ` + .expectToEqual({ result2: 3 }) + .getLuaResult(); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("result2 ="); + expect(mainFile.lua).not.toContain("result ="); +}); + +test("customName rename classes", () => { + const testModule = util.testModule` + /** @customName Class2 **/ + class Class { + test: string; + + constructor(test: string) { + this.test = test; + } + } + + export const result = new Class("hello world"); + `; + + const executionResult = testModule.getLuaExecutionResult(); + expect(executionResult.result).toBeDefined(); + expect(executionResult.result).toMatchObject({ test: "hello world" }); + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("local Class2 ="); + expect(mainFile.lua).not.toContain("local Class ="); +}); + +test("customName rename namespace", () => { + const testModule = util.testModule` + /** @customName Test2 **/ + namespace Test { + /** @customName Func2 **/ + export function Func(): string { + return "hi"; + } + } + + export const result = Test.Func(); + `; + + testModule.expectToEqual({ result: "hi" }); + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2 ="); + expect(mainFile.lua).toContain("Test2.Func2"); + expect(mainFile.lua).not.toContain("Test ="); + expect(mainFile.lua).not.toContain("Func("); +}); + +test("customName rename declared function", () => { + const testModule = util.testModule` + /** @customName Test2 **/ + declare function Test(this: void): void; + + Test(); + `; + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2("); + expect(mainFile.lua).not.toContain("Test("); +}); diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap index 8e1601a39..e3c25d948 100644 --- a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -4,7 +4,7 @@ exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable {}): 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 ____ = {[\\"$multi\\"] = ____}"`; +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = {["$multi"] = ____}"`; exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; @@ -71,7 +71,7 @@ exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts( exports[`invalid $multi implicit cast: code 1`] = ` "function badMulti(self) - return \\"foo\\", 42 + return "foo", 42 end" `; diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap index fff18a4cc..a4554a8a1 100644 --- a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`does not crash on invalid operator use global function: code 1`] = `""`; + +exports[`does not crash on invalid operator use global function: diagnostics 1`] = `"main.ts(3,13): error TS2554: Expected 2 arguments, but got 1."`; + +exports[`does not crash on invalid operator use method: code 1`] = `"left = {}"`; + +exports[`does not crash on invalid operator use method: diagnostics 1`] = `"main.ts(5,18): error TS2554: Expected 1 arguments, but got 0."`; + +exports[`does not crash on invalid operator use unary operator: code 1`] = `"op(_G)"`; + +exports[`does not crash on invalid operator use unary operator: diagnostics 1`] = `"main.ts(2,31): error TS2304: Cannot find name 'LuaUnaryMinus'."`; + 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 be called directly and cannot be referred to."`; @@ -20,6 +32,30 @@ exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must be called directly and cannot be referred to."`; +exports[`unsupported binary operator mapping (5.0 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.0 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.0."`; + 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."`; @@ -116,6 +152,10 @@ exports[`unsupported binary operator mapping (universal LuaFloorDivision): code 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.0 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.0 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + 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."`; diff --git a/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap index b54b0de77..f38856514 100644 --- a/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap @@ -3,7 +3,7 @@ exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIterable) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + local testIterable = {a1 = "a2", b1 = "b2", c1 = "c2"} for ____ in pairs(testIterable) do end end @@ -15,7 +15,7 @@ exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIt exports[`invalid LuaPairsIterable without destructuring ("let s; for (s of testIterable) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + local testIterable = {a1 = "a2", b1 = "b2", c1 = "c2"} local s for ____ in pairs(testIterable) do end diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap index 64273b8fe..73a56890b 100644 --- a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -33,7 +33,7 @@ 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`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Spread = ____lualib.__TS__Spread local ____exports = {} function ____exports.__main(self) @@ -67,7 +67,7 @@ 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`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Iterator = ____lualib.__TS__Iterator local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 9821d9777..24abd6e71 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -108,28 +108,36 @@ has = ____table.has" exports[`LuaTableHas extension invalid use method assignment ("LuaTable"): diagnostics 1`] = `"main.ts(3,29): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaMap"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaMap"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaSet"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaSet"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaTable"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaTable"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`does not crash on invalid extension use global function: code 1`] = `""`; + +exports[`does not crash on invalid extension use global function: diagnostics 1`] = `"main.ts(3,9): error TS2554: Expected 2 arguments, but got 1."`; + +exports[`does not crash on invalid extension use method: code 1`] = `"left = {}"`; + +exports[`does not crash on invalid extension use method: diagnostics 1`] = `"main.ts(5,14): error TS2554: Expected 2 arguments, but got 0."`; diff --git a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap index 819cc27a0..e2cf42298 100644 --- a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap @@ -24,12 +24,14 @@ 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, ...) +"local ____lualib = require("lualib_bundle") +local __TS__Spread = ____lualib.__TS__Spread +function foo(self, ...) end function bar(self) foo( _G, - table.unpack(____) + __TS__Spread(____) ) end" `; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index ed7213b2b..72b330887 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -327,3 +327,77 @@ test("return LuaMultiReturn from catch", () => { .withLanguageExtensions() .expectToEqual(2); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1404 +test("LuaMultiReturn applies after casting a function (#1404)", () => { + util.testFunction` + let swap: any = (a: number, b: number) => $multi(b, a); + let [a, b] = (swap as (...args: any) => LuaMultiReturn<[number, number]>)(4, 3); + return [a, b]; + ` + .withLanguageExtensions() + .expectToEqual([3, 4]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1411 +describe("LuaMultiReturn returns all values even when indexed with [0] #1411", () => { + const sharedCode = ` + declare function select(this:void, index: '#', ...args: T[]): number; + + function foo(this: void): LuaMultiReturn<[number, number]> { + return $multi(123, 456); + } + + function bar(this: void): number { + return foo()[0]; + } + `; + test("Returns the correct value", () => { + util.testFunction` + return bar(); + ` + .setTsHeader(sharedCode) + .withLanguageExtensions() + .expectToEqual(123); + }); + + // We require an extra test since the test above would succeed even if bar() returned more than one value. + // This is because our test helper always returns just the first lua value returned from the testFunction. + // Here we need to test explicitly that only one value is returned. + test("Does not return multiple values", () => { + util.testFunction` + return select("#", bar()); + ` + .setTsHeader(sharedCode) + .withLanguageExtensions() + .expectToEqual(1); + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1591 +test("LuaMultiReturn in LuaIterable (#1591)", () => { + const lua = util.testModule` + type IterableAlias = LuaIterable>; + + declare const iterable: IterableAlias; + + for (const [a, b] of iterable) {} + ` + .withLanguageExtensions() + .getMainLuaCodeChunk(); + + expect(lua).toContain("a, b"); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1591 +test("LuaMultiReturn in LuaIterable intersection (#1591)", () => { + const lua = util.testModule` + declare function iterator(): { a: string } & LuaIterable>; + + for (const [a, b] of iterator()) {} + ` + .withLanguageExtensions() + .getMainLuaCodeChunk(); + + expect(lua).toContain("a, b"); +}); diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index bdd28339c..303a5d0be 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -2,7 +2,11 @@ import * as path from "path"; import * as util from "../../util"; import * as tstl from "../../../src"; import { LuaTarget } from "../../../src"; -import { unsupportedForTarget, invalidCallExtensionUse } from "../../../src/transformation/utils/diagnostics"; +import { + unsupportedForTarget, + invalidCallExtensionUse, + invalidSpreadInCallExtension, +} from "../../../src/transformation/utils/diagnostics"; const operatorsProjectOptions: tstl.CompilerOptions = { luaTarget: LuaTarget.Lua54, @@ -113,7 +117,7 @@ test.each(binaryMathOperatorTests)( } ); -const luaTargetsPre53 = [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; +const luaTargetsPre53 = [LuaTarget.Lua50, LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; const operatorTypesPost53 = [ "LuaFloorDivision", @@ -389,3 +393,41 @@ test.each([ .setOptions(operatorsProjectOptions) .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); + +describe("does not crash on invalid operator use", () => { + test("global function", () => { + util.testModule` + declare const op: LuaAddition; + op(1) + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); + test("unary operator", () => { + util.testModule` + declare const op: LuaUnaryMinus; + op() + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); + test("method", () => { + util.testModule` + const left = {} as { + op: LuaAdditionMethod; + } + left.op() + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); +}); + +test("does not allow spread", () => { + util.testModule` + declare const op: LuaAddition; + op(...[1, 2] as const); + ` + .setOptions(operatorsProjectOptions) + .expectToHaveDiagnostics([invalidSpreadInCallExtension.code]); +}); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index ed9e8e37c..13af766fa 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -221,7 +221,7 @@ describe("LuaTableDelete extension", () => { .expectToEqual({ table: { baz: "baz" } }); }); - test("LuaTableHasMethod method", () => { + test("LuaTableDeleteMethod method", () => { util.testModule` interface TableWithDelete { delete: LuaTableDeleteMethod; @@ -235,33 +235,6 @@ describe("LuaTableDelete extension", () => { .withLanguageExtensions() .expectToEqual({ table: { bar: 12 } }); }); - - test.each([ - ["LuaTableDelete<{}, string>", 'func({}, "foo")', true], - ["LuaTableDelete<{}, string>", '"truthy" && func({}, "foo")', true], - ["LuaTableSet<{}, string, number>", 'func({}, "foo", 3)', undefined], - ])("Table functions used as expression", (funcType, expression, value) => { - util.testModule` - declare const func: ${funcType} - export const result = ${expression} - ` - .withLanguageExtensions() - .setReturnExport("result") - .expectToEqual(value); - }); - - test.each([ - ["LuaTableDeleteMethod", 'tbl.func("foo")', true], - ["LuaTableSetMethod", 'tbl.func("foo", 3)', undefined], - ])("Table methods used as expression", (funcType, expression, value) => { - util.testModule` - const tbl = {} as { func: ${funcType} } - export const result = ${expression} - ` - .withLanguageExtensions() - .setReturnExport("result") - .expectToEqual(value); - }); }); describe("LuaTableAddKey extension", () => { @@ -298,28 +271,90 @@ describe("LuaTableAddKey extension", () => { .withLanguageExtensions() .expectToEqual({ table: { bar: true } }); }); +}); + +describe("LuaIsEmpty extension", () => { + test("LuaIsEmpty standalone function", () => { + util.testModule` + declare const isTableEmpty: LuaTableIsEmpty<{}>; + + const table = { foo: "bar", baz: "baz" }; + const emptyTable = {}; + + export const result = [isTableEmpty(table), isTableEmpty(emptyTable)]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); + + test("LuaIsEmpty namespace function", () => { + util.testModule` + declare namespace Table { + export const isTableEmpty: LuaTableIsEmpty<{}>; + } + + const table = { foo: "bar", baz: "baz" }; + const emptyTable = {}; + export const result = [Table.isTableEmpty(table), Table.isTableEmpty(emptyTable)]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); + + test("LuaTableIsEmptyMethod method", () => { + util.testModule` + interface TableWithIsEmpty { + isEmpty: LuaTableIsEmptyMethod; + set: LuaTableSetMethod; + } + const table = {} as TableWithIsEmpty; + table.set("foo", 42); + table.set("bar", 12); + + const emptyTable = {} as TableWithIsEmpty; + + export const result = [table.isEmpty(), emptyTable.isEmpty()]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); +}); + +describe("Table extensions use as expression", () => { test.each([ ["LuaTableAddKey<{}, string>", 'func({}, "foo")', undefined], ["LuaTableAddKey<{}, string>", '"truthy" && func({}, "foo")', undefined], - ])("Table functions used as expression", (funcType, expression, value) => { + ["LuaTableDelete<{}, string>", 'func({}, "foo")', true], + ["LuaTableDelete<{}, string>", '"truthy" && func({}, "foo")', true], + ["LuaTableSet<{}, string, number>", 'func({}, "foo", 3)', undefined], + ["LuaTableIsEmpty<{}>", "func({})", true], + ["LuaTableIsEmpty<{}>", 'func({ foo: "bar", baz: "baz" })', false], + ["LuaTableIsEmpty<{}>", '"truthy" && func({})', true], + ])("functions used as expression", (funcType, expression, value) => { util.testModule` declare const func: ${funcType} export const result = ${expression} ` .withLanguageExtensions() .setReturnExport("result") + .ignoreDiagnostics([2872 /* TS2872: This kind of expression is always truthy. */]) .expectToEqual(value); }); - test("Method used as expression", () => { + test.each([ + ["LuaTableDeleteMethod", 'tbl.func("foo")', true], + ["LuaTableSetMethod", 'tbl.func("foo", 3)', undefined], + ["LuaTableAddKeyMethod", 'tbl.func("foo")', undefined], + ["LuaTableIsEmpty<{}>", "tbl.func({})", true], + ])("methods used as expression", (funcType, expression, value) => { util.testModule` - const tbl = {} as { func: LuaTableAddKeyMethod } - export const result = tbl.func("foo") + const tbl = {} as { func: ${funcType} } + export const result = ${expression} ` .withLanguageExtensions() .setReturnExport("result") - .expectToEqual(undefined); + .expectToEqual(value); }); }); @@ -415,9 +450,22 @@ describe("LuaTable extension interface", () => { .expectToEqual({ baz: 5 }); }); + test("table isEmpty", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + + const emptyTbl = new LuaTable(); + + return [tbl.isEmpty(), emptyTbl.isEmpty()]; + ` + .withLanguageExtensions() + .expectToEqual([false, true]); + }); + test("table add", () => { util.testFunction` - const tbl = new LuaSet() + const tbl = new LuaSet(); tbl.add("foo"); return tbl ` @@ -467,3 +515,25 @@ test.each([ .withLanguageExtensions() .expectToEqual(expected); }); + +describe("does not crash on invalid extension use", () => { + test("global function", () => { + util.testModule` + declare const op: LuaTableGet<{}, string, any> + op({}) + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(); + }); + + test("method", () => { + util.testModule` + const left = {} as { + op: LuaTableGet<{}, string, any> + } + left.op() + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(); + }); +}); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 427af9d06..903cf6a1e 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,5 +1,6 @@ import * as tstl from "../../src"; -import { forbiddenForIn, unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../src"; +import { forbiddenForIn } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test("while", () => { @@ -14,8 +15,9 @@ test("while", () => { `.expectToMatchJsResult(); }); -test("while with continue", () => { - util.testFunction` +util.testEachVersion( + "while with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; let i = 0; while (i < arrTest.length) { @@ -36,11 +38,13 @@ test("while with continue", () => { i++; } return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); -test("dowhile with continue", () => { - util.testFunction` +util.testEachVersion( + "dowhile with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; let i = 0; do { @@ -61,8 +65,9 @@ test("dowhile with continue", () => { i++; } while (i < arrTest.length) return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("for", () => { util.testFunction` @@ -85,8 +90,9 @@ test("for with expression", () => { `.expectToMatchJsResult(); }); -test("for with continue", () => { - util.testFunction` +util.testEachVersion( + "for with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; for (let i = 0; i < arrTest.length; i++) { if (i % 2 == 0) { @@ -101,8 +107,9 @@ test("for with continue", () => { } } return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("forMirror", () => { util.testFunction` @@ -216,7 +223,20 @@ test("forin[Array]", () => { `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); -test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p)", ({ inp }) => { +const luaTargetsExceptJit = [ + LuaTarget.Lua50, + LuaTarget.Lua51, + LuaTarget.Lua52, + LuaTarget.Lua53, + LuaTarget.Lua54, + LuaTarget.Universal, +]; + +test.each( + luaTargetsExceptJit.flatMap(target => + [{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }].map(testCase => [target, testCase] as const) + ) +)("forin with continue (%s %p)", (luaTarget, { inp }) => { util.testFunctionTemplate` let obj = ${inp}; for (let i in obj) { @@ -227,7 +247,9 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p) obj[i] = 0; } return obj; - `.expectToMatchJsResult(); + ` + .setOptions({ luaTarget }) + .expectToMatchJsResult(); }); test.each([{ inp: [0, 1, 2] }])("forof (%p)", ({ inp }) => { @@ -331,8 +353,9 @@ test("forof destructing with existing variables", () => { `.expectToMatchJsResult(); }); -test("forof with continue", () => { - util.testFunction` +util.testEachVersion( + "forof with continue", + () => util.testFunction` let testArr = [0, 1, 2, 3, 4]; let a = 0; for (let i of testArr) { @@ -350,8 +373,9 @@ test("forof with continue", () => { a++; } return testArr; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("forof with iterator", () => { util.testFunction` @@ -515,16 +539,24 @@ for (const testCase of [ "for (const a in {}) { continue; }", "for (const a of []) { continue; }", ]) { + const expectContinueVariable: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toMatch("local __continue2"); + const expectContinueGotoLabel: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); + const expectContinueStatement: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toMatch("continue;"); + util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { - [tstl.LuaTarget.Universal]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), - [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), + [tstl.LuaTarget.Universal]: expectContinueVariable, + [tstl.LuaTarget.Lua50]: expectContinueVariable, + [tstl.LuaTarget.Lua51]: expectContinueVariable, [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, + [tstl.LuaTarget.Luau]: () => expectContinueStatement, }); } diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index a250dbd46..8c40101e5 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -2,7 +2,7 @@ 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" `; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index bbe978226..d15f18463 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -291,3 +291,25 @@ test("import expression", () => { .setOptions({ module: ts.ModuleKind.ESNext }) .expectToEqual({ result: "foo" }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1572 +test("correctly exports @compileMembersOnly enums (#1572)", () => { + util.testModule` + export { val } from "./otherfile"; + ` + .addExtraFile( + "otherfile.ts", + ` + // Would put this in the main file, but we cannot transfer enum types over lua/js boundary + // but we still need to have an exported enum, hence it is in another file + /** @compileMembersOnly */ + export enum MyEnum { + A = 0, + B = 1, + C = 2 + } + export const val = MyEnum.B | MyEnum.C; + ` + ) + .expectToEqual({ val: 3 }); +}); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index b2c7194b5..26c147c68 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -87,6 +87,37 @@ test("doesn't resolve paths out of root dir", () => { .expectDiagnosticsToMatchSnapshot([couldNotResolveRequire.code]); }); +test("resolves non-standard requires", () => { + const { transpiledFiles } = util.testModule` + export * from "./externalLua"; + ` + .addExtraFile("externalLua.d.ts", "export const foo = 3;") + .addExtraFile( + "externalLua.lua", + ` + require("requiredLuaFile1") -- standard + require('requiredLuaFile2') -- single quote + require'requiredLuaFile3' -- no parentheses + require"requiredLuaFile4" -- no parentheses double quote + require "requiredLuaFile5" -- no parentheses and space + require "requiredLua'File6" -- no parentheses and space + require 'requiredLua"File7' -- no parentheses and space + ` + ) + .addExtraFile("requiredLuaFile1.lua", "") + .addExtraFile("requiredLuaFile2.lua", "") + .addExtraFile("requiredLuaFile3.lua", "") + .addExtraFile("requiredLuaFile4.lua", "") + .addExtraFile("requiredLuaFile5.lua", "") + .addExtraFile("requiredLua'File6.lua", "") + .addExtraFile('requiredLua"File7.lua', "") + .expectToHaveNoDiagnostics() + .getLuaResult(); + + // Expect main.lua, externalLua.lua and all 7 required lua files in there + expect(transpiledFiles.map(f => f.outPath)).toHaveLength(9); +}); + test.each([ { declarationStatement: ` diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 762152d67..01b2e3f92 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -144,3 +144,15 @@ test("enum in a namespace", () => { export const result = Test.TestEnum.A; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1431 +test("nested namespaces (#1431)", () => { + util.testModule` + namespace Foo.Bar {} + namespace Foo.Bar { + export const baz = 32; + } + + export { Foo } + `.expectToMatchJsResult(); +}); diff --git a/test/unit/nullishCoalescing.spec.ts b/test/unit/nullishCoalescing.spec.ts index 3728f2815..56db55332 100644 --- a/test/unit/nullishCoalescing.spec.ts +++ b/test/unit/nullishCoalescing.spec.ts @@ -1,18 +1,26 @@ import * as util from "../util"; test.each(["null", "undefined"])("nullish-coalesing operator returns rhs", nullishValue => { - util.testExpression`${nullishValue} ?? "Hello, World!"`.expectToMatchJsResult(); + util.testExpression`${nullishValue} ?? "Hello, World!"` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test.each([3, "foo", {}, [], true, false])("nullish-coalesing operator returns lhs", value => { - util.testExpression`${util.formatCode(value)} ?? "Hello, World!"`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(value)} ?? "Hello, World!"` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); test.each(["any", "unknown"])("nullish-coalesing operator with any/unknown type", type => { util.testFunction` const unknownType = false as ${type}; return unknownType ?? "This should not be returned!"; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test.each(["boolean | string", "number | false", "undefined | true"])( @@ -38,7 +46,9 @@ test("nullish-coalescing operator with side effect rhs", () => { let i = 0; const incI = () => ++i; return [i, undefined ?? incI(), i]; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test("nullish-coalescing operator with vararg", () => { diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 234bff14c..d99f18be9 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -4,16 +4,22 @@ import { ScriptTarget } from "typescript"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` - const obj: any = ${value}; + const obj: {foo: string} | null | undefined = ${value}; return obj?.foo; - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use "and" expression }); test("long optional chain", () => { util.testFunction` const a = { b: { c: { d: { e: { f: "hello!"}}}}}; return a.b?.c?.d.e.f; - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use "and" expression }); test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { @@ -69,7 +75,89 @@ test("optional element function calls", () => { const fooKey = "foo"; const barKey = "bar"; return obj[barKey]?.(5) ?? obj[fooKey]?.(15); - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should still use "and" statement, as functions have no self +}); + +test("unused expression", () => { + util.testFunction` + const obj = { foo: "bar" }; + obj?.foo; + ` + .expectToHaveNoDiagnostics() + .expectNoExecutionError() + .expectLuaToMatchSnapshot(); + // should use if statement, as result is not used +}); + +test("unused call", () => { + util.testFunction` + let result + const obj = { + foo() { + result = "bar" + } + }; + obj?.foo(); + return result; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as result is not used +}); + +test.each(["undefined", "{ foo: v=>v }"])("with preceding statements on right side", value => { + util.testFunction` + let i = 0 + const obj: any = ${value}; + return {result: obj?.foo(i++), i}; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements +}); + +// unused, with preceding statements on right side +test.each(["undefined", "{ foo(val) {return val} }"])( + "unused result with preceding statements on right side", + value => { + util.testFunction` + let i = 0 + const obj = ${value}; + obj?.foo(i++); + return i + ` + .expectToHaveNoDiagnostics() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements + } +); + +test.each(["undefined", "{ foo(v) { return v} }"])("with preceding statements on right side modifying left", value => { + util.testFunction` + let i = 0 + let obj: any = ${value}; + function bar() { + if(obj) obj.foo = undefined + obj = undefined + return 1 + } + + return {result: obj?.foo(bar(), i++), obj, i} + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements +}); + +test("does not suppress error if left side is false", () => { + const result = util.testFunction` + const obj: any = false + return obj?.foo + `.getLuaExecutionResult(); + expect(result).toBeInstanceOf(util.ExecutionError); }); describe("optional access method calls", () => { @@ -85,7 +173,7 @@ describe("optional access method calls", () => { `.expectToMatchJsResult(); }); - test("optional access call", () => { + test("property access call", () => { util.testFunction` const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { value: "foobar", @@ -253,7 +341,7 @@ describe("optional chaining function calls", () => { const result = func?.(i++); ` .setOptions({ - alwaysStrict: strict, + strict, target: ScriptTarget.ES5, }) .expectToMatchJsResult(); @@ -350,3 +438,22 @@ describe("Non-null chain", () => { `.expectToMatchJsResult(); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1585 +test("optional chaining of super call (#1585)", () => { + util.testFunction` + class Parent { + private name = "foo"; + M2() { return this.name; } + } + + class Child extends Parent { + M2() { + return super.M2?.(); + } + } + + const c = new Child(); + return c.M2(); + `.expectToMatchJsResult(); +}); diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts index f27d26494..1ce24da19 100644 --- a/test/unit/precedingStatements.spec.ts +++ b/test/unit/precedingStatements.spec.ts @@ -633,7 +633,11 @@ test("class member initializers", () => { } const inst = new MyClass(); return [inst.myField, inst.foo]; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); test("class member initializers in extended class", () => { @@ -644,5 +648,9 @@ test("class member initializers in extended class", () => { } const inst = new MyClass(); return inst.myField; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); diff --git a/test/unit/printer/__snapshots__/semicolons.spec.ts.snap b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap index af1deb303..ac34dbdf8 100644 --- a/test/unit/printer/__snapshots__/semicolons.spec.ts.snap +++ b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap @@ -3,9 +3,9 @@ exports[`semicolon insertion ("{}") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end do end @@ -18,9 +18,9 @@ return ____exports" exports[`semicolon insertion ("const a = 1; const b = a;") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local a = 1 local b = a; @@ -33,9 +33,9 @@ return ____exports" exports[`semicolon insertion ("const a = 1; let b: number; b = a;") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local a = 1 local b @@ -49,9 +49,9 @@ return ____exports" exports[`semicolon insertion ("function bar() {} bar();") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local function bar(self) end diff --git a/test/unit/printer/semicolons.spec.ts b/test/unit/printer/semicolons.spec.ts index addb66e53..7be461d0f 100644 --- a/test/unit/printer/semicolons.spec.ts +++ b/test/unit/printer/semicolons.spec.ts @@ -10,6 +10,7 @@ test.each(["const a = 1; const b = a;", "const a = 1; let b: number; b = a;", "{ (undefined || foo)(); return result; ` + .ignoreDiagnostics([2873 /* TS2873: This kind of expression is always falsy. */]) .expectToMatchJsResult() .expectLuaToMatchSnapshot(); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 29f7110d3..3a1add475 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -76,10 +76,12 @@ describe("in function call", () => { { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [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(), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); }); @@ -88,10 +90,12 @@ describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [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(), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); test("of array literal /w OmittedExpression", () => { @@ -133,58 +137,55 @@ describe("in object literal", () => { }); describe("vararg spread optimization", () => { - test("basic use", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("body-less arrow function", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("if statement", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("loop statement", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("block statement", () => { - util.testFunction` + util.testEachVersion( + "block statement", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { let result: string; @@ -193,14 +194,13 @@ describe("vararg spread optimization", () => { } return result; } - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("finally clause", () => { - util.testFunction` + util.testEachVersion( + "finally clause", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { try { @@ -210,11 +210,9 @@ describe("vararg spread optimization", () => { return pick(...args); } } - return test("a" ,"b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); test("$multi", () => { util.testFunction` @@ -231,68 +229,66 @@ describe("vararg spread optimization", () => { .expectToEqual("b"); }); - test("curry", () => { - util.testFunction` + util.testEachVersion( + "curry", + () => util.testFunction` function test(fn: (...args: A) => void, ...args: A) { return fn(...args); } - return test((arg: string) => arg, "foobar"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test((arg: string) => arg, "foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("curry with indirect type", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test({fn: (arg: string) => arg}, "foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("function type declared inside scope", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + test("foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("With cast", () => { - util.testFunction` + util.testEachVersion( + "With cast", + () => util.testFunction` function pick(...args: any[]) { return args[1]; } function testany>(...args: Parameters) { return pick(...(args as any[])); } - return test<(...args: string[])=>void>("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test<(...args: string[])=>void>("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); describe("vararg spread de-optimization", () => { - test("array modification", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("array modification in hoisted function", () => { - util.testFunction` + util.testEachVersion( + "array modification in hoisted function", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { hoisted(); @@ -300,12 +296,13 @@ describe("vararg spread de-optimization", () => { function hoisted() { args[1] = "foobar"; } return result; } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("array modification in secondary hoisted function", () => { - util.testFunction` + util.testEachVersion( + "array modification in secondary hoisted function", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { function triggersHoisted() { hoisted(); } @@ -314,103 +311,112 @@ describe("vararg spread de-optimization", () => { function hoisted() { args[1] = "foobar"; } return result; } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); describe("vararg spread in IIFE", () => { - test("comma operator", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("assignment expression", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("destructured assignment expression", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("property-access assignment expression", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("binary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("postfix unary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("prefix unary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("try clause", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("catch clause", () => { - util.testFunction` + util.testEachVersion( + "catch clause", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { try { @@ -419,64 +425,69 @@ describe("vararg spread in IIFE", () => { return pick(...args) } } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("class expression", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("self-referencing function expression", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("method indirect access (access args)", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("method indirect access (method args)", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("tagged template method indirect access", () => { - util.testFunction` + util.testEachVersion( + "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(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 @@ -500,7 +511,7 @@ test.each(["pairs", "ipairs"])("can spread %s (#1244)", func => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 -test.each(["LuaTable", "LuaMap"])("can spread %s (#1244)", type => { +test.each(["LuaTable", "LuaMap"])("can spread %s with pairs (#1244)", type => { const result: Array<[string, string]> = util.testFunction` const tbl = new ${type}(); tbl.set("foo", "bar"); @@ -515,6 +526,52 @@ test.each(["LuaTable", "LuaMap"])("can spread %s (#1244)", type => { // We don't know the order so match like this expect(result).toHaveLength(2); - expect(result.some(([k, v]) => k === "foo" && v === "bar")).toBe(true); - expect(result.some(([k, v]) => k === "fizz" && v === "buzz")).toBe(true); + expect(result).toContainEqual(["foo", "bar"]); + expect(result).toContainEqual(["fizz", "buzz"]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1384 +test.each(["LuaTable", "LuaMap"])("can spread %s (#1384)", type => { + const result: Array<[string, string]> = util.testFunction` + const tbl = new ${type}(); + tbl.set("foo", "bar"); + tbl.set("fizz", "buzz"); + return [...tbl]; + ` + .withLanguageExtensions() + .getLuaExecutionResult(); + + // We don't know the order so match like this + expect(result).toHaveLength(2); + expect(result).toContainEqual(["foo", "bar"]); + expect(result).toContainEqual(["fizz", "buzz"]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1384 +test("can spread LuaSet (#1384)", () => { + const result: Array<[string, string]> = util.testFunction` + const tbl = new LuaSet(); + tbl.add("foo"); + tbl.add("bar"); + return [...tbl]; + ` + .withLanguageExtensions() + .getLuaExecutionResult(); + + // We don't know the order so match like this + expect(result).toHaveLength(2); + expect(result).toContain("foo"); + expect(result).toContain("bar"); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1426 +test.each([true, false])("spread a decorator or array union type (#1426)", choice => { + util.testFunction` + function* things() { + yield "a"; + yield "b" + } + const c: boolean = ${util.formatCode(choice)}; + return [...(c ? things() : ["c", "d"])]; + `.expectToMatchJsResult(); }); diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts new file mode 100644 index 000000000..34b4fef67 --- /dev/null +++ b/test/unit/using.spec.ts @@ -0,0 +1,219 @@ +import { LuaLibImportKind } from "../../src"; +import * as util from "../util"; + +const usingTestLib = ` + export const logs: string[] = []; + + function loggedDisposable(id: string): Disposable { + logs.push(\`Creating \${id}\`); + + return { + [Symbol.dispose]() { + logs.push(\`Disposing \${id}\`); + } + } + }`; + +test("using disposes object at end of function", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); +}); + +test("handles multi-variable declarations", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"), b = loggedDisposable("b"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); +}); + +test("using disposes object at end of nested block", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + + { + using b = loggedDisposable("b"); + logs.push("nested block"); + } + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + logs: ["Creating a", "Creating b", "nested block", "Disposing b", "function content", "Disposing a"], + }); +}); + +test("using does not affect function return value", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + logs.push("function content"); + + return "success"; + } + + export const result = func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + result: "success", + logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"], + }); +}); + +test("using disposes even when error happens", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + throw "test-induced exception"; + } + + try + { + func(); + } + catch (e) + { + logs.push(\`caught exception: \${e}\`); + } + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + logs: [ + "Creating a", + "Creating b", + "Disposing b", + "Disposing a", + "caught exception: test-induced exception", + ], + }); +}); + +test("await using disposes object with await at end of function", () => { + util.testModule` + let disposeAsync; + + function loggedAsyncDisposable(id: string): AsyncDisposable { + logs.push(\`Creating \${id}\`); + + return { + [Symbol.asyncDispose]() { + logs.push(\`Disposing async \${id}\`); + return new Promise(resolve => { + disposeAsync = () => { + logs.push(\`Disposed \${id}\`); + resolve(); + }; + }); + } + } + } + + async function func() { + await using a = loggedAsyncDisposable("a"); + + logs.push("function content"); + return "function result"; + } + + const p = func().then(r => logs.push("promise resolved", r)); + + logs.push("function returned"); + + disposeAsync(); + ` + .setTsHeader(usingTestLib) + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToEqual({ + logs: [ + "Creating a", + "function content", + "Disposing async a", + "function returned", + "Disposed a", + "promise resolved", + "function result", + ], + }); +}); + +test("await using can handle non-async disposables", () => { + util.testModule` + async function func() { + await using a = loggedDisposable("a"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "function content", "Disposing a"] }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1571 +test("await using no extra diagnostics (#1571)", () => { + util.testModule` + async function getResource(): Promise { + return { + [Symbol.asyncDispose]: async () => {} + }; + } + + async function someOtherAsync() {} + + async function main() { + await using resource = await getResource(); + await someOtherAsync(); + } + `.expectToHaveNoDiagnostics(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1584 +test("works with disposable classes (#1584)", () => { + util.testFunction` + const log = []; + + class Scoped { + action(): void { + log.push("action") + } + [Symbol.dispose]() { + log.push("cleanup") + } + } + + function TestScoped(): void { + using s = new Scoped(); + s.action(); + } + + TestScoped(); + return log; + `.expectToEqual(["action", "cleanup"]); +}); diff --git a/test/util.ts b/test/util.ts index ffc6bac68..501b24bfb 100644 --- a/test/util.ts +++ b/test/util.ts @@ -11,14 +11,25 @@ import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; import { EmitHost, getEmitOutDir, transpileProject } from "../src"; import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; +import { resolveLuaLibDir } from "../src/LuaLib"; -const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +function readLuaLib(target: tstl.LuaTarget) { + return fs.readFileSync(path.join(resolveLuaLibDir(target), "lualib_bundle.lua"), "utf8"); +} + +function jsonLib(target: tstl.LuaTarget): string { + const fileName = target === tstl.LuaTarget.Lua50 ? "json.50.lua" : "json.lua"; + return fs.readFileSync(path.join(__dirname, fileName), "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.Lua50) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.50"); + return { lauxlib, lua, lualib }; + } if (target === tstl.LuaTarget.Lua51) { const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.51"); return { lauxlib, lua, lualib }; @@ -32,7 +43,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l return { lauxlib, lua, lualib }; } if (target === tstl.LuaTarget.LuaJIT) { - throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!"); + throw Error("Can't use executeLua() or expectToMatchJsResult() with LuaJIT as target!"); } const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54"); @@ -52,7 +63,7 @@ export function testEachVersion( ): void { for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) { const specialBuilder = special?.[version]; - if (specialBuilder === false) return; + if (specialBuilder === false) continue; const testName = name === undefined ? version : `${name} [${version}]`; defineTest(testName, () => { @@ -70,11 +81,13 @@ export function expectEachVersionExceptJit( ): Record void) | boolean> { return { [tstl.LuaTarget.Universal]: expectation, + [tstl.LuaTarget.Lua50]: expectation, [tstl.LuaTarget.Lua51]: expectation, [tstl.LuaTarget.Lua52]: expectation, [tstl.LuaTarget.Lua53]: expectation, [tstl.LuaTarget.Lua54]: expectation, [tstl.LuaTarget.LuaJIT]: false, // Exclude JIT + [tstl.LuaTarget.Luau]: false, }; } @@ -110,35 +123,35 @@ export abstract class TestBuilder { // TODO: Use testModule in these cases? protected tsHeader = ""; public setTsHeader(tsHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setTsHeader"); this.tsHeader = tsHeader; return this; } private luaHeader = ""; public setLuaHeader(luaHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setLuaHeader"); this.luaHeader += luaHeader; return this; } protected jsHeader = ""; public setJsHeader(jsHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setJsHeader"); this.jsHeader += jsHeader; return this; } protected abstract getLuaCodeWithWrapper(code: string): string; public setLuaFactory(luaFactory: (code: string) => string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setLuaFactory"); this.getLuaCodeWithWrapper = luaFactory; return this; } private semanticCheck = true; public disableSemanticCheck(): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("disableSemanticCheck"); this.semanticCheck = false; return this; } @@ -149,19 +162,19 @@ export abstract class TestBuilder { skipLibCheck: true, target: ts.ScriptTarget.ES2017, lib: ["lib.esnext.d.ts"], - moduleResolution: ts.ModuleResolutionKind.NodeJs, + moduleResolution: ts.ModuleResolutionKind.Node10, resolveJsonModule: true, - experimentalDecorators: true, sourceMap: true, }; public setOptions(options: tstl.CompilerOptions = {}): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setOptions"); Object.assign(this.options, options); return this; } public withLanguageExtensions(): this { - this.setOptions({ types: [path.resolve(__dirname, "..", "language-extensions")] }); + const langExtTypes = path.resolve(__dirname, "..", "language-extensions"); + this.options.types = this.options.types ? [...this.options.types, langExtTypes] : [langExtTypes]; // Polyfill lualib for JS this.setJsHeader(` function $multi(...args) { return args; } @@ -171,25 +184,31 @@ export abstract class TestBuilder { protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setMainFileName"); this.mainFileName = mainFileName; return this; } protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("addExtraFile"); this.extraFiles[fileName] = normalizeSlashes(code); return this; } private customTransformers?: ts.CustomTransformers; public setCustomTransformers(customTransformers?: ts.CustomTransformers): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setCustomTransformers"); this.customTransformers = customTransformers; return this; } + private throwIfProgramExists(name: string) { + if (this.hasProgram) { + throw new Error(`${name}() should not be called after an .expect() or .debug()`); + } + } + // Transpilation and execution public getTsCode(): string { @@ -224,7 +243,7 @@ export abstract class TestBuilder { public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({ program, customTransformers: this.customTransformers, @@ -239,11 +258,18 @@ export abstract class TestBuilder { @memoize public getMainLuaFileResult(): ExecutableTranspiledFile { const { transpiledFiles } = this.getLuaResult(); + const mainFileName = normalizeSlashes(this.mainFileName); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => f.fileName === normalizeSlashes(this.mainFileName)) - ); + : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === mainFileName)); + + if (mainFile === undefined) { + throw new Error( + `No source file could be found matching main file: ${mainFileName}.\nSource files in test:\n${transpiledFiles + .flatMap(f => f.sourceFiles.map(sf => sf.fileName)) + .join("\n")}` + ); + } expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; @@ -265,7 +291,7 @@ export abstract class TestBuilder { const program = this.getProgram(); program.getCompilerOptions().module = ts.ModuleKind.CommonJS; - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics } = program.emit(undefined, collector.writeFile); return { transpiledFiles: collector.files, diagnostics: [...diagnostics] }; } @@ -301,12 +327,23 @@ export abstract class TestBuilder { // Actions public debug(includeLualib = false): this { - const transpiledFiles = this.getLuaResult().transpiledFiles; + const { transpiledFiles, diagnostics } = this.getLuaResult(); const luaCode = transpiledFiles .filter(f => includeLualib || f.outPath !== "lualib_bundle.lua") .map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat.format(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); + + if (diagnostics.length > 0) { + console.log( + ts.formatDiagnostics(diagnostics.map(tstl.prepareDiagnosticForFormatting), { + getCurrentDirectory: () => "", + getCanonicalFileName: fileName => fileName, + getNewLine: () => "\n", + }) + ); + } + return this; } @@ -334,6 +371,11 @@ export abstract class TestBuilder { return this; } + public expectNoTranspileException(): this { + expect(() => this.getLuaResult()).not.toThrow(); + return this; + } + public expectNoExecutionError(): this { const luaResult = this.getLuaExecutionResult(); if (luaResult instanceof ExecutionError) { @@ -402,20 +444,21 @@ export abstract class TestBuilder { // Main file const mainFile = this.getMainLuaCodeChunk(); - const { lauxlib, lua, lualib } = getLuaBindingsForVersion(this.options.luaTarget ?? tstl.LuaTarget.Lua54); + const luaTarget = this.options.luaTarget ?? tstl.LuaTarget.Lua54; + const { lauxlib, lua, lualib } = getLuaBindingsForVersion(luaTarget); const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Load modules // Json - this.packagePreloadLuaFile(L, lua, lauxlib, "json", jsonLib); + this.injectLuaFile(L, lua, lauxlib, "json", jsonLib(luaTarget)); // Lua lib if ( this.options.luaLibImport === tstl.LuaLibImportKind.Require || mainFile.includes('require("lualib_bundle")') ) { - this.packagePreloadLuaFile(L, lua, lauxlib, "lualib_bundle", luaLib); + this.injectLuaFile(L, lua, lauxlib, "lualib_bundle", readLuaLib(luaTarget)); } // Load all transpiled files into Lua's package cache @@ -423,7 +466,7 @@ export abstract class TestBuilder { 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); + this.injectLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); } } @@ -454,12 +497,26 @@ end)());`; } } - 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 injectLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { + let extension = this.options.extension ?? ".lua"; + if (!extension.startsWith(".")) { + extension = `.${extension}`; + } + const modName = fileName.endsWith(extension) + ? formatPathToLuaPath(fileName.substring(0, fileName.length - extension.length)) + : fileName; + if (this.options.luaTarget === tstl.LuaTarget.Lua50) { + // Adding source Lua to the _LOADED cache will allow require to find it + lua.lua_getglobal(state, "_LOADED"); + lauxlib.luaL_dostring(state, fileContent); + lua.lua_setfield(state, -2, modName); + } else { + // 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, modName); + } } private executeJs(): any { @@ -589,7 +646,7 @@ class ProjectTestBuilder extends ModuleTestBuilder { @memoize public getLuaResult(): tstl.TranspileVirtualProjectResult { // Override getLuaResult to use transpileProject with tsconfig.json instead - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile); return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 5a3543a03..87366ea76 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -44,13 +44,13 @@ "description": "Specifies how js standard features missing in lua are imported.", "type": "string", "default": "require", - "enum": ["none", "inline", "require"] + "enum": ["none", "inline", "require", "require-minimal"] }, "luaTarget": { "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["universal", "5.1", "5.2", "5.3", "JIT"] + "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "JIT", "Luau"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy