From 110b56f57045cd7cae2088f31e15ffac84036c84 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 13 Jul 2020 22:16:28 +0200 Subject: [PATCH 01/91] Changelog 0.35.0 --- CHANGELOG.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 044cba2e3..25033b16f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,18 @@ # Changelog -## Unreleased - -- `Function.length` is supported now - +## 0.35.0 + +- In preparation for some new features, some public APIs have been changed: + - High-level APIs that read input files from the file system (`transpileFiles` and `transpileProject`) now write transpiled files by default. This behavior can be changed by providing a `writeFile` callback, similarly to TypeScript's `program.emit`. + - `transpile` and `emitTranspiledFiles` functions have been replaced with the `Transpiler` class. See [documentation](https://typescripttolua.github.io/docs/api/overview#low-level-api) for usage examples. +- Fixed `declarationDir` option not being respected. +- `Function.length` is supported now. +- String iteration is now supported. +- Exposed `parseConfigFileWithSystem` to parse _tsconfig.json_ files as part of the tstl API. - Fixed `string.replace` incorrectly escaping some `replaceValue` characters (`().+-*?[^$`) +- Fixed several other string operations behaving differently from JS (mostly regarding indices out of bounds and NaN arguments). +- Fixed a bug where the length argument of `String.prototype.substr` was evaluated twice. +- Fixed some missing dependencies in LuaLib classes (Map, Set, WeakMap, WeakSet) ## 0.34.0 From 8dd12a93778fb2465cbcf393ad72a68915a75e23 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:20:39 -0600 Subject: [PATCH 02/91] fixed declarations that reference their own identifiers (#910) * fixed variable declarations that reference their own identifiers in the initializer * Update src/transformation/utils/lua-ast.ts Co-authored-by: ark120202 * compiler error fix * moved tests to assignments Co-authored-by: Tom Co-authored-by: ark120202 --- src/transformation/utils/lua-ast.ts | 25 +++++++++++--------- test/unit/assignments.spec.ts | 36 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 236e32437..b9b600c90 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -4,8 +4,7 @@ import * as lua from "../../LuaAST"; import { assert, castArray } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; -import { peekScope, ScopeType } from "./scope"; -import { isFunctionType } from "./typescript"; +import { peekScope, ScopeType, Scope } from "./scope"; import { transformLuaLibFunction } from "./lualib"; import { LuaLibFeature } from "../../LuaLib"; @@ -129,6 +128,17 @@ export function createHoistableVariableDeclarationStatement( return declaration; } +function hasMultipleReferences(scope: Scope, identifiers: lua.Identifier | lua.Identifier[]) { + const scopeSymbols = scope.referencedSymbols; + if (!scopeSymbols) { + return false; + } + + const referenceLists = castArray(identifiers).map(i => i.symbolId && scopeSymbols.get(i.symbolId)); + + return referenceLists.some(symbolRefs => symbolRefs && symbolRefs.length > 1); +} + export function createLocalOrExportedOrGlobalDeclaration( context: TransformationContext, lhs: lua.Identifier | lua.Identifier[], @@ -163,15 +173,8 @@ export function createLocalOrExportedOrGlobalDeclaration( const isTopLevelVariable = scope.type === ScopeType.File; if (context.isModule || !isTopLevelVariable) { - const isPossibleWrappedFunction = - !isFunctionDeclaration && - tsOriginal && - ts.isVariableDeclaration(tsOriginal) && - tsOriginal.initializer && - isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); - - if (isPossibleWrappedFunction || scope.type === ScopeType.Switch) { - // Split declaration and assignment for wrapped function types to allow recursion + if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { + // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } else { diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 02e1a3b9b..7ae3e1bb0 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -323,3 +323,39 @@ test.each([ return { r, o, a }; `.expectToMatchJsResult(); }); + +test("local variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return "foo"; + } + + let bar = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); + +test("local multiple variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return ["a", "foo", "c"]; + } + + let [a, bar, c] = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); From 1093e8f084155bcf1a0b57c0405808b8da4dc30c Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 14 Sep 2020 17:44:25 +1000 Subject: [PATCH 03/91] Update to TypeScript 4 (#914) * Print numbers overflowing the float limit as math.huge * Update TypeScript * Equalize Object.assign change * Use ts-ignore instead of Object.assign * Update dependencies, fix minor issues * Add package-lock.json changes * Update package.json Co-authored-by: ark120202 * Remove some skipped accessors tests, TypeScript no longer accepts that code * Rename transformFunctionBodyStatements -> transformFunctionBodyContent * Slight refactor for return.ts Co-authored-by: ark120202 --- package-lock.json | 333 +++++++++++++++--- package.json | 6 +- .../utils/assignment-validation.ts | 4 +- .../visitors/binary-expression/compound.ts | 7 +- .../visitors/binary-expression/index.ts | 31 +- .../visitors/class/members/constructor.ts | 4 +- src/transformation/visitors/function.ts | 29 +- src/transformation/visitors/return.ts | 63 ++-- test/unit/classes/accessors.spec.ts | 72 ---- 9 files changed, 365 insertions(+), 184 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a7114663..fa1a4185c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1671,6 +1671,32 @@ "chalk": "^3.0.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@sinonjs/commons": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", @@ -1736,12 +1762,6 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -1940,61 +1960,57 @@ } }, "@typescript-eslint/parser": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.31.0.tgz", - "integrity": "sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", + "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", "dev": true, "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.31.0", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-visitor-keys": "^1.1.0" + "@typescript-eslint/scope-manager": "4.1.0", + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/typescript-estree": "4.1.0", + "debug": "^4.1.1" }, "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", + "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", "dev": true, "requires": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0", "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", + "globby": "^11.0.1", "is-glob": "^4.0.1", "lodash": "^4.17.15", - "semver": "^6.3.0", + "semver": "^7.3.2", "tsutils": "^3.17.1" } }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } }, + "@typescript-eslint/scope-manager": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", + "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0" + } + }, + "@typescript-eslint/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", + "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "dev": true + }, "@typescript-eslint/typescript-estree": { "version": "2.23.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", @@ -2027,6 +2043,24 @@ } } }, + "@typescript-eslint/visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", + "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.0", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + } + } + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -2160,6 +2194,12 @@ "is-string": "^1.0.5" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -2836,6 +2876,23 @@ "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", "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" + }, + "dependencies": { + "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 + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3603,6 +3660,20 @@ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3615,6 +3686,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "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", @@ -3847,6 +3927,28 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", @@ -7193,6 +7295,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -7987,6 +8095,12 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8011,6 +8125,12 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "rxjs": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", @@ -8849,29 +8969,142 @@ } }, "ts-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz", - "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", + "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", "dev": true, "requires": { + "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", + "jest-util": "26.x", "json5": "2.x", "lodash.memoize": "4.x", "make-error": "1.x", - "micromatch": "4.x", "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "18.x" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/jest": { + "version": "26.0.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", + "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "dev": true, + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-util": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -8954,9 +9187,9 @@ } }, "typescript": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", - "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==" }, "union-value": { "version": "1.0.1", diff --git a/package.json b/package.json index 744d4571b..a149df59c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "^3.9.2" + "typescript": ">=4.0.2" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -47,7 +47,7 @@ "@types/node": "^13.7.7", "@types/resolve": "1.14.0", "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^2.31.0", + "@typescript-eslint/parser": "^4.1.0", "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", @@ -58,7 +58,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "prettier": "^2.0.5", - "ts-jest": "^26.0.0", + "ts-jest": "^26.3.0", "ts-node": "^8.6.2" } } diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index a31a24fdf..e62045248 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -34,8 +34,8 @@ export function validateAssignment( validateFunctionAssignment(context, node, fromType, toType, toName); - const fromTypeNode = context.checker.typeToTypeNode(fromType); - const toTypeNode = context.checker.typeToTypeNode(toType); + const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined); + const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined); if (!fromTypeNode || !toTypeNode) { return; } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 0eec44875..c82fe6862 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -48,7 +48,7 @@ type CompoundAssignmentToken = | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; -const compoundToAssignmentTokens: Record = { +const compoundToAssignmentTokens: Partial> = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, @@ -66,8 +66,9 @@ const compoundToAssignmentTokens: Record token in compoundToAssignmentTokens; -export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => - compoundToAssignmentTokens[token]; +export const unwrapCompoundAssignmentToken = ( + token: ts.CompoundAssignmentOperator +): CompoundAssignmentToken | undefined => compoundToAssignmentTokens[token]; export function transformCompoundAssignmentExpression( context: TransformationContext, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 356b2bcff..f150d848e 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; +import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf, unsupportedNodeKind } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -77,14 +77,13 @@ export const transformBinaryExpression: FunctionVisitor = ( } if (isCompoundAssignmentToken(operator)) { - return transformCompoundAssignmentExpression( - context, - node, - node.left, - node.right, - unwrapCompoundAssignmentToken(operator), - false - ); + const token = unwrapCompoundAssignmentToken(operator); + if (!token) { + context.diagnostics.push(unsupportedNodeKind(node, operator)); + return lua.createNilLiteral(node); + } + + return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false); } switch (operator) { @@ -157,13 +156,13 @@ export function transformBinaryExpressionStatement( if (isCompoundAssignmentToken(operator)) { // +=, -=, etc... - return transformCompoundAssignmentStatement( - context, - expression, - expression.left, - expression.right, - unwrapCompoundAssignmentToken(operator) - ); + const token = unwrapCompoundAssignmentToken(operator); + if (!token) { + context.diagnostics.push(unsupportedNodeKind(node, operator)); + return; + } + + return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token); } else if (operator === ts.SyntaxKind.EqualsToken) { return transformAssignmentStatement(context, expression as ts.AssignmentExpression); } else if (operator === ts.SyntaxKind.CommaToken) { diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index fe25a21b2..571c1022c 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -3,7 +3,7 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; -import { transformFunctionBodyHeader, transformFunctionBodyStatements, transformParameters } from "../../function"; +import { transformFunctionBodyHeader, transformFunctionBodyContent, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; @@ -28,7 +28,7 @@ export function transformConstructorDeclaration( // Transform body const scope = pushScope(context, ScopeType.Function); - const body = transformFunctionBodyStatements(context, statement.body); + const body = transformFunctionBodyContent(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( context, diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index cfbd8622d..b62a115be 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,6 +15,7 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; +import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; function transformParameterDefaultValueDeclaration( @@ -52,7 +53,12 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); } -export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] { +export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { + if (!ts.isBlock(body)) { + const returnStatement = transformExpressionBodyToReturnStatement(context, body); + return [returnStatement]; + } + const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); return bodyStatements; } @@ -107,11 +113,11 @@ export function transformFunctionBodyHeader( export function transformFunctionBody( context: TransformationContext, parameters: ts.NodeArray, - body: ts.Block, + body: ts.ConciseBody, spreadIdentifier?: lua.Identifier ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); - const bodyStatements = transformFunctionBodyStatements(context, body); + const bodyStatements = transformFunctionBodyContent(context, body); const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); return [[...headerStatements, ...bodyStatements], scope]; @@ -184,18 +190,13 @@ export function transformFunctionToExpression( flags |= lua.FunctionExpressionFlags.Declaration; } - let body: ts.Block; - if (ts.isBlock(node.body)) { - body = node.body; - } else { - const returnExpression = ts.createReturn(node.body); - body = ts.createBlock([returnExpression]); - returnExpression.parent = body; - if (node.body) body.parent = node.body.parent; - } - const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); - const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); + const [transformedBody, functionScope] = transformFunctionBody( + context, + node.parameters, + node.body, + spreadIdentifier + ); const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), paramNames, diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 970db6be0..c5ec3c740 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -1,12 +1,51 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; +import { FunctionVisitor, TransformationContext } from "../context"; import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; +function transformExpressionsInReturn( + context: TransformationContext, + node: ts.Expression, + insideTryCatch: boolean +): lua.Expression[] { + if (!isInTupleReturnFunction(context, node)) { + return [context.transformExpression(node)]; + } + + let results: lua.Expression[]; + const expressionType = context.checker.getTypeAtLocation(node); + + // Parent function is a TupleReturn function + if (ts.isArrayLiteralExpression(node)) { + // If return expression is an array literal, leave out brackets. + results = node.elements.map(e => context.transformExpression(e)); + } else if (!isTupleReturnCall(context, node) && isArrayType(context, expressionType)) { + // If return expression is an array-type and not another TupleReturn call, unpack it + results = [createUnpackCall(context, context.transformExpression(node), node)]; + } else { + results = [context.transformExpression(node)]; + } + + // Wrap tupleReturn results when returning inside try/catch + if (insideTryCatch) { + results = [wrapInTable(...results)]; + } + + return results; +} + +export function transformExpressionBodyToReturnStatement( + context: TransformationContext, + node: ts.Expression +): lua.Statement { + const expressions = transformExpressionsInReturn(context, node, false); + return lua.createReturnStatement(expressions, node); +} + export const transformReturnStatement: FunctionVisitor = (statement, context) => { // Bubble up explicit return flag and check if we're inside a try/catch block let insideTryCatch = false; @@ -29,27 +68,7 @@ export const transformReturnStatement: FunctionVisitor = (st validateAssignment(context, statement, expressionType, returnType); } - if (isInTupleReturnFunction(context, statement)) { - // Parent function is a TupleReturn function - if (ts.isArrayLiteralExpression(statement.expression)) { - // If return expression is an array literal, leave out brackets. - results = statement.expression.elements.map(e => context.transformExpression(e)); - } else if (!isTupleReturnCall(context, statement.expression) && isArrayType(context, expressionType)) { - // If return expression is an array-type and not another TupleReturn call, unpack it - results = [ - createUnpackCall(context, context.transformExpression(statement.expression), statement.expression), - ]; - } else { - results = [context.transformExpression(statement.expression)]; - } - - // Wrap tupleReturn results when returning inside try/catch - if (insideTryCatch) { - results = [wrapInTable(...results)]; - } - } else { - results = [context.transformExpression(statement.expression)]; - } + results = transformExpressionsInReturn(context, statement.expression, insideTryCatch); } else { // Empty return results = []; diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 4004a43f2..8a39fb21b 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -23,34 +23,6 @@ test("get accessor in base class", () => { `.expectToMatchJsResult(); }); -test.skip("get accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - get foo() { return this._foo + "bar"; } - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - -test.skip("get accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo { - foo = "bar"; - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - test("get accessor override accessor", () => { util.testFunction` class Foo { @@ -125,37 +97,6 @@ test("set accessor in base class", () => { `.expectToMatchJsResult(); }); -test("set accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - set foo(val: string) { this._foo = val; } - } - const b = new Bar(); - b.foo = "bar" - return b._foo; - `.expectToMatchJsResult(); -}); - -test("set accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "baz"; - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo { - foo = "foo"; // triggers base class setter - } - const b = new Bar(); - const fooOriginal = b._foo; - b.foo = "bar" - return fooOriginal + b._foo; - `.expectToMatchJsResult(); -}); - test("set accessor override accessor", () => { util.testFunction` class Foo { @@ -250,19 +191,6 @@ test("static get accessor override", () => { `.expectToMatchJsResult(); }); -test.skip("static get accessor overridden", () => { - util.testFunction` - class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo { - static foo = "bar"; - } - return Bar.foo; - `.expectToMatchJsResult(); -}); - test("static get accessor override accessor", () => { util.testFunction` class Foo { From 849f630d8199edc8b5742c98f9756b7d60aa66f9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 3 Oct 2020 18:42:06 +0200 Subject: [PATCH 04/91] Add in missing 4.0 compound assignments (#919) * Add in missing 4.0 compound assignments * Compound assignments 4.0 take 2 * Addressed PR comments * Removed obsolete exception case in transformBinaryExpression --- .../visitors/binary-expression/compound.ts | 87 +++++++++++- .../visitors/binary-expression/index.ts | 24 ++-- test/unit/assignments.spec.ts | 134 ++++++++++++++++++ 3 files changed, 223 insertions(+), 22 deletions(-) diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index c82fe6862..3b92ade58 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; +import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; @@ -46,9 +46,12 @@ type CompoundAssignmentToken = | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken - | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken + | ts.SyntaxKind.BarBarToken + | ts.SyntaxKind.AmpersandAmpersandToken + | ts.SyntaxKind.QuestionQuestionToken; -const compoundToAssignmentTokens: Partial> = { +const compoundToAssignmentTokens: Record = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, @@ -61,14 +64,16 @@ const compoundToAssignmentTokens: Partial token in compoundToAssignmentTokens; -export const unwrapCompoundAssignmentToken = ( - token: ts.CompoundAssignmentOperator -): CompoundAssignmentToken | undefined => compoundToAssignmentTokens[token]; +export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => + compoundToAssignmentTokens[token]; export function transformCompoundAssignmentExpression( context: TransformationContext, @@ -139,6 +144,15 @@ export function transformCompoundAssignmentExpression( const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatements = transformAssignment(context, lhs, tmpIdentifier); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return createImmediatelyInvokedFunctionExpression( + [tmpDeclaration, ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs)], + tmpIdentifier, + expression + ); + } + return createImmediatelyInvokedFunctionExpression( [tmpDeclaration, ...assignStatements], tmpIdentifier, @@ -175,13 +189,74 @@ export function transformCompoundAssignmentStatement( [context.transformExpression(objExpression), context.transformExpression(indexExpression)] ); const accessExpression = lua.createTableIndexExpression(obj, index); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return [ + objAndIndexDeclaration, + ...transformSetterSkippingCompoundAssignment(context, accessExpression, operator, rhs, node), + ]; + } + const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, node); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return [objAndIndexDeclaration, assignStatement]; } else { + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + const luaLhs = context.transformExpression(lhs) as lua.AssignmentLeftHandSideExpression; + return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node); + } + // Simple statements // ${left} = ${left} ${replacementOperator} ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, node); return transformAssignment(context, lhs, operatorExpression); } } + +/* These setter-skipping operators will not execute the setter if result does not change. + * x.y ||= z does NOT call the x.y setter if x.y is already true. + * x.y &&= z does NOT call the x.y setter if x.y is already false. + * x.y ??= z does NOT call the x.y setter if x.y is already not nullish. + */ +type SetterSkippingCompoundAssignmentOperator = ts.LogicalOperator | ts.SyntaxKind.QuestionQuestionToken; + +function isSetterSkippingCompoundAssignmentOperator( + operator: ts.BinaryOperator +): operator is SetterSkippingCompoundAssignmentOperator { + return ( + operator === ts.SyntaxKind.AmpersandAmpersandToken || + operator === ts.SyntaxKind.BarBarToken || + operator === ts.SyntaxKind.QuestionQuestionToken + ); +} + +function transformSetterSkippingCompoundAssignment( + context: TransformationContext, + lhs: lua.AssignmentLeftHandSideExpression, + operator: SetterSkippingCompoundAssignmentOperator, + rhs: ts.Expression, + node?: ts.Node +): lua.Statement[] { + // These assignments have the form 'if x then y = z', figure out what condition x is first. + let condition: lua.Expression; + + if (operator === ts.SyntaxKind.AmpersandAmpersandToken) { + condition = lhs; + } else if (operator === ts.SyntaxKind.BarBarToken) { + condition = lua.createUnaryExpression(lhs, lua.SyntaxKind.NotOperator); + } else if (operator === ts.SyntaxKind.QuestionQuestionToken) { + condition = lua.createBinaryExpression(lhs, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator); + } else { + assertNever(operator); + } + + // if condition then lhs = rhs end + return [ + lua.createIfStatement( + condition, + lua.createBlock([lua.createAssignmentStatement(lhs, context.transformExpression(rhs))]), + undefined, + node + ), + ]; +} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index f150d848e..001591c01 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf, unsupportedNodeKind } from "../../utils/diagnostics"; +import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -15,6 +15,7 @@ import { transformCompoundAssignmentStatement, unwrapCompoundAssignmentToken, } from "./compound"; +import { assert } from "../../../utils"; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -45,13 +46,18 @@ export function transformBinaryOperation( context: TransformationContext, left: lua.Expression, right: lua.Expression, - operator: BitOperator | SimpleOperator, + operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node ): lua.Expression { if (isBitOperator(operator)) { return transformBinaryBitOperation(context, node, left, right, operator); } + if (operator === ts.SyntaxKind.QuestionQuestionToken) { + assert(ts.isBinaryExpression(node)); + return transformNullishCoalescingExpression(context, node); + } + let luaOperator = simpleOperatorsToLua[operator]; // Check if we need to use string concat operator @@ -78,11 +84,6 @@ export const transformBinaryExpression: FunctionVisitor = ( if (isCompoundAssignmentToken(operator)) { const token = unwrapCompoundAssignmentToken(operator); - if (!token) { - context.diagnostics.push(unsupportedNodeKind(node, operator)); - return lua.createNilLiteral(node); - } - return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false); } @@ -131,10 +132,6 @@ export const transformBinaryExpression: FunctionVisitor = ( ); } - case ts.SyntaxKind.QuestionQuestionToken: { - return transformNullishCoalescingExpression(context, node); - } - default: return transformBinaryOperation( context, @@ -157,11 +154,6 @@ export function transformBinaryExpressionStatement( if (isCompoundAssignmentToken(operator)) { // +=, -=, etc... const token = unwrapCompoundAssignmentToken(operator); - if (!token) { - context.diagnostics.push(unsupportedNodeKind(node, operator)); - return; - } - return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token); } else if (operator === ts.SyntaxKind.EqualsToken) { return transformAssignmentStatement(context, expression as ts.AssignmentExpression); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 7ae3e1bb0..d2d80f08b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -121,6 +121,9 @@ test.each([ "x ^= y", "x <<= y", "x >>>= y", + "x &&= y", + "x ||= y", + "x ??= y", ])("Operator assignment statements (%p)", statement => { util.testFunction` let x = 3; @@ -359,3 +362,134 @@ test("local multiple variable declaration referencing self indirectly", () => { return bar; `.expectToMatchJsResult(); }); + +describe.each(["x &&= y", "x ||= y"])("boolean compound assignment (%p)", assignment => { + const booleanCases = [ + [false, false], + [false, true], + [true, false], + [true, true], + ]; + test.each(booleanCases)("matches JS", (x, y) => { + util.testFunction` + let x = ${x}; + let y = ${y}; + ${assignment}; + return x; + `.expectToMatchJsResult(); + }); +}); + +test.each([undefined, 3])("nullish coalescing compound assignment", initialValue => { + util.testFunction` + let x: number = ${util.formatCode(initialValue)}; + x ??= 5; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment lhs false", () => { + util.testFunction` + let x = false; + x ??= true; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment side effect not evaluated", () => { + util.testFunction` + let x = 3; + let y = 10; + x ??= (y += 5); + return [x, y]; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + inst.prop ${operator} 8; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter as expression", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + export const result = (inst.prop ${operator} 8); + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "+=", initialValue: 3 }, + { operator: "-=", initialValue: 10 }, + { operator: "*=", initialValue: 4 }, + { operator: "/=", initialValue: 20 }, + { operator: "||=", initialValue: false }, + { operator: "&&=", initialValue: true }, + { operator: "??=", initialValue: undefined }, +])("compound assignment side effects", ({ operator, initialValue }) => { + // Test if when assigning to something with potential side effects, they are only evaluated once. + util.testFunction` + const obj: { prop: any} = { prop: ${initialValue} }; + + let objGot = 0; + function getObj() { + objGot++; + return obj; + } + + getObj().prop ${operator} 4; + + return [obj, objGot]; + `.expectToMatchJsResult(); +}); From 7b6580b640368d7198dc27551dc2a558e0b0a036 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 8 Oct 2020 18:34:35 +0200 Subject: [PATCH 05/91] Implement parseInt and parseFloat (#920) * Alias parseInt parseFloat to tonumber * Implemented ParseFloat and ParseInt as lualib functions * PR comments --- src/LuaLib.ts | 2 + src/lualib/ParseFloat.ts | 11 ++++++ src/lualib/ParseInt.ts | 41 ++++++++++++++++++++ src/lualib/declarations/math.d.ts | 3 ++ src/lualib/declarations/string.d.ts | 1 + src/transformation/builtins/global.ts | 4 ++ test/unit/builtins/numbers.spec.ts | 54 +++++++++++++++++++++++++++ 7 files changed, 116 insertions(+) create mode 100644 src/lualib/ParseFloat.ts create mode 100644 src/lualib/ParseInt.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index c476882c7..1898be2cf 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -49,6 +49,8 @@ export enum LuaLibFeature { ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", + ParseFloat = "ParseFloat", + ParseInt = "ParseInt", Set = "Set", WeakMap = "WeakMap", WeakSet = "WeakSet", diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts new file mode 100644 index 000000000..1cd069111 --- /dev/null +++ b/src/lualib/ParseFloat.ts @@ -0,0 +1,11 @@ +function __TS__ParseFloat(this: void, numberString: string): number { + // Check if string is infinity + const infinityMatch = string.match(numberString, "^%s*(-?Infinity)"); + if (infinityMatch) { + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + return infinityMatch[0] === "-" ? -Infinity : Infinity; + } + + const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")); + return number ?? NaN; +} diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts new file mode 100644 index 000000000..b1d5710a0 --- /dev/null +++ b/src/lualib/ParseInt.ts @@ -0,0 +1,41 @@ +const __TS__parseInt_base_pattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; + +function __TS__ParseInt(this: void, numberString: string, base?: number): number { + // Check which base to use if none specified + if (base === undefined) { + base = 10; + const hexMatch = string.match(numberString, "^%s*-?0[xX]"); + if (hexMatch) { + base = 16; + numberString = string.match(hexMatch, "-") + ? "-" + numberString.substr(hexMatch.length) + : numberString.substr(hexMatch.length); + } + } + + // Check if base is in bounds + if (base < 2 || base > 36) { + return NaN; + } + + // Calculate string match pattern to use + const allowedDigits = + base <= 10 + ? __TS__parseInt_base_pattern.substring(0, base) + : __TS__parseInt_base_pattern.substr(0, 10 + 2 * (base - 10)); + const pattern = `^%s*(-?[${allowedDigits}]*)`; + + // Try to parse with Lua tonumber + const number = tonumber(string.match(numberString, pattern), base); + + if (number === undefined) { + return NaN; + } + + // Lua uses a different floor convention for negative numbers than JS + if (number >= 0) { + return math.floor(number); + } else { + return math.ceil(number); + } +} diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts index 837f717f9..54568c031 100644 --- a/src/lualib/declarations/math.d.ts +++ b/src/lualib/declarations/math.d.ts @@ -8,4 +8,7 @@ declare namespace math { function atan(y: number, x?: number): number; function atan2(y: number, x: number): number; + + function ceil(x: number): number; + function floor(x: number): number; } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index e8d657da6..2857690cb 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -13,4 +13,5 @@ declare namespace string { ): [string, number]; function sub(s: string, i: number, j?: number): string; function format(formatstring: string, ...args: any[]): string; + function match(string: string, pattern: string): string; } diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 2021951a5..79f359bbd 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -30,5 +30,9 @@ export function transformGlobalCall( node, ...numberParameters ); + case "parseFloat": + return transformLuaLibFunction(context, LuaLibFeature.ParseFloat, node, ...parameters); + case "parseInt": + return transformLuaLibFunction(context, LuaLibFeature.ParseInt, node, ...parameters); } } diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 2f52c1d7d..0ae65efb3 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -78,3 +78,57 @@ test("number intersected method", () => { test("numbers overflowing the float limit become math.huge", () => { util.testExpression`1e309`.expectToMatchJsResult(); }); + +describe.each(["parseInt", "parseFloat"])("parse numbers with %s", parseFunction => { + const numberStrings = ["3", "3.0", "9", "42", "239810241", "-20391", "3.1415", "2.7182", "-34910.3"]; + + test.each(numberStrings)("parses (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test("empty string", () => { + util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); + }); + + test("invalid string", () => { + util.testExpression`${parseFunction}("bla")`.expectToMatchJsResult(); + }); + + test.each(["1px", "2300m", "3,4", "452adkfl"])("trailing text (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test.each([" 3", " 4", " -231", " 1px"])("leading whitespace (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); +}); + +test.each(["Infinity", "-Infinity", " -Infinity"])("parseFloat handles Infinity", numberString => { + util.testExpression`parseFloat("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36", base: 8 }, + { numberString: "-36", base: 8 }, + { numberString: "100010101101", base: 2 }, + { numberString: "-100010101101", base: 2 }, + { numberString: "3F", base: 16 }, +])("parseInt with base (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + +test.each(["0x4A", "-0x42", "0X42", " 0x391", " -0x8F"])("parseInt detects hexadecimal", numberString => { + util.testExpression`parseInt("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([1, 37, -100])("parseInt with invalid base (%p)", base => { + util.testExpression`parseInt("11111", ${base})`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36px", base: 8 }, + { numberString: "10001010110231", base: 2 }, + { numberString: "3Fcolor", base: 16 }, +])("parseInt with base and trailing text (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); From c76813f91ae505089b5bef7f16543e7fe2f5c159 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 17 Oct 2020 15:26:32 +0500 Subject: [PATCH 06/91] `yield*` support (#923) * `yield*` support * Remove `.debug()` call --- src/LuaLib.ts | 1 + src/lualib/DelegatedYield.ts | 32 +++++++++++++++ src/lualib/Iterator.ts | 8 ++-- src/transformation/visitors/function.ts | 16 +++++--- test/unit/functions/generators.spec.ts | 53 +++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 src/lualib/DelegatedYield.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 1898be2cf..1b4c2aa2b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -29,6 +29,7 @@ export enum LuaLibFeature { Class = "Class", ClassExtends = "ClassExtends", Decorate = "Decorate", + DelegatedYield = "DelegatedYield", Descriptors = "Descriptors", Error = "Error", FunctionBind = "FunctionBind", diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts new file mode 100644 index 000000000..6b524365a --- /dev/null +++ b/src/lualib/DelegatedYield.ts @@ -0,0 +1,32 @@ +function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { + if (typeof iterable === "string") { + for (const index of forRange(0, iterable.length - 1)) { + coroutine.yield(iterable[index]); + } + } else if ("____coroutine" in iterable) { + const co = iterable.____coroutine; + while (true) { + const [status, value] = coroutine.resume(co); + if (!status) throw value; + if (coroutine.status(co) === "dead") { + return value; + } else { + coroutine.yield(value); + } + } + } else if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + return result.value; + } else { + coroutine.yield(result.value); + } + } + } else { + for (const value of iterable as readonly T[]) { + coroutine.yield(value); + } + } +} diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index e55de6404..809ca69ee 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -26,15 +26,15 @@ function __TS__IteratorStringStep(this: string, index: number): [number, string] /** @tupleReturn */ function __TS__Iterator( this: void, - iterable: Iterable | GeneratorIterator | readonly T[] + iterable: string | GeneratorIterator | Iterable | readonly T[] ): [(...args: any[]) => [any, any] | [], ...any[]] { - if ("____coroutine" in iterable) { + if (typeof iterable === "string") { + return [__TS__IteratorStringStep, iterable, 0]; + } else if ("____coroutine" in iterable) { return [__TS__IteratorGeneratorStep, iterable]; } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; - } else if (typeof iterable === "string") { - return [__TS__IteratorStringStep, iterable, 0]; } else { return ipairs(iterable as readonly T[]) as any; } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index b62a115be..d3fb88a5a 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -279,9 +279,13 @@ export const transformFunctionDeclaration: FunctionVisitor = (expression, context) => - lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), - expression.expression ? [context.transformExpression(expression.expression)] : [], - expression - ); +export const transformYieldExpression: FunctionVisitor = (expression, context) => { + const parameters = expression.expression ? [context.transformExpression(expression.expression)] : []; + return expression.asteriskToken + ? transformLuaLibFunction(context, LuaLibFeature.DelegatedYield, expression, ...parameters) + : lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), + parameters, + expression + ); +}; diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 90fb67aa4..7065aecf6 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -51,6 +51,59 @@ test("for..of", () => { `.expectToMatchJsResult(); }); +describe("yield*", () => { + test("generator", () => { + util.testFunction` + function* subGenerator() { + yield 1; + yield 2; + yield 3; + } + + function* generator() { + yield 0; + return yield* subGenerator(); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("array", () => { + util.testFunction` + function* generator() { + return yield* [1, 2, 3]; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("string", () => { + util.testFunction` + function* generator() { + return yield* "abc"; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("iterable", () => { + util.testFunction` + function* generator() { + return yield* new Set([1, 2, 3]); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); +}); + test("function expression", () => { util.testFunction` const generator = function*() { From 70f3e392a71f8ed7deec6930a51bf2c97f499ec9 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 17 Oct 2020 15:26:50 +0500 Subject: [PATCH 07/91] Add devcontainer.json configuration (#922) --- .devcontainer/devcontainer.json | 14 ++++++++++++++ .gitattributes | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..311827173 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "TypeScriptToLua", + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "extensions": [ + "ark120202.vscode-typescript-to-lua", + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode" + ], + "postCreateCommand": "npm ci" +} diff --git a/.gitattributes b/.gitattributes index fcadb2cf9..6313b56c5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text eol=lf +* text=auto eol=lf From 5a6ba5667b7242afb42b3f1169d0d144a3f0125f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sun, 18 Oct 2020 23:57:12 +1000 Subject: [PATCH 08/91] Method and Method Property decorators (#905) * Improve decorator use cases * Implementing descriptors * Refactoring * Revert tsconfig change * Single pass over class members * Add and fix more tests * Move decorator descriptor tests to descriptors * Refactoring and more consistent naming * Inline object.ts lines * Remove unnecessary descriptor clone * Use assignment instead for simple descriptors * Stop throwing an error when deletion attempt was disallowed * Use expectToMatchJsResult again for descriptor test * Use expectToMatchJsResult for existing array test case * Update test/unit/classes/decorators.spec.ts Co-authored-by: ark120202 * Update test/unit/builtins/array.spec.ts Co-authored-by: ark120202 * Update src/lualib/ObjectGetOwnPropertyDescriptors.ts Co-authored-by: ark120202 * Fix tests for DeleteExpressions * Remove unnecessary question tokens from method * Fix array tests * Capture error in a variable * Move Decorators with descriptors tests to decorator tests * Move descriptors tests to object * Add more getOwnPropertyDescriptor tests * Refactor ObjectDefineProperty slightly * Remove Descriptors LuaLib feature * Remove bar property * Improve targetKind statement * Merge class member decorating tests Co-authored-by: ark120202 --- src/LuaLib.ts | 11 ++- src/lualib/CloneDescriptor.ts | 26 ++++++ src/lualib/Decorate.ts | 20 ++++- src/lualib/DecorateParam.ts | 3 + src/lualib/Delete.ts | 19 ++++ src/lualib/ObjectDefineProperty.ts | 29 ++++++ src/lualib/ObjectGetOwnPropertyDescriptor.ts | 6 ++ src/lualib/ObjectGetOwnPropertyDescriptors.ts | 5 ++ .../{Descriptors.ts => SetDescriptor.ts} | 39 ++++---- src/transformation/builtins/object.ts | 18 ++-- .../visitors/class/decorators.ts | 56 ++++++------ src/transformation/visitors/class/index.ts | 66 ++++++++------ .../visitors/class/members/accessors.ts | 22 ++--- .../visitors/class/members/constructor.ts | 9 +- .../visitors/class/members/fields.ts | 32 +++++++ .../visitors/class/members/method.ts | 73 ++++++++++++--- src/transformation/visitors/delete.ts | 48 ++++++---- .../visitors/expression-statement.ts | 6 -- .../__snapshots__/expressions.spec.ts.snap | 26 +++--- test/unit/builtins/array.spec.ts | 20 +++-- test/unit/builtins/object.spec.ts | 90 +++++++++++++++++++ test/unit/classes/decorators.spec.ts | 58 ++++++++++++ 22 files changed, 520 insertions(+), 162 deletions(-) create mode 100644 src/lualib/CloneDescriptor.ts create mode 100644 src/lualib/DecorateParam.ts create mode 100644 src/lualib/Delete.ts create mode 100644 src/lualib/ObjectDefineProperty.ts create mode 100644 src/lualib/ObjectGetOwnPropertyDescriptor.ts create mode 100644 src/lualib/ObjectGetOwnPropertyDescriptors.ts rename src/lualib/{Descriptors.ts => SetDescriptor.ts} (65%) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 1b4c2aa2b..fde43c604 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -28,9 +28,11 @@ export enum LuaLibFeature { ArraySetLength = "ArraySetLength", Class = "Class", ClassExtends = "ClassExtends", + CloneDescriptor = "CloneDescriptor", Decorate = "Decorate", + DecorateParam = "DecorateParam", + Delete = "Delete", DelegatedYield = "DelegatedYield", - Descriptors = "Descriptors", Error = "Error", FunctionBind = "FunctionBind", Generator = "Generator", @@ -45,14 +47,18 @@ export enum LuaLibFeature { NumberIsNaN = "NumberIsNaN", NumberToString = "NumberToString", ObjectAssign = "ObjectAssign", + ObjectDefineProperty = "ObjectDefineProperty", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", + ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor", + ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors", ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", ParseFloat = "ParseFloat", ParseInt = "ParseInt", Set = "Set", + SetDescriptor = "SetDescriptor", WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", @@ -82,11 +88,14 @@ export enum LuaLibFeature { const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], + Decorate: [LuaLibFeature.CloneDescriptor], + Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], Error: [LuaLibFeature.New, LuaLibFeature.Class], FunctionBind: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], + ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], diff --git a/src/lualib/CloneDescriptor.ts b/src/lualib/CloneDescriptor.ts new file mode 100644 index 000000000..d74292bab --- /dev/null +++ b/src/lualib/CloneDescriptor.ts @@ -0,0 +1,26 @@ +function __TS__CloneDescriptor( + this: void, + { enumerable, configurable, get, set, writable, value }: PropertyDescriptor +): PropertyDescriptor { + const descriptor: PropertyDescriptor = { + enumerable: enumerable === true, + configurable: configurable === true, + }; + + const hasGetterOrSetter = get !== undefined || set !== undefined; + const hasValueOrWritableAttribute = writable !== undefined || value !== undefined; + + if (hasGetterOrSetter && hasValueOrWritableAttribute) { + throw "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute."; + } + + if (get || set) { + descriptor.get = get; + descriptor.set = set; + } else { + descriptor.value = value; + descriptor.writable = writable === true; + } + + return descriptor; +} diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 15dbee15d..e5cad0218 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,7 +1,7 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: string, desc?: any): {} { +function __TS__Decorate(this: void, decorators: Function[], target: any, key?: any, desc?: any): {} { let result = target; for (let i = decorators.length; i >= 0; i--) { @@ -11,8 +11,22 @@ function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: st if (key === undefined) { result = decorator(result); - } else if (desc !== undefined) { - result = decorator(target, key, result); + } else if (desc === true) { + const value = rawget(target, key); + const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) || { + configurable: true, + writable: true, + value, + }; + const desc = decorator(target, key, descriptor) || descriptor; + const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set; + if (isSimpleValue) { + rawset(target, key, desc.value); + } else { + __TS__SetDescriptor(target, key, { ...descriptor, ...desc }); + } + } else if (desc === false) { + result = decorator(target, key, desc); } else { result = decorator(target, key); } diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts new file mode 100644 index 000000000..ed0c28309 --- /dev/null +++ b/src/lualib/DecorateParam.ts @@ -0,0 +1,3 @@ +function __TS__DecorateParam(this: void, paramIndex: number, decorator: Function): {} { + return (target: Function, key?: string) => decorator(target, key, paramIndex); +} diff --git a/src/lualib/Delete.ts b/src/lualib/Delete.ts new file mode 100644 index 000000000..079dcb93d --- /dev/null +++ b/src/lualib/Delete.ts @@ -0,0 +1,19 @@ +function __TS__Delete(this: void, target: any, key: any): boolean { + const descriptors = __TS__ObjectGetOwnPropertyDescriptors(target); + const descriptor = descriptors[key]; + if (descriptor) { + if (!descriptor.configurable) { + throw `Cannot delete property ${key} of ${target}.`; + } + + descriptors[key] = undefined; + return true; + } + + if (target[key] !== undefined) { + target[key] = undefined; + return true; + } + + return false; +} diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts new file mode 100644 index 000000000..68297c420 --- /dev/null +++ b/src/lualib/ObjectDefineProperty.ts @@ -0,0 +1,29 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty +function __TS__ObjectDefineProperty(this: void, target: any, key: any, desc: PropertyDescriptor): object { + const luaKey = typeof key === "number" ? key + 1 : key; + const value = rawget(target, luaKey); + + const hasGetterOrSetter = desc.get !== undefined || desc.set !== undefined; + + let descriptor: PropertyDescriptor; + if (hasGetterOrSetter) { + if (value !== undefined) { + throw `Cannot redefine property: ${key}`; + } + + descriptor = desc; + } else { + const valueExists = value !== undefined; + descriptor = { + set: desc.set, + get: desc.get, + configurable: desc.configurable !== undefined ? desc.configurable : valueExists, + enumerable: desc.enumerable !== undefined ? desc.enumerable : valueExists, + writable: desc.writable !== undefined ? desc.writable : valueExists, + value: desc.value !== undefined ? desc.value : value, + }; + } + + __TS__SetDescriptor(target, luaKey, descriptor); + return target; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts new file mode 100644 index 000000000..84dab33df --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -0,0 +1,6 @@ +function __TS__ObjectGetOwnPropertyDescriptor(this: void, object: any, key: any): PropertyDescriptor | undefined { + const metatable = getmetatable(object); + if (!metatable) return; + if (!rawget(metatable, "_descriptors")) return; + return rawget(metatable, "_descriptors")[key]; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts new file mode 100644 index 000000000..9adc0071e --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -0,0 +1,5 @@ +function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { + const metatable = getmetatable(object); + if (!metatable) return {}; + return rawget(metatable, "_descriptors"); +} diff --git a/src/lualib/Descriptors.ts b/src/lualib/SetDescriptor.ts similarity index 65% rename from src/lualib/Descriptors.ts rename to src/lualib/SetDescriptor.ts index 7b6410ed6..49c7a0bf2 100644 --- a/src/lualib/Descriptors.ts +++ b/src/lualib/SetDescriptor.ts @@ -19,7 +19,7 @@ function ____descriptorIndex(this: any, key: string): void { return descriptor.get.call(this); } - return; + return descriptor.value; } } @@ -36,8 +36,13 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { if (descriptor) { if (descriptor.set) { descriptor.set.call(this, value); - } + } else { + if (descriptor.writable === false) { + throw `Cannot assign to read only property '${key}' of object '${this}'`; + } + descriptor.value = value; + } return; } } @@ -49,27 +54,19 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { } // It's also used directly in class transform to add descriptors to the prototype -function __TS__SetDescriptor(this: void, metatable: Metatable, prop: string, descriptor: PropertyDescriptor): void { - if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; - metatable._descriptors[prop] = descriptor; - - if (descriptor.get) metatable.__index = ____descriptorIndex; - if (descriptor.set) metatable.__newindex = ____descriptorNewindex; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty( - this: void, - object: T, - prop: string, - descriptor: PropertyDescriptor -): T { - let metatable = getmetatable(object); +function __TS__SetDescriptor(this: void, target: any, key: any, desc: PropertyDescriptor, isPrototype = false): void { + let metatable = isPrototype ? target : getmetatable(target); if (!metatable) { metatable = {}; - setmetatable(object, metatable); + setmetatable(target, metatable); } - __TS__SetDescriptor(metatable, prop, descriptor); - return object; + const value = rawget(target, key); + if (value !== undefined) rawset(target, key, undefined); + + if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; + const descriptor = __TS__CloneDescriptor(desc); + metatable._descriptors[key] = descriptor; + metatable.__index = ____descriptorIndex; + metatable.__newindex = ____descriptorNewindex; } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 358bebbf5..2db793f91 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -9,20 +9,26 @@ export function transformObjectConstructorCall( expression: PropertyCallExpression ): lua.Expression | undefined { const method = expression.expression; - const parameters = transformArguments(context, expression.arguments); + const args = transformArguments(context, expression.arguments); const methodName = method.name.text; switch (methodName) { case "assign": - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...args); + case "defineProperty": + return transformLuaLibFunction(context, LuaLibFeature.ObjectDefineProperty, expression, ...args); case "entries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...args); case "fromEntries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...args); + case "getOwnPropertyDescriptor": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, expression, ...args); + case "getOwnPropertyDescriptors": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, expression, ...args); case "keys": - return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...args); case "values": - return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...args); default: context.diagnostics.push(unsupportedProperty(method.name, "Object", methodName)); } diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 5cae0cf17..4b913485c 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -2,42 +2,38 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { decoratorInvalidContext } from "../../utils/diagnostics"; -import { addExportToIdentifier } from "../../utils/export"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { transformIdentifier } from "../identifier"; -export function createConstructorDecorationStatement( - context: TransformationContext, - declaration: ts.ClassLikeDeclaration -): lua.AssignmentStatement | undefined { - const className = - declaration.name !== undefined - ? addExportToIdentifier(context, transformIdentifier(context, declaration.name)) - : lua.createAnonymousIdentifier(); - - const decorators = declaration.decorators; - if (!decorators) { - return undefined; +export function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression { + const expression = decorator.expression; + const type = context.checker.getTypeAtLocation(expression); + const callContext = getFunctionContextType(context, type); + if (callContext === ContextType.Void) { + context.diagnostics.push(decoratorInvalidContext(decorator)); } - const decoratorExpressions = decorators.map(decorator => { - const expression = decorator.expression; - const type = context.checker.getTypeAtLocation(expression); - const callContext = getFunctionContextType(context, type); - if (callContext === ContextType.Void) { - context.diagnostics.push(decoratorInvalidContext(decorator)); - } + return context.transformExpression(expression); +} - return context.transformExpression(expression); - }); +export function createDecoratingExpression( + context: TransformationContext, + kind: ts.SyntaxKind, + decorators: lua.Expression[], + targetTableName: lua.Expression, + targetFieldExpression?: lua.Expression +): lua.Expression { + const decoratorTable = lua.createTableExpression(decorators.map(e => lua.createTableFieldExpression(e))); + const trailingExpressions = [decoratorTable, targetTableName]; - const decoratorTable = lua.createTableExpression( - decoratorExpressions.map(expression => lua.createTableFieldExpression(expression)) - ); + if (targetFieldExpression) { + trailingExpressions.push(targetFieldExpression); + const isMethodOrAccessor = + kind === ts.SyntaxKind.MethodDeclaration || + kind === ts.SyntaxKind.GetAccessor || + kind === ts.SyntaxKind.SetAccessor; + trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral()); + } - return lua.createAssignmentStatement( - className, - transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, decoratorTable, className) - ); + return transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, ...trailingExpressions); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 59ecc10b7..d70095bff 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 { getOrUpdate, isNonNull } from "../../../utils"; +import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { @@ -28,11 +28,15 @@ import { popScope, pushScope, ScopeType } from "../../utils/scope"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { createConstructorDecorationStatement } from "./decorators"; +import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; -import { transformClassInstanceFields } from "./members/fields"; -import { transformMethodDeclaration } from "./members/method"; +import { + createPropertyDecoratingExpression, + transformClassInstanceFields, + transformStaticPropertyDeclaration, +} from "./members/fields"; +import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; import { checkForLuaLibType } from "./new"; import { createClassSetup } from "./setup"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; @@ -134,7 +138,6 @@ function transformClassLikeDeclaration( const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); // Divide properties into static and non-static - const staticFields = properties.filter(isStaticNode); const instanceFields = properties.filter(prop => !isStaticNode(prop)); const result: lua.Statement[] = []; @@ -282,29 +285,42 @@ function transformClassLikeDeclaration( } } - // Transform methods - result.push( - ...classDeclaration.members - .filter(ts.isMethodDeclaration) - .map(m => transformMethodDeclaration(context, m, localClassName, isExtension || isMetaExtension)) - .filter(isNonNull) - ); - - // Add static declarations - for (const field of staticFields) { - const fieldName = transformPropertyName(context, field.name); - const value = field.initializer ? context.transformExpression(field.initializer) : undefined; - - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), fieldName); - - const fieldAssign = lua.createAssignmentStatement(classField, value); + const noPrototype = isExtension || isMetaExtension; + const decorationStatements: lua.Statement[] = []; - result.push(fieldAssign); + for (const member of classDeclaration.members) { + if (ts.isAccessor(member)) { + const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } else if (ts.isMethodDeclaration(member)) { + const statement = transformMethodDeclaration(context, member, localClassName, noPrototype); + if (statement) result.push(statement); + if (member.body) { + const statement = createMethodDecoratingExpression(context, member, localClassName, noPrototype); + if (statement) decorationStatements.push(statement); + } + } else if (ts.isPropertyDeclaration(member)) { + if (isStaticNode(member)) { + const statement = transformStaticPropertyDeclaration(context, member, localClassName); + if (statement) decorationStatements.push(statement); + } + const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } } - const decorationStatement = createConstructorDecorationStatement(context, classDeclaration); - if (decorationStatement) { - result.push(decorationStatement); + result.push(...decorationStatements); + + // Decorate the class + if (classDeclaration.decorators) { + const decoratingExpression = createDecoratingExpression( + context, + classDeclaration.kind, + classDeclaration.decorators.map(d => transformDecoratorExpression(context, d)), + localClassName + ); + const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); + result.push(decoratingStatement); } superInfo.pop(); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 88a7f1545..6a2709c74 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -2,10 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { importLuaLibFeature, LuaLibFeature } from "../../../utils/lualib"; +import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; import { getExtendedType, isStaticNode } from "../utils"; +import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); @@ -31,19 +32,12 @@ export function transformAccessorDeclarations( descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); } - importLuaLibFeature(context, LuaLibFeature.Descriptors); - const call = isStaticNode(firstAccessor) - ? lua.createCallExpression(lua.createIdentifier("__TS__ObjectDefineProperty"), [ - lua.cloneIdentifier(className), - propertyName, - descriptor, - ]) - : lua.createCallExpression(lua.createIdentifier("__TS__SetDescriptor"), [ - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - propertyName, - descriptor, - ]); - + const isStatic = isStaticNode(firstAccessor); + const target = isStatic ? lua.cloneIdentifier(className) : createPrototypeName(className); + const feature = isStatic ? LuaLibFeature.ObjectDefineProperty : LuaLibFeature.SetDescriptor; + const parameters: lua.Expression[] = [target, propertyName, descriptor]; + if (!isStatic) parameters.push(lua.createBooleanLiteral(true)); + const call = transformLuaLibFunction(context, feature, undefined, ...parameters); return lua.createExpressionStatement(call); } diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 571c1022c..49329ed12 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -7,11 +7,12 @@ import { transformFunctionBodyHeader, transformFunctionBodyContent, transformPar import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; +export function createPrototypeName(className: lua.Identifier): lua.TableIndexExpression { + return lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); +} + export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { - return lua.createTableIndexExpression( - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - lua.createStringLiteral("____constructor") - ); + return lua.createTableIndexExpression(createPrototypeName(className), lua.createStringLiteral("____constructor")); } export function transformConstructorDeclaration( diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 9117c1519..0237a9f4d 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -4,6 +4,26 @@ import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformPropertyName } from "../../literal"; import { isGetAccessorOverride } from "./accessors"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { transformMemberExpressionOwnerName } from "./method"; + +export function createPropertyDecoratingExpression( + context: TransformationContext, + node: ts.PropertyDeclaration | ts.AccessorDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Expression | undefined { + if (!node.decorators) return; + const propertyName = transformPropertyName(context, node.name); + const propertyOwnerTable = transformMemberExpressionOwnerName(node, className, noPrototype); + return createDecoratingExpression( + context, + node.kind, + node.decorators.map(d => transformDecoratorExpression(context, d)), + propertyOwnerTable, + propertyName + ); +} export function transformClassInstanceFields( context: TransformationContext, @@ -49,3 +69,15 @@ export function transformClassInstanceFields( return statements; } + +export function transformStaticPropertyDeclaration( + context: TransformationContext, + field: ts.PropertyDeclaration, + className: lua.Identifier +): lua.AssignmentStatement | undefined { + if (!field.initializer) return; + const fieldName = transformPropertyName(context, field.name); + const value = context.transformExpression(field.initializer); + const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); + return lua.createAssignmentStatement(classField, value); +} diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 6f6df45b0..24cd77f44 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -4,6 +4,26 @@ import { TransformationContext } from "../../../context"; import { transformFunctionToExpression } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { createPrototypeName } from "./constructor"; +import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; +import { isNonNull } from "../../../../utils"; + +export function transformMemberExpressionOwnerName( + node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Expression { + return isStaticNode(node) || noPrototype ? lua.cloneIdentifier(className) : createPrototypeName(className); +} + +export function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression { + const methodName = transformPropertyName(context, node.name); + if (lua.isStringLiteral(methodName) && methodName.value === "toString") { + return lua.createStringLiteral("__tostring", node.name); + } + return methodName; +} export function transformMethodDeclaration( context: TransformationContext, @@ -12,20 +32,10 @@ export function transformMethodDeclaration( noPrototype: boolean ): lua.Statement | undefined { // Don't transform methods without body (overload declarations) - if (!node.body) { - return undefined; - } - - const methodTable = - isStaticNode(node) || noPrototype - ? lua.cloneIdentifier(className) - : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); - - let methodName = transformPropertyName(context, node.name); - if (lua.isStringLiteral(methodName) && methodName.value === "toString") { - methodName = lua.createStringLiteral("__tostring", node.name); - } + if (!node.body) return; + const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); return lua.createAssignmentStatement( @@ -34,3 +44,40 @@ export function transformMethodDeclaration( node ); } + +export function createMethodDecoratingExpression( + context: TransformationContext, + node: ts.MethodDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Statement | undefined { + const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodName = transformMethodName(context, node); + + const parameterDecorators = node.parameters + .flatMap((parameter, index) => + parameter.decorators?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) + ) + ) + .filter(isNonNull); + + const methodDecorators = node.decorators?.map(d => transformDecoratorExpression(context, d)) ?? []; + + if (methodDecorators.length > 0 || parameterDecorators.length > 0) { + const decorateMethod = createDecoratingExpression( + context, + node.kind, + [...methodDecorators, ...parameterDecorators], + methodTable, + methodName + ); + return lua.createExpressionStatement(decorateMethod); + } +} diff --git a/src/transformation/visitors/delete.ts b/src/transformation/visitors/delete.ts index 34e378be8..39bbf1d57 100644 --- a/src/transformation/visitors/delete.ts +++ b/src/transformation/visitors/delete.ts @@ -1,25 +1,35 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { cast } from "../../utils"; -import { FunctionVisitor, TransformationContext } from "../context"; -import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; +import { FunctionVisitor } from "../context"; +import { transformLuaLibFunction, LuaLibFeature } from "../utils/lualib"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { isArrayType, isNumberType } from "../utils/typescript"; +import { addToNumericExpression } from "../utils/lua-ast"; export const transformDeleteExpression: FunctionVisitor = (node, context) => { - const lhs = cast(context.transformExpression(node.expression), lua.isAssignmentLeftHandSideExpression); - const assignment = lua.createAssignmentStatement(lhs, lua.createNilLiteral(), node); - return createImmediatelyInvokedFunctionExpression([assignment], [lua.createBooleanLiteral(true)], node); -}; + let ownerExpression: lua.Expression | undefined; + let propertyExpression: lua.Expression | undefined; + + if (ts.isPropertyAccessExpression(node.expression)) { + if (ts.isPrivateIdentifier(node.expression.name)) throw new Error("PrivateIdentifier is not supported"); + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = lua.createStringLiteral(node.expression.name.text); + } else if (ts.isElementAccessExpression(node.expression)) { + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = context.transformExpression(node.expression.argumentExpression); -export function transformDeleteExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - if (ts.isDeleteExpression(expression)) { - return lua.createAssignmentStatement( - cast(context.transformExpression(expression.expression), lua.isAssignmentLeftHandSideExpression), - lua.createNilLiteral(), - expression - ); + const type = context.checker.getTypeAtLocation(node.expression.expression); + const argumentType = context.checker.getTypeAtLocation(node.expression.argumentExpression); + + if (isArrayType(context, type) && isNumberType(context, argumentType)) { + propertyExpression = addToNumericExpression(propertyExpression, 1); + } } -} + + if (!ownerExpression || !propertyExpression) { + context.diagnostics.push(unsupportedProperty(node, "delete", ts.SyntaxKind[node.kind])); + return lua.createNilLiteral(); + } + + return transformLuaLibFunction(context, LuaLibFeature.Delete, node, ownerExpression, propertyExpression); +}; diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 0b338be6f..890695be0 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { transformDeleteExpressionStatement } from "./delete"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -22,11 +21,6 @@ export const transformExpressionStatement: FunctionVisitor { `.expectToMatchJsResult(); }); - test("returns true when element exists", () => { + test("returns true when deletion attempt was allowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[2]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + const success = delete array[2]; + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); - test("returns false when element not exists", () => { + test("returns false when deletion attempt was disallowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[4]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + Object.defineProperty(array, 2, { configurable: false }); + + let success; + try { + success = delete array[2]; + } catch { + success = "error"; + } + + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); }); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index b4866d2e7..cc7e380d6 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -121,3 +121,93 @@ describe(".hasOwnProperty()", () => { `.expectToMatchJsResult(); }); }); + +const trueFalseTests = [[true], [false]] as const; + +describe("Object.defineProperty", () => { + test.each(trueFalseTests)("writable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { writable: ${value} }); + let error = false; + try { + foo.bar = false; + } catch { + error = true; + } + return { foobar: foo.bar, error }; + `.expectToMatchJsResult(); + }); + + test.each(trueFalseTests)("configurable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { configurable: ${value} }); + try { delete foo.bar } catch {}; + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("defines a new property", () => { + util.testFunction` + const foo: any = {}; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("overwrites an existing property", () => { + util.testFunction` + const foo = { bar: false }; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("default descriptor", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); + + test.each([ + ["{ value: true, get: () => true }"], + ["{ value: true, set: value => {} }"], + ["{ writable: true, get: () => true }"], + ])("invalid descriptor (%p)", props => { + util.testFunction` + const foo: any = {}; + let err = false; + + try { + Object.defineProperty(foo, "bar", ${props}); + } catch { + err = true; + } + + return { prop: foo.bar, err }; + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptor", () => { + test("descriptor is exactly the same as the last one set", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptors", () => { + test("all descriptors match", () => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptors(foo); + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index cba245c1f..dadb73655 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -126,3 +126,61 @@ test("Exported class decorator", () => { .setReturnExport("Foo", "bar") .expectToMatchJsResult(); }); + +test.each([ + ["@decorator method() {}"], + ["@decorator property;"], + ["@decorator propertyWithInitializer = () => {};"], + ["@decorator ['evaluated property'];"], + ["@decorator get getter() { return 5 }"], + ["@decorator set setter(value) {}"], + ["@decorator static method() {}"], + ["@decorator static property;"], + ["@decorator static propertyWithInitializer = () => {}"], + ["@decorator static get getter() { return 5 }"], + ["@decorator static set setter(value) {}"], + ["@decorator static ['evaluated property'];"], + ["method(@decorator a) {}"], + ["static method(@decorator a) {}"], +])("Decorate class member (%p)", classMember => { + util.testFunction` + let decoratorParameters: any; + + const decorator = (target, key, index?) => { + const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; + decoratorParameters = { targetKind, key, index: typeof index }; + }; + + class Foo { + ${classMember} + } + + return decoratorParameters; + `.expectToMatchJsResult(); +}); + +describe("Decorators /w descriptors", () => { + test.each([ + ["return { writable: true }", "return { configurable: true }"], + ["desc.writable = true", "return { configurable: true }"], + ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { + util.testFunction` + const A = (target, key, desc): any => { ${decorateA} }; + const B = (target, key, desc): any => { ${decorateB} }; + class Foo { @A @B static method() {} } + const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); + return rest; + `.expectToMatchJsResult(); + }); + + test.each(["return { value: true }", "desc.value = true"])( + "Use decorator to override method value", + overrideStatement => { + util.testFunction` + const decorator = (target, key, desc): any => { ${overrideStatement} }; + class Foo { @decorator static method() {} } + return Foo.method; + `.expectToMatchJsResult(); + } + ); +}); From b1eb04141da93263d80a8bb762f4dfc1b6d2b207 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 18 Oct 2020 18:57:33 +0500 Subject: [PATCH 09/91] Shebang support (#924) --- src/LuaAST.ts | 26 ++++++++++++++++++ src/LuaPrinter.ts | 32 +++++++++-------------- src/transformation/context/visitors.ts | 2 +- src/transformation/index.ts | 22 +++------------- src/transformation/visitors/sourceFile.ts | 4 ++- src/transpilation/transpile.ts | 10 +++---- src/transpilation/utils.ts | 2 +- test/unit/__snapshots__/file.spec.ts.snap | 11 ++++++++ test/unit/file.spec.ts | 27 +++++++++++++++++++ test/unit/json.spec.ts | 11 -------- 10 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 test/unit/__snapshots__/file.spec.ts.snap create mode 100644 test/unit/file.spec.ts delete mode 100644 test/unit/json.spec.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 99af02718..8efb23817 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,9 +5,11 @@ // because we don't create the AST from text import * as ts from "typescript"; +import { LuaLibFeature } from "./transformation/utils/lualib"; import { castArray } from "./utils"; export enum SyntaxKind { + File, Block, // Statements @@ -186,6 +188,30 @@ export function getOriginalPos(node: Node): TextRange { return { line: node.line, column: node.column }; } +export interface File extends Node { + kind: SyntaxKind.File; + statements: Statement[]; + luaLibFeatures: Set; + trivia: string; +} + +export function isFile(node: Node): node is File { + return node.kind === SyntaxKind.File; +} + +export function createFile( + statements: Statement[], + luaLibFeatures: Set, + trivia: string, + tsOriginal?: ts.Node +): File { + const file = createNode(SyntaxKind.File, tsOriginal) as File; + file.statements = statements; + file.luaLibFeatures = luaLibFeatures; + file.trivia = trivia; + return file; +} + export interface Block extends Node { kind: SyntaxKind.Block; statements: Statement[]; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 63654c595..a021ae7d5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -6,7 +6,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, trimExtension, normalizeSlashes } from "./utils"; +import { intersperse, normalizeSlashes, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -71,13 +71,7 @@ function isSimpleExpression(expression: lua.Expression): boolean { type SourceChunk = string | SourceNode; -export type Printer = ( - program: ts.Program, - emitHost: EmitHost, - fileName: string, - block: lua.Block, - luaLibFeatures: Set -) => PrintResult; +export type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, file: lua.File) => PrintResult; export interface PrintResult { code: string; @@ -87,7 +81,7 @@ export interface PrintResult { export function createPrinter(printers: Printer[]): Printer { if (printers.length === 0) { - return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args); + return (program, emitHost, fileName, file) => new LuaPrinter(emitHost, program, fileName).print(file); } else if (printers.length === 1) { return printers[0]; } else { @@ -148,17 +142,17 @@ export class LuaPrinter { } } - public print(block: lua.Block, luaLibFeatures: Set): PrintResult { + public print(file: lua.File): PrintResult { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { - luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); + file.luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); } const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" : ""; - const rootSourceNode = this.printImplementation(block, luaLibFeatures); + const rootSourceNode = this.printFile(file); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); let code = rootSourceNode.toString(); @@ -203,8 +197,8 @@ export class LuaPrinter { return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printImplementation(block: lua.Block, luaLibFeatures: Set): SourceNode { - let header = ""; + private printFile(file: lua.File): SourceNode { + let header = file.trivia; if (!this.options.noHeader) { header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; @@ -213,23 +207,21 @@ export class LuaPrinter { const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if ( luaLibImport === LuaLibImportKind.Always || - (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) + (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) ) { // Require lualib bundle header += 'require("lualib_bundle");\n'; - } else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { + } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features header += "-- Lua Library inline imports\n"; - header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); + header += loadLuaLibFeatures(file.luaLibFeatures, this.emitHost); } if (this.options.sourceMapTraceback) { header += "{#SourceMapTraceback}\n"; } - const fileBlockNode = this.printBlock(block); - - return this.concatNodes(header, fileBlockNode); + return this.concatNodes(header, ...this.printStatementArray(file.statements)); } protected pushIndent(): void { diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index 5967c18b4..df7cd7acb 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -143,7 +143,7 @@ export type VisitorResult = T extends ExpressionLikeNode : T extends StatementLikeNode ? OneToManyVisitorResult : T extends ts.SourceFile - ? lua.Block + ? lua.File : OneToManyVisitorResult; export type Visitor = FunctionVisitor | ObjectVisitor; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 69b098811..5b6fca647 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -1,9 +1,7 @@ import * as ts from "typescript"; import * as lua from "../LuaAST"; -import { LuaLibFeature } from "../LuaLib"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; -import { getUsedLuaLibFeatures } from "./utils/lualib"; import { standardVisitors } from "./visitors"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { @@ -29,23 +27,9 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { return visitorMap; } -export interface TransformSourceFileResult { - luaAst: lua.Block; - luaLibFeatures: Set; - diagnostics: ts.Diagnostic[]; -} - -export function transformSourceFile( - program: ts.Program, - sourceFile: ts.SourceFile, - visitorMap: VisitorMap -): TransformSourceFileResult { +export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { const context = new TransformationContext(program, sourceFile, visitorMap); - const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; + const [file] = context.transformNode(sourceFile) as [lua.File]; - return { - luaAst, - luaLibFeatures: getUsedLuaLibFeatures(context), - diagnostics: context.diagnostics, - }; + return { file, diagnostics: context.diagnostics }; } diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 539c9f9d7..604aa0c7e 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; import { createExportsIdentifier } from "../utils/lua-ast"; +import { getUsedLuaLibFeatures } from "../utils/lualib"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; @@ -39,5 +40,6 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } } - return lua.createBlock(statements, node); + const trivia = node.getFullText().match(/^#!.*\r?\n/)?.[0] ?? ""; + return lua.createFile(statements, getUsedLuaLibFeatures(context), trivia, node); }; diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 01d9278c5..cbc77c13c 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -60,18 +60,14 @@ export function getProgramTranspileResult( const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { - const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformSourceFile( - program, - sourceFile, - visitorMap - ); + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { - const printResult = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures); + const printResult = printer(program, emitHost, sourceFile.fileName, file); const sourceRootDir = program.getCommonSourceDirectory(); const fileName = path.resolve(sourceRootDir, sourceFile.fileName); - transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst, ...printResult }); + transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst: file, ...printResult }); } }; diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 98c3f5cc6..099dfd400 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -21,7 +21,7 @@ interface BaseFile { export interface ProcessedFile extends BaseFile { fileName: string; - luaAst?: lua.Block; + luaAst?: lua.File; /** @internal */ sourceMapNode?: SourceNode; } diff --git a/test/unit/__snapshots__/file.spec.ts.snap b/test/unit/__snapshots__/file.spec.ts.snap new file mode 100644 index 000000000..12a004c6c --- /dev/null +++ b/test/unit/__snapshots__/file.spec.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`shebang CRLF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; + +exports[`shebang LF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; diff --git a/test/unit/file.spec.ts b/test/unit/file.spec.ts new file mode 100644 index 000000000..3a810dc60 --- /dev/null +++ b/test/unit/file.spec.ts @@ -0,0 +1,27 @@ +import * as util from "../util"; + +describe("JSON", () => { + test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { + util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); + }); + + test("empty file throws runtime error", () => { + util.testModule("") + .setMainFileName("main.json") + .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); + }); +}); + +describe("shebang", () => { + test("LF", () => { + util.testModule`#!/usr/bin/env lua\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); + + test("CRLF", () => { + util.testModule`#!/usr/bin/env lua\r\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); +}); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts deleted file mode 100644 index 2f4b0d6a5..000000000 --- a/test/unit/json.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as util from "../util"; - -test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { - util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); -}); - -test("Empty JSON file error", () => { - util.testModule("") - .setMainFileName("main.json") - .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); -}); From ccf95d75b1ee4baa83af77cc717d9ef98c356e2b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 18 Oct 2020 16:21:59 +0200 Subject: [PATCH 10/91] 0.36.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa1a4185c..dbe13db2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.35.0", + "version": "0.36.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a149df59c..a2623d785 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.35.0", + "version": "0.36.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From d9878951320358b50942f9266d4b5b3c3a4e169c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 18 Oct 2020 16:47:15 +0200 Subject: [PATCH 11/91] CHANGELOG.md 0.36.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25033b16f..64ef0e7c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.36.0 + +- Upgraded to TypeScript 4.0. +- Added support for `parseInt` and `parseFloat`. +- Added support for `yield*` [for generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*). +- Added support for [method, property and accessor decorators](https://www.typescriptlang.org/docs/handbook/decorators.html). +- Shebangs at the top of a .ts file will now be preserved. +- Fixed an issue causing declarations referencing their own identifier to cause a nil reference error. + ## 0.35.0 - In preparation for some new features, some public APIs have been changed: From ea748a3eceb5fb86ebd87d911045a08a6546f935 Mon Sep 17 00:00:00 2001 From: Justin Walsh Date: Wed, 21 Oct 2020 11:00:58 -0700 Subject: [PATCH 12/91] Add test for argument passing in plugin config (#931) --- src/CompilerOptions.ts | 1 + test/transpile/plugins/arguments.ts | 28 ++++++++++++++++++++++++++ test/transpile/plugins/plugins.spec.ts | 8 ++++++++ 3 files changed, 37 insertions(+) create mode 100644 test/transpile/plugins/arguments.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 2e78b2b87..889a5837a 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -21,6 +21,7 @@ export interface TransformerImport { export interface LuaPluginImport { name: string; import?: string; + [option: string]: any; } export type CompilerOptions = OmitIndexSignature & { diff --git a/test/transpile/plugins/arguments.ts b/test/transpile/plugins/arguments.ts new file mode 100644 index 000000000..f6aa2ba6e --- /dev/null +++ b/test/transpile/plugins/arguments.ts @@ -0,0 +1,28 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +interface Options { + name: string; + option: boolean; +} + +// eslint-disable-next-line import/no-default-export +export default function plugin(options: Options): tstl.Plugin { + return { + visitors: { + [ts.SyntaxKind.ReturnStatement]: () => + tstl.createReturnStatement([ + tstl.createTableExpression([ + tstl.createTableFieldExpression( + tstl.createStringLiteral(options.name), + tstl.createStringLiteral("name") + ), + tstl.createTableFieldExpression( + tstl.createBooleanLiteral(options.option), + tstl.createStringLiteral("option") + ), + ]), + ]), + }, + }; +} diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index ce2ebc7a6..e78cc4201 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -22,3 +22,11 @@ test("visitor using super", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "visitor-super.ts") }] }) .expectToEqual("bar"); }); + +test("passing arguments", () => { + util.testFunction` + return {}; + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "arguments.ts"), option: true }] }) + .expectToEqual({ name: path.join(__dirname, "arguments.ts"), option: true }); +}); From dae7abab3f9f3225a4c504492cf961fbc760436f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 21 Oct 2020 20:01:36 +0200 Subject: [PATCH 13/91] Get benchmark data to visualizer (#878) * Try zlibbing output data * Try with lz-string * Explicitly install lz-string * Another try with regular zlib * Use deflateSync now * Try without extra dependencies * Once more, with dollarsign * Output raw results instead of processed table * Fix run script * reverted package-lock * Add link to visualizer to benchmark result * prettier fix * Removed forgotten comment from benchmarking CI --- .github/workflows/ci.yml | 10 +++++++--- benchmark/src/run.ts | 11 +++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cff50e60..d8ac390a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,8 +61,7 @@ jobs: node-version: 12.13.1 # NPM - name: NPM master - # TODO Lua types is only added manually to test the benchmark PR this can be removed again once the PR is merged - run: npm ci && npm run build && npm install -D lua-types + run: npm ci && npm run build working-directory: master - name: NPM commit run: npm ci && npm run build @@ -112,7 +111,12 @@ jobs: const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); - const summary = `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; + const zlib = require('zlib'); + const buffer = Buffer.from(core.getInput('benchmark-info-lua', { required: true })); + const compressed = zlib.deflateSync(buffer); + + const summary = `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString('base64')})\n` + + `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index c632efe39..22e4ec70c 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -27,11 +27,8 @@ function benchmark(): void { oldBenchmarkResults = json.decode(oldBenchmarkData) as BenchmarkResult[]; } - // Compare results - const comparisonInfo = compareBenchmarks(oldBenchmarkResults, newBenchmarkResults); - // Output comparison info - outputBenchmarkData(comparisonInfo, newBenchmarkResults); + outputBenchmarkData(oldBenchmarkResults, newBenchmarkResults); } benchmark(); @@ -44,12 +41,14 @@ function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkR return { summary: memoryComparisonInfo.summary, text: memoryComparisonInfo.text }; } -function outputBenchmarkData(comparisonInfo: { summary: string; text: string }, newResults: BenchmarkResult[]): void { +function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { if (!arg[2]) { // Output to stdout as json by default, this is used by the CI to retrieve the info - print(json.encode(comparisonInfo)); + print(json.encode({ old: oldResults, new: newResults })); } else { // Output to file as markdown if arg[2] is set, this is useful for local development + // Compare results + const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); } From 86cc1b965971f2a967364866656ce7e7ae633418 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 21 Oct 2020 23:09:58 +0500 Subject: [PATCH 14/91] Remove class field/accessor compatibility code (#929) --- src/transformation/visitors/class/index.ts | 9 +-- .../visitors/class/members/accessors.ts | 69 +------------------ .../visitors/class/members/constructor.ts | 4 +- .../visitors/class/members/fields.ts | 22 ------ 4 files changed, 7 insertions(+), 97 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index d70095bff..9142775f7 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -29,7 +29,7 @@ import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; -import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; +import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; import { createPropertyDecoratingExpression, @@ -238,15 +238,12 @@ function transformClassLikeDeclaration( ); if (constructorResult) result.push(constructorResult); - } else if ( - instanceFields.length > 0 || - classDeclaration.members.some(m => isGetAccessorOverride(context, m, classDeclaration)) - ) { + } else if (instanceFields.length > 0) { // Generate a constructor if none was defined in a class with instance fields that need initialization // localClassName.prototype.____constructor = function(self, ...) // baseClassName.prototype.____constructor(self, ...) // ... - const constructorBody = transformClassInstanceFields(context, classDeclaration, instanceFields); + const constructorBody = transformClassInstanceFields(context, instanceFields); const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 6a2709c74..f774b9645 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -2,10 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; +import { LuaLibFeature, transformLuaLibFunction } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; -import { getExtendedType, isStaticNode } from "../utils"; +import { isStaticNode } from "../utils"; import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { @@ -40,68 +40,3 @@ export function transformAccessorDeclarations( const call = transformLuaLibFunction(context, feature, undefined, ...parameters); return lua.createExpressionStatement(call); } - -function* classWithAncestors( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase -): Generator { - yield classDeclaration; - - const extendsType = getExtendedType(context, classDeclaration); - if (!extendsType) { - return false; - } - - const symbol = extendsType.getSymbol(); - if (symbol === undefined) { - return false; - } - - const symbolDeclarations = symbol.getDeclarations(); - if (symbolDeclarations === undefined) { - return false; - } - - const declaration = symbolDeclarations.find(ts.isClassLike); - if (!declaration) { - return false; - } - - yield* classWithAncestors(context, declaration); -} - -export const hasMemberInClassOrAncestor = ( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase, - callback: (m: ts.ClassElement) => boolean -) => [...classWithAncestors(context, classDeclaration)].some(c => c.members.some(callback)); - -function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { - if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { - return propertyName.text; - } else { - return undefined; // TODO: how to handle computed property names? - } -} - -function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { - const aName = getPropertyName(a); - const bName = getPropertyName(b); - return aName !== undefined && aName === bName; -} - -export function isGetAccessorOverride( - context: TransformationContext, - element: ts.ClassElement, - classDeclaration: ts.ClassLikeDeclarationBase -): element is ts.GetAccessorDeclaration { - if (!ts.isGetAccessor(element) || isStaticNode(element)) { - return false; - } - - return hasMemberInClassOrAncestor( - context, - classDeclaration, - m => ts.isPropertyDeclaration(m) && m.initializer !== undefined && isSamePropertyName(m.name, element.name) - ); -} diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 49329ed12..11766d2a8 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -3,7 +3,7 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; -import { transformFunctionBodyHeader, transformFunctionBodyContent, transformParameters } from "../../function"; +import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; @@ -43,7 +43,7 @@ export function transformConstructorDeclaration( // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - const classInstanceFields = transformClassInstanceFields(context, classDeclaration, instanceFields); + const classInstanceFields = transformClassInstanceFields(context, instanceFields); // If there are field initializers and the first statement is a super call, // move super call between default assignments and initializers diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 0237a9f4d..5d07033dd 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -3,7 +3,6 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformPropertyName } from "../../literal"; -import { isGetAccessorOverride } from "./accessors"; import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; import { transformMemberExpressionOwnerName } from "./method"; @@ -27,7 +26,6 @@ export function createPropertyDecoratingExpression( export function transformClassInstanceFields( context: TransformationContext, - classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): lua.Statement[] { const statements: lua.Statement[] = []; @@ -47,26 +45,6 @@ export function transformClassInstanceFields( statements.push(assignClassField); } - // TODO: Remove when `useDefineForClassFields` would be `true` by default - - const getOverrides = classDeclaration.members.filter((m): m is ts.GetAccessorDeclaration => - isGetAccessorOverride(context, m, classDeclaration) - ); - - for (const getter of getOverrides) { - const getterName = transformPropertyName(context, getter.name); - - const resetGetter = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("rawset"), [ - createSelfIdentifier(), - getterName, - lua.createNilLiteral(), - ]), - classDeclaration.members.find(ts.isConstructorDeclaration) ?? classDeclaration - ); - statements.push(resetGetter); - } - return statements; } From 54569aac73c553e86a03b47a0fc755e9c83d3927 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 23 Nov 2020 20:59:52 +0100 Subject: [PATCH 15/91] Fixed various benchmark issues (#935) * Fixed various benchmark issues Benchmarks now hopefully work for pull requests from a fork Fixed comparison info not beeing emmitted correctly after #878 Bump actions/github-script from 0.9.0 to v3 Moved create benchmark check script to standalone js file * Formatting & Adjusted script path * Pass core to the js file * Output markdown directly to CLI instead of creating an actions check * Fixed github-script usage * Fixed visualizer data passing * Linting :) * Return benchmark info from github-script * Fixed glow flags * Update name of final step * Update .github/workflows/ci.yml Co-authored-by: ark120202 Co-authored-by: ark120202 --- .github/scripts/create_benchmark_check.js | 22 + .github/workflows/ci.yml | 52 +- benchmark/src/run.ts | 22 +- package-lock.json | 11616 +++++++++++++++++++- package.json | 2 +- 5 files changed, 11665 insertions(+), 49 deletions(-) create mode 100644 .github/scripts/create_benchmark_check.js diff --git a/.github/scripts/create_benchmark_check.js b/.github/scripts/create_benchmark_check.js new file mode 100644 index 000000000..e1d303e06 --- /dev/null +++ b/.github/scripts/create_benchmark_check.js @@ -0,0 +1,22 @@ +module.exports = ({ github, context, core }) => { + const fs = require("fs"); + + const benchmarkResultPathLua = core.getInput("benchmark-result-path-lua", { required: true }); + const benchmarkInfoLua = JSON.parse(fs.readFileSync(benchmarkResultPathLua)); + + const benchmarkResultPathJIT = core.getInput("benchmark-result-path-jit", { required: true }); + const benchmarkInfoJIT = JSON.parse(fs.readFileSync(benchmarkResultPathJIT)); + + // Remove Comparison info to save some bytes + const benchmarkInfoForVizLua = { old: benchmarkInfoLua.old, new: benchmarkInfoLua.new }; + const buffer = Buffer.from(JSON.stringify(benchmarkInfoForVizLua)); + + const zlib = require("zlib"); + const compressed = zlib.deflateSync(buffer); + + const summary = + `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString("base64")})\n` + + `### Lua5.3\n${benchmarkInfoLua.comparison.summary}\n### LuaJIT\n${benchmarkInfoJIT.comparison.summary}`; + + return summary; +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8ac390a1..13df095ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,8 @@ jobs: steps: - name: Lua Install run: sudo apt-get install lua5.3 luajit + - name: Glow Install + run: brew install glow # Checkout master & commit - name: Checkout master uses: actions/checkout@v2 @@ -93,50 +95,24 @@ jobs: working-directory: commit/benchmark - name: Run benchmark Lua 5.3 commit id: benchmark-lua-commit - run: echo ::set-output name=info::`lua5.3 -- run.lua ../data/benchmark_commit_53.json ../data/benchmark_master_53.json` + run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json working-directory: commit/benchmark/dist - name: Build benchmark LuaJIT commit run: node ../dist/tstl.js -p tsconfig.jit.json working-directory: commit/benchmark - name: Run benchmark LuaJIT commit id: benchmark-jit-commit - run: echo ::set-output name=info::`luajit -- run.lua ../data/benchmark_commit_jit.json ../data/benchmark_master_jit.json` + run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json working-directory: commit/benchmark/dist - - name: Create benchmark check - uses: actions/github-script@0.9.0 + - name: Combine benchmark results + id: script-combine-results + uses: actions/github-script@v3 with: - benchmark-info-lua: ${{steps.benchmark-lua-commit.outputs.info}} - benchmark-info-jit: ${{steps.benchmark-jit-commit.outputs.info}} + benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json + benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json + result-encoding: string script: | - const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); - const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); - - const zlib = require('zlib'); - const buffer = Buffer.from(core.getInput('benchmark-info-lua', { required: true })); - const compressed = zlib.deflateSync(buffer); - - const summary = `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString('base64')})\n` - + `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; - - const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; - - const pull_request = context.payload.pull_request; - if (!pull_request || pull_request.head.repo.url === pull_request.base.repo.url) { - // This only works if not in a fork. - github.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: "Benchmark results", - head_sha: context.sha, - status: "completed", - conclusion: "neutral", - output: { - title: "Benchmark results", - summary: summary, - text: text - } - }); - } else { - console.log(summary); - console.log(text); - } + const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); + return createBenchmarkCheck({ github, context, core }); + - name: Benchmark results + run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index 22e4ec70c..b880537e5 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -42,19 +42,23 @@ function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkR } function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { - if (!arg[2]) { - // Output to stdout as json by default, this is used by the CI to retrieve the info - print(json.encode({ old: oldResults, new: newResults })); - } else { + // Output benchmark results to json + if (arg[0]) { + if (arg[1]) { + // if baseline is provide output full comparison info + const comparisonInfo = compareBenchmarks(oldResults, newResults); + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode({ old: oldResults, new: newResults, comparison: comparisonInfo })); + } else { + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode(newResults)); + } + } + if (arg[2]) { // Output to file as markdown if arg[2] is set, this is useful for local development // Compare results const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); } - // Output benchmark results to json - if (arg[0]) { - const jsonDataFile = io.open(arg[0], "w+")[0]!; - jsonDataFile.write(json.encode(newResults)); - } } diff --git a/package-lock.json b/package-lock.json index dbe13db2e..73ebb5214 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,11622 @@ { "name": "typescript-to-lua", "version": "0.36.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "typescript-to-lua", + "version": "0.36.0", + "license": "MIT", + "dependencies": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": ">=4.0.2" + }, + "bin": { + "tstl": "dist/tstl.js" + }, + "devDependencies": { + "@types/fs-extra": "^8.1.0", + "@types/glob": "^7.1.1", + "@types/jest": "^25.1.3", + "@types/node": "^13.7.7", + "@types/resolve": "1.14.0", + "@typescript-eslint/eslint-plugin": "^2.31.0", + "@typescript-eslint/parser": "^4.1.0", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jest": "^23.8.2", + "fengari": "^0.1.4", + "fs-extra": "^8.1.0", + "javascript-stringify": "^2.0.1", + "jest": "^26.0.1", + "jest-circus": "^25.1.0", + "lua-types": "^2.8.0", + "prettier": "^2.0.5", + "ts-jest": "^26.3.0", + "ts-node": "^8.6.2" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.8.3" + } + }, + "node_modules/@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "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_modules/@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.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=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", + "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", + "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "dependencies": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "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, + "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/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/core": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", + "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/reporters": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.0.1", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-resolve-dependencies": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "jest-watcher": "^26.0.1", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/core/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@jest/core/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/globals": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", + "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/types": "^26.0.1", + "expect": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/globals/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", + "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "node-notifier": "^7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/source-map": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", + "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/source-map/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", + "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/test-sequencer/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/test-sequencer/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/transform": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", + "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.0.1", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.0.1", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/transform/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", + "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", + "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", + "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "node_modules/@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "dependencies": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", + "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "dev": true, + "dependencies": { + "jest-diff": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", + "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", + "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "2.31.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/experimental-utils": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", + "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.23.0", + "eslint-scope": "^5.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", + "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.1.0", + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/typescript-estree": "4.1.0", + "debug": "^4.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", + "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", + "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", + "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", + "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", + "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "node_modules/acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", + "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "dev": true, + "dependencies": { + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", + "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-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" + } + }, + "node_modules/babel-preset-jest": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", + "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^26.0.0", + "babel-preset-current-node-syntax": "^0.1.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "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/eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "node_modules/eslint-import-resolver-node/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-import-resolver-node/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-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/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-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/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-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "dependencies": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=4" + } + }, + "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": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-jest": { + "version": "23.8.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", + "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/eslint/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/eslint/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/eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fengari": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", + "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", + "dev": true, + "dependencies": { + "readline-sync": "^1.4.9", + "sprintf-js": "^1.1.1", + "tmp": "^0.0.33" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-extra/node_modules/graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "dependencies": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-stringify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", + "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", + "dev": true + }, + "node_modules/jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", + "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "dev": true, + "dependencies": { + "@jest/core": "^26.0.1", + "import-local": "^3.0.2", + "jest-cli": "^26.0.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", + "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-changed-files/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", + "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-changed-files/node_modules/get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-circus": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", + "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", + "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.0.1", + "@jest/types": "^26.0.1", + "babel-jest": "^26.0.1", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.0.1", + "jest-environment-node": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "micromatch": "^4.0.2", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-config/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-diff": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", + "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1", + "jsdom": "^16.2.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-node": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", + "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-node/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-environment-node/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-haste-map": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", + "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.0.0", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-haste-map/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-haste-map/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-haste-map/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-jasmine2": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", + "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.0.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.0.1", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-each": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", + "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-jasmine2/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-jasmine2/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-leak-detector": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", + "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", + "dev": true, + "dependencies": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", + "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runner": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", + "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.0.1", + "jest-jasmine2": "^26.0.1", + "jest-leak-detector": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runner/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runner/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", + "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/globals": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runtime/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-serializer": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", + "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-serializer/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-util/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", + "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.0.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watcher/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest/node_modules/jest-cli": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", + "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "dev": true, + "dependencies": { + "@jest/core": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", + "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.0.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "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 + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/lua-types": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", + "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-notifier": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "dev": true, + "optional": true, + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^7.2.1", + "shellwords": "^0.1.1", + "uuid": "^7.0.3", + "which": "^2.0.2" + } + }, + "node_modules/node-notifier/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-notifier/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "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/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "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/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/readline-sync": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", + "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "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" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-jest": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", + "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", + "dev": true, + "dependencies": { + "@types/jest": "26.x", + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "26.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "18.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/ts-jest/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/@types/jest": { + "version": "26.0.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", + "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "dev": true, + "dependencies": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "node_modules/ts-jest/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/ts-jest/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/jest-util": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.3.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-script": "dist/script.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.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/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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": "8.x.x || >=10.10.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "dev": true, + "engines": { + "node": ">=8.3.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": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "node_modules/yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.8.3", diff --git a/package.json b/package.json index a2623d785..c56a3dc05 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "postversion": "git push && git push --tags" }, "bin": { - "tstl": "./dist/tstl.js" + "tstl": "dist/tstl.js" }, "engines": { "node": ">=12.13.0" From 0d61965aa8a0f166c56eb5cba9e2962f3e5c9f27 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sun, 13 Dec 2020 21:28:59 +1000 Subject: [PATCH 16/91] Fix spread bug #898 (#936) --- .../visitors/variable-declaration.ts | 40 ++++++++++++------- test/unit/destructuring.spec.ts | 2 + 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 12ffeb763..bec7548e5 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -36,14 +36,13 @@ export function transformBindingPattern( propertyAccessStack: ts.PropertyName[] = [] ): lua.Statement[] { const result: lua.Statement[] = []; - const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (const [index, element] of pattern.elements.entries()) { if (ts.isOmittedExpression(element)) continue; if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { // nested binding pattern - const propertyName = isObjectBindingPattern + const propertyName = ts.isObjectBindingPattern(pattern) ? element.propertyName : ts.createNumericLiteral(String(index + 1)); @@ -73,16 +72,29 @@ export function transformBindingPattern( continue; } - if (isObjectBindingPattern) { - const elements = pattern.elements as ts.NodeArray; - const usedProperties = elements.map(e => - lua.createTableFieldExpression( - lua.createBooleanLiteral(true), - lua.createStringLiteral( - ((e.propertyName ?? e.name) as ts.Identifier).text, - e.propertyName ?? e.name - ) - ) + if (ts.isObjectBindingPattern(pattern)) { + const excludedProperties: ts.Identifier[] = []; + + for (const element of pattern.elements) { + // const { ...x } = ...; + // ~~~~ + if (element.dotDotDotToken) continue; + + // const { x } = ...; + // ~ + if (ts.isIdentifier(element.name) && !element.propertyName) { + excludedProperties.push(element.name); + } + + // const { x: ... } = ...; + // ~~~~~~ + if (element.propertyName && element.name && ts.isIdentifier(element.propertyName)) { + excludedProperties.push(element.propertyName); + } + } + + const excludedPropertiesTable = excludedProperties.map(e => + lua.createTableFieldExpression(lua.createBooleanLiteral(true), lua.createStringLiteral(e.text, e)) ); expression = transformLuaLibFunction( @@ -90,7 +102,7 @@ export function transformBindingPattern( LuaLibFeature.ObjectRest, undefined, tableExpression, - lua.createTableExpression(usedProperties) + lua.createTableExpression(excludedPropertiesTable) ); } else { expression = transformLuaLibFunction( @@ -104,7 +116,7 @@ export function transformBindingPattern( } else { expression = lua.createTableIndexExpression( tableExpression, - isObjectBindingPattern ? propertyName : lua.createNumericLiteral(index + 1) + ts.isObjectBindingPattern(pattern) ? propertyName : lua.createNumericLiteral(index + 1) ); } diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 761930ec2..2ec12c7d1 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -12,6 +12,8 @@ const testCases = [ { binding: "{ ...rest }", value: {} }, { binding: "{ x, ...rest }", value: { x: "x" } }, { binding: "{ x, ...rest }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x, ...y }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x: y, ...z }", value: { x: "x", y: "y", z: "z" } }, { binding: "[]", value: [] }, { binding: "[x, y]", value: ["x", "y"] }, From a3bfc2dfce5782cb3bdb01bda1ac3831cc263942 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Tue, 15 Dec 2020 05:45:42 +1000 Subject: [PATCH 17/91] Fix export all bug and add NamespaceExport support (#937) * Fix export all bug #927 * Support NamespaceExport #928 * Update snapshots * Add unsafe Lua name NamespaceExport test * Add comments to transformExportAll and add export default if NamespaceExport --- src/transformation/visitors/modules/export.ts | 56 ++++++++++++++++--- .../__snapshots__/transformation.spec.ts.snap | 4 +- test/unit/modules/modules.spec.ts | 29 ++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 5e12c6c5e..0fa5d9ee4 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -36,7 +36,7 @@ export const transformExportAssignment: FunctionVisitor = ( } }; -function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { +function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { assert(node.moduleSpecifier); if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { @@ -44,26 +44,64 @@ function transformExportAllFrom(context: TransformationContext, node: ts.ExportD } const moduleRequire = createModuleRequire(context, node.moduleSpecifier); - const tempModuleIdentifier = lua.createIdentifier("____export"); + // export * as ns from "..."; + // exports.ns = require(...) + if (node.exportClause && ts.isNamespaceExport(node.exportClause)) { + const assignToExports = lua.createAssignmentStatement( + lua.createTableIndexExpression( + createExportsIdentifier(), + lua.createStringLiteral(node.exportClause.name.text) + ), + moduleRequire + ); + return assignToExports; + } + + // export * from "..."; + // exports all values EXCEPT "default" from "..." + const result: lua.Statement[] = []; + + // local ____export = require(...) + const tempModuleIdentifier = lua.createIdentifier("____export"); const declaration = lua.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + result.push(declaration); + // ____exports[____exportKey] = ____exportValue const forKey = lua.createIdentifier("____exportKey"); const forValue = lua.createIdentifier("____exportValue"); + const leftAssignment = lua.createAssignmentStatement( + lua.createTableIndexExpression(createExportsIdentifier(), forKey), + forValue + ); - const body = lua.createBlock([ - lua.createAssignmentStatement(lua.createTableIndexExpression(createExportsIdentifier(), forKey), forValue), - ]); + // if key ~= "default" then + // -- export the value, do not export "default" values + // end + const ifBody = lua.createBlock([leftAssignment]); + const ifStatement = lua.createIfStatement( + lua.createBinaryExpression( + lua.cloneIdentifier(forKey), + lua.createStringLiteral("default"), + lua.SyntaxKind.InequalityOperator + ), + ifBody + ); + // for ____exportKey, ____exportValue in ____export do + // -- export ____exportValue, unless ____exportKey is "default" + // end const pairsIdentifier = lua.createIdentifier("pairs"); const forIn = lua.createForInStatement( - body, + lua.createBlock([ifStatement]), [lua.cloneIdentifier(forKey), lua.cloneIdentifier(forValue)], [lua.createCallExpression(pairsIdentifier, [lua.cloneIdentifier(tempModuleIdentifier)])] ); + result.push(forIn); + // Wrap this in a DoStatement to prevent polluting the scope. - return lua.createDoStatement([declaration, forIn], node); + return lua.createDoStatement(result, node); } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => @@ -127,7 +165,7 @@ export const getExported = (context: TransformationContext, exportSpecifiers: ts export const transformExportDeclaration: FunctionVisitor = (node, context) => { if (!node.exportClause) { // export * from "..."; - return transformExportAllFrom(context, node); + return transformExportAll(context, node); } if (!context.resolver.isValueAliasDeclaration(node)) { @@ -136,7 +174,7 @@ export const transformExportDeclaration: FunctionVisitor = if (ts.isNamespaceExport(node.exportClause)) { // export * as ns from "..."; - throw new Error("NamespaceExport is not supported"); + return transformExportAll(context, node); } const exportSpecifiers = getExported(context, node.exportClause); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 942f17aa2..a299f2640 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -64,7 +64,9 @@ ____exports.uwv = xyz do local ____export = require(\\"xyz\\") for ____exportKey, ____exportValue in pairs(____export) do - ____exports[____exportKey] = ____exportValue + if ____exportKey ~= \\"default\\" then + ____exports[____exportKey] = ____exportValue + end end end do diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 885f24541..b6aefdc0c 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -275,3 +275,32 @@ test("export default function with future reference", () => { .setReturnExport("result") .expectToMatchJsResult(); }); + +const moduleFile = ` +export default true; +export const foo = "bar"; +`; + +test("export all does not include default", () => { + util.testBundle` + export * from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ foo: "bar" }); +}); + +test("namespace export does not include default", () => { + util.testBundle` + export * as result from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ result: { default: true, foo: "bar" } }); +}); + +test("namespace export with unsafe Lua name", () => { + util.testBundle` + export * as $$$ from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ $$$: { default: true, foo: "bar" } }); +}); From befc0c745b3886ba290a8f24ddc748fc9531f09e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Dec 2020 20:49:27 +0100 Subject: [PATCH 18/91] 0.36.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73ebb5214..85e431644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index c56a3dc05..16e3e20a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 5ced4c74ff5fada401a7a6f5e3672e2d6c19d40a Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 21 Dec 2020 21:51:27 +1000 Subject: [PATCH 19/91] Omit tostring from template literal spans if they are strings (#948) * Omit tostring from template literal spans if they are a definite string type * Add negative tests * Simplify and split templateLiteral tests --- src/transformation/visitors/template.ts | 8 +++++++- test/unit/templateLiterals.spec.ts | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 784cf7e4e..1b714d765 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; +import { isStringType } from "../utils/typescript/types"; import { transformArguments, transformContextualCallExpression } from "./call"; // TODO: Source positions @@ -25,7 +26,12 @@ export const transformTemplateExpression: FunctionVisitor for (const span of node.templateSpans) { const expression = context.transformExpression(span.expression); - parts.push(wrapInToStringForConcat(expression)); + const spanType = context.checker.getTypeAtLocation(span.expression); + if (isStringType(context, spanType)) { + parts.push(expression); + } else { + parts.push(wrapInToStringForConcat(expression)); + } const text = span.literal.text; if (text.length > 0) { diff --git a/test/unit/templateLiterals.spec.ts b/test/unit/templateLiterals.spec.ts index 7db192a88..d5dc519a5 100644 --- a/test/unit/templateLiterals.spec.ts +++ b/test/unit/templateLiterals.spec.ts @@ -60,3 +60,26 @@ test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`no `.expectToMatchJsResult(); } ); + +test.each(["number", "string | any"])("template span expect tostring for non string type (%p)", type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("tostring")) + .expectToMatchJsResult(); +}); + +test.each(["string", "'string literal type'", "string & unknown"])( + "template span expect no tostring for string-like type (%p)", + type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("tostring")) + .expectToMatchJsResult(); + } +); From 237a788354640a3f9e7141b067e22bcb1b0b8e23 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Dec 2020 15:32:15 +0100 Subject: [PATCH 20/91] Fixed incorrect variable declarations in some cases when there is no initializer (#952) --- src/transformation/utils/lua-ast.ts | 4 +++- test/unit/hoisting.spec.ts | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index b9b600c90..91e81bc9a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -176,7 +176,9 @@ export function createLocalOrExportedOrGlobalDeclaration( if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); - assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + if (rhs) { + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + } } else { declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 997c53f73..16172b410 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -254,3 +254,14 @@ test("Hoisting Shorthand Property", () => { return foo();`; expect(util.transpileAndExecute(code)).toBe("foobar"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944 +test("Hoisting variable without initializer", () => { + util.testFunction` + function foo() { + return x; + } + let x: number; + return foo(); + `.expectToMatchJsResult(); +}); From 3546f59d39555c539be6b1ff4281a5e89918c0c6 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Tue, 22 Dec 2020 13:23:57 -0800 Subject: [PATCH 21/91] Deprecate phantom, metaExtension, extension, pureAbstract (#949) * Deprecate phantom, metaExtension, extension, pureAbstract I tried to keep the deprecation warnings seperate from existing code/tests, so they can be easily removed once we delete the the deprecated annotations. Fixes #652 * Add URL to annotationDeprecated diangostic * LowerCase deprecated links Ignore all warnings in legacyutils transpileString --- package-lock.json | 2 +- src/transformation/utils/diagnostics.ts | 77 ++++++++++++------- src/transformation/visitors/class/index.ts | 8 ++ src/transformation/visitors/class/utils.ts | 5 ++ src/transformation/visitors/namespace.ts | 2 + test/legacy-utils.ts | 9 ++- test/translation/transformation.spec.ts | 2 + .../__snapshots__/deprecated.spec.ts.snap | 26 +++++++ .../__snapshots__/extension.spec.ts.snap | 30 ++++++-- .../__snapshots__/metaExtension.spec.ts.snap | 10 ++- test/unit/annotations/deprecated.spec.ts | 27 +++++++ test/unit/annotations/extension.spec.ts | 7 +- test/unit/annotations/metaExtension.spec.ts | 13 +++- test/util.ts | 10 ++- 14 files changed, 180 insertions(+), 48 deletions(-) create mode 100644 test/unit/annotations/__snapshots__/deprecated.spec.ts.snap create mode 100644 test/unit/annotations/deprecated.spec.ts diff --git a/package-lock.json b/package-lock.json index 85e431644..f775485f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index a5bdb35db..0197d90c2 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -3,21 +3,32 @@ import { LuaTarget } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; -const createDiagnosticFactory = (message: string | ((...args: TArgs) => string)) => +type MessageProvider = string | ((...args: TArgs) => string); + +const createDiagnosticFactory = ( + category: ts.DiagnosticCategory, + message: MessageProvider +) => createSerialDiagnosticFactory((node: ts.Node, ...args: TArgs) => ({ file: node.getSourceFile(), start: node.getStart(), length: node.getWidth(), messageText: typeof message === "string" ? message : message(...args), + category, })); -export const unsupportedNodeKind = createDiagnosticFactory( +const createErrorDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Error, message); +const createWarningDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Warning, message); + +export const unsupportedNodeKind = createErrorDiagnosticFactory( (kind: ts.SyntaxKind) => `Unsupported node kind ${ts.SyntaxKind[kind]}` ); -export const forbiddenForIn = createDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); +export const forbiddenForIn = createErrorDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); -export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedNoSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + @@ -25,7 +36,7 @@ export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name ); }); -export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + @@ -33,7 +44,7 @@ export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: ); }); -export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: string) => { +export const unsupportedOverloadAssignment = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` to '${name}'` : ""; return ( `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + @@ -41,88 +52,98 @@ export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: str ); }); -export const decoratorInvalidContext = createDiagnosticFactory("Decorator function cannot have 'this: void'."); +export const decoratorInvalidContext = createErrorDiagnosticFactory("Decorator function cannot have 'this: void'."); -export const annotationInvalidArgumentCount = createDiagnosticFactory( +export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const extensionCannotConstruct = createDiagnosticFactory( +export const extensionCannotConstruct = createErrorDiagnosticFactory( "Cannot construct classes with '@extension' or '@metaExtension' annotation." ); -export const extensionCannotExtend = createDiagnosticFactory( +export const extensionCannotExtend = createErrorDiagnosticFactory( "Cannot extend classes with '@extension' or '@metaExtension' annotation." ); -export const extensionCannotExport = createDiagnosticFactory( +export const extensionCannotExport = createErrorDiagnosticFactory( "Cannot export classes with '@extension' or '@metaExtension' annotation." ); -export const extensionInvalidInstanceOf = createDiagnosticFactory( +export const extensionInvalidInstanceOf = createErrorDiagnosticFactory( "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." ); -export const extensionAndMetaExtensionConflict = createDiagnosticFactory( +export const extensionAndMetaExtensionConflict = createErrorDiagnosticFactory( "Cannot use both '@extension' and '@metaExtension' annotations on the same class." ); -export const metaExtensionMissingExtends = createDiagnosticFactory( +export const metaExtensionMissingExtends = createErrorDiagnosticFactory( "'@metaExtension' annotation requires the extension of the metatable class." ); -export const invalidForRangeCall = createDiagnosticFactory((message: string) => `Invalid @forRange call: ${message}.`); +export const invalidForRangeCall = createErrorDiagnosticFactory( + (message: string) => `Invalid @forRange call: ${message}.` +); -export const luaTableMustBeAmbient = createDiagnosticFactory( +export const luaTableMustBeAmbient = createErrorDiagnosticFactory( "Classes with the '@luaTable' annotation must be ambient." ); -export const luaTableCannotBeExtended = createDiagnosticFactory( +export const luaTableCannotBeExtended = createErrorDiagnosticFactory( "Cannot extend classes with the '@luaTable' annotation." ); -export const luaTableInvalidInstanceOf = createDiagnosticFactory( +export const luaTableInvalidInstanceOf = createErrorDiagnosticFactory( "The instanceof operator cannot be used with a '@luaTable' class." ); -export const luaTableCannotBeAccessedDynamically = createDiagnosticFactory("@luaTable cannot be accessed dynamically."); +export const luaTableCannotBeAccessedDynamically = createErrorDiagnosticFactory( + "@luaTable cannot be accessed dynamically." +); -export const luaTableForbiddenUsage = createDiagnosticFactory( +export const luaTableForbiddenUsage = createErrorDiagnosticFactory( (description: string) => `Invalid @luaTable usage: ${description}.` ); -export const luaIteratorForbiddenUsage = createDiagnosticFactory( +export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + "You must use a destructuring statement to catch results from a lua iterator with " + "the '@tupleReturn' annotation." ); -export const unsupportedAccessorInObjectLiteral = createDiagnosticFactory( +export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( "Accessors in object literal are not supported." ); -export const unsupportedRightShiftOperator = createDiagnosticFactory( +export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); -export const unsupportedForTarget = createDiagnosticFactory( +export const unsupportedForTarget = createErrorDiagnosticFactory( (functionality: string, version: Exclude) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); -export const unsupportedProperty = createDiagnosticFactory( +export const unsupportedProperty = createErrorDiagnosticFactory( (parentName: string, property: string) => `${parentName}.${property} is unsupported.` ); -export const invalidAmbientIdentifierName = createDiagnosticFactory( +export const invalidAmbientIdentifierName = createErrorDiagnosticFactory( (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` ); -export const unresolvableRequirePath = createDiagnosticFactory( +export const unresolvableRequirePath = createErrorDiagnosticFactory( (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` ); -export const unsupportedVarDeclaration = createDiagnosticFactory( +export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); + +export const annotationDeprecated = createWarningDiagnosticFactory( + (kind: AnnotationKind) => + `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` +); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 9142775f7..d9da80cf7 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -4,6 +4,7 @@ import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { + annotationDeprecated, extensionAndMetaExtensionConflict, extensionCannotExport, extensionCannotExtend, @@ -94,6 +95,13 @@ function transformClassLikeDeclaration( const isExtension = extensionDirective !== undefined; const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); + if (isExtension) { + context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.Extension)); + } + if (isMetaExtension) { + context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.MetaExtension)); + } + if (isExtension && isMetaExtension) { context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); } diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 9ba263818..88388adf8 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { annotationDeprecated } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -22,6 +23,10 @@ export function getExtendedNode( if (!annotations.has(AnnotationKind.PureAbstract)) { return extendsClause.types[0]; } + + if (annotations.has(AnnotationKind.PureAbstract)) { + context.diagnostics.push(annotationDeprecated(extendsClause, AnnotationKind.PureAbstract)); + } } export function getExtendedType( diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 35190705f..3316ace4b 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { annotationDeprecated } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, @@ -53,6 +54,7 @@ export const transformModuleDeclaration: FunctionVisitor = const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Phantom)); return context.transformStatements(node.body.statements); } diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index de781d954..534c5849a 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -13,7 +13,9 @@ export function transpileString( const { diagnostics, file } = transpileStringResult(str, options); expect(file.lua).toBeDefined(); - const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); + const errors = diagnostics.filter( + d => (!ignoreDiagnostics || d.source === "typescript-to-lua") && d.category === ts.DiagnosticCategory.Error + ); expect(errors).not.toHaveDiagnostics(); return file.lua!.trim(); @@ -86,14 +88,15 @@ export function transpileAndExecute( tsStr: string, compilerOptions?: tstl.CompilerOptions, luaHeader?: string, - tsHeader?: string + tsHeader?: string, + ignoreDiagnostics = false ): any { const wrappedTsString = `${tsHeader ?? ""} declare function JSONStringify(this: void, p: any): string; function __runTest(this: void): any {${tsStr}}`; const lua = `${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} + ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnostics)} return __runTest();`; return executeLua(lua); diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 7a5088fcb..4e0d7dd9d 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -1,6 +1,7 @@ import * as fs from "fs"; import * as path from "path"; import * as tstl from "../../src"; +import { annotationDeprecated } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; const fixturesPath = path.join(__dirname, "./transformation"); @@ -13,6 +14,7 @@ const fixtures = fs test.each(fixtures)("Transformation (%s)", (_name, content) => { util.testModule(content) .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .ignoreDiagnostics([annotationDeprecated.code]) .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap new file mode 100644 index 000000000..956143495 --- /dev/null +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`extension deprecation: code 1`] = `""`; + +exports[`extension deprecation: code 2`] = `"local __meta__A = debug.getregistry().A"`; + +exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; + +exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; + +exports[`phantom deprecation: code 1`] = ` +"function nsMember(self) +end" +`; + +exports[`phantom deprecation: diagnostics 1`] = `"main.ts(3,9): warning TSTL: '@phantom' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; + +exports[`pureAbstract deprecation: code 1`] = ` +"require(\\"lualib_bundle\\"); +ClassB = __TS__Class() +ClassB.name = \\"ClassB\\" +function ClassB.prototype.____constructor(self) +end" +`; + +exports[`pureAbstract deprecation: diagnostics 1`] = `"main.ts(4,22): warning TSTL: '@pureAbstract' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap index f69a1315a..606d21635 100644 --- a/test/unit/annotations/__snapshots__/extension.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/extension.spec.ts.snap @@ -5,7 +5,10 @@ exports[`Class construct extension ("extension"): code 1`] = ` b = __TS__New(B)" `; -exports[`Class construct extension ("extension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class construct extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class construct extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -13,7 +16,10 @@ local __meta__A = debug.getregistry().A b = __TS__New(B)" `; -exports[`Class construct extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class construct extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class extends extension ("extension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -22,7 +28,10 @@ C.name = \\"C\\" __TS__ClassExtends(C, B)" `; -exports[`Class extends extension ("extension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class extends extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class extends extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -32,14 +41,20 @@ C.name = \\"C\\" __TS__ClassExtends(C, B)" `; -exports[`Class extends extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class extends extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." +`; exports[`instanceof extension ("extension"): code 1`] = ` "require(\\"lualib_bundle\\"); result = __TS__InstanceOf(foo, B)" `; -exports[`instanceof extension ("extension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; +exports[`instanceof extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." +`; exports[`instanceof extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -47,4 +62,7 @@ local __meta__A = debug.getregistry().A result = __TS__InstanceOf(foo, B)" `; -exports[`instanceof extension ("metaExtension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; +exports[`instanceof extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." +`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap index ba6b5e0a1..ad3f2ac51 100644 --- a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap @@ -6,7 +6,10 @@ local __meta___LOADED = debug.getregistry()._LOADED e = __TS__New(Ext)" `; -exports[`DontAllowInstantiation: diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`DontAllowInstantiation: diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`IncorrectUsage: code 1`] = ` "function LoadedExt.test(self) @@ -14,4 +17,7 @@ exports[`IncorrectUsage: code 1`] = ` end" `; -exports[`IncorrectUsage: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class."`; +exports[`IncorrectUsage: diagnostics 1`] = ` +"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class. +main.ts(3,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information." +`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts new file mode 100644 index 000000000..488b66a28 --- /dev/null +++ b/test/unit/annotations/deprecated.spec.ts @@ -0,0 +1,27 @@ +import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; +import * as util from "../../util"; + +test.each(["extension", "metaExtension"])("extension deprecation", extensionType => { + util.testModule` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("phantom deprecation", () => { + util.testModule` + /** @phantom **/ + namespace A { + function nsMember() {} + } + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("pureAbstract deprecation", () => { + util.testModule` + /** @pureAbstract */ + declare class ClassA {} + class ClassB extends ClassA {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts index c8da1b81b..27093801b 100644 --- a/test/unit/annotations/extension.spec.ts +++ b/test/unit/annotations/extension.spec.ts @@ -1,4 +1,5 @@ import { + annotationDeprecated, extensionCannotConstruct, extensionCannotExtend, extensionInvalidInstanceOf, @@ -11,7 +12,7 @@ test.each(["extension", "metaExtension"])("Class extends extension (%p)", extens /** @${extensionType} **/ class B extends A {} class C extends B {} - `.expectDiagnosticsToMatchSnapshot([extensionCannotExtend.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotExtend.code]); }); test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { @@ -20,7 +21,7 @@ test.each(["extension", "metaExtension"])("Class construct extension (%p)", exte /** @${extensionType} **/ class B extends A {} const b = new B(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); }); test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { @@ -30,5 +31,5 @@ test.each(["extension", "metaExtension"])("instanceof extension (%p)", extension class B extends A {} declare const foo: any; const result = foo instanceof B; - `.expectDiagnosticsToMatchSnapshot([extensionInvalidInstanceOf.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionInvalidInstanceOf.code]); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index 405eeee5a..aec48f4cf 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -1,4 +1,8 @@ -import { extensionCannotConstruct, metaExtensionMissingExtends } from "../../../src/transformation/utils/diagnostics"; +import { + annotationDeprecated, + extensionCannotConstruct, + metaExtensionMissingExtends, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("MetaExtension", () => { @@ -19,7 +23,8 @@ test("MetaExtension", () => { 'return debug.getregistry()["_LOADED"].test();', undefined, undefined, - tsHeader + tsHeader, + true ); expect(result).toBe(5); @@ -33,7 +38,7 @@ test("IncorrectUsage", () => { return 5; } } - `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code]); + `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code, annotationDeprecated.code]); }); test("DontAllowInstantiation", () => { @@ -42,5 +47,5 @@ test("DontAllowInstantiation", () => { /** @metaExtension */ class Ext extends _LOADED {} const e = new Ext(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); }); diff --git a/test/util.ts b/test/util.ts index 560b0102f..7be98e727 100644 --- a/test/util.ts +++ b/test/util.ts @@ -298,7 +298,9 @@ export abstract class TestBuilder { private getLuaDiagnostics(): ts.Diagnostic[] { const { diagnostics } = this.getLuaResult(); - return diagnostics.filter(d => this.semanticCheck || d.source === "typescript-to-lua"); + return diagnostics.filter( + d => (this.semanticCheck || d.source === "typescript-to-lua") && !this.ignoredDiagnostics.includes(d.code) + ); } // Actions @@ -311,6 +313,12 @@ export abstract class TestBuilder { } private diagnosticsChecked = false; + private ignoredDiagnostics: number[] = []; + + public ignoreDiagnostics(ignored: number[]): this { + this.ignoredDiagnostics.push(...ignored); + return this; + } public expectToHaveDiagnostics(expected?: number[]): this { if (this.diagnosticsChecked) return this; From 0cb8f5f000759cdff2da81bbf5ba2385177447c1 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 23 Dec 2020 23:34:58 +1000 Subject: [PATCH 22/91] Multi Helper (#821) * Add tuple helper * Elide helper import declarations * tuple validation progress * Use Visitors * Fix VariableDeclaration * Implement tuple helper * Use nil if no arguments were provided to tuple * Add destructuring assignment support * Support side effects and add more validation * Add unit tests * Add test for tuple within multiple VariableDeclarations * Can be used inside for loops * Fix syntax error in test case * Remove unnecessary boilerplate from tuple helper * Use some instead of every * Use flatMap in tuple instead of map * Use Boolean instead of ternary in tuple * Import helpers from /helpers * Do not use ts-ignore in tuple test cases * Use more specific test case names for tuple * Remove unsafe cast in for-of * Remove tuple visitors * Rename to multi and MultiReturn * Revert FunctionVisitor conversion * Rename tupleResult to multiResult * Update tsconfig.json Co-Authored-By: ark120202 * Update test/unit/helpers/multi.spec.ts Co-Authored-By: ark120202 * Refactor for new createVirtualProgram code * Move helper transformer to transformation * Use nullish operator instead of Boolean constructor * Attempt a CommonJS implementation of multi * Add MultiReturn alias MR * Add export in front of multi function * Simplify multi js implementation * Remove MR alias * Make multi helper global * Revert multi helper import changes * Apply suggestions from code review Co-Authored-By: ark120202 * Inline and join multi conditions * Rename to $multi * Use declare for top level $multi * Add empty tuple to MultiReturn * Add declare to MultiReturn to top level declaration * Reduce number of diagnostics for multi error * Improve multi diagnostics * Apply suggestions from code review Co-Authored-By: ark120202 * Rename utils to helpers * Include helpers inside lualib's tsconfig * Fix esnext target error * Drop support for VariableDeclarations, support only ReturnStatements * Simplify multi tests a bit * Remove multi.js * Revert "Drop support for VariableDeclarations, support only ReturnStatements" This reverts commit b7d1ec0c6b29ccbcf5b904974f76ce20108fe1aa. * State that multi can only be used in return statements * Throw an error if a helper is unknown * Improve multi nomenclature * Disallow multi function use in non-return statements * Merge helpers together into index.d.ts * Prefer for loop to filter/map/foreach * Add test to return spreaded multi type from multi type function * Rename to language extensions / extensions * Remove remaining helper references * Allow multi call as ConciseBody * Remove ts-ignore * Add check first to all multi transforms * Add multi example use case Co-authored-by: ark120202 --- language-extensions/index.d.ts | 2 + package.json | 3 +- src/lualib/tsconfig.json | 2 +- src/transformation/utils/diagnostics.ts | 26 +++ .../utils/language-extensions.ts | 28 +++ src/transformation/visitors/call.ts | 6 +- .../visitors/expression-statement.ts | 10 + src/transformation/visitors/function.ts | 5 + src/transformation/visitors/identifier.ts | 8 +- .../visitors/language-extensions/multi.ts | 188 ++++++++++++++++++ src/transformation/visitors/literal.ts | 9 +- src/transformation/visitors/return.ts | 9 + .../visitors/variable-declaration.ts | 9 + src/transpilation/index.ts | 16 +- test/tsconfig.json | 3 +- .../__snapshots__/multi.spec.ts.snap | 135 +++++++++++++ test/unit/language-extensions/multi.spec.ts | 128 ++++++++++++ 17 files changed, 575 insertions(+), 12 deletions(-) create mode 100644 language-extensions/index.d.ts create mode 100644 src/transformation/utils/language-extensions.ts create mode 100644 src/transformation/visitors/language-extensions/multi.ts create mode 100644 test/unit/language-extensions/__snapshots__/multi.spec.ts.snap create mode 100644 test/unit/language-extensions/multi.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts new file mode 100644 index 000000000..d7270be32 --- /dev/null +++ b/language-extensions/index.d.ts @@ -0,0 +1,2 @@ +declare function $multi(...values: T): MultiReturn; +declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; diff --git a/package.json b/package.json index 16e3e20a1..017169255 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "files": [ "dist/**/*.js", "dist/**/*.lua", - "dist/**/*.ts" + "dist/**/*.ts", + "language-extensions/**/*.ts" ], "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index b9d6de8ce..f16968dc1 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "../../dist/lualib", "target": "esnext", "lib": ["esnext"], - "types": [], + "types": ["../../language-extensions"], "skipLibCheck": true, "noUnusedLocals": true, diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 0197d90c2..8f69eadd9 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -142,6 +142,32 @@ export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); +export const invalidMultiFunctionUse = createErrorDiagnosticFactory( + "The $multi function must be called in an expression that is returned." +); + +export const invalidMultiTypeToNonArrayBindingPattern = createErrorDiagnosticFactory( + "Expected an array destructuring pattern." +); + +export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); + +export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosticFactory( + "There must be one or more elements specified here." +); + +export const invalidMultiTypeArrayBindingPatternElementInitializer = createErrorDiagnosticFactory( + "This array binding pattern cannot have initializers." +); + +export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnosticFactory( + "This array literal pattern cannot have initializers." +); + +export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( + "Omitted expressions and BindingElements are expected here." +); + 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. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts new file mode 100644 index 000000000..8f3b07672 --- /dev/null +++ b/src/transformation/utils/language-extensions.ts @@ -0,0 +1,28 @@ +import * as ts from "typescript"; +import * as path from "path"; + +export enum ExtensionKind { + MultiFunction = "MultiFunction", + MultiType = "MultiType", +} + +function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { + const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); + const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); + return extensionDirectory === sourceFileDirectory; +} + +export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { + const sourceFile = declaration.getSourceFile(); + if (isSourceFileFromLanguageExtensions(sourceFile)) { + if (ts.isFunctionDeclaration(declaration) && declaration?.name?.text === "$multi") { + return ExtensionKind.MultiFunction; + } + + if (ts.isTypeAliasDeclaration(declaration) && declaration.name.text === "MultiReturn") { + return ExtensionKind.MultiType; + } + + throw new Error("Unknown extension kind"); + } +} diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 366ff8041..90959a580 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -11,6 +11,7 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; +import { returnsMultiType } from "./language-extensions/multi"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -250,9 +251,8 @@ export const transformCallExpression: FunctionVisitor = (node // TODO: Currently it's also used as an array member export const transformSpreadElement: FunctionVisitor = (node, context) => { const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) { - return innerExpression; - } + if (isTupleReturnCall(context, node.expression)) return innerExpression; + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { return lua.createDotsLiteral(node); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 890695be0..4901a3210 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -4,8 +4,18 @@ import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; +import { returnsMultiType, transformMultiDestructuringAssignmentStatement } from "./language-extensions/multi"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { + if ( + ts.isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isCallExpression(node.expression.right) && + returnsMultiType(context, node.expression.right) + ) { + return transformMultiDestructuringAssignmentStatement(context, node); + } + const luaTableResult = transformLuaTableExpressionStatement(context, node); if (luaTableResult) { return luaTableResult; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index d3fb88a5a..424e75efe 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,6 +15,7 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; +import { isMultiFunction, transformMultiCallExpressionToReturnStatement } from "./language-extensions/multi"; import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; @@ -55,6 +56,10 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { + if (ts.isCallExpression(body) && isMultiFunction(context, body)) { + return [transformMultiCallExpressionToReturnStatement(context, body)]; + } + const returnStatement = transformExpressionBodyToReturnStatement(context, body); return [returnStatement]; } diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 54ed2a2f0..6e95411a5 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,13 +3,19 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall } from "../utils/diagnostics"; +import { invalidForRangeCall, invalidMultiFunctionUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; +import { isMultiFunctionNode } from "./language-extensions/multi"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { + if (isMultiFunctionNode(context, identifier)) { + context.diagnostics.push(invalidMultiFunctionUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts new file mode 100644 index 000000000..a6cb2a755 --- /dev/null +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -0,0 +1,188 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { transformAssignmentLeftHandSideExpression } from "../binary-expression/assignments"; +import { transformIdentifier } from "../identifier"; +import { transformArguments } from "../call"; +import { getDependenciesOfSymbol, createExportedIdentifier } from "../../utils/export"; +import { createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; +import { + invalidMultiTypeArrayBindingPatternElementInitializer, + invalidMultiTypeArrayLiteralElementInitializer, + invalidMultiTypeToEmptyPatternOrArrayLiteral, + invalidMultiTypeToNonArrayBindingPattern, + invalidMultiTypeToNonArrayLiteral, + unsupportedMultiFunctionAssignment, + invalidMultiFunctionUse, +} from "../../utils/diagnostics"; +import { assert } from "../../../utils"; + +const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; + +const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; + +export function isMultiFunction(context: TransformationContext, expression: ts.CallExpression): boolean { + const type = context.checker.getTypeAtLocation(expression.expression); + return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; +} + +export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + return signature?.getReturnType().aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; +} + +export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const type = context.checker.getTypeAtLocation(node); + return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; +} + +export function transformMultiCallExpressionToReturnStatement( + context: TransformationContext, + expression: ts.Expression +): lua.Statement { + assert(ts.isCallExpression(expression)); + + const expressions = transformArguments(context, expression.arguments); + return lua.createReturnStatement(expressions, expression); +} + +export function transformMultiReturnStatement( + context: TransformationContext, + statement: ts.ReturnStatement +): lua.Statement { + assert(statement.expression); + + return transformMultiCallExpressionToReturnStatement(context, statement.expression); +} + +function transformMultiFunctionArguments( + context: TransformationContext, + expression: ts.CallExpression +): lua.Expression[] | lua.Expression { + if (!isMultiFunction(context, expression)) { + return context.transformExpression(expression); + } + + if (expression.arguments.length === 0) { + return lua.createNilLiteral(expression); + } + + return expression.arguments.map(e => context.transformExpression(e)); +} + +export function transformMultiVariableDeclaration( + context: TransformationContext, + declaration: ts.VariableDeclaration +): lua.Statement[] { + assert(declaration.initializer); + assert(ts.isCallExpression(declaration.initializer)); + + if (!ts.isArrayBindingPattern(declaration.name)) { + context.diagnostics.push(invalidMultiTypeToNonArrayBindingPattern(declaration.name)); + return []; + } + + if (declaration.name.elements.length < 1) { + context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(declaration.name)); + return []; + } + + if (declaration.name.elements.some(e => ts.isBindingElement(e) && e.initializer)) { + context.diagnostics.push(invalidMultiTypeArrayBindingPatternElementInitializer(declaration.name)); + return []; + } + + if (isMultiFunction(context, declaration.initializer)) { + context.diagnostics.push(invalidMultiFunctionUse(declaration.initializer)); + return []; + } + + const leftIdentifiers: lua.Identifier[] = []; + + for (const element of declaration.name.elements) { + if (ts.isBindingElement(element)) { + if (ts.isIdentifier(element.name)) { + leftIdentifiers.push(transformIdentifier(context, element.name)); + } else { + context.diagnostics.push(unsupportedMultiFunctionAssignment(element)); + } + } else if (ts.isOmittedExpression(element)) { + leftIdentifiers.push(lua.createAnonymousIdentifier(element)); + } + } + + const rightExpressions = transformMultiFunctionArguments(context, declaration.initializer); + return createLocalOrExportedOrGlobalDeclaration(context, leftIdentifiers, rightExpressions, declaration); +} + +export function transformMultiDestructuringAssignmentStatement( + context: TransformationContext, + statement: ts.ExpressionStatement +): lua.Statement[] | undefined { + assert(ts.isBinaryExpression(statement.expression)); + assert(ts.isCallExpression(statement.expression.right)); + + if (!ts.isArrayLiteralExpression(statement.expression.left)) { + context.diagnostics.push(invalidMultiTypeToNonArrayLiteral(statement.expression.left)); + return []; + } + + if (statement.expression.left.elements.some(ts.isBinaryExpression)) { + context.diagnostics.push(invalidMultiTypeArrayLiteralElementInitializer(statement.expression.left)); + return []; + } + + if (statement.expression.left.elements.length < 1) { + context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(statement.expression.left)); + return []; + } + + if (isMultiFunction(context, statement.expression.right)) { + context.diagnostics.push(invalidMultiFunctionUse(statement.expression.right)); + return []; + } + + const transformLeft = (expression: ts.Expression): lua.AssignmentLeftHandSideExpression => + ts.isOmittedExpression(expression) + ? lua.createAnonymousIdentifier(expression) + : transformAssignmentLeftHandSideExpression(context, expression); + + const leftIdentifiers = statement.expression.left.elements.map(transformLeft); + + const rightExpressions = transformMultiFunctionArguments(context, statement.expression.right); + + const trailingStatements = statement.expression.left.elements.flatMap(expression => { + const symbol = context.checker.getSymbolAtLocation(expression); + const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; + return dependentSymbols.map(symbol => { + const identifierToAssign = createExportedIdentifier(context, lua.createIdentifier(symbol.name)); + return lua.createAssignmentStatement(identifierToAssign, transformLeft(expression)); + }); + }); + + return [lua.createAssignmentStatement(leftIdentifiers, rightExpressions, statement), ...trailingStatements]; +} + +export function findMultiAssignmentViolations( + context: TransformationContext, + node: ts.ObjectLiteralExpression +): ts.Node[] { + const result: ts.Node[] = []; + + for (const element of node.properties) { + if (!ts.isShorthandPropertyAssignment(element)) continue; + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + const declaration = valueSymbol.valueDeclaration; + if (declaration && isMultiFunctionDeclaration(declaration)) { + context.diagnostics.push(invalidMultiFunctionUse(element)); + result.push(element); + } + } + } + + return result; +} diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 6544367a2..36c7e48c6 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; +import { unsupportedAccessorInObjectLiteral, invalidMultiFunctionUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -10,6 +10,7 @@ import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; +import { findMultiAssignmentViolations } from "./language-extensions/multi"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -62,6 +63,12 @@ const transformNumericLiteralExpression: FunctionVisitor = ex }; const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } + let properties: lua.TableFieldExpression[] = []; const tableExpressions: lua.Expression[] = []; diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index c5ec3c740..c13d571ff 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -6,6 +6,7 @@ import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; +import { isMultiFunction, transformMultiReturnStatement } from "./language-extensions/multi"; function transformExpressionsInReturn( context: TransformationContext, @@ -59,6 +60,14 @@ export const transformReturnStatement: FunctionVisitor = (st insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; } + if ( + statement.expression && + ts.isCallExpression(statement.expression) && + isMultiFunction(context, statement.expression) + ) { + return transformMultiReturnStatement(context, statement); + } + let results: lua.Expression[]; if (statement.expression) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index bec7548e5..6ddd4acdc 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -10,6 +10,7 @@ import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../u import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; import { transformPropertyName } from "./literal"; +import { returnsMultiType, transformMultiVariableDeclaration } from "./language-extensions/multi"; export function transformArrayBindingElement( context: TransformationContext, @@ -229,6 +230,14 @@ export function transformVariableDeclaration( context: TransformationContext, statement: ts.VariableDeclaration ): lua.Statement[] { + if ( + statement.initializer && + ts.isCallExpression(statement.initializer) && + returnsMultiType(context, statement.initializer) + ) { + return transformMultiVariableDeclaration(context, statement); + } + if (statement.initializer && statement.type) { const initializerType = context.checker.getTypeAtLocation(statement.initializer); const varType = context.checker.getTypeFromTypeNode(statement.type); diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 628246ec9..608b42818 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -59,14 +59,22 @@ export function createVirtualProgram(input: Record, options: Com return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false); } + let filePath: string | undefined; + if (fileName.startsWith("lib.")) { - if (libCache[fileName]) return libCache[fileName]; const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, fileName); - const content = fs.readFileSync(filePath, "utf8"); + filePath = path.join(typeScriptDir, fileName); + } - libCache[fileName] = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false); + if (fileName.includes("language-extensions")) { + const dtsName = fileName.replace(/(\.d)?(\.ts)$/, ".d.ts"); + filePath = path.resolve(dtsName); + } + if (filePath !== undefined) { + if (libCache[fileName]) return libCache[fileName]; + const content = fs.readFileSync(filePath, "utf8"); + libCache[fileName] = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, false); return libCache[fileName]; } }, diff --git a/test/tsconfig.json b/test/tsconfig.json index de0b21bdd..2c06244c7 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -13,6 +13,7 @@ "cli/watch", "transpile/directories", "transpile/outFile", - "../src/lualib" + "../src/lualib", + "../language-extensions" ] } diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap new file mode 100644 index 000000000..587cdfd90 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -0,0 +1,135 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`; + +exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`; + +exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` +"local function ____(____, ____bindingPattern0) + if ____bindingPattern0 == nil then + ____bindingPattern0 = ____(_G, 1) + end + local a = ____bindingPattern0[1] +end" +`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; + +exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = `""`; + +exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,15): error TSTL: This array binding pattern cannot have initializers."`; + +exports[`invalid $multi call (const {} = $multi();): code 1`] = `""`; + +exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; + +exports[`invalid $multi call (const a = $multi();): code 1`] = `""`; + +exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; + +exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local _ = nil +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local ar = {1} +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +do + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +do + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in an expression that is returned."`; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts new file mode 100644 index 000000000..ed5353bbc --- /dev/null +++ b/test/unit/language-extensions/multi.spec.ts @@ -0,0 +1,128 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { + invalidMultiFunctionUse, + invalidMultiTypeToNonArrayBindingPattern, + invalidMultiTypeArrayBindingPatternElementInitializer, +} from "../../../src/transformation/utils/diagnostics"; + +const multiProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test("multi example use case", () => { + util.testModule` + function multiReturn(): MultiReturn<[string, number]> { + return $multi("foo", 5); + } + + const [a, b] = multiReturn(); + export { a, b }; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: "foo", b: 5 }); +}); + +test.each<[string, any]>([ + ["$multi()", undefined], + ["$multi(true)", true], + ["$multi(1, 2)", 1], +])("$multi call on return statement (%s)", (expression, result) => { + util.testFunction` + return ${expression}; + ` + .setOptions(multiProjectOptions) + .expectToEqual(result); +}); + +const multiFunction = ` +function multi(...args) { + return $multi(...args); +} +`; + +const createCasesThatCall = (name: string): Array<[string, any]> => [ + [`let a; [a] = ${name}()`, undefined], + [`const [a] = ${name}()`, undefined], + [`const [a] = ${name}(1)`, 1], + [`const ar = [1]; const [a] = ${name}(...ar)`, 1], + [`const _ = null, [a] = ${name}(1)`, 1], + [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], + [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], +]; + +test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionUse.code]); +}); + +test.each<[string, any]>(createCasesThatCall("multi"))( + "valid indirect $multi function use (%s)", + (statement, result) => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectToEqual(result); + } +); + +test.each<[string, number[]]>([ + ["$multi", [invalidMultiFunctionUse.code]], + ["$multi()", [invalidMultiFunctionUse.code]], + ["({ $multi });", [invalidMultiFunctionUse.code]], + ["const a = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["const {} = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]], + ["const [a = 0] = $multi()", [invalidMultiTypeArrayBindingPatternElementInitializer.code]], +])("invalid $multi call (%s)", (statement, diagnostics) => { + util.testModule` + ${statement} + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot(diagnostics); +}); + +test("function to spread multi type result from multi type function", () => { + util.testFunction` + ${multiFunction} + function m() { + return $multi(...multi(true)); + } + return m(); + ` + .setOptions(multiProjectOptions) + .expectToEqual(true); +}); + +test("$multi call with destructuring assignment side effects", () => { + util.testModule` + ${multiFunction} + let a; + export { a }; + [a] = multi(1); + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectToEqual(1); +}); + +test("allow $multi call in ArrowFunction body", () => { + util.testFunction` + const call = () => $multi(1); + const [result] = call(); + return result; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); From e58da3fbe9363967def2cb65311bfa0e4e435b6d Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 27 Dec 2020 02:53:29 -0800 Subject: [PATCH 23/91] Add homepage and bugs to package.json (#956) --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 017169255..464daf98f 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "0.36.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "homepage": "https://typescripttolua.github.io/", + "bugs": { + "url": "https://github.com/TypeScriptToLua/TypeScriptToLua/issues" + }, "license": "MIT", "keywords": [ "typescript", From 7d1696a11f516459312adc5bc1aa841f2f65ba51 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 30 Dec 2020 20:03:32 +0100 Subject: [PATCH 24/91] 0.37.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f775485f5..7cc4c921f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 464daf98f..c10a7aecd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.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/", From f90f6af8bd49908fcfde4667649ddbfc1d9f7691 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 30 Dec 2020 22:40:13 +0100 Subject: [PATCH 25/91] Changelog 0.37.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64ef0e7c3..5f277e056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.37.0 + +- **[Important]** Deprecated the @phantom, @extension, @metaExtension and @pureAbstract annotations. This is done because there are good alternatives in regular TypeScript, and this helps us simplify the transpiler. For now, using these annotations will result in a warning but they will still continue to function. A few months from now these annotations will no longer be supported, so upgrade if possible. See [Compiler Annotations](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for more info. +- Added the `MultiReturn<>` type and `$multi()` helper function as the first language extensions. This is to provide a type-safe alternative to the `@tupleReturn` annotation. For more information see [the new Language Extensions page](https://typescripttolua.github.io/docs/advanced/language-extensions) on the docs website. +- Removed some class transformation code from the transpiler that was no longer used. +- Fixed a bug causing object spread to malfunction in some cases ([#898](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/898)). +- Omitted `tostring` for parameters of template literals (`` `${}` ``) that are already known strings. +- Fixed a bug causing incorrect Lua syntax to be generated in some cases ([#944](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944)). + ## 0.36.0 - Upgraded to TypeScript 4.0. From 3c9e369fcc80f91f2c4c38b1c13de2b6d305f604 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Fri, 8 Jan 2021 05:29:10 +1000 Subject: [PATCH 26/91] Allow numeric access to MultiReturn (#962) --- src/transformation/utils/diagnostics.ts | 4 +++ src/transformation/visitors/access.ts | 21 ++++++++++++- .../__snapshots__/multi.spec.ts.snap | 31 +++++++++++++++++++ test/unit/language-extensions/multi.spec.ts | 20 ++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8f69eadd9..d7b7b6467 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -164,6 +164,10 @@ export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnos "This array literal pattern cannot have initializers." ); +export const invalidMultiReturnAccess = createErrorDiagnosticFactory( + "The MultiReturn type can only be accessed via an element access expression of a numeric type." +); + export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( "Omitted expressions and BindingElements are expected here." ); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index eaa5591b7..6cf61a62c 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,10 +3,12 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { invalidMultiReturnAccess } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; +import { returnsMultiType } from "./language-extensions/multi"; import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; export function transformElementAccessArgument( @@ -41,7 +43,20 @@ export const transformElementAccessExpression: FunctionVisitor = ( @@ -63,6 +78,10 @@ export const transformPropertyAccessExpression: FunctionVisitor { .setOptions(multiProjectOptions) .expectToEqual(1); }); + +test.each(["0", "i"])("allow MultiReturn numeric access", expression => { + util.testFunction` + ${multiFunction} + const i = 0; + return multi(1)[${expression}]; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); + +test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-numeric access", expression => { + util.testFunction` + ${multiFunction} + return ${expression}; + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); +}); From 6ac1980195e71264e1e4bfa97110556fb98ebcb4 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 7 Jan 2021 21:13:06 +0100 Subject: [PATCH 27/91] 0.37.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7cc4c921f..d98d38972 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index c10a7aecd..d4d39ce59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "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/", From 948f71bff43932aa22d8a8217db6d7c35d0262af Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Wed, 13 Jan 2021 11:29:37 -0800 Subject: [PATCH 28/91] Added optional chaining unsupported diagnostic (#966) --- src/transformation/utils/diagnostics.ts | 2 ++ src/transformation/visitors/access.ts | 6 +++++- test/unit/optionalChaining.spec.ts | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/unit/optionalChaining.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index d7b7b6467..2c1a6793d 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -177,3 +177,5 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); + +export const optionalChainingNotSupported = createErrorDiagnosticFactory("Optional chaining is not supported yet."); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 6cf61a62c..d33c5c5c6 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { invalidMultiReturnAccess } from "../utils/diagnostics"; +import { invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; @@ -63,6 +63,10 @@ export const transformPropertyAccessExpression: FunctionVisitor { + if (ts.isOptionalChain(expression)) { + context.diagnostics.push(optionalChainingNotSupported(expression)); + } + const constEnumValue = tryGetConstEnumValue(context, expression); if (constEnumValue) { return constEnumValue; diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts new file mode 100644 index 000000000..33d0802db --- /dev/null +++ b/test/unit/optionalChaining.spec.ts @@ -0,0 +1,9 @@ +import { optionalChainingNotSupported } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test("Diagnostic optional chaining is not supported yet", () => { + util.testFunction` + let func = (value: number) => value != 0 ? {value} : undefined; + return func(1)?.value; + `.expectToHaveDiagnostics([optionalChainingNotSupported.code]); +}); From 0158732bdb597132b7b4a22cd40e7ce61ef37877 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 26 Jan 2021 13:06:02 -0700 Subject: [PATCH 29/91] Operator Mapping Library Extensions (#969) * initial setup of add operator mapping * basic add operator mappings working, including tests and invalid use checks * overload tests for operator mapping * added unary operator map for len and updated tests * added missing operator extensions * added checks for unsupported operators in pre-53 lua versions * reverting package-lock.json to correct version * tabs to spaces * fixed snapshot * addressed feedback * Update src/transformation/utils/diagnostics.ts Co-authored-by: Perry van Wesel * snapshot update Co-authored-by: Tom Co-authored-by: Perry van Wesel --- language-extensions/index.d.ts | 402 ++++++++++++++++++ src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 83 +++- src/transformation/visitors/call.ts | 5 + src/transformation/visitors/identifier.ts | 7 +- .../visitors/language-extensions/operators.ts | 177 ++++++++ .../__snapshots__/operators.spec.ts.snap | 133 ++++++ .../language-extensions/operators.spec.ts | 392 +++++++++++++++++ 8 files changed, 1200 insertions(+), 3 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/operators.ts create mode 100644 test/unit/language-extensions/__snapshots__/operators.spec.ts.snap create mode 100644 test/unit/language-extensions/operators.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index d7270be32..87a7f1395 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,2 +1,404 @@ declare function $multi(...values: T): MultiReturn; declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; + +/** + * Calls to functions with this type are translated to `left + right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaAdditionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & { + readonly __luaAdditionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left - right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaSubtractionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & { + readonly __luaSubtractionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left * right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaMultiplicationBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & { + readonly __luaMultiplicationMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left / right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaDivisionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & { + readonly __luaDivisionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left % right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaModuloBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModuloMethod = ((right: TRight) => TReturn) & { + readonly __luaModuloMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left ^ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaPowerBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPowerMethod = ((right: TRight) => TReturn) & { + readonly __luaPowerMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left // right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaFloorDivisionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & { + readonly __luaFloorDivisionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left & right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseAndBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseAndMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left | right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseOrBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseOrMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left ~ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseExclusiveOrBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseExclusiveOrMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left << right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseLeftShiftBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseLeftShiftMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left >> right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseRightShiftBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseRightShiftMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left .. right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaConcatBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcatMethod = ((right: TRight) => TReturn) & { + readonly __luaConcatMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left < right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaLessThanBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & { + readonly __luaLessThanMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left > right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaGreaterThanBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & { + readonly __luaGreaterThanMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `-operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegation = ((operand: TOperand) => TReturn) & { + readonly __luaNegationBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNegationMethodBrand: unique symbol }; + +/** + * Calls to functions with this type are translated to `~operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & { + readonly __luaBitwiseNotBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBitwiseNotMethodBrand: unique symbol }; + +/** + * Calls to functions with this type are translated to `#operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLength = ((operand: TOperand) => TReturn) & { + readonly __luaLengthBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLengthMethod = (() => TReturn) & { readonly __luaLengthMethodBrand: unique symbol }; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 2c1a6793d..8cd721421 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -172,6 +172,10 @@ export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( "Omitted expressions and BindingElements are expected here." ); +export const invalidOperatorMappingUse = createErrorDiagnosticFactory( + "This function must always be directly called and cannot be referred to." +); + 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. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 8f3b07672..6838d6b55 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -4,8 +4,84 @@ import * as path from "path"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", + AdditionOperatorType = "AdditionOperatorType", + AdditionOperatorMethodType = "AdditionOperatorMethodType", + SubtractionOperatorType = "SubtractionOperatorType", + SubtractionOperatorMethodType = "SubtractionOperatorMethodType", + MultiplicationOperatorType = "MultiplicationOperatorType", + MultiplicationOperatorMethodType = "MultiplicationOperatorMethodType", + DivisionOperatorType = "DivisionOperatorType", + DivisionOperatorMethodType = "DivisionOperatorMethodType", + ModuloOperatorType = "ModuloOperatorType", + ModuloOperatorMethodType = "ModuloOperatorMethodType", + PowerOperatorType = "PowerOperatorType", + PowerOperatorMethodType = "PowerOperatorMethodType", + FloorDivisionOperatorType = "FloorDivisionOperatorType", + FloorDivisionOperatorMethodType = "FloorDivisionOperatorMethodType", + BitwiseAndOperatorType = "BitwiseAndOperatorType", + BitwiseAndOperatorMethodType = "BitwiseAndOperatorMethodType", + BitwiseOrOperatorType = "BitwiseOrOperatorType", + BitwiseOrOperatorMethodType = "BitwiseOrOperatorMethodType", + BitwiseExclusiveOrOperatorType = "BitwiseExclusiveOrOperatorType", + BitwiseExclusiveOrOperatorMethodType = "BitwiseExclusiveOrOperatorMethodType", + BitwiseLeftShiftOperatorType = "BitwiseLeftShiftOperatorType", + BitwiseLeftShiftOperatorMethodType = "BitwiseLeftShiftOperatorMethodType", + BitwiseRightShiftOperatorType = "BitwiseRightShiftOperatorType", + BitwiseRightShiftOperatorMethodType = "BitwiseRightShiftOperatorMethodType", + ConcatOperatorType = "ConcatOperatorType", + ConcatOperatorMethodType = "ConcatOperatorMethodType", + LessThanOperatorType = "LessThanOperatorType", + LessThanOperatorMethodType = "LessThanOperatorMethodType", + GreaterThanOperatorType = "GreaterThanOperatorType", + GreaterThanOperatorMethodType = "GreaterThanOperatorMethodType", + NegationOperatorType = "NegationOperatorType", + NegationOperatorMethodType = "NegationOperatorMethodType", + BitwiseNotOperatorType = "BitwiseNotOperatorType", + BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", + LengthOperatorType = "LengthOperatorType", + LengthOperatorMethodType = "LengthOperatorMethodType", } +const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { + MultiReturn: ExtensionKind.MultiType, + LuaAddition: ExtensionKind.AdditionOperatorType, + LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, + LuaSubtraction: ExtensionKind.SubtractionOperatorType, + LuaSubtractionMethod: ExtensionKind.SubtractionOperatorMethodType, + LuaMultiplication: ExtensionKind.MultiplicationOperatorType, + LuaMultiplicationMethod: ExtensionKind.MultiplicationOperatorMethodType, + LuaDivision: ExtensionKind.DivisionOperatorType, + LuaDivisionMethod: ExtensionKind.DivisionOperatorMethodType, + LuaModulo: ExtensionKind.ModuloOperatorType, + LuaModuloMethod: ExtensionKind.ModuloOperatorMethodType, + LuaPower: ExtensionKind.PowerOperatorType, + LuaPowerMethod: ExtensionKind.PowerOperatorMethodType, + LuaFloorDivision: ExtensionKind.FloorDivisionOperatorType, + LuaFloorDivisionMethod: ExtensionKind.FloorDivisionOperatorMethodType, + LuaBitwiseAnd: ExtensionKind.BitwiseAndOperatorType, + LuaBitwiseAndMethod: ExtensionKind.BitwiseAndOperatorMethodType, + LuaBitwiseOr: ExtensionKind.BitwiseOrOperatorType, + LuaBitwiseOrMethod: ExtensionKind.BitwiseOrOperatorMethodType, + LuaBitwiseExclusiveOr: ExtensionKind.BitwiseExclusiveOrOperatorType, + LuaBitwiseExclusiveOrMethod: ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + LuaBitwiseLeftShift: ExtensionKind.BitwiseLeftShiftOperatorType, + LuaBitwiseLeftShiftMethod: ExtensionKind.BitwiseLeftShiftOperatorMethodType, + LuaBitwiseRightShift: ExtensionKind.BitwiseRightShiftOperatorType, + LuaBitwiseRightShiftMethod: ExtensionKind.BitwiseRightShiftOperatorMethodType, + LuaConcat: ExtensionKind.ConcatOperatorType, + LuaConcatMethod: ExtensionKind.ConcatOperatorMethodType, + LuaLessThan: ExtensionKind.LessThanOperatorType, + LuaLessThanMethod: ExtensionKind.LessThanOperatorMethodType, + LuaGreaterThan: ExtensionKind.GreaterThanOperatorType, + LuaGreaterThanMethod: ExtensionKind.GreaterThanOperatorMethodType, + LuaNegation: ExtensionKind.NegationOperatorType, + LuaNegationMethod: ExtensionKind.NegationOperatorMethodType, + LuaBitwiseNot: ExtensionKind.BitwiseNotOperatorType, + LuaBitwiseNotMethod: ExtensionKind.BitwiseNotOperatorMethodType, + LuaLength: ExtensionKind.LengthOperatorType, + LuaLengthMethod: ExtensionKind.LengthOperatorMethodType, +}; + function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); @@ -19,8 +95,11 @@ export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | u return ExtensionKind.MultiFunction; } - if (ts.isTypeAliasDeclaration(declaration) && declaration.name.text === "MultiReturn") { - return ExtensionKind.MultiType; + if (ts.isTypeAliasDeclaration(declaration)) { + const extensionKind = typeNameToExtensionKind[declaration.name.text]; + if (extensionKind) { + return extensionKind; + } } throw new Error("Unknown extension kind"); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 90959a580..20583d007 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -12,6 +12,7 @@ import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignmen import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; import { returnsMultiType } from "./language-extensions/multi"; +import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -208,6 +209,10 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResult ? wrapInTable(builtinResult) : builtinResult; } + if (isOperatorMapping(context, node)) { + return transformOperatorMappingExpression(context, node); + } + if (ts.isPropertyAccessExpression(node.expression)) { const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 6e95411a5..dd69699b3 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,12 +3,13 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall, invalidMultiFunctionUse } from "../utils/diagnostics"; +import { invalidForRangeCall, invalidMultiFunctionUse, invalidOperatorMappingUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; import { isMultiFunctionNode } from "./language-extensions/multi"; +import { isOperatorMapping } from "./language-extensions/operators"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -16,6 +17,10 @@ export function transformIdentifier(context: TransformationContext, identifier: return lua.createAnonymousIdentifier(identifier); } + if (isOperatorMapping(context, identifier)) { + context.diagnostics.push(invalidOperatorMappingUse(identifier)); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts new file mode 100644 index 000000000..b217a26e8 --- /dev/null +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -0,0 +1,177 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { assert } from "../../../utils"; +import { findFirstNodeAbove } from "../../utils/typescript"; +import { LuaTarget } from "../../../CompilerOptions"; +import { unsupportedForTarget } from "../../utils/diagnostics"; + +const binaryOperatorMappings = new Map([ + [extensions.ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.AdditionOperatorMethodType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.SubtractionOperatorType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.SubtractionOperatorMethodType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.MultiplicationOperatorType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.MultiplicationOperatorMethodType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.DivisionOperatorType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.DivisionOperatorMethodType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.ModuloOperatorType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.ModuloOperatorMethodType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.PowerOperatorType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.PowerOperatorMethodType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.FloorDivisionOperatorType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.FloorDivisionOperatorMethodType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.BitwiseAndOperatorType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseAndOperatorMethodType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseOrOperatorType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseOrOperatorMethodType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.ConcatOperatorType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.ConcatOperatorMethodType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.LessThanOperatorType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.LessThanOperatorMethodType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorType, lua.SyntaxKind.GreaterThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorMethodType, lua.SyntaxKind.GreaterThanOperator], +]); + +const unaryOperatorMappings = new Map([ + [extensions.ExtensionKind.NegationOperatorType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.NegationOperatorMethodType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.BitwiseNotOperatorType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.BitwiseNotOperatorMethodType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.LengthOperatorType, lua.SyntaxKind.LengthOperator], + [extensions.ExtensionKind.LengthOperatorMethodType, lua.SyntaxKind.LengthOperator], +]); + +const operatorMapExtensions = new Set([ + ...binaryOperatorMappings.keys(), + ...unaryOperatorMappings.keys(), +]); + +const bitwiseOperatorMapExtensions = new Set([ + extensions.ExtensionKind.BitwiseAndOperatorType, + extensions.ExtensionKind.BitwiseAndOperatorMethodType, + extensions.ExtensionKind.BitwiseOrOperatorType, + extensions.ExtensionKind.BitwiseOrOperatorMethodType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseRightShiftOperatorType, + extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseNotOperatorType, + extensions.ExtensionKind.BitwiseNotOperatorMethodType, +]); + +function getTypeDeclaration(declaration: ts.Declaration) { + return ts.isTypeAliasDeclaration(declaration) + ? declaration + : findFirstNodeAbove(declaration, ts.isTypeAliasDeclaration); +} + +function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { + const signature = context.checker.getResolvedSignature(node); + if (!signature || !signature.declaration) { + return; + } + const typeDeclaration = getTypeDeclaration(signature.declaration); + if (!typeDeclaration) { + return; + } + const mapping = extensions.getExtensionKind(typeDeclaration); + if (mapping !== undefined && operatorMapExtensions.has(mapping)) { + return mapping; + } +} + +function isOperatorMapDeclaration(declaration: ts.Declaration) { + const typeDeclaration = getTypeDeclaration(declaration); + if (typeDeclaration) { + const extensionKind = extensions.getExtensionKind(typeDeclaration); + return extensionKind !== undefined ? operatorMapExtensions.has(extensionKind) : false; + } +} + +function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { + if (type.isUnionOrIntersection()) { + return type.types.some(t => isOperatorMapType(context, t)); + } else { + return type.symbol?.declarations?.some(isOperatorMapDeclaration); + } +} + +function isOperatorMapIdentifier(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return isOperatorMapType(context, type); +} + +export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { + if (ts.isCallExpression(node)) { + return getOperatorMapExtensionKindForCall(context, node) !== undefined; + } else { + return isOperatorMapIdentifier(context, node); + } +} + +export function transformOperatorMappingExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression { + const extensionKind = getOperatorMapExtensionKindForCall(context, node); + assert(extensionKind); + + const isBefore53 = + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Lua52 || + context.luaTarget === LuaTarget.LuaJIT || + context.luaTarget === LuaTarget.Universal; + if (isBefore53) { + const luaTarget = context.luaTarget === LuaTarget.Universal ? LuaTarget.Lua51 : context.luaTarget; + if (bitwiseOperatorMapExtensions.has(extensionKind)) { + context.diagnostics.push(unsupportedForTarget(node, "Native bitwise operations", luaTarget)); + } else if ( + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorType || + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorMethodType + ) { + context.diagnostics.push(unsupportedForTarget(node, "Floor division operator", luaTarget)); + } + } + + const args = node.arguments.slice(); + if (binaryOperatorMappings.has(extensionKind)) { + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + const luaOperator = binaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createBinaryExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + luaOperator + ); + } else { + let arg: ts.Expression; + if ( + args.length === 0 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + arg = node.expression.expression; + } else { + arg = args[0]; + } + + const luaOperator = unaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createUnaryExpression(context.transformExpression(arg), luaOperator); + } +} diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap new file mode 100644 index 000000000..cfeef91c8 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): code 1`] = `"foo = op(_G, 1, 2)"`; + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = [op];): code 1`] = `"foo = {op}"`; + +exports[`operator mapping - invalid use (const foo = [op];): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): code 1`] = `"foo = tostring(op)"`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): diagnostics 1`] = `"main.ts(3,24): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): code 1`] = `"foo = op"`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): diagnostics 1`] = `"main.ts(3,30): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): code 1`] = `"foo(_G, op)"`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts new file mode 100644 index 000000000..4559ff7e6 --- /dev/null +++ b/test/unit/language-extensions/operators.spec.ts @@ -0,0 +1,392 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidOperatorMappingUse } from "../../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../../src"; +import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; + +const operatorsProjectOptions: tstl.CompilerOptions = { + luaTarget: LuaTarget.Lua53, + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +const operatorMapTestObject = ` + class OpTest { + public value: number; + public constructor(value: number) { this.value = value; } + + public __add(other: OpTest): OpTest; + public __add(other: number): number; + public __add(other: OpTest | number) { + if (typeof other === "number") { + return this.value + other; + } else { + return new OpTest(this.value + other.value); + } + } + public __sub(other: OpTest) { return new OpTest(this.value - other.value); } + public __mul(other: OpTest) { return new OpTest(this.value * other.value); } + public __div(other: OpTest) { return new OpTest(this.value / other.value); } + public __mod(other: OpTest) { return new OpTest(this.value % other.value); } + public __pow(other: OpTest) { return new OpTest(this.value ** other.value); } + public __idiv(other: OpTest) { return new OpTest(Math.floor(this.value / other.value)); } + public __band(other: OpTest) { return new OpTest(this.value & other.value); } + public __bor(other: OpTest) { return new OpTest(this.value | other.value); } + public __bxor(other: OpTest) { return new OpTest(this.value ^ other.value); } + public __shl(other: OpTest) { return new OpTest(this.value << other.value); } + public __shr(other: OpTest) { return new OpTest(this.value >>> other.value); } + + public __lt(other: OpTest) { return this.value < other.value; } + public __gt(other: OpTest) { return this.value > other.value; } + + public __concat(other: OpTest) { return this.value.toString() + other.value.toString(); } + + public __unm() { return -this.value; } + public __bnot() { return ~this.value; } + public __len() { return this.value; } + } +`; + +const binaryMathOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: number }> = [ + { opType: "LuaAddition", left: 7, right: 4, expectResult: 11 }, + { opType: "LuaSubtraction", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaMultiplication", left: 7, right: 4, expectResult: 28 }, + { opType: "LuaDivision", left: 7, right: 4, expectResult: 1.75 }, + { opType: "LuaModulo", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaPower", left: 7, right: 4, expectResult: 2401 }, + { opType: "LuaFloorDivision", left: 7, right: 4, expectResult: 1 }, + { opType: "LuaBitwiseAnd", left: 6, right: 5, expectResult: 4 }, + { opType: "LuaBitwiseOr", left: 6, right: 5, expectResult: 7 }, + { opType: "LuaBitwiseExclusiveOr", left: 6, right: 5, expectResult: 3 }, + { opType: "LuaBitwiseLeftShift", left: 7, right: 2, expectResult: 28 }, + { opType: "LuaBitwiseRightShift", left: 7, right: 2, expectResult: 1 }, +]; + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +const luaTargetsPre53 = [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; + +const operatorTypesPost53 = [ + "LuaFloorDivision", + "LuaBitwiseAnd", + "LuaBitwiseOr", + "LuaBitwiseExclusiveOr", + "LuaBitwiseLeftShift", + "LuaBitwiseRightShift", +]; + +test.each(luaTargetsPre53.flatMap(target => operatorTypesPost53.map(opType => [target, opType] as const)))( + "unsupported binary operator mapping (%s %s)", + (luaTarget, opType) => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: ${opType}; + declare const left: OpTest; + declare const right: OpTest; + op(left, right); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + } +); + +const comparisonOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: boolean }> = [ + { opType: "LuaLessThan", left: 7, right: 4, expectResult: false }, + { opType: "LuaLessThan", left: 4, right: 7, expectResult: true }, + { opType: "LuaGreaterThan", left: 7, right: 4, expectResult: true }, + { opType: "LuaGreaterThan", left: 4, right: 7, expectResult: false }, +]; + +test.each(comparisonOperatorTests)( + "comparison operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test("concat operator mapping - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaConcat; + const left = new OpTest(7); + const right = new OpTest(4); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaConcat; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaConcatMethod; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +const unaryOperatorTests: Array<{ opType: string; operand: number; expectResult: number }> = [ + { opType: "LuaNegation", operand: 13, expectResult: -13 }, + { opType: "LuaBitwiseNot", operand: 13, expectResult: -14 }, + { opType: "LuaLength", operand: 13, expectResult: 13 }, +]; + +test.each(unaryOperatorTests)("unary operator mapping - global function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const operand = new OpTest(${operand}); + export const result = op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - static function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const operand = new OpTest(${operand}); + export const result = OpTest.op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - method (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const operand = new OpTest(${operand}); + export const result = operand.op(); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(luaTargetsPre53)("unsupported unary operator mapping (%s LuaBitwiseNot)", luaTarget => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: LuaBitwiseNot; + declare const operand: OpTest; + op(operand); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +test("operator mapping overload - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaAddition & LuaAddition; + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = op(left, right).value; + const resultB = op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaAddition & LuaAddition; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = OpTest.op(left, right).value; + const resultB = OpTest.op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaAdditionMethod & LuaAdditionMethod; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = left.op(right).value; + const resultB = left.op(13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping - method element call", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + add: LuaAdditionMethod; + } + const left = new OpTest(7); + export const result = left["add"](4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test("operator mapping - function element call", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const add: LuaAddition; + } + const left = new OpTest(7); + export const result = OpTest["add"](left, 4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test.each([ + "const foo: unknown = op;", + "const foo = `${op}`", + "declare function foo(op: LuaAddition): void; foo(op);", + "const foo = (op as any)(1, 2);", + "const foo = [op];", +])("operator mapping - invalid use (%s)", invalidCode => { + util.testModule` + declare const op: LuaAddition; + ${invalidCode} + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidOperatorMappingUse.code]); +}); From 39c7420a28d4c5fbb527d2c526656d16c37a9d69 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Jan 2021 21:13:15 +0100 Subject: [PATCH 30/91] Feature/arrayisarray (#970) * Added Array.IsArray to lualib * Fix bug in string.split lualib dependencies * Fix isArray test for empty object actually testing an object * Used Array.isArray in array.prototype.concat --- src/LuaLib.ts | 7 +++++-- src/lualib/ArrayConcat.ts | 5 ++--- src/lualib/ArrayFlat.ts | 8 +------- src/lualib/ArrayFlatMap.ts | 7 +------ src/lualib/ArrayIsArray.ts | 5 +++++ src/transformation/builtins/array.ts | 17 +++++++++++++++++ src/transformation/builtins/index.ts | 4 +++- test/unit/builtins/array.spec.ts | 20 ++++++++++++++++++++ test/unit/builtins/string.spec.ts | 7 +++++++ test/unit/spread.spec.ts | 2 +- 10 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 src/lualib/ArrayIsArray.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index fde43c604..8a3fee340 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -10,6 +10,7 @@ export enum LuaLibFeature { ArrayFindIndex = "ArrayFindIndex", ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", + ArrayIsArray = "ArrayIsArray", ArrayJoin = "ArrayJoin", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", @@ -86,8 +87,9 @@ export enum LuaLibFeature { } const luaLibDependencies: Partial> = { - ArrayFlat: [LuaLibFeature.ArrayConcat], - ArrayFlatMap: [LuaLibFeature.ArrayConcat], + ArrayConcat: [LuaLibFeature.ArrayIsArray], + ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], + ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], Decorate: [LuaLibFeature.CloneDescriptor], Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], Error: [LuaLibFeature.New, LuaLibFeature.Class], @@ -102,6 +104,7 @@ const luaLibDependencies: Partial> = { WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], + StringSplit: [LuaLibFeature.StringSubstring], SymbolRegistry: [LuaLibFeature.Symbol], }; diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index a133bb97a..30da83514 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -4,9 +4,8 @@ function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { out[out.length] = val; } for (const arg of args) { - // Hack because we don't have an isArray function - if (pcall(() => (arg as any[]).length) && type(arg) !== "string") { - const argAsArray = arg as any[]; + if (Array.isArray(arg)) { + const argAsArray = arg; for (const val of argAsArray) { out[out.length] = val; } diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index 54120e69a..2bed314cb 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,13 +1,7 @@ function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { let result: any[] = []; for (const value of array) { - if ( - depth > 0 && - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined) - ) { + if (depth > 0 && Array.isArray(value)) { result = result.concat(__TS__ArrayFlat(value, depth - 1)); } else { result[result.length] = value; diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 02d58329b..c31af9046 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -6,12 +6,7 @@ function __TS__ArrayFlatMap( let result: U[] = []; for (let i = 0; i < array.length; i++) { const value = callback(array[i], i, array); - if ( - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value as any, undefined) === undefined) - ) { + if (type(value) === "table" && Array.isArray(value)) { result = result.concat(value); } else { result[result.length] = value as U; diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts new file mode 100644 index 000000000..38a4525ef --- /dev/null +++ b/src/lualib/ArrayIsArray.ts @@ -0,0 +1,5 @@ +function __TS__ArrayIsArray(this: void, value: any): value is any[] { + // Workaround to determine if value is an array or not (fails in case of objects without keys) + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/7 + return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 35be01a00..a04e0e98b 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -6,6 +6,23 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; import { isStringType, isNumberType } from "../utils/typescript"; +export function transformArrayConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "isArray": + return transformLuaLibFunction(context, LuaLibFeature.ArrayIsArray, node, ...params); + default: + context.diagnostics.push(unsupportedProperty(expression.name, "Array", expressionName)); + } +} + export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 1125e96b2..6d7f0bd8b 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -15,7 +15,7 @@ import { } from "../utils/typescript"; import { PropertyCallExpression } from "../visitors/call"; import { checkForLuaLibType } from "../visitors/class/new"; -import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; +import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { transformGlobalCall } from "./global"; @@ -79,6 +79,8 @@ export function transformBuiltinCallExpression( if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); switch (symbol?.name) { + case "ArrayConstructor": + return transformArrayConstructorCall(context, node); case "Console": return transformConsoleCall(context, node); case "Math": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index ecaaaca53..2cabbac29 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -618,3 +618,23 @@ test.each(genericChecks)("array constrained generic length (%p)", signature => { `; expect(util.transpileAndExecute(code)).toBe(3); }); + +test.each(["[]", '"hello"', "42", "[1, 2, 3]", '{ a: "foo", b: "bar" }'])( + "Array.isArray matches JavaScript (%p)", + valueString => { + util.testExpression`Array.isArray(${valueString})`.expectToMatchJsResult(); + } +); + +test("Array.isArray returns true for empty objects", () => { + // Important edge case we cannot handle correctly due to [] and {} + // being identical in Lua. We assume [] is more common than Array.isArray({}), + // so it is more important to handle [] right, sacrificing the result for {}. + // See discussion: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + util.testExpression`Array.isArray({})`.expectToEqual(true); +}); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/738 +test("array.prototype.concat issue #738", () => { + util.testExpression`([] as any[]).concat(13, 323, {x: 3}, [2, 3])`.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 00f5c878d..37dadeedc 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -1,3 +1,4 @@ +import { LuaLibImportKind } from "../../../src"; import * as util from "../../util"; test("Supported lua string function", () => { @@ -193,6 +194,12 @@ test.each([ util.testExpressionTemplate`${inp}.split(${separator})`.expectToMatchJsResult(); }); +test("string.split inline", () => { + util.testExpression`"a, b, c".split(",")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index b3b7c95a0..3384b60fb 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -93,7 +93,7 @@ describe("in array literal", () => { test("of array literal /w OmittedExpression", () => { util.testFunction` - const array = [1, 2, ...[3], , 5]; + const array = [1, 2, ...[3], 5, , 6]; return { a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); From a67b61a30a46b1e94528a8af4c34a85d00cc99b4 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 28 Jan 2021 12:21:45 -0800 Subject: [PATCH 31/91] Added string.includes (#971) --- src/LuaLib.ts | 1 + src/lualib/StringIncludes.ts | 9 +++++++++ src/lualib/declarations/string.d.ts | 6 ++++++ src/transformation/builtins/string.ts | 2 ++ test/unit/builtins/string.spec.ts | 14 ++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 src/lualib/StringIncludes.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 8a3fee340..7168d0067 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -69,6 +69,7 @@ export enum LuaLibFeature { StringCharCodeAt = "StringCharCodeAt", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", + StringIncludes = "StringIncludes", StringPadEnd = "StringPadEnd", StringPadStart = "StringPadStart", StringReplace = "StringReplace", diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts new file mode 100644 index 000000000..cba5bf15f --- /dev/null +++ b/src/lualib/StringIncludes.ts @@ -0,0 +1,9 @@ +function __TS__StringIncludes(this: string, searchString: string, position?: number): boolean { + // http://lua-users.org/wiki/StringLibraryTutorial + if (!position) { + position = 1; + } else { + position += 1; + } + return string.find(this, searchString, position, true) !== undefined; +} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 2857690cb..778257d7f 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -14,4 +14,10 @@ declare namespace string { function sub(s: string, i: number, j?: number): string; function format(formatstring: string, ...args: any[]): string; function match(string: string, pattern: string): string; + function find( + string: string, + pattern: string, + start?: number, + plainflag?: boolean + ): MultiReturn<[number, number]> | undefined; } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 65a76d28b..4cb21ea93 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -129,6 +129,8 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringStartsWith, node, caller, ...params); case "endsWith": return transformLuaLibFunction(context, LuaLibFeature.StringEndsWith, node, caller, ...params); + case "includes": + return transformLuaLibFunction(context, LuaLibFeature.StringIncludes, node, caller, ...params); case "repeat": const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 37dadeedc..3a1cbe772 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -240,6 +240,7 @@ test.each([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["hello"] }, + { inp: "HELLO test", args: ["hello"] }, { inp: "hello test", args: ["test"] }, { inp: "hello test", args: ["test", 6] }, ])("string.startsWith (%p)", ({ inp, args }) => { @@ -249,12 +250,25 @@ test.each<{ inp: string; args: Parameters }>([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["test"] }, + { inp: "hello TEST", args: ["test"] }, { inp: "hello test", args: ["hello"] }, { inp: "hello test", args: ["hello", 5] }, ])("string.endsWith (%p)", ({ inp, args }) => { util.testExpression`"${inp}".endsWith(${util.formatCode(...args)})`.expectToMatchJsResult(); }); +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["test"] }, + { inp: "HELLO TEST", args: ["test"] }, + { inp: "hello test", args: ["hello"] }, + { inp: "HELLO TEST", args: ["hello"] }, + { inp: "hello test", args: ["hello", 5] }, + { inp: "hello test", args: ["test", 6] }, +])("string.includes (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".includes(${util.formatCode(...args)})`.expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", count: 0 }, { inp: "hello test", count: 1 }, From 8578376ce2c48a90c3ca01d4079f1acdd7b3dd67 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sat, 6 Feb 2021 07:24:47 -0800 Subject: [PATCH 32/91] Remove legacy test utils (#957) * Delete legacy-utils.ts * Updated some test suites to use new testbuilder * Added module capabilities to testbuilder * Fixed more test cases * Updated remaining test cases that used legacy utils * Fixed unused variable * Fix prettier * Fixed remaining tests Fixed function assignment test according to discord discussion (https://discord.com/channels/515854149821267971/600291243523702805/800403280512417792) Fixed hoisting by hardcoding the expected value, because the current TestBuilder.executeJS() setup does not handle module hoisting * Addressed review comments * Addressed 2nd review --- test/json.lua | 6 +- test/legacy-utils.ts | 168 ------- test/transpile/bundle.spec.ts | 3 +- .../__snapshots__/expressions.spec.ts.snap | 12 + .../__snapshots__/identifiers.spec.ts.snap | 8 + .../annotations/customConstructor.spec.ts | 9 +- test/unit/annotations/luaIterator.spec.ts | 54 +-- test/unit/annotations/luaTable.spec.ts | 52 +- test/unit/annotations/metaExtension.spec.ts | 17 +- test/unit/annotations/tupleReturn.spec.ts | 24 +- test/unit/assignments.spec.ts | 3 +- test/unit/builtins/array.spec.ts | 38 +- test/unit/builtins/map.spec.ts | 123 +++-- test/unit/builtins/string.spec.ts | 19 +- test/unit/builtins/weakMap.spec.ts | 66 +-- test/unit/builtins/weakSet.spec.ts | 41 +- test/unit/error.spec.ts | 70 ++- test/unit/expressions.spec.ts | 14 +- test/unit/functions/functions.spec.ts | 14 +- .../invalidFunctionAssignments.spec.ts.snap | 10 +- .../functionExpressionTypeInference.spec.ts | 82 ++-- .../validation/functionPermutations.ts | 2 +- .../validFunctionAssignments.spec.ts | 196 ++++---- test/unit/hoisting.spec.ts | 157 +++--- test/unit/identifiers.spec.ts | 456 ++++++++---------- test/unit/loops.spec.ts | 66 ++- test/unit/modules/modules.spec.ts | 171 +++---- test/unit/namespaces.spec.ts | 15 +- test/unit/overloads.spec.ts | 60 +-- test/unit/printer/deadCodeAfterReturn.spec.ts | 24 +- test/unit/printer/parenthesis.spec.ts | 13 +- test/util.ts | 232 ++++++--- 32 files changed, 991 insertions(+), 1234 deletions(-) delete mode 100644 test/legacy-utils.ts diff --git a/test/json.lua b/test/json.lua index e41c3798a..cd345c9b4 100644 --- a/test/json.lua +++ b/test/json.lua @@ -142,8 +142,4 @@ encode = function(val, stack) error("unexpected type '" .. t .. "'") end - --- TODO: Since it supports NaN and Infinity it is considered a superset of JSON, so it probably should be renamed -function JSONStringify(val) - return ( encode(val) ) -end +return {stringify = function(val) return ( encode(val) ) end} \ No newline at end of file diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts deleted file mode 100644 index 534c5849a..000000000 --- a/test/legacy-utils.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import * as tstl from "../src"; -import { formatPathToLuaPath } from "../src/utils"; - -export function transpileString( - str: string | { [filename: string]: string }, - options: tstl.CompilerOptions = {}, - ignoreDiagnostics = true -): string { - const { diagnostics, file } = transpileStringResult(str, options); - expect(file.lua).toBeDefined(); - - const errors = diagnostics.filter( - d => (!ignoreDiagnostics || d.source === "typescript-to-lua") && d.category === ts.DiagnosticCategory.Error - ); - expect(errors).not.toHaveDiagnostics(); - - return file.lua!.trim(); -} - -function transpileStringsAsProject(input: Record, options: tstl.CompilerOptions = {}) { - return tstl.transpileVirtualProject(input, { - luaTarget: tstl.LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: ["lib.esnext.d.ts"], - experimentalDecorators: true, - ...options, - }); -} - -function transpileStringResult( - input: string | Record, - options: tstl.CompilerOptions = {} -): Required { - const { diagnostics, transpiledFiles } = transpileStringsAsProject( - typeof input === "string" ? { "main.ts": input } : input, - options - ); - - const file = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => /\bmain\.[a-z]+$/.test(f.fileName))); - if (file === undefined) { - throw new Error('Program should have a file named "main"'); - } - - return { diagnostics, file }; -} - -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; -export function executeLua(luaStr: string, withLib = true): any { - luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); - if (withLib) { - luaStr = minimalTestLib + luaStr; - } - - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); - - if (status === lua.LUA_OK) { - // Read the return value from stack depending on its type. - if (lua.lua_isboolean(L, -1)) { - return lua.lua_toboolean(L, -1); - } else if (lua.lua_isnil(L, -1)) { - return undefined; - } else if (lua.lua_isnumber(L, -1)) { - return lua.lua_tonumber(L, -1); - } else if (lua.lua_isstring(L, -1)) { - return lua.lua_tojsstring(L, -1); - } else { - throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); - } - } else { - // If the lua VM did not terminate with status code LUA_OK an error occurred. - // Throw a JS error with the message, retrieved by reading a string from the stack. - - // Filter control characters out of string which are in there because ???? - throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20))); - } -} - -export function transpileAndExecute( - tsStr: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string, - tsHeader?: string, - ignoreDiagnostics = false -): any { - const wrappedTsString = `${tsHeader ?? ""} - declare function JSONStringify(this: void, p: any): string; - function __runTest(this: void): any {${tsStr}}`; - - const lua = `${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnostics)} - return __runTest();`; - - return executeLua(lua); -} - -function getExportPath(fileName: string, options: ts.CompilerOptions): string { - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); -} - -export function transpileAndExecuteProjectReturningMainExport( - typeScriptFiles: Record, - exportName: string, - options: tstl.CompilerOptions = {} -): [any, string] { - const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); - if (!mainFile) { - throw new Error("An entry point file needs to be specified. This should be called main.ts"); - } - - const joinedTranspiledFiles = Object.keys(typeScriptFiles) - .filter(typeScriptFileName => typeScriptFileName !== "main.ts") - .map(typeScriptFileName => { - const modulePath = getExportPath(typeScriptFileName, options); - const tsCode = typeScriptFiles[typeScriptFileName]; - const luaCode = transpileString(tsCode, options); - return `package.preload["${modulePath}"] = function() - ${luaCode} - end`; - }) - .join("\n"); - - const luaCode = `return (function() - ${joinedTranspiledFiles} - ${transpileString(typeScriptFiles[mainFile])} - end)().${exportName}`; - - try { - return [executeLua(luaCode), luaCode]; - } catch (err) { - throw new Error(` - Encountered an error when executing the following Lua code: - - ${luaCode} - - ${err} - `); - } -} - -export function transpileExecuteAndReturnExport( - tsStr: string, - returnExport: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string -): any { - const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; - ${tsStr}`; - - const lua = `return (function() - ${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - end)().${returnExport}`; - - return executeLua(lua); -} diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 21e9f153a..0ccab7c70 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -15,5 +15,6 @@ test("should transpile into one file", () => { // Verify the name is as specified in tsconfig expect(name).toBe("bundle/bundle.lua"); // Verify exported module by executing - expect(util.executeLuaModule(text)).toEqual({ myNumber: 3 }); + // Use an empty TS string because we already transpiled the TS project + util.testModule("").setLuaHeader(text).expectToEqual({ myNumber: 3 }); }); diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index d3ff509a2..b743ed0c8 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -431,6 +431,12 @@ ____exports.__result = bit.bor(a, b) return ____exports" `; +exports[`Null Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unary expressions basic ("!a") 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -523,6 +529,12 @@ end return ____exports" `; +exports[`Undefined Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unsupported bitop 5.3 ("a>>=b"): code 1`] = ` "local ____exports = {} ____exports.__result = (function() diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 6ab8a4433..d955068e5 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -128,6 +128,14 @@ exports[`ambient identifier must be a valid lua identifier (object literal short exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; +exports[`declaration-only variable with lua keyword as name is not renamed 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + type(7) +end +return ____exports" +`; + exports[`undeclared identifier must be a valid lua identifier ("$$"): code 1`] = `"foo = _____24_24_24"`; exports[`undeclared identifier must be a valid lua identifier ("$$"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index 007c64c3f..86858f700 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -19,9 +19,12 @@ test("CustomCreate", () => { } `; - const result = util.transpileAndExecute("return new Point2D(1, 2).x;", undefined, luaHeader, tsHeader); - - expect(result).toBe(1); + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule`export default new Point2D(1, 2).x;` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setReturnExport("default") + .expectToEqual(1); }); test("IncorrectUsage", () => { diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts index 46e324bc5..b1efc62ca 100644 --- a/test/unit/annotations/luaIterator.spec.ts +++ b/test/unit/annotations/luaIterator.spec.ts @@ -2,7 +2,7 @@ import * as util from "../../util"; import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; test("forof lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -13,13 +13,11 @@ test("forof lua iterator", () => { let result = ""; for (let e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof array lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Array {} @@ -30,13 +28,11 @@ test("forof array lua iterator", () => { let result = ""; for (let e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof lua iterator with existing variable", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -48,13 +44,11 @@ test("forof lua iterator with existing variable", () => { let e: string; for (e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof lua iterator destructuring", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable<[string, string]> {} @@ -65,13 +59,11 @@ test("forof lua iterator destructuring", () => { let result = ""; for (let [a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator destructuring with existing variables", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable<[string, string]> {} @@ -84,13 +76,11 @@ test("forof lua iterator destructuring with existing variables", () => { let b: string; for ([a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -106,13 +96,11 @@ test("forof lua iterator tuple-return", () => { let result = ""; for (let [a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return with existing variables", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -130,9 +118,7 @@ test("forof lua iterator tuple-return with existing variables", () => { let b: string; for ([a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return single variable", () => { @@ -161,7 +147,7 @@ test("forof lua iterator tuple-return single existing variable", () => { }); test("forof forwarded lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -177,13 +163,11 @@ test("forof forwarded lua iterator", () => { let result = ""; for (let a of forward()) { result += a; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof forwarded lua iterator with tupleReturn", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -203,7 +187,5 @@ test("forof forwarded lua iterator with tupleReturn", () => { let result = ""; for (let [a, b] of forward()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts index 8829938bb..0f9cbbf36 100644 --- a/test/unit/annotations/luaTable.spec.ts +++ b/test/unit/annotations/luaTable.spec.ts @@ -35,41 +35,47 @@ declare let tbl: Table; `; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule(tableLib + "const table = new Table(true);").expectDiagnosticsToMatchSnapshot([ - luaTableForbiddenUsage.code, - ]); + util.testModule("const table = new Table(true);") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])( "LuaTable set() cannot be used in a LuaTable call expression", tableLib => { - util.testModule(tableLib + 'const exp = tbl.set("value", 5)').expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); + util.testModule('const exp = tbl.set("value", 5)') + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); } ); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule("tbl.other()").setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "let x = tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule("let x = tbl.other()") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass])("LuaTable new", tableLib => { - const content = tableLib + "tbl = new Table();"; - expect(util.transpileString(content)).toEqual("tbl = {}"); + expect(util.testFunction("tbl = new Table();").setTsHeader(tableLib).getMainLuaCodeChunk()).toContain("tbl = {}"); }); test.each([tableLibClass])("LuaTable length", tableLib => { - const content = tableLib + "tbl = new Table();\nreturn tbl.length;"; - const lua = util.transpileString(content); - expect(util.executeLua(lua)).toEqual(0); + util.testFunction` + tbl = new Table(); + return tbl.length; + ` + .setTsHeader(tableLib) + .expectToEqual(0); }); test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule(tableLib + "tbl.length = 2;").expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); + util.testModule("tbl.length = 2;") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { @@ -82,7 +88,9 @@ test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib 'tbl.set(...(["field", 0] as const))', 'tbl.set("field", ...([0] as const))', ])("Forbidden LuaTable use (%p)", invalidCode => { - util.testModule(tableLib + invalidCode).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); + util.testModule(invalidCode) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); }); @@ -90,7 +98,9 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( "Cannot extend LuaTable class (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); + util.testModule(code) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); } ); }); @@ -105,7 +115,7 @@ test.each([ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); + util.testModule(code).setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); }); }); @@ -113,9 +123,9 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( "Cannot use ElementAccessExpression on a LuaTable (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([ - luaTableCannotBeAccessedDynamically.code, - ]); + util.testModule(code) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableCannotBeAccessedDynamically.code]); } ); }); @@ -136,6 +146,6 @@ test.each([tableLibClass])("LuaTable functional tests", tableLib => { ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], ])("LuaTable test (%p)", (code, expectedReturnValue) => { - expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); + util.testFunction(code).setTsHeader(tableLib).expectToEqual(expectedReturnValue); }); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index aec48f4cf..b0fa56578 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -19,15 +19,14 @@ test("MetaExtension", () => { } `; - const result = util.transpileAndExecute( - 'return debug.getregistry()["_LOADED"].test();', - undefined, - undefined, - tsHeader, - true - ); - - expect(result).toBe(5); + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule` + export default debug.getregistry()["_LOADED"].test(); + ` + .setTsHeader(tsHeader) + .ignoreDiagnostics([annotationDeprecated.code]) + .setReturnExport("default") + .expectToEqual(5); }); test("IncorrectUsage", () => { diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts index 7c7c7ae9b..337e52c37 100644 --- a/test/unit/annotations/tupleReturn.spec.ts +++ b/test/unit/annotations/tupleReturn.spec.ts @@ -405,39 +405,27 @@ test("TupleReturn method assignment", () => { }); test("TupleReturn functional", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } const [a, b] = abc(); return b + a; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); + `.expectToMatchJsResult(); }); test("TupleReturn single", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } const res = abc(); return res.length - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe(2); + `.expectToMatchJsResult(); }); test("TupleReturn in expression", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } return abc()[1] + abc()[0]; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index d2d80f08b..5f9209c41 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -12,7 +12,8 @@ test.each(["const", "let"])("%s declaration not top-level is not global", declar }); test.each(["const", "let"])("top-level %s declaration is global", declarationKind => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo; ` diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 2cabbac29..584f686bb 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -594,29 +594,27 @@ const genericChecks = [ ]; test.each(genericChecks)("array constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - let sum = 0; - array.forEach(item => { - if (typeof item === "number") { - sum += item; - } - }); - return sum; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + let sum = 0; + array.forEach(item => { + if (typeof item === "number") { + sum += item; + } + }); + return sum; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); }); test.each(genericChecks)("array constrained generic length (%p)", signature => { - const code = ` - ${signature}: number { - return array.length; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(3); + util.testFunction` + ${signature}: number { + return array.length; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); }); test.each(["[]", '"hello"', "42", "[1, 2, 3]", '{ a: "foo", b: "bar" }'])( diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index e9edd2508..7eec8844d 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -1,95 +1,94 @@ import * as util from "../../util"; test("map constructor", () => { - const result = util.transpileAndExecute("let mymap = new Map(); return mymap.size;"); - - expect(result).toBe(0); + util.testFunction` + let mymap = new Map(); + return mymap.size; + `.expectToMatchJsResult(); }); test("map iterable constructor", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); - return mymap.has("a") && mymap.has("b");` - ); - - expect(result).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.has("a") && mymap.has("b"); + `.expectToMatchJsResult(); }); test("map iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` let mymap = new Map(new Map([["a", "c"],["b", "d"]])); return mymap.has("a") && mymap.has("b"); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("map clear", () => { const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();'; - const size = util.transpileAndExecute(mapTS + "return mymap.size;"); - expect(size).toBe(0); + util.testExpression("mymap.size").setTsHeader(mapTS).expectToMatchJsResult(); - const contains = util.transpileAndExecute(mapTS + 'return !mymap.has("a") && !mymap.has("b");'); - expect(contains).toBe(true); + util.testExpression('!mymap.has("a") && !mymap.has("b")').setTsHeader(mapTS).expectToMatchJsResult(); }); test("map delete", () => { - const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");'; - const contains = util.transpileAndExecute(mapTS + 'return mymap.has("b") && !mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + mymap.delete("a"); + return mymap.has("b") && !mymap.has("a"); + `.expectToMatchJsResult(); }); test("map entries", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const [key, value] of mymap.entries()) { count += key + value; } - return count;` - ); - expect(result).toBe(27); + return count; + `.expectToMatchJsResult(); }); test("map foreach", () => { - const result = util.transpileAndExecute( + util.testFunction( `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); let count = 0; mymap.forEach(i => count += i); return count;` - ); - - expect(result).toBe(9); + ).expectToMatchJsResult(); }); test("map foreach keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; mymap.forEach((value, key) => { count += key; }); - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map get", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");'); - - expect(result).toBe("c"); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("a"); + `.expectToMatchJsResult(); }); test("map get missing", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");'); - expect(result).toBeUndefined(); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("c"); + `.expectToMatchJsResult(); }); test("map has", () => { - const contains = util.transpileAndExecute('let mymap = new Map([["a", "c"]]); return mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"]]); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test("map has false", () => { - const contains = util.transpileAndExecute('let mymap = new Map(); return mymap.has("a");'); - expect(contains).toBe(false); + util.testFunction` + let mymap = new Map(); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test.each([ @@ -117,42 +116,36 @@ test.each([ }); test("map keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const key of mymap.keys()) { count += key; } - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map set", () => { const mapTS = 'let mymap = new Map(); mymap.set("a", 5);'; - const has = util.transpileAndExecute(mapTS + 'return mymap.has("a");'); - expect(has).toBe(true); + util.testFunction(mapTS + 'return mymap.has("a");').expectToMatchJsResult(); - const value = util.transpileAndExecute(mapTS + 'return mymap.get("a")'); - expect(value).toBe(5); + util.testFunction(mapTS + 'return mymap.get("a")').expectToMatchJsResult(); }); test("map values", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const value of mymap.values()) { count += value; } - return count;` - ); - - expect(result).toBe(9); + return count; + `.expectToMatchJsResult(); }); test("map size", () => { - expect(util.transpileAndExecute("let m = new Map(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map(); m.set(1,3); return m.size;")).toBe(1); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); return m.size;")).toBe(2); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;")).toBe(1); + util.testFunction("let m = new Map(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map(); m.set(1,3); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;").expectToMatchJsResult(); }); const iterationMethods = ["entries", "keys", "values"]; diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 3a1cbe772..5e1790573 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -165,9 +165,9 @@ test.each([ { inp: "hello test", start: 3, ignored: 0, end: 2 }, ])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - - expect(result).toBe(inp.substr(start, end)); + util.testExpression` + "${inp}".substr(${paramStr}) + `.expectToMatchJsResult(); }); test.each(["", "h", "hello"])("string.length (%p)", input => { @@ -303,13 +303,12 @@ test.each([ "function generic(string: T)", "type StringType = string; function generic(string: T)", ])("string constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - return string.length; - } - return generic("string"); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + return string.length; + } + return generic("string"); + `.expectToMatchJsResult(); }); const trimTestCases = [ diff --git a/test/unit/builtins/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts index ab3ba12fb..812e43622 100644 --- a/test/unit/builtins/weakMap.spec.ts +++ b/test/unit/builtins/weakMap.spec.ts @@ -6,94 +6,76 @@ const initRefsTs = ` `; test("weakMap constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [ref2, 2]]); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap(new Map([[ref, 1], [ref2, 2]])); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true], [ref2, true]]); mymap.delete(ref2); return mymap.has(ref) && !mymap.has(ref2); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap get", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [{}, 2]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap get missing", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.get({}); - `); - - expect(result).toBeUndefined(); + `.expectToMatchJsResult(); }); test("weakMap has", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap has false", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref2); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap has null", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.has(null); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap set", () => { @@ -103,20 +85,20 @@ test("weakMap set", () => { mymap.set(ref, 5); `; - const has = util.transpileAndExecute(init + "return mymap.has(ref);"); - expect(has).toBe(true); + util.testFunction(init + "return mymap.has(ref);").expectToMatchJsResult(); - const value = util.transpileAndExecute(init + "return mymap.get(ref)"); - expect(value).toBe(5); + util.testFunction(init + "return mymap.get(ref)").expectToMatchJsResult(); }); test("weakMap has no map features (size)", () => { - expect(util.transpileAndExecute("return (new WeakMap() as any).size")).toBeUndefined(); + util.testExpression("(new WeakMap() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakMap has no map features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakMap() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakMap() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/builtins/weakSet.spec.ts b/test/unit/builtins/weakSet.spec.ts index fe6accf45..33c5e80c3 100644 --- a/test/unit/builtins/weakSet.spec.ts +++ b/test/unit/builtins/weakSet.spec.ts @@ -6,74 +6,65 @@ const initRefsTs = ` `; test("weakSet constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref]); return myset.has(ref) - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor set", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(new Set([ref, ref2])); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add(ref); return myset.has(ref); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add different references", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add({}); return myset.has({}); - `); - - expect(result).toBe(false); + `.expectToMatchJsResult(); }); test("weakSet delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); myset.delete(ref); return myset.has(ref2) && !myset.has(ref); - `); - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet has no set features (size)", () => { - expect(util.transpileAndExecute("return (new WeakSet() as any).size")).toBeUndefined(); + util.testExpression("(new WeakSet() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakSet has no set features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakSet() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakSet() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 27e0ce839..9174f941c 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -51,7 +51,7 @@ test("re-throw (no catch var)", () => { }); test("return from try", () => { - const code = ` + util.testFunction` function foobar() { try { return "foobar"; @@ -59,12 +59,11 @@ test("return from try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return nil from try", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -75,12 +74,11 @@ test("return nil from try", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); test("tuple return from try", () => { - const code = ` + const testBuilder = util.testFunction` /** @tupleReturn */ function foobar() { try { @@ -91,12 +89,12 @@ test("tuple return from try", () => { const [foo, bar] = foobar(); return foo + bar; `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toBe("foobar"); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -105,12 +103,11 @@ test("return from catch", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + `.expectToMatchJsResult(); }); test("return nil from catch", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -122,12 +119,11 @@ test("return nil from catch", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); test("tuple return from catch", () => { - const code = ` + const testBuilder = util.testFunction` /** @tupleReturn */ function foobar(): [string, string] { try { @@ -139,12 +135,12 @@ test("tuple return from catch", () => { const [foo, bar] = foobar(); return foo + bar; `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from nested try", () => { - const code = ` + util.testFunction` function foobar() { try { try { @@ -155,12 +151,11 @@ test("return from nested try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return from nested catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -173,15 +168,11 @@ test("return from nested catch", () => { } } return foobar(); - `; - const result = util.transpileAndExecute(code); - expect(result).toMatch("catch1"); - expect(result).toMatch("catch2"); - expect(result).toMatch("foobar"); + `.expectToMatchJsResult(); }); test("return from try->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -196,12 +187,11 @@ test("return from try->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("return from catch->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -217,12 +207,11 @@ test("return from catch->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("tuple return from try->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; @@ -239,12 +228,11 @@ test("tuple return from try->finally", () => { } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("tuple return from catch->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; @@ -262,12 +250,11 @@ test("tuple return from catch->finally", () => { } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("return from nested finally", () => { - const code = ` + util.testFunction` let x = ""; function foobar() { try { @@ -282,8 +269,7 @@ test("return from nested finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally AB"); + `.expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 6720fe8fb..fd6c8ab0d 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -30,12 +30,10 @@ test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1 ); test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Binary expression in (%p)", input => { - const tsHeader = "declare var obj: any;"; - const tsSource = `return ${input}`; - const luaHeader = "obj = { existingKey = 1 }"; - const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); - - expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); + util.testFunction` + let obj = { existingKey: 1 }; + return ${input}; + `.expectToMatchJsResult(); }); test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions overridden operators (%p)", input => { @@ -119,11 +117,11 @@ test("Binary Comma Statement in For Loop", () => { }); test("Null Expression", () => { - expect(util.transpileString("null")).toBe("local ____ = nil"); + util.testExpression("null").expectLuaToMatchSnapshot(); }); test("Undefined Expression", () => { - expect(util.transpileString("undefined")).toBe("local ____ = nil"); + util.testExpression("undefined").expectLuaToMatchSnapshot(); }); test.each(["i++", "i--", "++i", "--i"])("Incrementor value (%p)", expression => { diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 20f76e273..2d9d8f1e3 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -66,19 +66,12 @@ test("Function default parameter", () => { }); test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - const callArgs = inp.join(","); - const result = util.transpileAndExecute( + util.testFunction( `let add = function(a: number = 3, b: number = 4) { return a+b; }; return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); + ).expectToMatchJsResult(); }); test("Function default array binding parameter", () => { @@ -476,7 +469,8 @@ test("missing declaration name", () => { }); test("top-level function declaration is global", () => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo(); ` diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index 55e61f9ae..7ed8e7560 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -247,7 +247,7 @@ exports[`Invalid function argument ({"definition": "interface FuncPropInterface const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -639,7 +639,7 @@ exports[`Invalid function assignment ({"definition": "interface FuncPropInterfac const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1031,7 +1031,7 @@ exports[`Invalid function generic argument ({"definition": "interface FuncPropIn const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1391,7 +1391,7 @@ exports[`Invalid function return ({"definition": "interface FuncPropInterface { const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1791,7 +1791,7 @@ exports[`Invalid function variable declaration ({"definition": "interface FuncPr const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ diff --git a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts index e475f2216..abac4e483 100644 --- a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -13,7 +13,7 @@ test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", no const c = new NS.C(); return c.method(foo); `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + util.testFunction(code).setTsHeader(header).expectToMatchJsResult(); }); test("noSelfInFile works when first statement has other annotations", () => { @@ -30,20 +30,21 @@ test("noSelfInFile works when first statement has other annotations", () => { test.each(["(this: void, s: string) => string", "(this: any, s: string) => string", "(s: string) => string"])( "Function expression type inference in binary operator (%p)", funcType => { - const header = `declare const undefinedFunc: ${funcType};`; - const code = ` - let func: ${funcType} = s => s; - func = undefinedFunc || (s => s); - return func("foo"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + const header = `let undefinedFunc: (${funcType}) | undefined;`; + util.testFunction` + let func: ${funcType} = s => s; + func = undefinedFunc || (s => s); + return func("foo"); + ` + .setTsHeader(header) + .expectToMatchJsResult(); } ); test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { return s; })"])( "Function expression type inference in class (%p)", funcExp => { - const code = ` + util.testFunction` class Foo { func: (this: void, s: string) => string = ${funcExp}; method: (s: string) => string = ${funcExp}; @@ -52,8 +53,7 @@ test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { re } const foo = new Foo(); return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d"); - `; - expect(util.transpileAndExecute(code)).toBe("abcd"); + `.expectToMatchJsResult(); } ); @@ -67,23 +67,21 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (%p)", ({ assignTo, funcExp }) => { - const code = ` + util.testFunction` interface Foo { func(this: void, s: string): string; method(this: this, s: string): string; } ${assignTo} = {func: ${funcExp}, method: ${funcExp}}; return foo.method("foo") + foo.func("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("Function expression type inference in object literal assigned to narrower type", () => { - const code = ` + util.testFunction` let foo: {} = {bar: s => s}; return (foo as {bar: (a: any) => any}).bar("foobar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -96,14 +94,13 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (generic key) (%p)", ({ assignTo, funcExp }) => { - const code = ` - interface Foo { - [f: string]: (this: void, s: string) => string; - } - ${assignTo} = {func: ${funcExp}}; - return foo.func("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + util.testFunction` + interface Foo { + [f: string]: (this: void, s: string) => string; + } + ${assignTo} = {func: ${funcExp}}; + return foo.func("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -204,7 +201,7 @@ test.each([ funcExp: "(function(s) { return s; })", }, ])("Function expression type inference in tuple (%p)", ({ assignTo, func, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -217,8 +214,7 @@ test.each([ ${assignTo} = [${funcExp}, ${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo") + ${func}("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -239,7 +235,7 @@ test.each([ { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "function(s) { return s; }" }, { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in array (%p)", ({ assignTo, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -249,8 +245,7 @@ test.each([ ${assignTo} = [${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -261,12 +256,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` type U = string | number | (${funcType}); const u: U = ${funcExp}; return (u as ${funcType})("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -277,12 +271,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union tuple (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` interface I { callback: ${funcType}; } let a: I[] | number = [{ callback: ${funcExp} }]; return a[0].callback("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -293,11 +286,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in as cast (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = (${funcExp}) as (${funcType}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -308,11 +300,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in type assertion (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = <${funcType}>(${funcExp}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -323,13 +314,12 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in constructor (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` class C { result: string; constructor(fn: ${funcType}) { this.result = fn("foo"); } } const c = new C(${funcExp}); return c.result; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index ebf00dfae..f95af8ab3 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -87,7 +87,7 @@ export const selfTestFunctions: TestFunction[] = [ { value: "methodInterface.method", definition: `interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };`, }, { value: "anonMethodInterface.anonMethod", diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index a491ccd7b..d9613692d 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -15,54 +15,64 @@ import { } from "./functionPermutations"; test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { - const code = `const fn: ${functionType} = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + const fn: ${functionType} = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function assignment (%p)", (testFunction, functionType) => { - const code = `let fn: ${functionType}; - fn = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: ${functionType}; + fn = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function assignment with cast (%p)", (testFunction, castedFunction) => { - const code = ` - let fn: typeof ${testFunction.value}; - fn = ${castedFunction}; - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFunction, functionType) => { - const code = ` - function takesFunction(fn: ${functionType}) { - return fn("foobar"); - } - return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: ${functionType}) { + return fn("foobar"); + } + return takesFunction(${testFunction.value}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid lua lib function argument", () => { - const code = `let result = ""; + util.testFunction` + let result = ""; function foo(this: any, value: string) { result += value; } const a = ['foo', 'bar']; a.forEach(foo); - return result;`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function argument with cast (%p)", (testFunction, castedFunction) => { - const code = ` - function takesFunction(fn: typeof ${testFunction.value}) { - return fn("foobar"); - } - return takesFunction(${castedFunction}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: typeof ${testFunction.value}) { + return fn("foobar"); + } + return takesFunction(${castedFunction}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ @@ -77,60 +87,66 @@ test.each([ ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ])("Valid function generic argument (%p)", (testFunction, functionType) => { - const code = ` + util.testFunction` function takesFunction(fn: T) { return fn("foobar"); } return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ ...anonTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...selfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...noSelfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["'foobar'"]]), -])("Valid function expression argument with no signature (%p)", (testFunction, args) => { - const code = ` +])("Valid function expression argument with no signature (%p, %p)", (testFunction, args) => { + util.testFunction` const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { return fn(...args); } return takesFunction(${testFunction.value}, ${args.join(", ")}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToEqual("foobar"); }); test.each(validTestFunctionAssignments)("Valid function return (%p)", (testFunction, functionType) => { - const code = ` - function returnsFunction(): ${functionType} { - return ${testFunction.value}; - } - const fn = returnsFunction(); - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function return with cast (%p)", (testFunction, castedFunction) => { - const code = `function returnsFunction(): typeof ${testFunction.value} { - return ${castedFunction}; - } - const fn = returnsFunction(); - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid function tuple assignment", () => { - const code = `interface Func { (this: void, s: string): string; } - function getTuple(): [number, Func] { return [1, s => s]; } - let [i, f]: [number, Func] = getTuple(); - return f("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Func { (this: void, s: string): string; } + function getTuple(): [number, Func] { return [1, s => s]; } + let [i, f]: [number, Func] = getTuple(); + return f("foo"); + `.expectToMatchJsResult(); }); test("Interface method assignment", () => { - const code = ` + util.testFunction` class Foo { method(s: string): string { return s + "+method"; } lambdaProp: (s: string) => string = s => s + "+lambdaProp"; @@ -141,46 +157,44 @@ test("Interface method assignment", () => { } const foo: IFoo = new Foo(); return foo.method("foo") + "|" + foo.lambdaProp("bar"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo+method|bar+lambdaProp"); + `.expectToMatchJsResult(); }); test("Valid interface method assignment", () => { - const code = `interface A { fn(this: void, s: string): string; } - interface B { fn(this: void, s: string): string; } - const a: A = { fn(this: void, s) { return s; } }; - const b: B = a; - return b.fn("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface A { fn(this: void, s: string): string; } + interface B { fn(this: void, s: string): string; } + const a: A = { fn(this: void, s) { return s; } }; + const b: B = a; + return b.fn("foo"); + `.expectToMatchJsResult(); }); test("Valid method tuple assignment", () => { - const code = `interface Foo { method(s: string): string; } - interface Meth { (this: Foo, s: string): string; } - let meth: Meth = s => s; - function getTuple(): [number, Meth] { return [1, meth]; } - let [i, f]: [number, Meth] = getTuple(); - let foo: Foo = {method: f}; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Foo { method(s: string): string; } + interface Meth { (this: Foo, s: string): string; } + let meth: Meth = s => s; + function getTuple(): [number, Meth] { return [1, meth]; } + let [i, f]: [number, Meth] = getTuple(); + let foo: Foo = {method: f}; + return foo.method("foo"); + `.expectToMatchJsResult(); }); test.each([ - { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, - { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, - { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"], expectResult: "foobaz" }, - { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"], expectResult: "foobaz" }, -])("Valid function overload assignment (%p)", ({ assignType, args, expectResult }) => { - const code = `interface O { - (s1: string, s2: string): string; - (s: string): string; - } - const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); - let f: ${assignType} = o; - return f(${args.map(a => '"' + a + '"').join(", ")});`; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + { assignType: "(this: any, s: string) => string", args: ["foo"] }, + { assignType: "{(this: any, s: string): string}", args: ["foo"] }, + { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"] }, + { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"] }, +])("Valid function overload assignment (%p)", ({ assignType, args }) => { + util.testFunction` + interface O { + (s1: string, s2: string): string; + (s: string): string; + } + const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); + let f: ${assignType} = o; + return f(${args.map(a => '"' + a + '"').join(", ")}); + `.expectToMatchJsResult(); }); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 16172b410..9caefb300 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -2,110 +2,101 @@ import * as ts from "typescript"; import * as util from "../util"; test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { - const code = ` + util.testFunction` let bar: string; function setBar() { bar = foo; } ${varType} foo = "foo"; setBar(); return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test.each(["let", "const"])("Exported Let/Const Hoisting (%p)", varType => { - const code = ` + util.testModule` let bar: string; function setBar() { bar = foo; } export ${varType} foo = "foo"; setBar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Global Function Hoisting", () => { - const code = ` + util.testFunction` const foo = bar(); function bar() { return "bar"; } return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Local Function Hoisting", () => { - const code = ` + util.testModule` export const foo = bar(); function bar() { return "bar"; } - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Exported Function Hoisting", () => { - const code = ` + util.testModule` const foo = bar(); export function bar() { return "bar"; } export const baz = foo; - `; - const result = util.transpileExecuteAndReturnExport(code, "baz"); - expect(result).toBe("bar"); + ` + .setReturnExport("baz") + .expectToMatchJsResult(); }); test("Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction` + return foo; + ` + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); test("Exported Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - export function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction("return foo;") + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + export function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); -test.each([ - { varType: "let", expectResult: "bar" }, - { varType: "const", expectResult: "bar" }, -])("Hoisting in Non-Function Scope (%p)", ({ varType, expectResult }) => { - const code = ` - function foo() { - ${varType} bar = "bar"; - for (let i = 0; i < 1; ++i) { - ${varType} bar = "foo"; - } - return bar; +test.each(["let", "const"])("Hoisting in Non-Function Scope (%p)", varType => { + util.testFunction` + function foo() { + ${varType} bar = "bar"; + for (let i = 0; i < 1; ++i) { + ${varType} bar = "foo"; } - return foo(); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + return bar; + } + return foo(); + `.expectToMatchJsResult(); }); test("Hoisting due to reference from hoisted function", () => { - const code = ` + util.testFunction` const foo = "foo"; const result = bar(); function bar() { return foo; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Hoisting with synthetic source file node", () => { @@ -131,7 +122,7 @@ test("Hoisting with synthetic source file node", () => { }); test("Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -139,13 +130,11 @@ test("Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Exported Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -153,9 +142,7 @@ test("Exported Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Nested Namespace Hoisting", () => { @@ -176,7 +163,7 @@ test("Nested Namespace Hoisting", () => { }); test("Class Hoisting", () => { - const code = ` + util.testModule` function makeFoo() { return new Foo(); } @@ -184,13 +171,11 @@ test("Class Hoisting", () => { public bar = "foo"; } export const foo = makeFoo().bar; - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Enum Hoisting", () => { - const code = ` + util.testModule` function bar() { return E.A; } @@ -198,13 +183,14 @@ test("Enum Hoisting", () => { A = "foo" } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToHaveNoDiagnostics(); }); test("Import hoisting (named)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = foo; import { foo } from "./module"; ` @@ -213,16 +199,22 @@ test("Import hoisting (named)", () => { }); test("Import hoisting (namespace)", () => { - util.testBundle` - export const result = module.foo; - import * as module from "./module"; + // TODO cant be tested with expectToEqualJSresult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` + export const result = m.foo; + import * as m from "./module"; ` .addExtraFile("module.ts", "export const foo = true;") .expectToEqual({ result: true }); }); test("Import hoisting (side-effect)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = (globalThis as any).result; import "./module"; ` @@ -231,7 +223,8 @@ test("Import hoisting (side-effect)", () => { }); test("Import hoisted before function", () => { - util.testBundle` + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule` export let result: any; baz(); @@ -246,13 +239,13 @@ test("Import hoisted before function", () => { }); test("Hoisting Shorthand Property", () => { - const code = ` + util.testFunction` function foo() { return { bar }.bar; } let bar = "foobar"; - return foo();`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo(); + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944 diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index ba2bcd8a0..9f72ad671 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -132,20 +132,21 @@ test.each(validTsInvalidLuaNames)( ); test.each(validTsInvalidLuaNames)("exported values with invalid lua identifier names (%p)", name => { - const code = `export const ${name} = "foobar";`; - const lua = util.transpileString(code); + const testBuilder = util.testModule(`export const ${name} = "foobar";`); + const lua = testBuilder.getMainLuaCodeChunk(); + const luaResult = testBuilder.getLuaExecutionResult(); expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); - expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); + expect(luaResult[name]).toBe("foobar"); }); test("exported identifiers referenced in namespace (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace NS { export const bar = foo; } - export const baz = NS.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = NS.bar; + `.expectToMatchJsResult(); }); test("exported namespace identifiers referenced in different namespace (%p)", () => { @@ -157,31 +158,31 @@ test("exported namespace identifiers referenced in different namespace (%p)", () } export const baz = B.bar; }`; - expect(util.transpileAndExecute("return A.baz", undefined, undefined, tsHeader)).toBe("foobar"); + util.testFunction("return A.baz").setTsHeader(tsHeader).expectToMatchJsResult(); }); test("exported identifiers referenced in nested scope (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace A { export namespace B { export const bar = foo; } } - export const baz = A.B.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = A.B.bar; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaNames)( "exported values with invalid lua identifier names referenced in different scope (%p)", name => { - const code = ` - export const ${name} = "foobar"; - namespace NS { - export const foo = ${name}; - } - export const bar = NS.foo;`; - expect(util.transpileExecuteAndReturnExport(code, "bar")).toBe("foobar"); + util.testModule` + export const ${name} = "foobar"; + namespace NS { + export const foo = ${name}; + } + export const bar = NS.foo; + `.expectToMatchJsResult(); } ); @@ -223,103 +224,92 @@ test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua nam describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { - const code = ` + util.testFunction` const nil = "foobar"; - return \`\${undefined}|\${nil}\``; - - expect(util.transpileAndExecute(code)).toBe("nil|foobar"); + return \`\${undefined}|\${nil}\` + `.expectToEqual("nil|foobar"); }); test("variable (and)", () => { - const code = ` + util.testFunction` const and = "foobar"; - return true && and;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return true && and; + `.expectToMatchJsResult(); }); test("variable (elseif)", () => { - const code = ` + util.testFunction` const elseif = "foobar"; if (false) { } else if (elseif) { return elseif; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (end)", () => { - const code = ` + util.testFunction` const end = "foobar"; { return end; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (local)", () => { - const code = ` + util.testFunction` const local = "foobar"; - return local;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return local; + `.expectToMatchJsResult(); }); test("variable (not)", () => { - const code = ` + util.testFunction` const not = "foobar"; - return (!false) && not;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (!false) && not; + `.expectToMatchJsResult(); }); test("variable (or)", () => { - const code = ` + util.testFunction` const or = "foobar"; - return false || or;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return false || or; + `.expectToMatchJsResult(); }); test("variable (repeat)", () => { - const code = ` + util.testFunction` const repeat = "foobar"; do {} while (false); - return repeat;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return repeat; + `.expectToMatchJsResult(); }); test("variable (then)", () => { - const code = ` + util.testFunction` const then = "foobar"; if (then) { return then; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (until)", () => { - const code = ` + util.testFunction` const until = "foobar"; do {} while (false); - return until;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return until; + `.expectToMatchJsResult(); }); test("variable (goto)", () => { - const code = ` + util.testFunction` const goto = "foobar"; switch (goto) { case goto: return goto; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (print)", () => { @@ -332,42 +322,48 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` - const print = "foobar"; - console.log(print); - return result;`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toBe("foobar"); + util.testFunction` + const print = "foobar"; + console.log(print); + return result; + ` + .setLuaHeader(luaHeader) + .setTsHeader(tsHeader) + .setOptions(compilerOptions) + .expectToEqual("foobar"); }); test("variable (type)", () => { - const code = ` + util.testFunction` function type(this: void, a: unknown) { return (typeof a) + "|foobar"; } - return type(7);`; - - expect(util.transpileAndExecute(code)).toBe("number|foobar"); + return type(7); + `.expectToMatchJsResult(); }); test("variable (error)", () => { - const code = ` + const executionResult = util.testFunction` const error = "foobar"; - throw error;`; + throw error; + `.getLuaExecutionResult(); - expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: foobar$/); + expect(executionResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (assert)", () => { - const code = ` - const assert = false; - console.assert(assert, "foobar");`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow(/^LUA ERROR: .+ foobar$/); + const luaResult = util.testFunction` + const assert = false; + console.assert(assert, "foobar"); + ` + .setOptions(compilerOptions) + .getLuaExecutionResult(); + + expect(luaResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (debug)", () => { @@ -380,297 +376,272 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + const luaResult = util.testFunction` const debug = "foobar"; console.trace(debug); - return result;`; - - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + return result; + ` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setOptions(compilerOptions) + .getLuaExecutionResult(); - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toMatch( - /^foobar\nstack traceback.+/ - ); + expect(luaResult).toMatch(/^foobar\nstack traceback.+/); }); test("variable (string)", () => { - const code = ` + util.testFunction` const string = "foobar"; - return string[0];`; - - expect(util.transpileAndExecute(code)).toBe("f"); + return string[0]; + `.expectToMatchJsResult(); }); test("variable (math)", () => { - const code = ` + util.testFunction` const math = -17; - return Math.abs(math);`; - - expect(util.transpileAndExecute(code)).toBe(17); + return Math.abs(math); + `.expectToMatchJsResult(); }); test("variable (table)", () => { - const code = ` + util.testFunction` const table = ["foobar"]; - return table.pop();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return table.pop(); + `.expectToMatchJsResult(); }); test("variable (coroutine)", () => { - const code = ` + util.testFunction` const coroutine = "foobar"; function *foo() { yield coroutine; } - return foo().next().value;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo().next().value; + `.expectToMatchJsResult(); }); test("variable (pairs)", () => { - const code = ` + util.testFunction` const pairs = {foobar: "foobar"}; let result = ""; for (const key in pairs) { result += key; } - return result;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test("variable (pcall)", () => { - const code = ` + util.testFunction` const pcall = "foobar"; try {} finally {} - return pcall;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return pcall; + `.expectToMatchJsResult(); }); test("variable (rawget)", () => { - const code = ` + util.testFunction` const rawget = {foobar: "foobar"}; - return rawget.hasOwnProperty("foobar");`; - - expect(util.transpileAndExecute(code)).toBe(true); + return rawget.hasOwnProperty("foobar"); + `.expectToMatchJsResult(); }); test("variable (require)", () => { - const code = ` + const luaHeader = 'package.loaded.someModule = {foo = "bar"}'; + + const luaResult = util.testModule` const require = "foobar"; export { foo } from "someModule"; - export const result = require;`; - - const lua = ` - package.loaded.someModule = {foo = "bar"} - return (function() - ${util.transpileString(code, undefined, true)} - end)().result`; + export const result = require; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult.result).toBe("foobar"); }); test("variable (tostring)", () => { - const code = ` + util.testFunction` const tostring = 17; - return tostring.toString();`; - - expect(util.transpileAndExecute(code)).toBe(17); + return tostring.toString(); + `.expectToMatchJsResult(); }); test("variable (unpack)", () => { - const code = ` - const unpack = ["foo", "bar"]; - const [foo, bar] = unpack;`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = "unpack = table.unpack"; - const lua = ` - unpack = table.unpack - ${util.transpileString(code, undefined, false)} - return foo .. bar`; + const luaResult = util.testFunction` + const unpack = ["foo", "bar"]; + const [foo, bar] = unpack; + return foo + bar; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult).toBe("foobar"); }); test("variable (_G)", () => { - const code = ` + util.testFunction` const _G = "bar"; (globalThis as any).foo = "foo"; return (globalThis as any).foo + _G; - `; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("function parameter", () => { - const code = ` + util.testFunction` function foo(type: unknown) { return \`\${typeof type}|\${type}\`; } - return foo("foobar");`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo("foobar"); + `.expectToMatchJsResult(); }); test("destructured property function parameter", () => { - const code = ` + util.testFunction` function foo({type}: any) { return \`\${typeof type}|\${type}\`; } - return foo({type: "foobar"});`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo({type: "foobar"}); + `.expectToMatchJsResult(); }); test("destructured array element function parameter", () => { - const code = ` + util.testFunction` function foo([type]: any) { return \`\${typeof type}|\${type}\`; } - return foo(["foobar"]);`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo(["foobar"]); + `.expectToMatchJsResult(); }); test("property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type: type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("shorthand property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type: type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured shorthand property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured array element", () => { - const code = ` + util.testFunction` const foo = ["foobar"]; const [type] = foo; - return type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|string"); + return type + "|" + typeof type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("imported variable (%p)", importName => { - const luaHeader = ` - package.loaded.someModule = {type = "foobar"}`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - const code = ` + const luaResult = util.testModule` import {${importName}} from "someModule"; export const result = typeof 7 + "|" + type; - `; - - const lua = util.transpileString(code); - const result = util.executeLua(`${luaHeader} return (function() ${lua} end)().result`); + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(result).toBe("number|foobar"); + expect(luaResult.result).toBe("number|foobar"); }); - test.each([ - { returnExport: "type", expectResult: "foobar" }, - { returnExport: "mytype", expectResult: "foobar" }, - { returnExport: "result", expectResult: "string|foobar" }, - ])("separately exported variable (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("separately exported variable (%p)", () => { + util.testModule` const type = "foobar"; export { type } export { type as mytype } - export const result = typeof type + "|" + type;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type + "|" + type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("re-exported variable with lua keyword as name (%p)", importName => { - const code = ` - export { ${importName} } from "someModule"`; + // Can't use expectToMatchJsResult because above is not valid TS/JS - const lua = ` - package.loaded.someModule = {type = "foobar"} - return (function() - ${util.transpileString(code)} - end)().type`; + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - expect(util.executeLua(lua)).toBe("foobar"); + const luaResult = util.testModule` + export { ${importName} } from "someModule"; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); + + expect(luaResult.type).toBe("foobar"); }); test("class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - return t.method() + "|" + type.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return t.method() + "|" + type.staticMethod(); + `.expectToMatchJsResult(); }); test("subclass of class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - return foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return foo.method() + "|" + Foo.staticMethod(); + `.expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - export const result = t.method() + "|" + type.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = t.method() + "|" + type.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("subclass of exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("subclass of exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - export const result = foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = foo.method() + "|" + Foo.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); test("namespace", () => { @@ -682,20 +653,16 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const code = ` return typeof type.foo + "|" + type.foo`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("string|foobar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "string|foobar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("exported namespace (%p)", () => { + util.testModule` export namespace type { export const foo = "foobar"; } - export const result = typeof type.foo + "|" + type.foo;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type.foo + "|" + type.foo; + `.expectToMatchJsResult(); }); test("merged namespace", () => { @@ -717,14 +684,11 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const t = new type(); return \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("number|boolean|string|foo|bar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|boolean|string|foo|bar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported merged namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported merged namespace (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof true; } @@ -739,25 +703,23 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { } const t = new type(); - export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`; + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); }); test("declaration-only variable with lua keyword as name is not renamed", () => { - const code = ` - declare function type(this: void, a: unknown): string; - type(7);`; - - expect(util.transpileString(code, undefined, false)).toBe("type(7)"); + util.testFunction("type(7)") + .setTsHeader("declare function type(this: void, a: unknown): string;") + .expectLuaToMatchSnapshot(); }); test("exported variable with lua keyword as name is not renamed", () => { - const code = ` - export const print = "foobar";`; - - expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); + util.testModule` + export const print = "foobar"; + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/846 diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index b35bbd767..c644776e5 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -198,18 +198,15 @@ test("for scope", () => { test.each([ { inp: { test1: 0, test2: 1, test3: 2 }, - expected: { test1: 1, test2: 2, test3: 3 }, }, -])("forin[Object] (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +])("forin[Object] (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; for (let key in objTest) { objTest[key] = objTest[key] + 1; } - return JSONStringify(objTest);` - ); - - expect(JSON.parse(result)).toEqual(expected); + return objTest; + `.expectToMatchJsResult(); }); test("forin[Array]", () => { @@ -219,11 +216,9 @@ test("forin[Array]", () => { `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); -test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( - "forin with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let obj = ${JSON.stringify(inp)}; +test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p)", ({ inp }) => { + util.testFunctionTemplate` + let obj = ${inp}; for (let i in obj) { if (obj[i] % 2 == 0) { continue; @@ -231,24 +226,19 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2 obj[i] = 0; } - return JSONStringify(obj);` - ); - - expect(result).toBe(JSON.stringify(expected)); - } -); + return obj; + `.expectToMatchJsResult(); +}); -test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2] }])("forof (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; let arrResultTest = []; for (let value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrResultTest; + `.expectToMatchJsResult(); }); test("Tuple loop", () => { @@ -455,31 +445,29 @@ test.each(["", "abc", "a\0c"])("forof string (%p)", string => { describe("for...of empty destructuring", () => { const declareTests = (destructuringPrefix: string) => { test("array", () => { - const code = ` + util.testFunction` const arr = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of arr) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); test("iterable", () => { - const code = ` + util.testFunction` const iter: Iterable = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of iter) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); test("luaIterator", () => { - const code = ` + const luaResult = util.testFunction` const arr = [["a"], ["b"], ["c"]]; /** @luaIterator */ interface Iter extends Iterable {} @@ -492,12 +480,13 @@ describe("for...of empty destructuring", () => { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.getLuaExecutionResult(); + // Can't use expectToMatchJsResult because above is not valid TS/JS + expect(luaResult).toBe(3); }); test("luaIterator+tupleReturn", () => { - const code = ` + const luaResult = util.testFunction` const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; /** * @luaIterator @@ -520,8 +509,9 @@ describe("for...of empty destructuring", () => { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.getLuaExecutionResult(); + // Can't use expectToMatchJsResult because above is not valid TS/JS + expect(luaResult).toBe(3); }); }; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index b6aefdc0c..dd3d1dd7a 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -66,130 +66,106 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ ); test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - export { default } from "./module"; - `, - "module.ts": ` + util.testModule` + export { default } from "./module"; + ` + .addExtraFile( + "module.ts", + ` export const value = true; ${exportStatement}; - `, - }, - "default" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Default Import and Export Expression", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport; - `, - "module.ts": ` + util.testModule` + import defaultExport from "./module"; + export const value = defaultExport; + ` + .addExtraFile( + "module.ts", + ` export default 1 + 2 + 3; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Import and Export Assignment", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as m from "./module"; - export const value = m; - `, - "module.ts": ` + util.testModule` + // @ts-ignore + import * as m from "./module"; + export const value = m; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .addExtraFile( + "module.ts", + ` export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Named Imports", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, { a, b, c } from "./module"; - export const value = defaultExport + b + c; - `, - "module.ts": ` + util.testModule` + import defaultExport, { a, b, c } from "./module"; + export const value = defaultExport + b + c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Namespace Import", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, * as ns from "./module"; - export const value = defaultExport + ns.b + ns.c; - `, - "module.ts": ` + util.testModule` + import defaultExport, * as ns from "./module"; + export const value = defaultExport + ns.b + ns.c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Export Default Function", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport(); - `, - "module.ts": ` + const mainCode = ` + import defaultExport from "./module"; + export const value = defaultExport(); + `; + util.testModule(mainCode) + .addExtraFile( + "module.ts", + ` export default function() { return true; } - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Export Equals", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as module from "./module"; - export const value = module; - `, - "module.ts": ` - export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + util.testModule` + export = true; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .expectToMatchJsResult(); }); const reassignmentTestCases = [ @@ -282,25 +258,26 @@ export const foo = "bar"; `; test("export all does not include default", () => { - util.testBundle` + util.testModule` export * from "./module"; ` + .setOptions({ module: ts.ModuleKind.CommonJS }) .addExtraFile("module.ts", moduleFile) - .expectToEqual({ foo: "bar" }); + .expectToMatchJsResult(); }); test("namespace export does not include default", () => { - util.testBundle` + util.testModule` export * as result from "./module"; ` .addExtraFile("module.ts", moduleFile) - .expectToEqual({ result: { default: true, foo: "bar" } }); + .expectToMatchJsResult(); }); test("namespace export with unsafe Lua name", () => { - util.testBundle` + util.testModule` export * as $$$ from "./module"; ` .addExtraFile("module.ts", moduleFile) - .expectToEqual({ $$$: { default: true, foo: "bar" } }); + .expectToMatchJsResult(); }); diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 159fb8534..762152d67 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -11,14 +11,9 @@ test("legacy internal module syntax", () => { }); test("global scoping", () => { - const result = util.transpileAndExecute( - "return a.foo();", - undefined, - undefined, - 'namespace a { export function foo() { return "bar"; } }' - ); - - expect(result).toBe("bar"); + util.testFunction("return a.foo();") + .setTsHeader('namespace a { export function foo() { return "bar"; } }') + .expectToMatchJsResult(); }); test("nested namespace", () => { @@ -94,7 +89,7 @@ test("namespace merging across files", () => { } `; - util.testBundle` + util.testModule` import './a'; import './b'; @@ -102,7 +97,7 @@ test("namespace merging across files", () => { ` .addExtraFile("a.ts", a) .addExtraFile("b.ts", b) - .expectToEqual({ result: { foo: "foo", bar: "bar" } }); + .expectToMatchJsResult(); }); test("declared namespace function call", () => { diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index f911eeb2f..d18daa000 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -1,8 +1,8 @@ import * as util from "../util"; test("overload function1", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -11,15 +11,13 @@ test("overload function1", () => { return def; } } - return abc(3);` - ); - - expect(result).toBe("jkl9"); + return abc(3); + `.expectToMatchJsResult(); }); test("overload function2", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -28,15 +26,13 @@ test("overload function2", () => { return def; } } - return abc("ghj");` - ); - - expect(result).toBe("ghj"); + return abc("ghj"); + `.expectToMatchJsResult(); }); test("overload method1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -47,15 +43,13 @@ test("overload method1", () => { } } } - return myclass.abc(3);` - ); - - expect(result).toBe("jkl9"); + return myclass.abc(3); + `.expectToMatchJsResult(); }); test("overload method2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -66,15 +60,13 @@ test("overload method2", () => { } } } - return myclass.abc("ghj");` - ); - - expect(result).toBe("ghj"); + return myclass.abc("ghj"); + `.expectToMatchJsResult(); }); test("constructor1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -89,15 +81,13 @@ test("constructor1", () => { } } const inst = new myclass(3); - return inst.num` - ); - - expect(result).toBe(3); + return inst.num; + `.expectToMatchJsResult(); }); test("constructor2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -112,8 +102,6 @@ test("constructor2", () => { } } const inst = new myclass("ghj"); - return inst.str` - ); - - expect(result).toBe("ghj"); + return inst.str + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/deadCodeAfterReturn.spec.ts b/test/unit/printer/deadCodeAfterReturn.spec.ts index 0ccead50e..fba16387a 100644 --- a/test/unit/printer/deadCodeAfterReturn.spec.ts +++ b/test/unit/printer/deadCodeAfterReturn.spec.ts @@ -37,25 +37,25 @@ test("Method dead code after return", () => { }); test("for dead code after return", () => { - const result = util.transpileAndExecute("for (let i = 0; i < 10; i++) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let i = 0; i < 10; i++) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..in dead code after return", () => { - const result = util.transpileAndExecute('for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }'); - - expect(result).toBe(3); + util.testFunction` + for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..of dead code after return", () => { - const result = util.transpileAndExecute("for (let a of [1,2,4]) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let a of [1,2,4]) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("while dead code after return", () => { - const result = util.transpileAndExecute("while (true) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + while (true) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/parenthesis.spec.ts b/test/unit/printer/parenthesis.spec.ts index ef08a6e3d..6c8e58156 100644 --- a/test/unit/printer/parenthesis.spec.ts +++ b/test/unit/printer/parenthesis.spec.ts @@ -1,7 +1,7 @@ import * as util from "../../util"; test("binary expression with 'as' type assertion wrapped in parenthesis", () => { - expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); + util.testFunction("return 2 * (3 - 2 as number);").expectToMatchJsResult(); }); test.each([ @@ -26,7 +26,7 @@ test.each([ declare function z(this: void): unknown; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).not.toMatch(/\(.+\)/); }); @@ -50,15 +50,14 @@ test.each([ declare let y: {}; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).toMatch(/\(.+\)/); }); test("not operator precedence (%p)", () => { - const code = ` + util.testFunction` const a = true; const b = false; - return !a && b;`; - - expect(util.transpileAndExecute(code)).toBe(false); + return !a && b; + `.expectToMatchJsResult(); }); diff --git a/test/util.ts b/test/util.ts index 7be98e727..8cc36f6ca 100644 --- a/test/util.ts +++ b/test/util.ts @@ -10,7 +10,8 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -export * from "./legacy-utils"; +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -41,76 +42,6 @@ export function testEachVersion( } } -function executeLua(code: string): any { - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(code)); - - if (status === lua.LUA_OK) { - if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); - return result === null ? undefined : result; - } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); - throw new Error(`Unsupported Lua return type: ${returnType}`); - } - } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); - return new ExecutionError(message); - } -} - -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -export function executeLuaModule(code: string): any { - const lualibImport = code.includes('require("lualib_bundle")') - ? `package.preload.lualib_bundle = function()\n${lualibContent}\nend` - : ""; - - return executeLua(`${minimalTestLib}\n${lualibImport}\nreturn JSONStringify((function()\n${code}\nend)())`); -} - -function executeJsModule(code: string): any { - const exports = {}; - const context = vm.createContext({ exports, module: { exports } }); - context.global = context; - let result: unknown; - try { - result = vm.runInContext(code, context); - } catch (error) { - return new ExecutionError(error.message); - } - - function transform(currentValue: any): any { - if (currentValue === null) { - return undefined; - } - - if (Array.isArray(currentValue)) { - return currentValue.map(transform); - } - - if (typeof currentValue === "object") { - for (const [key, value] of Object.entries(currentValue)) { - currentValue[key] = transform(value); - if (currentValue[key] === undefined) { - delete currentValue[key]; - } - } - - if (Object.keys(currentValue).length === 0) { - return []; - } - } - - return currentValue; - } - - return transform(result); -} - const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); @@ -162,7 +93,7 @@ export abstract class TestBuilder { return this; } - protected abstract getLuaCodeWithWrapper: (code: string) => string; + protected abstract getLuaCodeWithWrapper(code: string): string; public setLuaFactory(luaFactory: (code: string) => string): this { expect(this.hasProgram).toBe(false); this.getLuaCodeWithWrapper = luaFactory; @@ -200,7 +131,7 @@ export abstract class TestBuilder { return this; } - private extraFiles: Record = {}; + protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { expect(this.hasProgram).toBe(false); this.extraFiles[fileName] = code; @@ -263,7 +194,7 @@ export abstract class TestBuilder { @memoize public getLuaExecutionResult(): any { - return executeLuaModule(this.getLuaCodeWithWrapper(this.getMainLuaCodeChunk())); + return this.executeLua(); } @memoize @@ -277,7 +208,7 @@ export abstract class TestBuilder { } @memoize - protected getMainJsCodeChunk(): string { + public getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) ?.js; @@ -291,7 +222,7 @@ export abstract class TestBuilder { @memoize public getJsExecutionResult(): any { - return executeJsModule(this.getJsCodeWithWrapper()); + return this.executeJs(); } // Utilities @@ -345,9 +276,19 @@ export abstract class TestBuilder { return this; } + private expectNoJsExecutionError(): this { + const jsResult = this.getJsExecutionResult(); + if (jsResult instanceof ExecutionError) { + throw jsResult; + } + + return this; + } + public expectToMatchJsResult(allowErrors = false): this { this.expectToHaveNoDiagnostics(); if (!allowErrors) this.expectNoExecutionError(); + if (!allowErrors) this.expectNoJsExecutionError(); const luaResult = this.getLuaExecutionResult(); const jsResult = this.getJsExecutionResult(); @@ -389,12 +330,148 @@ export abstract class TestBuilder { callback(this); return this; } + + private executeLua(): any { + // Main file + const mainFile = this.getMainLuaCodeChunk(); + + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + + // Load modules + // Json + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(minimalTestLib)); + lua.lua_setfield(L, -2, "json"); + // Lua lib + if ( + this.options.luaLibImport === tstl.LuaLibImportKind.Require || + mainFile.includes('require("lualib_bundle")') + ) { + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(lualibContent)); + lua.lua_setfield(L, -2, "lualib_bundle"); + } + + // Extra files + const { transpiledFiles } = this.getLuaResult(); + + Object.keys(this.extraFiles).forEach(fileName => { + const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === fileName) + ); + if (transpiledExtraFile?.lua) { + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(transpiledExtraFile.lua)); + lua.lua_setfield(L, -2, fileName.replace(".ts", "")); + } + }); + + // Execute Main + const wrappedMainCode = ` +local JSON = require("json"); +return JSON.stringify((function() + ${this.getLuaCodeWithWrapper(mainFile)} +end)());`; + + const status = lauxlib.luaL_dostring(L, to_luastring(wrappedMainCode)); + + if (status === lua.LUA_OK) { + if (lua.lua_isstring(L, -1)) { + const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + return result === null ? undefined : result; + } else { + const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + throw new Error(`Unsupported Lua return type: ${returnType}`); + } + } else { + // Filter out control characters appearing on some systems + const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); + const message = to_jsstring(luaStackString).replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + return new ExecutionError(message); + } + } + + private executeJs(): any { + const { transpiledFiles } = this.getJsResult(); + // Custom require for extra files. Really basic. Global support is hacky + // TODO Should be replaced with vm.Module https://nodejs.org/api/vm.html#vm_class_vm_module + // once stable + const globalContext: any = {}; + const mainExports = {}; + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + globalContext.require = (fileName: string) => { + // create clean export object for "module" + const moduleExports = {}; + globalContext.exports = moduleExports; + globalContext.module = { exports: moduleExports }; + const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === fileName.replace("./", "") + ".ts") + ); + + if (transpiledExtraFile?.js) { + vm.runInContext(transpiledExtraFile.js, globalContext); + } + + // Have to return globalContext.module.exports + // becuase module.exports might no longer be equal to moduleExports (export assignment) + const result = globalContext.module.exports; + // Reset module/export + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + return result; + }; + + vm.createContext(globalContext); + + let result: unknown; + try { + result = vm.runInContext(this.getJsCodeWithWrapper(), globalContext); + } catch (error) { + return new ExecutionError(error.message); + } + + function removeUndefinedFields(obj: any): any { + if (obj === null) { + return undefined; + } + + if (Array.isArray(obj)) { + return obj.map(removeUndefinedFields); + } + + if (typeof obj === "object") { + const copy: any = {}; + for (const [key, value] of Object.entries(obj)) { + if (obj[key] !== undefined) { + copy[key] = removeUndefinedFields(value); + } + } + + if (Object.keys(copy).length === 0) { + return []; + } + + return copy; + } + + return obj; + } + + return removeUndefinedFields(result); + } } class AccessorTestBuilder extends TestBuilder { protected accessor = ""; - protected getLuaCodeWithWrapper = (code: string) => `return (function()\n${code}\nend)()${this.accessor}`; + protected getLuaCodeWithWrapper(code: string) { + return `return (function()\n${code}\nend)()${this.accessor}`; + } @memoize protected getJsCodeWithWrapper(): string { @@ -420,7 +497,6 @@ class ModuleTestBuilder extends AccessorTestBuilder { return this; } } - class FunctionTestBuilder extends AccessorTestBuilder { protected accessor = ".__main()"; public getTsCode(): string { From 2766de134c526916380f31a55043e8487cd67bfc Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:05:27 +0000 Subject: [PATCH 33/91] $range language extension (#979) * added $range language extension * addressing feedback * fixed mis-named range spec and test which were actually broken * checking for $range function based on symbol instead of type to reduce redundant diagnostics * deprecated @forRange annotation and fixed some tabs Co-authored-by: Tom --- language-extensions/index.d.ts | 10 +++ src/lualib/ArrayIncludes.ts | 2 +- src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/DelegatedYield.ts | 2 +- src/lualib/declarations/tstl.d.ts | 3 - src/transformation/utils/diagnostics.ts | 6 ++ .../utils/language-extensions.ts | 13 ++- src/transformation/visitors/identifier.ts | 13 ++- .../visitors/language-extensions/range.ts | 53 +++++++++++ src/transformation/visitors/loops/for-of.ts | 9 +- .../__snapshots__/deprecated.spec.ts.snap | 7 ++ test/unit/annotations/deprecated.spec.ts | 10 ++- test/unit/annotations/forRange.spec.ts | 31 +++++-- .../__snapshots__/range.spec.ts.snap | 88 +++++++++++++++++++ test/unit/language-extensions/range.spec.ts | 68 ++++++++++++++ 17 files changed, 299 insertions(+), 22 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/range.ts create mode 100644 test/unit/language-extensions/__snapshots__/range.spec.ts.snap create mode 100644 test/unit/language-extensions/range.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 87a7f1395..437db5a85 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,6 +1,16 @@ declare function $multi(...values: T): MultiReturn; declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; +/** + * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param start The first number in the sequence to iterate over. + * @param limit The last number in the sequence to iterate over. + * @param step The amount to increment each iteration. + */ +declare function $range(start: number, limit: number, step?: number): Iterable; + /** * Calls to functions with this type are translated to `left + right`. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts index a9ff19ba4..b012f87bf 100644 --- a/src/lualib/ArrayIncludes.ts +++ b/src/lualib/ArrayIncludes.ts @@ -11,7 +11,7 @@ function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boo k = 0; } - for (const i of forRange(k, len)) { + for (const i of $range(k, len)) { if (this[i] === searchElement) { return true; } diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 8dda6ebd5..edb6825e6 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -20,7 +20,7 @@ function __TS__ArrayReduce( throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, len - 1)) { + for (const i of $range(k, len - 1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index a57f78697..8e5336f61 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -20,7 +20,7 @@ function __TS__ArrayReduceRight( throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, 0, -1)) { + for (const i of $range(k, 0, -1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 5df67938f..1b0bf9cff 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -66,7 +66,7 @@ function __TS__ArraySplice(this: void, list: T[], ...args: Vararg) } let j = actualStart; - for (const i of forRange(3, actualArgumentCount)) { + for (const i of $range(3, actualArgumentCount)) { list[j] = select(i, ...args) as T; j++; } diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts index 6b524365a..ab47d02d8 100644 --- a/src/lualib/DelegatedYield.ts +++ b/src/lualib/DelegatedYield.ts @@ -1,6 +1,6 @@ function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { if (typeof iterable === "string") { - for (const index of forRange(0, iterable.length - 1)) { + for (const index of $range(0, iterable.length - 1)) { coroutine.yield(iterable[index]); } } else if ("____coroutine" in iterable) { diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 57e436ae3..4a718a31a 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -3,9 +3,6 @@ /** @vararg */ type Vararg = T & { __luaVararg?: never }; -/** @forRange */ -declare function forRange(start: number, limit: number, step?: number): number[]; - interface Metatable { _descriptors?: Record; __index?: any; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8cd721421..79f21528e 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -86,6 +86,12 @@ export const invalidForRangeCall = createErrorDiagnosticFactory( (message: string) => `Invalid @forRange call: ${message}.` ); +export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); + +export const invalidRangeControlVariable = createErrorDiagnosticFactory( + "For loop using $range must declare a single control variable." +); + export const luaTableMustBeAmbient = createErrorDiagnosticFactory( "Classes with the '@luaTable' annotation must be ambient." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 6838d6b55..b260d9fae 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -4,6 +4,7 @@ import * as path from "path"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", + RangeFunction = "RangeFunction", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -42,6 +43,11 @@ export enum ExtensionKind { LengthOperatorMethodType = "LengthOperatorMethodType", } +const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { + $multi: ExtensionKind.MultiFunction, + $range: ExtensionKind.RangeFunction, +}; + const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { MultiReturn: ExtensionKind.MultiType, LuaAddition: ExtensionKind.AdditionOperatorType, @@ -91,8 +97,11 @@ function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { const sourceFile = declaration.getSourceFile(); if (isSourceFileFromLanguageExtensions(sourceFile)) { - if (ts.isFunctionDeclaration(declaration) && declaration?.name?.text === "$multi") { - return ExtensionKind.MultiFunction; + if (ts.isFunctionDeclaration(declaration) && declaration.name?.text) { + const extensionKind = functionNameToExtensionKind[declaration.name.text]; + if (extensionKind) { + return extensionKind; + } } if (ts.isTypeAliasDeclaration(declaration)) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index dd69699b3..e872e841e 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,13 +3,19 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall, invalidMultiFunctionUse, invalidOperatorMappingUse } from "../utils/diagnostics"; +import { + invalidForRangeCall, + invalidMultiFunctionUse, + invalidOperatorMappingUse, + invalidRangeUse, +} from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; import { isMultiFunctionNode } from "./language-extensions/multi"; import { isOperatorMapping } from "./language-extensions/operators"; +import { isRangeFunctionNode } from "./language-extensions/range"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -21,6 +27,11 @@ export function transformIdentifier(context: TransformationContext, identifier: context.diagnostics.push(invalidOperatorMappingUse(identifier)); } + if (isRangeFunctionNode(context, identifier)) { + context.diagnostics.push(invalidRangeUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts new file mode 100644 index 000000000..d68729c3c --- /dev/null +++ b/src/transformation/visitors/language-extensions/range.ts @@ -0,0 +1,53 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding } from "../loops/utils"; +import { transformIdentifier } from "../identifier"; +import { transformArguments } from "../call"; +import { assert } from "../../../utils"; +import { invalidRangeControlVariable } from "../../utils/diagnostics"; + +const isRangeFunctionDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.RangeFunction; + +export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { + const type = context.checker.getTypeAtLocation(expression.expression); + return type.symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; +} + +export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; +} + +function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { + if (!ts.isVariableDeclarationList(statement.initializer)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (!ts.isIdentifier(binding)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + return transformIdentifier(context, binding); +} + +export function transformRangeStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + assert(ts.isCallExpression(statement.expression)); + const controlVariable = + getControlVariable(context, statement) ?? lua.createAnonymousIdentifier(statement.initializer); + const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( + context, + statement.expression.arguments, + context.checker.getResolvedSignature(statement.expression) + ); + return lua.createForStatement(block, controlVariable, start, limit, step, statement); +} diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 67adb2ca2..047ed3535 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -3,11 +3,12 @@ import * as lua from "../../../LuaAST"; import { assert, cast } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; +import { annotationDeprecated, invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; +import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformArrayBindingElement } from "../variable-declaration"; import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; @@ -18,6 +19,8 @@ function transformForRangeStatement( ): lua.Statement { assert(ts.isCallExpression(statement.expression)); + context.diagnostics.push(annotationDeprecated(statement.expression, AnnotationKind.ForRange)); + const callArguments = statement.expression.arguments; if (callArguments.length !== 2 && callArguments.length !== 3) { context.diagnostics.push( @@ -149,7 +152,9 @@ function transformForOfIteratorStatement( export const transformForOfStatement: FunctionVisitor = (node, context) => { const body = lua.createBlock(transformLoopBody(context, node)); - if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { + if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { + return transformRangeStatement(context, node, body); + } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { return transformForRangeStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { return transformForOfLuaIteratorStatement(context, node, body); diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 956143495..5be0a22b4 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -8,6 +8,13 @@ exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; +exports[`forRange deprecation: code 1`] = ` +"for i = 1, 10 do +end" +`; + +exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; + exports[`phantom deprecation: code 1`] = ` "function nsMember(self) end" diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 488b66a28..4fe836014 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -22,6 +22,14 @@ test("pureAbstract deprecation", () => { util.testModule` /** @pureAbstract */ declare class ClassA {} - class ClassB extends ClassA {} + class ClassB extends ClassA {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("forRange deprecation", () => { + util.testModule` + /** @forRange */ + declare function forRange(start: number, limit: number, step?: number): number[]; + for (const i of forRange(1, 10)) {} `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); }); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts index 661c45253..35dc285b1 100644 --- a/test/unit/annotations/forRange.spec.ts +++ b/test/unit/annotations/forRange.spec.ts @@ -1,4 +1,4 @@ -import { invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; +import { annotationDeprecated, invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` @@ -21,6 +21,7 @@ test.each([ } ` .setReturnExport("results") + .ignoreDiagnostics([annotationDeprecated.code]) .expectToEqual(results); }); @@ -29,14 +30,18 @@ describe("invalid usage", () => { util.testModule` /** @forRange */ function luaRange() {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { util.testModule` ${createForRangeDeclaration("...args: number[]")} for (const i of luaRange(${args})) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("non-declared loop variable", () => { @@ -44,28 +49,36 @@ describe("invalid usage", () => { ${createForRangeDeclaration()} let i: number; for (i of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("argument types", () => { util.testModule` ${createForRangeDeclaration("i: string, j: number")} for (const i of luaRange("foo", 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("variable destructuring", () => { util.testModule` ${createForRangeDeclaration(undefined, "number[][]")} for (const [i] of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("return type", () => { util.testModule` ${createForRangeDeclaration(undefined, "string[]")} for (const i of luaRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test.each([ @@ -78,6 +91,8 @@ describe("invalid usage", () => { util.testModule` ${createForRangeDeclaration()} ${statement} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); }); diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap new file mode 100644 index 000000000..f066c1260 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$range invalid control variable: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i + for ____ = 1, 5 do + end +end +return ____exports" +`; + +exports[`$range invalid control variable: diagnostics 1`] = `"main.ts(3,14): error TSTL: For loop using $range must declare a single control variable."`; + +exports[`$range invalid use ("const range = $range;"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local range = ____ +end +return ____exports" +`; + +exports[`$range invalid use ("const range = $range;"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const x = $range(1, 10);"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = ____(nil, 1, 10) +end +return ____exports" +`; + +exports[`$range invalid use ("const x = $range(1, 10);"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local y = { + __TS__Spread( + ____(nil, 1, 10) + ) + } +end +return ____exports" +`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for i in pairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for ____, i in ipairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + for ____, i in __TS__Iterator( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): diagnostics 1`] = `"main.ts(2,26): error TSTL: $range can only be used in a for...of loop."`; diff --git a/test/unit/language-extensions/range.spec.ts b/test/unit/language-extensions/range.spec.ts new file mode 100644 index 000000000..56ac65251 --- /dev/null +++ b/test/unit/language-extensions/range.spec.ts @@ -0,0 +1,68 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidRangeControlVariable, invalidRangeUse } from "../../../src/transformation/utils/diagnostics"; + +const rangeProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test("$range basic use", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 5)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([1, 2, 3, 4, 5]); +}); + +test("$range basic use with step", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 10, 2)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([1, 3, 5, 7, 9]); +}); + +test("$range basic use reverse", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(5, 1, -1)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([5, 4, 3, 2, 1]); +}); + +test("$range invalid control variable", () => { + util.testFunction` + let i: number; + for (i of $range(1, 5)) {} + ` + .setOptions(rangeProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidRangeControlVariable.code]); +}); + +test.each([ + "for (const i in $range(1, 10, 2)) {}", + "const x = $range(1, 10);", + "const range = $range;", + "const y = [...$range(1, 10)];", + "for (const i of ($range(1, 10, 2))) {}", + "for (const i of $range(1, 10, 2) as number[]) {}", +])("$range invalid use (%p)", statement => { + util.testFunction` + ${statement} + ` + .setOptions(rangeProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidRangeUse.code]); +}); From eae12b6c96fc15418d3373b2b51718bf7490fbcd Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:06:43 +0000 Subject: [PATCH 34/91] Multi-Return update (#978) * renamed MultiReturn to LuaMultiReturn and added some doc comments * refactored LuaMultiReturn to handle a number of cases it couldn't before * fixed issues found with tests * diagnostic for checking implicit cast from LuaMultiReturn and additional tests * fixed LuaMultiReturn used in assignment expressions * tests for mtulreturn in try/catch * removed unnecessary check in isMultiReturnType * fixed string.find declaration * addressing feedback * snapshot update * renamed multiReturnCallShouldBeWrapped to shouldMultiReturnCallBeWrapped Co-authored-by: Tom --- language-extensions/index.d.ts | 18 +- src/lualib/StringIncludes.ts | 3 +- src/lualib/declarations/string.d.ts | 2 +- src/transformation/utils/diagnostics.ts | 20 +- .../utils/language-extensions.ts | 2 +- .../visitors/binary-expression/assignments.ts | 10 +- src/transformation/visitors/call.ts | 5 +- src/transformation/visitors/errors.ts | 3 +- .../visitors/expression-statement.ts | 10 - src/transformation/visitors/function.ts | 5 - .../visitors/language-extensions/multi.ts | 175 +++++------------- src/transformation/visitors/return.ts | 39 +++- .../visitors/variable-declaration.ts | 14 +- .../__snapshots__/multi.spec.ts.snap | 145 ++++++++++++--- test/unit/language-extensions/multi.spec.ts | 124 ++++++++++++- 15 files changed, 356 insertions(+), 219 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 437db5a85..033012960 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,5 +1,19 @@ -declare function $multi(...values: T): MultiReturn; -declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; +/** + * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + * @param values Return values. + */ +declare function $multi(...values: T): LuaMultiReturn; + +/** + * Represents multiple return values as a tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + */ +declare type LuaMultiReturn = T & { readonly __luaMultiReturnBrand: unique symbol }; /** * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts index cba5bf15f..7508a2a42 100644 --- a/src/lualib/StringIncludes.ts +++ b/src/lualib/StringIncludes.ts @@ -5,5 +5,6 @@ function __TS__StringIncludes(this: string, searchString: string, position?: num } else { position += 1; } - return string.find(this, searchString, position, true) !== undefined; + const [index] = string.find(this, searchString, position, true); + return index !== undefined; } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 778257d7f..ed5aa27e5 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -19,5 +19,5 @@ declare namespace string { pattern: string, start?: number, plainflag?: boolean - ): MultiReturn<[number, number]> | undefined; + ): LuaMultiReturn<[number, number] | [undefined]>; } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 79f21528e..76e8b4632 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -149,11 +149,11 @@ export const unsupportedVarDeclaration = createErrorDiagnosticFactory( ); export const invalidMultiFunctionUse = createErrorDiagnosticFactory( - "The $multi function must be called in an expression that is returned." + "The $multi function must be called in a return statement." ); -export const invalidMultiTypeToNonArrayBindingPattern = createErrorDiagnosticFactory( - "Expected an array destructuring pattern." +export const invalidMultiFunctionReturnType = createErrorDiagnosticFactory( + "The $multi function cannot be cast to a non-LuaMultiReturn type." ); export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); @@ -162,20 +162,8 @@ export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosti "There must be one or more elements specified here." ); -export const invalidMultiTypeArrayBindingPatternElementInitializer = createErrorDiagnosticFactory( - "This array binding pattern cannot have initializers." -); - -export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnosticFactory( - "This array literal pattern cannot have initializers." -); - export const invalidMultiReturnAccess = createErrorDiagnosticFactory( - "The MultiReturn type can only be accessed via an element access expression of a numeric type." -); - -export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( - "Omitted expressions and BindingElements are expected here." + "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); export const invalidOperatorMappingUse = createErrorDiagnosticFactory( diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index b260d9fae..391993f8a 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -49,7 +49,7 @@ const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { }; const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { - MultiReturn: ExtensionKind.MultiType, + LuaMultiReturn: ExtensionKind.MultiType, LuaAddition: ExtensionKind.AdditionOperatorType, LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, LuaSubtraction: ExtensionKind.SubtractionOperatorType, diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 94e17e9c7..df99a2a7d 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -11,6 +11,7 @@ import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; +import { isMultiReturnCall } from "../language-extensions/multi"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -91,7 +92,7 @@ export function transformAssignmentExpression( const rootIdentifier = lua.createAnonymousIdentifier(expression.left); let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } @@ -184,7 +185,10 @@ export function transformAssignmentStatement( const rightType = context.checker.getTypeAtLocation(expression.right); let right = context.transformExpression(expression.right); - if (!isTupleReturnCall(context, expression.right) && isArrayType(context, rightType)) { + if ( + !(isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) && + isArrayType(context, rightType) + ) { right = createUnpackCall(context, right, expression.right); } @@ -194,7 +198,7 @@ export function transformAssignmentStatement( } let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 20583d007..f29cbd4e9 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -11,7 +11,7 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; -import { returnsMultiType } from "./language-extensions/multi"; +import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -201,8 +201,9 @@ export const transformCallExpression: FunctionVisitor = (node node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); - const wrapResult = + const wrapTupleReturn = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; + const wrapResult = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); const builtinResult = transformBuiltinCallExpression(context, node); if (builtinResult) { diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 6d683c475..e05ed55f3 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -6,6 +6,7 @@ import { createUnpackCall } from "../utils/lua-ast"; import { findScope, ScopeType } from "../utils/scope"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; +import { isInMultiReturnFunction } from "./language-extensions/multi"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); @@ -88,7 +89,7 @@ export const transformTryStatement: FunctionVisitor = (statemen returnValues.push(lua.createBooleanLiteral(true)); } - if (isInTupleReturnFunction(context, statement)) { + if (isInTupleReturnFunction(context, statement) || isInMultiReturnFunction(context, statement)) { returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); } else { returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 4901a3210..890695be0 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -4,18 +4,8 @@ import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; -import { returnsMultiType, transformMultiDestructuringAssignmentStatement } from "./language-extensions/multi"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - if ( - ts.isBinaryExpression(node.expression) && - node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && - ts.isCallExpression(node.expression.right) && - returnsMultiType(context, node.expression.right) - ) { - return transformMultiDestructuringAssignmentStatement(context, node); - } - const luaTableResult = transformLuaTableExpressionStatement(context, node); if (luaTableResult) { return luaTableResult; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 424e75efe..d3fb88a5a 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,7 +15,6 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; -import { isMultiFunction, transformMultiCallExpressionToReturnStatement } from "./language-extensions/multi"; import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; @@ -56,10 +55,6 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { - if (ts.isCallExpression(body) && isMultiFunction(context, body)) { - return [transformMultiCallExpressionToReturnStatement(context, body)]; - } - const returnStatement = transformExpressionBodyToReturnStatement(context, body); return [returnStatement]; } diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index a6cb2a755..8ddb54c83 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -1,22 +1,8 @@ import * as ts from "typescript"; -import * as lua from "../../../LuaAST"; import * as extensions from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { transformAssignmentLeftHandSideExpression } from "../binary-expression/assignments"; -import { transformIdentifier } from "../identifier"; -import { transformArguments } from "../call"; -import { getDependenciesOfSymbol, createExportedIdentifier } from "../../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; -import { - invalidMultiTypeArrayBindingPatternElementInitializer, - invalidMultiTypeArrayLiteralElementInitializer, - invalidMultiTypeToEmptyPatternOrArrayLiteral, - invalidMultiTypeToNonArrayBindingPattern, - invalidMultiTypeToNonArrayLiteral, - unsupportedMultiFunctionAssignment, - invalidMultiFunctionUse, -} from "../../utils/diagnostics"; -import { assert } from "../../../utils"; +import { invalidMultiFunctionUse } from "../../utils/diagnostics"; +import { findFirstNodeAbove } from "../../utils/typescript"; const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; @@ -24,14 +10,23 @@ const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; -export function isMultiFunction(context: TransformationContext, expression: ts.CallExpression): boolean { +export function isMultiReturnType(type: ts.Type): boolean { + return type.aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; +} + +export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { const type = context.checker.getTypeAtLocation(expression.expression); return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; } export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { const signature = context.checker.getResolvedSignature(node); - return signature?.getReturnType().aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; +} + +export function isMultiReturnCall(context: TransformationContext, expression: ts.Expression) { + return ts.isCallExpression(expression) && returnsMultiType(context, expression); } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { @@ -39,131 +34,59 @@ export function isMultiFunctionNode(context: TransformationContext, node: ts.Nod return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; } -export function transformMultiCallExpressionToReturnStatement( - context: TransformationContext, - expression: ts.Expression -): lua.Statement { - assert(ts.isCallExpression(expression)); - - const expressions = transformArguments(context, expression.arguments); - return lua.createReturnStatement(expressions, expression); -} - -export function transformMultiReturnStatement( - context: TransformationContext, - statement: ts.ReturnStatement -): lua.Statement { - assert(statement.expression); - - return transformMultiCallExpressionToReturnStatement(context, statement.expression); -} - -function transformMultiFunctionArguments( - context: TransformationContext, - expression: ts.CallExpression -): lua.Expression[] | lua.Expression { - if (!isMultiFunction(context, expression)) { - return context.transformExpression(expression); - } - - if (expression.arguments.length === 0) { - return lua.createNilLiteral(expression); +export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; } - - return expression.arguments.map(e => context.transformExpression(e)); + const signature = context.checker.getSignatureFromDeclaration(declaration); + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; } -export function transformMultiVariableDeclaration( - context: TransformationContext, - declaration: ts.VariableDeclaration -): lua.Statement[] { - assert(declaration.initializer); - assert(ts.isCallExpression(declaration.initializer)); - - if (!ts.isArrayBindingPattern(declaration.name)) { - context.diagnostics.push(invalidMultiTypeToNonArrayBindingPattern(declaration.name)); - return []; +export function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression) { + if (!returnsMultiType(context, node)) { + return false; } - if (declaration.name.elements.length < 1) { - context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(declaration.name)); - return []; + // Variable declaration with destructuring + if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + return false; } - if (declaration.name.elements.some(e => ts.isBindingElement(e) && e.initializer)) { - context.diagnostics.push(invalidMultiTypeArrayBindingPatternElementInitializer(declaration.name)); - return []; + // Variable assignment with destructuring + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(node.parent.left) + ) { + return false; } - if (isMultiFunction(context, declaration.initializer)) { - context.diagnostics.push(invalidMultiFunctionUse(declaration.initializer)); - return []; + // Spread operator + if (ts.isSpreadElement(node.parent)) { + return false; } - const leftIdentifiers: lua.Identifier[] = []; - - for (const element of declaration.name.elements) { - if (ts.isBindingElement(element)) { - if (ts.isIdentifier(element.name)) { - leftIdentifiers.push(transformIdentifier(context, element.name)); - } else { - context.diagnostics.push(unsupportedMultiFunctionAssignment(element)); - } - } else if (ts.isOmittedExpression(element)) { - leftIdentifiers.push(lua.createAnonymousIdentifier(element)); - } + // Stand-alone expression + if (ts.isExpressionStatement(node.parent)) { + return false; } - const rightExpressions = transformMultiFunctionArguments(context, declaration.initializer); - return createLocalOrExportedOrGlobalDeclaration(context, leftIdentifiers, rightExpressions, declaration); -} - -export function transformMultiDestructuringAssignmentStatement( - context: TransformationContext, - statement: ts.ExpressionStatement -): lua.Statement[] | undefined { - assert(ts.isBinaryExpression(statement.expression)); - assert(ts.isCallExpression(statement.expression.right)); - - if (!ts.isArrayLiteralExpression(statement.expression.left)) { - context.diagnostics.push(invalidMultiTypeToNonArrayLiteral(statement.expression.left)); - return []; + // Forwarded multi-return call + if ( + (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + isInMultiReturnFunction(context, node) + ) { + return false; } - if (statement.expression.left.elements.some(ts.isBinaryExpression)) { - context.diagnostics.push(invalidMultiTypeArrayLiteralElementInitializer(statement.expression.left)); - return []; + // Element access expression 'foo()[0]' will be optimized using 'select' + if (ts.isElementAccessExpression(node.parent)) { + return false; } - if (statement.expression.left.elements.length < 1) { - context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(statement.expression.left)); - return []; - } - - if (isMultiFunction(context, statement.expression.right)) { - context.diagnostics.push(invalidMultiFunctionUse(statement.expression.right)); - return []; - } - - const transformLeft = (expression: ts.Expression): lua.AssignmentLeftHandSideExpression => - ts.isOmittedExpression(expression) - ? lua.createAnonymousIdentifier(expression) - : transformAssignmentLeftHandSideExpression(context, expression); - - const leftIdentifiers = statement.expression.left.elements.map(transformLeft); - - const rightExpressions = transformMultiFunctionArguments(context, statement.expression.right); - - const trailingStatements = statement.expression.left.elements.flatMap(expression => { - const symbol = context.checker.getSymbolAtLocation(expression); - const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; - return dependentSymbols.map(symbol => { - const identifierToAssign = createExportedIdentifier(context, lua.createIdentifier(symbol.name)); - return lua.createAssignmentStatement(identifierToAssign, transformLeft(expression)); - }); - }); - - return [lua.createAssignmentStatement(leftIdentifiers, rightExpressions, statement), ...trailingStatements]; + return true; } export function findMultiAssignmentViolations( diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index c13d571ff..7e7a7ddf8 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -6,13 +6,42 @@ import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; -import { isMultiFunction, transformMultiReturnStatement } from "./language-extensions/multi"; +import { transformArguments } from "./call"; +import { + returnsMultiType, + shouldMultiReturnCallBeWrapped, + isMultiFunctionCall, + isMultiReturnType, +} from "./language-extensions/multi"; +import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; function transformExpressionsInReturn( context: TransformationContext, node: ts.Expression, insideTryCatch: boolean ): lua.Expression[] { + if (ts.isCallExpression(node)) { + // $multi(...) + if (isMultiFunctionCall(context, node)) { + // Don't allow $multi to be implicitly cast to something other than LuaMultiReturn + const type = context.checker.getContextualType(node); + if (type && !isMultiReturnType(type)) { + context.diagnostics.push(invalidMultiFunctionReturnType(node)); + } + + let returnValues = transformArguments(context, node.arguments); + if (insideTryCatch) { + returnValues = [wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch + } + return returnValues; + } + + // Force-wrap LuaMultiReturn when returning inside try/catch + if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { + return [wrapInTable(context.transformExpression(node))]; + } + } + if (!isInTupleReturnFunction(context, node)) { return [context.transformExpression(node)]; } @@ -60,14 +89,6 @@ export const transformReturnStatement: FunctionVisitor = (st insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; } - if ( - statement.expression && - ts.isCallExpression(statement.expression) && - isMultiFunction(context, statement.expression) - ) { - return transformMultiReturnStatement(context, statement); - } - let results: lua.Expression[]; if (statement.expression) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 6ddd4acdc..12f6717c4 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -9,8 +9,8 @@ import { addExportToIdentifier } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; +import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; -import { returnsMultiType, transformMultiVariableDeclaration } from "./language-extensions/multi"; export function transformArrayBindingElement( context: TransformationContext, @@ -173,8 +173,8 @@ export function transformBindingVariableDeclaration( : lua.createAnonymousIdentifier(); if (initializer) { - if (isTupleReturnCall(context, initializer)) { - // Don't unpack @tupleReturn annotated functions + if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + // Don't unpack @tupleReturn or LuaMultiReturn functions statements.push( ...createLocalOrExportedOrGlobalDeclaration( context, @@ -230,14 +230,6 @@ export function transformVariableDeclaration( context: TransformationContext, statement: ts.VariableDeclaration ): lua.Statement[] { - if ( - statement.initializer && - ts.isCallExpression(statement.initializer) && - returnsMultiType(context, statement.initializer) - ) { - return transformMultiVariableDeclaration(context, statement); - } - if (statement.initializer && statement.type) { const initializerType = context.checker.getTypeAtLocation(statement.initializer); const varType = context.checker.getTypeFromTypeNode(statement.type); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index b745edf27..a280fe331 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`disallow MultiReturn non-numeric access: code 1`] = ` +exports[`disallow LuaMultiReturn non-numeric access: code 1`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) @@ -15,56 +15,113 @@ end return ____exports" `; -exports[`disallow MultiReturn non-numeric access: code 2`] = ` +exports[`disallow LuaMultiReturn non-numeric access: code 2`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) local args = {...} return table.unpack(args) end - return multi(nil).forEach + return ({ + multi(nil) + }).forEach end return ____exports" `; -exports[`disallow MultiReturn non-numeric access: diagnostics 1`] = `"main.ts(7,16): error TSTL: The MultiReturn type can only be accessed via an element access expression of a numeric type."`; +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 1`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; -exports[`disallow MultiReturn non-numeric access: diagnostics 2`] = `"main.ts(7,16): error TSTL: The MultiReturn type can only be accessed via an element access expression of a numeric type."`; +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 2`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`; -exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`; -exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` "local function ____(____, ____bindingPattern0) if ____bindingPattern0 == nil then - ____bindingPattern0 = ____(_G, 1) + ____bindingPattern0 = { + ____(_G, 1) + } end local a = ____bindingPattern0[1] end" `; -exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; -exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = ` +"a = ____(_G) +if a == nil then + a = 0 +end" +`; + +exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const {} = $multi();): code 1`] = ` +"local ____ = { + ____(_G) +}" +`; + +exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const a = $multi();): code 1`] = ` +"a = { + ____(_G) +}" +`; + +exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,19): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = `""`; +exports[`invalid $multi implicit cast: code 1`] = ` +"function badMulti(self) + return \\"foo\\", 42 +end" +`; -exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,15): error TSTL: This array binding pattern cannot have initializers."`; +exports[`invalid $multi implicit cast: diagnostics 1`] = `"main.ts(3,20): error TSTL: The $multi function cannot be cast to a non-LuaMultiReturn type."`; -exports[`invalid $multi call (const {} = $multi();): code 1`] = `""`; +exports[`invalid direct $multi function use (const [a = 1] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a = ____(nil) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; -exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; +exports[`invalid direct $multi function use (const [a = 1] = $multi()): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const a = $multi();): code 1`] = `""`; +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a = ____(nil, 2) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; -exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` "local ____exports = {} @@ -72,11 +129,12 @@ local function multi(self, ...) local args = {...} return table.unpack(args) end +local a = ____(nil) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` "local ____exports = {} @@ -84,11 +142,12 @@ local function multi(self, ...) local args = {...} return table.unpack(args) end +local a = ____(nil, 1) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` "local ____exports = {} @@ -97,11 +156,12 @@ local function multi(self, ...) return table.unpack(args) end local _ = nil +local a = ____(nil, 1) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` "local ____exports = {} @@ -110,11 +170,15 @@ local function multi(self, ...) return table.unpack(args) end local ar = {1} +local a = ____( + nil, + table.unpack(ar) +) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` "local ____exports = {} @@ -123,11 +187,16 @@ local function multi(self, ...) return table.unpack(args) end local a +local ____ = { + ____(nil) +} +a = ____[1] +____exports.a = a ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} @@ -137,6 +206,11 @@ local function multi(self, ...) end local a do + local ____ = { + ____(nil, 1, 2) + } + a = ____[1] + ____exports.a = a while false do local ____ = 1 end @@ -145,7 +219,7 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} @@ -155,6 +229,7 @@ local function multi(self, ...) end local a do + local a = ____(nil, 1, 2) while false do local ____ = 1 end @@ -163,4 +238,28 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +if (function() + local ____ = { + ____(nil, 1) + } + a = ____[1] + ____exports.a = a + return ____ +end)() then + a = a + 1 + ____exports.a = a +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): diagnostics 1`] = `"main.ts(7,26): error TSTL: The $multi function must be called in a return statement."`; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index c697cbad0..ff1fd403a 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -3,9 +3,8 @@ import * as util from "../../util"; import * as tstl from "../../../src"; import { invalidMultiFunctionUse, - invalidMultiTypeToNonArrayBindingPattern, - invalidMultiTypeArrayBindingPatternElementInitializer, invalidMultiReturnAccess, + invalidMultiFunctionReturnType, } from "../../../src/transformation/utils/diagnostics"; const multiProjectOptions: tstl.CompilerOptions = { @@ -14,7 +13,7 @@ const multiProjectOptions: tstl.CompilerOptions = { test("multi example use case", () => { util.testModule` - function multiReturn(): MultiReturn<[string, number]> { + function multiReturn(): LuaMultiReturn<[string, number]> { return $multi("foo", 5); } @@ -47,10 +46,13 @@ const createCasesThatCall = (name: string): Array<[string, any]> => [ [`let a; [a] = ${name}()`, undefined], [`const [a] = ${name}()`, undefined], [`const [a] = ${name}(1)`, 1], + [`const [a = 1] = ${name}()`, 1], + [`const [a = 1] = ${name}(2)`, 2], [`const ar = [1]; const [a] = ${name}(...ar)`, 1], [`const _ = null, [a] = ${name}(1)`, 1], [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], + [`let a; if ([a] = ${name}(1)) { ++a; }`, 2], ]; test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { @@ -82,10 +84,10 @@ test.each<[string, number[]]>([ ["$multi", [invalidMultiFunctionUse.code]], ["$multi()", [invalidMultiFunctionUse.code]], ["({ $multi });", [invalidMultiFunctionUse.code]], - ["const a = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], - ["const {} = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["const a = $multi();", [invalidMultiFunctionUse.code]], + ["const {} = $multi();", [invalidMultiFunctionUse.code]], ["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]], - ["const [a = 0] = $multi()", [invalidMultiTypeArrayBindingPatternElementInitializer.code]], + ["const [a = 0] = $multi()", [invalidMultiFunctionUse.code]], ])("invalid $multi call (%s)", (statement, diagnostics) => { util.testModule` ${statement} @@ -128,7 +130,18 @@ test("allow $multi call in ArrowFunction body", () => { .expectToEqual(1); }); -test.each(["0", "i"])("allow MultiReturn numeric access", expression => { +test("forward $multi call in ArrowFunction body", () => { + util.testFunction` + const foo = () => $multi(1); + const call = () => foo(); + const [result] = call(); + return result; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); + +test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { util.testFunction` ${multiFunction} const i = 0; @@ -138,7 +151,7 @@ test.each(["0", "i"])("allow MultiReturn numeric access", expression => { .expectToEqual(1); }); -test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-numeric access", expression => { +test.each(["multi()['forEach']", "multi().forEach"])("disallow LuaMultiReturn non-numeric access", expression => { util.testFunction` ${multiFunction} return ${expression}; @@ -146,3 +159,98 @@ test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-n .setOptions(multiProjectOptions) .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); }); + +test("invalid $multi implicit cast", () => { + util.testModule` + function badMulti(): [string, number] { + return $multi("foo", 42); + } + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionReturnType.code]); +}); + +test.each([ + { flag: true, result: 4 }, + { flag: false, result: 7 }, +])("overloaded $multi/non-$multi return", ({ flag, result }) => { + util.testFunction` + function multiOverload(flag: true): LuaMultiReturn<[string, number]>; + function multiOverload(flag: false): [string, number]; + function multiOverload(flag: boolean) { + if (flag) { + return $multi("foo", 4); + } else { + return ["bar", 7]; + } + } + const [x, y] = multiOverload(${flag}); + return y; + ` + .setOptions(multiProjectOptions) + .expectToEqual(result); +}); + +test("return $multi from try", () => { + util.testFunction` + function multiTest() { + try { + return $multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return $multi from catch", () => { + util.testFunction` + function multiTest() { + try { + throw "error"; + } catch { + return $multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return LuaMultiReturn from try", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + return multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return LuaMultiReturn from catch", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + throw "error"; + } catch { + return multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); From de18e7b8888ecd33cf52f36e491b6b1eca11694f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 11 Feb 2021 21:54:23 +0100 Subject: [PATCH 35/91] Implemented enum merging (#980) * Implemented enum merging * Made enum merging work over multiple files --- src/transformation/utils/typescript/nodes.ts | 13 ++++++ src/transformation/visitors/enum.ts | 9 +++- test/unit/enum.spec.ts | 49 ++++++++++++++++++++ test/util.ts | 7 ++- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index db0f85641..3007c4d7d 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { TransformationContext } from "../../context"; export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); @@ -23,3 +24,15 @@ export function isInDestructingAssignment(node: ts.Node): boolean { (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) ); } + +/** + * Quite hacky, avoid unless absolutely necessary! + */ +export function getSymbolOfNode(context: TransformationContext, node: ts.Node): ts.Symbol | undefined { + return (node as any).symbol ?? context.checker.getSymbolAtLocation(node); +} + +export function isFirstDeclaration(context: TransformationContext, node: ts.Node) { + const symbol = getSymbolOfNode(context, node); + return symbol ? symbol.valueDeclaration === node : true; +} diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index e915440c7..918e685f6 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -4,6 +4,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { getSymbolExportScope } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration } from "../utils/lua-ast"; +import { isFirstDeclaration } from "../utils/typescript"; import { transformIdentifier } from "./identifier"; import { transformPropertyName } from "./literal"; @@ -28,9 +29,13 @@ export const transformEnumDeclaration: FunctionVisitor = (no const membersOnly = getTypeAnnotations(type).has(AnnotationKind.CompileMembersOnly); const result: lua.Statement[] = []; - if (!membersOnly) { + if (!membersOnly && isFirstDeclaration(context, node)) { const name = transformIdentifier(context, node.name); - const table = lua.createTableExpression(); + const table = lua.createBinaryExpression( + lua.cloneIdentifier(name), + lua.createTableExpression(), + lua.SyntaxKind.OrOperator + ); result.push(...createLocalOrExportedOrGlobalDeclaration(context, name, table, node)); } diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 8da16355c..f421be2c5 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -154,3 +154,52 @@ test("toString", () => { return foo(TestEnum.A); `.expectToMatchJsResult(); }); + +test("enum merging", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 3, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging with overlap", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 1, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging multiple files", () => { + util.testModule` + import "./otherfile" + enum TestEnum { + A, B + } + + export default ${serializeEnum("TestEnum")} + ` + .addExtraFile( + "otherfile.ts", + `enum TestEnum { + C = 3, + D + }` + ) + .expectToMatchJsResult(); +}); diff --git a/test/util.ts b/test/util.ts index 8cc36f6ca..5a59793be 100644 --- a/test/util.ts +++ b/test/util.ts @@ -237,9 +237,12 @@ export abstract class TestBuilder { // Actions public debug(): this { - const luaCode = this.getMainLuaCodeChunk().replace(/^/gm, " "); + const transpiledFiles = this.getLuaResult().transpiledFiles; + const luaCode = transpiledFiles.map( + f => `[${f.sourceFiles.map(sf => sf.fileName).join(",")}]:\n${f.lua?.replace(/^/gm, " ")}` + ); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); - console.log(`Lua Code:\n${luaCode}\n\nValue:\n${value}`); + console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; } From 5b01ee2d5e603ffc4c8f9f1bc011830bdcfcf1b7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Feb 2021 22:07:46 +0100 Subject: [PATCH 36/91] 0.38.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d98d38972..70e4a7f8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index d4d39ce59..b09cef649 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.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/", From 28d0a57cd3055f61406d78bfb9a5fe95f4ebcfff Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Feb 2021 22:44:52 +0100 Subject: [PATCH 37/91] CHANGELOG 0.38.0 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f277e056..ae1502099 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.38.0 + +- **[Breaking]** Renamed `MultiReturn` to `LuaMultiReturn` to be consistent with other language extensions all starting with Lua-. +- Fixed various bugs and issues related to `LuaMultiReturn`, including its value not correctly being wrapped in some cases. +- Added support for indexing `LuaMultiReturn` values without destructing. +- Added language extensions to allow translation directly to (overwritten) Lua operators like `+`,`-`,`..`. For more information see [Operator Map Types](https://typescripttolua.github.io/docs/advanced/language-extensions#operator-map-types). +- Added language extension `$range()`. This function can be used to create numeric lua loops, for example `for (const i of $range(1, 10)) {` translates to `for i=1,10 do`. For more information see [\$range Iterator Function](https://typescripttolua.github.io/docs/advanced/language-extensions#range-iterator-function). +- Added support for `Array.isArray`, formalizing tstl's isArray convention (**note:** Due to `[]` and `{}` being the same in Lua, `{}` - without any keys - is considered an array too.) +- Added support for `string.prototype.includes`. +- Added support for enum merging. +- Fixed missing lualib dependency in `string.prototype.split`. +- Added a not-supported diagnostic for not-yet-implemented optional chaining (`a?.b`). +- Moved remaining legacy tests to modern testing utils, removing the legacy testing code. + ## 0.37.0 - **[Important]** Deprecated the @phantom, @extension, @metaExtension and @pureAbstract annotations. This is done because there are good alternatives in regular TypeScript, and this helps us simplify the transpiler. For now, using these annotations will result in a warning but they will still continue to function. A few months from now these annotations will no longer be supported, so upgrade if possible. See [Compiler Annotations](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for more info. From 0fba69b06767811f554f21fa8f3d20cb51d5b25c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Feb 2021 18:24:43 +0100 Subject: [PATCH 38/91] Added comments to statements in the Lua AST (#982) * Added comments to statements in the Lua AST * Added support for arrays as multiline comments * Removed pushed indent from multiline comments * factored out printComment --- src/LuaAST.ts | 2 + src/LuaPrinter.ts | 36 +++++++++++ .../__snapshots__/plugins.spec.ts.snap | 29 +++++++++ test/transpile/plugins/add-comments.ts | 62 +++++++++++++++++++ test/transpile/plugins/plugins.spec.ts | 10 +++ 5 files changed, 139 insertions(+) create mode 100644 test/transpile/plugins/__snapshots__/plugins.spec.ts.snap create mode 100644 test/transpile/plugins/add-comments.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 8efb23817..661500e4a 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -229,6 +229,8 @@ export function createBlock(statements: Statement[], tsOriginal?: ts.Node): Bloc export interface Statement extends Node { _statementBrand: any; + leadingComments?: Array; + trailingComments?: Array; } export interface DoStatement extends Statement { diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index a021ae7d5..912ab33f5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -297,6 +297,42 @@ export class LuaPrinter { } public printStatement(statement: lua.Statement): SourceNode { + let resultNode = this.printStatementExcludingComments(statement); + + if (statement.leadingComments) { + resultNode = this.concatNodes( + statement.leadingComments.map(c => this.printComment(c)).join("\n"), + "\n", + resultNode + ); + } + + if (statement.trailingComments) { + resultNode = this.concatNodes( + resultNode, + "\n", + statement.trailingComments.map(c => this.printComment(c)).join("\n") + ); + } + + return resultNode; + } + + public printComment(comment: string | string[]): SourceChunk { + if (Array.isArray(comment)) { + if (comment.length === 0) { + return this.indent("--[[]]"); + } else { + const [firstLine, ...restLines] = comment; + const commentLines = this.concatNodes(...restLines.map(c => this.concatNodes("\n", this.indent(c)))); + return this.concatNodes(this.indent("--[["), firstLine, commentLines, "]]"); + } + } else { + return this.indent(`--${comment}`); + } + } + + protected printStatementExcludingComments(statement: lua.Statement): SourceNode { switch (statement.kind) { case lua.SyntaxKind.DoStatement: return this.printDoStatement(statement as lua.DoStatement); diff --git a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap new file mode 100644 index 000000000..9902416ab --- /dev/null +++ b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`statement comments 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + --This comment on variable declaration was added by a plugin! + --- This one too! + local foo = \\"bar\\" + -- This trailing comment was also added by a plugin! + --- Example luadoc comment + ---@param paramName ParamClass + foo = \\"baz\\" + --[[ This plugin can also (kinda) create multiline comments. + -- Line 2 + --]] + --[[Multiline comments are supported as arrays + This is the second line!]] + while true do + end + --Single line comments and multiline comments can also be mixed + --[[Like this + Pretty cool!]] + --Empty multiline comment below: + --[[]] + --Single line multiline comment: + --[[Single line]] +end +return ____exports" +`; diff --git a/test/transpile/plugins/add-comments.ts b/test/transpile/plugins/add-comments.ts new file mode 100644 index 000000000..9beb01432 --- /dev/null +++ b/test/transpile/plugins/add-comments.ts @@ -0,0 +1,62 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + visitors: { + [ts.SyntaxKind.VariableStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + "This comment on variable declaration was added by a plugin!", + "- This one too!", + ]; + + lastLuaStatement.trailingComments = [" This trailing comment was also added by a plugin!"]; + + return result; + }, + [ts.SyntaxKind.ExpressionStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = ["- Example luadoc comment", "-@param paramName ParamClass"]; + + lastLuaStatement.trailingComments = [ + "[[ This plugin can also (kinda) create multiline comments.", + " Line 2", + "]]", + ]; + + return result; + }, + [ts.SyntaxKind.WhileStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + ["Multiline comments are supported as arrays", "This is the second line!"], + ]; + + lastLuaStatement.trailingComments = [ + "Single line comments and multiline comments can also be mixed", + ["Like this", "Pretty cool!"], + "Empty multiline comment below:", + [], + "Single line multiline comment:", + ["Single line"], + ]; + + return result; + }, + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index e78cc4201..46988dae0 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -30,3 +30,13 @@ test("passing arguments", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "arguments.ts"), option: true }] }) .expectToEqual({ name: path.join(__dirname, "arguments.ts"), option: true }); }); + +test("statement comments", () => { + util.testFunction` + let foo = "bar"; + foo = "baz"; + while (true) {} + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "add-comments.ts") }] }) + .expectLuaToMatchSnapshot(); +}); From d075097c79413501f2ac66a4fea635b10953e772 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Fri, 19 Feb 2021 12:31:59 -0800 Subject: [PATCH 39/91] Precompile lualib and jsonlib for tests (#983) --- test/util.ts | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/test/util.ts b/test/util.ts index 5a59793be..67cfcef57 100644 --- a/test/util.ts +++ b/test/util.ts @@ -10,8 +10,32 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +export function toByteCode(luaCode: string) { + const L = lauxlib.luaL_newstate(); + + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); + + const writer = (_: any, newBytes: Uint8Array, size: number, data: number[]) => { + data.push(...newBytes.slice(0, size)); + return 0; + }; + + const data: number[] = []; + + const dumpExitCode = lua.lua_dump(L, writer, data, false); + + if (dumpExitCode !== 0) { + throw Error("Unable to dump byte code"); + } + + return Uint8Array.from(data); +} + +const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const jsonLibByteCode = toByteCode(jsonLib); + +const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +const luaLibByteCode = toByteCode(luaLib); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -345,7 +369,7 @@ export abstract class TestBuilder { // Json lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(minimalTestLib)); + lauxlib.luaL_loadstring(L, jsonLibByteCode); lua.lua_setfield(L, -2, "json"); // Lua lib if ( @@ -354,7 +378,7 @@ export abstract class TestBuilder { ) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(lualibContent)); + lauxlib.luaL_loadstring(L, luaLibByteCode); lua.lua_setfield(L, -2, "lualib_bundle"); } From 10117134324fb63bb94702c91033b9fd73cb0316 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 20 Feb 2021 10:50:36 -0700 Subject: [PATCH 40/91] LuaIterable language extension (#981) * added LuaIterable and LuaMultiIterable language extensions * indentation fix * remove LuaMultiIterable in favor of LuaIterable * switched from expectToHaveDiagnostics to expectDiagnosticsToMatchSnapshot * updates based on feedback and discussions - LuaIterable type reworked for better lua compatibility - language extensions now checked by brand instead of type alias name - fixed LuaMultiReturn indirect forward, which also affected LuaIterable - reorganized tests and added some for manual iterable usage * fixed issue with no-state vs state iterables, and updated tests to check both (also added test for property based iterables) * updated extension kind checking to reduce complexity * updated new multi tests to actually use multiple values * replaced raw brands with LuaExtension type Co-authored-by: Tom --- language-extensions/index.d.ts | 214 +++---- src/lualib/Iterator.ts | 4 +- src/lualib/declarations/global.d.ts | 8 +- src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 123 ++-- .../visitors/language-extensions/iterable.ts | 82 +++ .../visitors/language-extensions/multi.ts | 26 +- .../visitors/language-extensions/operators.ts | 21 +- .../visitors/language-extensions/range.ts | 8 +- src/transformation/visitors/loops/for-of.ts | 3 + src/transformation/visitors/return.ts | 7 +- .../__snapshots__/iterable.spec.ts.snap | 52 ++ .../unit/language-extensions/iterable.spec.ts | 552 ++++++++++++++++++ test/unit/language-extensions/multi.spec.ts | 30 +- 14 files changed, 913 insertions(+), 221 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/iterable.ts create mode 100644 test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap create mode 100644 test/unit/language-extensions/iterable.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 033012960..79067b1cd 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,3 +1,11 @@ +/** + * Indicates a type is a language extension provided by TypescriptToLua. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TBrand A string used to uniquely identify the language extension type + */ +declare type LuaExtension = { [T in TBrand]: { readonly __luaExtensionSymbol: unique symbol } }; + /** * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -5,7 +13,7 @@ * @param T A tuple type with each element type representing a return value's type. * @param values Return values. */ -declare function $multi(...values: T): LuaMultiReturn; +declare const $multi: ((...values: T) => LuaMultiReturn) & LuaExtension<"__luaMultiFunctionBrand">; /** * Represents multiple return values as a tuple. @@ -13,7 +21,7 @@ declare function $multi(...values: T): LuaMultiReturn; * * @param T A tuple type with each element type representing a return value's type. */ -declare type LuaMultiReturn = T & { readonly __luaMultiReturnBrand: unique symbol }; +declare type LuaMultiReturn = T & LuaExtension<"__luaMultiReturnBrand">; /** * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. @@ -23,7 +31,42 @@ declare type LuaMultiReturn = T & { readonly __luaMultiReturnBr * @param limit The last number in the sequence to iterate over. * @param step The amount to increment each iteration. */ -declare function $range(start: number, limit: number, step?: number): Iterable; +declare const $range: ((start: number, limit: number, step?: number) => Iterable) & + LuaExtension<"__luaRangeFunctionBrand">; + +/** + * Represents a Lua-style iterator which is returned from a LuaIterable. + * For simple iterators (with no state), this is just a function. + * For complex iterators that use a state, this is a LuaMultiReturn tuple containing a function, the state, and the initial value to pass to the function. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param state The state object returned from the LuaIterable. + * @param lastValue The last value returned from this function. If iterating LuaMultiReturn values, this is the first value of the tuple. + */ +declare type LuaIterator = TState extends undefined + ? (this: void) => TValue + : LuaMultiReturn< + [ + ( + this: void, + state: TState, + lastValue: TValue extends LuaMultiReturn ? TTuple[0] : TValue + ) => TValue, + TState, + TValue extends LuaMultiReturn ? TTuple[0] : TValue + ] + >; + +/** + * Represents a Lua-style iteratable which iterates single values in a `for...in` loop (ex. `for x in iter() do`). + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TValue The type of value returned each iteration. If this is LuaMultiReturn, multiple values will be returned each iteration. + * @param TState The type of the state value passed back to the iterator function each iteration. + */ +declare type LuaIterable = Iterable & + LuaIterator & + LuaExtension<"__luaIterableBrand">; /** * Calls to functions with this type are translated to `left + right`. @@ -33,9 +76,8 @@ declare function $range(start: number, limit: number, step?: number): Iterable = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaAdditionBrand: unique symbol; -}; +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaAdditionBrand">; /** * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. @@ -44,9 +86,8 @@ declare type LuaAddition = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaAdditionMethod = ((right: TRight) => TReturn) & { - readonly __luaAdditionMethodBrand: unique symbol; -}; +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaAdditionMethodBrand">; /** * Calls to functions with this type are translated to `left - right`. @@ -56,9 +97,8 @@ declare type LuaAdditionMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaSubtractionBrand: unique symbol; -}; +declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionBrand">; /** * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. @@ -67,9 +107,8 @@ declare type LuaSubtraction = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & { - readonly __luaSubtractionMethodBrand: unique symbol; -}; +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionMethodBrand">; /** * Calls to functions with this type are translated to `left * right`. @@ -79,9 +118,8 @@ declare type LuaSubtractionMethod = ((right: TRight) => TReturn * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaMultiplicationBrand: unique symbol; -}; +declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationBrand">; /** * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. @@ -90,9 +128,8 @@ declare type LuaMultiplication = ((left: TLeft, right: T * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & { - readonly __luaMultiplicationMethodBrand: unique symbol; -}; +declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationMethodBrand">; /** * Calls to functions with this type are translated to `left / right`. @@ -102,9 +139,8 @@ declare type LuaMultiplicationMethod = ((right: TRight) => TRet * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaDivisionBrand: unique symbol; -}; +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaDivisionBrand">; /** * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. @@ -113,9 +149,8 @@ declare type LuaDivision = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivisionMethod = ((right: TRight) => TReturn) & { - readonly __luaDivisionMethodBrand: unique symbol; -}; +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaDivisionMethodBrand">; /** * Calls to functions with this type are translated to `left % right`. @@ -125,9 +160,8 @@ declare type LuaDivisionMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaModuloBrand: unique symbol; -}; +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaModuloBrand">; /** * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. @@ -136,9 +170,7 @@ declare type LuaModulo = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModuloMethod = ((right: TRight) => TReturn) & { - readonly __luaModuloMethodBrand: unique symbol; -}; +declare type LuaModuloMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaModuloMethodBrand">; /** * Calls to functions with this type are translated to `left ^ right`. @@ -148,9 +180,8 @@ declare type LuaModuloMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaPowerBrand: unique symbol; -}; +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaPowerBrand">; /** * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. @@ -159,9 +190,7 @@ declare type LuaPower = ((left: TLeft, right: TRight) => * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPowerMethod = ((right: TRight) => TReturn) & { - readonly __luaPowerMethodBrand: unique symbol; -}; +declare type LuaPowerMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaPowerMethodBrand">; /** * Calls to functions with this type are translated to `left // right`. @@ -171,9 +200,8 @@ declare type LuaPowerMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaFloorDivisionBrand: unique symbol; -}; +declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionBrand">; /** * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. @@ -182,9 +210,8 @@ declare type LuaFloorDivision = ((left: TLeft, right: TR * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & { - readonly __luaFloorDivisionMethodBrand: unique symbol; -}; +declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionMethodBrand">; /** * Calls to functions with this type are translated to `left & right`. @@ -194,9 +221,8 @@ declare type LuaFloorDivisionMethod = ((right: TRight) => TRetu * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseAndBrand: unique symbol; -}; +declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndBrand">; /** * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. @@ -205,9 +231,8 @@ declare type LuaBitwiseAnd = ((left: TLeft, right: TRigh * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseAndMethodBrand: unique symbol; -}; +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndMethodBrand">; /** * Calls to functions with this type are translated to `left | right`. @@ -217,9 +242,8 @@ declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseOrBrand: unique symbol; -}; +declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrBrand">; /** * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. @@ -228,9 +252,8 @@ declare type LuaBitwiseOr = ((left: TLeft, right: TRight * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseOrMethodBrand: unique symbol; -}; +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrMethodBrand">; /** * Calls to functions with this type are translated to `left ~ right`. @@ -240,9 +263,8 @@ declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseExclusiveOrBrand: unique symbol; -}; +declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrBrand">; /** * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. @@ -251,9 +273,8 @@ declare type LuaBitwiseExclusiveOr = ((left: TLeft, righ * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseExclusiveOrMethodBrand: unique symbol; -}; +declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrMethodBrand">; /** * Calls to functions with this type are translated to `left << right`. @@ -263,9 +284,8 @@ declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseLeftShiftBrand: unique symbol; -}; +declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftBrand">; /** * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. @@ -274,9 +294,8 @@ declare type LuaBitwiseLeftShift = ((left: TLeft, right: * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseLeftShiftMethodBrand: unique symbol; -}; +declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftMethodBrand">; /** * Calls to functions with this type are translated to `left >> right`. @@ -286,9 +305,8 @@ declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TR * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseRightShiftBrand: unique symbol; -}; +declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftBrand">; /** * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. @@ -297,9 +315,8 @@ declare type LuaBitwiseRightShift = ((left: TLeft, right * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseRightShiftMethodBrand: unique symbol; -}; +declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftMethodBrand">; /** * Calls to functions with this type are translated to `left .. right`. @@ -309,9 +326,8 @@ declare type LuaBitwiseRightShiftMethod = ((right: TRight) => T * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaConcatBrand: unique symbol; -}; +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaConcatBrand">; /** * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. @@ -320,9 +336,7 @@ declare type LuaConcat = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcatMethod = ((right: TRight) => TReturn) & { - readonly __luaConcatMethodBrand: unique symbol; -}; +declare type LuaConcatMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaConcatMethodBrand">; /** * Calls to functions with this type are translated to `left < right`. @@ -332,9 +346,8 @@ declare type LuaConcatMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaLessThanBrand: unique symbol; -}; +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaLessThanBrand">; /** * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. @@ -343,9 +356,8 @@ declare type LuaLessThan = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThanMethod = ((right: TRight) => TReturn) & { - readonly __luaLessThanMethodBrand: unique symbol; -}; +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaLessThanMethodBrand">; /** * Calls to functions with this type are translated to `left > right`. @@ -355,9 +367,8 @@ declare type LuaLessThanMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaGreaterThanBrand: unique symbol; -}; +declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanBrand">; /** * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. @@ -366,9 +377,8 @@ declare type LuaGreaterThan = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & { - readonly __luaGreaterThanMethodBrand: unique symbol; -}; +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanMethodBrand">; /** * Calls to functions with this type are translated to `-operand`. @@ -377,9 +387,7 @@ declare type LuaGreaterThanMethod = ((right: TRight) => TReturn * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegation = ((operand: TOperand) => TReturn) & { - readonly __luaNegationBrand: unique symbol; -}; +declare type LuaNegation = ((operand: TOperand) => TReturn) & LuaExtension<"__luaNegationBrand">; /** * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. @@ -387,7 +395,7 @@ declare type LuaNegation = ((operand: TOperand) => TReturn) & * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNegationMethodBrand: unique symbol }; +declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"__luaNegationMethodBrand">; /** * Calls to functions with this type are translated to `~operand`. @@ -396,9 +404,7 @@ declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNega * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & { - readonly __luaBitwiseNotBrand: unique symbol; -}; +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & LuaExtension<"__luaBitwiseNotBrand">; /** * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. @@ -406,7 +412,7 @@ declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBitwiseNotMethodBrand: unique symbol }; +declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"__luaBitwiseNotMethodBrand">; /** * Calls to functions with this type are translated to `#operand`. @@ -415,9 +421,7 @@ declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBi * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLength = ((operand: TOperand) => TReturn) & { - readonly __luaLengthBrand: unique symbol; -}; +declare type LuaLength = ((operand: TOperand) => TReturn) & LuaExtension<"__luaLengthBrand">; /** * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. @@ -425,4 +429,4 @@ declare type LuaLength = ((operand: TOperand) => TReturn) & { * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLengthMethod = (() => TReturn) & { readonly __luaLengthMethodBrand: unique symbol }; +declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 809ca69ee..d6112cd88 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -27,7 +27,7 @@ function __TS__IteratorStringStep(this: string, index: number): [number, string] function __TS__Iterator( this: void, iterable: string | GeneratorIterator | Iterable | readonly T[] -): [(...args: any[]) => [any, any] | [], ...any[]] { +): [(...args: any[]) => [any, any] | [], ...any[]] | LuaIterable> { if (typeof iterable === "string") { return [__TS__IteratorStringStep, iterable, 0]; } else if ("____coroutine" in iterable) { @@ -36,6 +36,6 @@ function __TS__Iterator( const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; } else { - return ipairs(iterable as readonly T[]) as any; + return ipairs(iterable as readonly T[]); } } diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 450fba8dc..117438817 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -25,10 +25,4 @@ declare function unpack(list: T[], i?: number, j?: number): T[]; declare function select(index: number, ...args: T[]): T; declare function select(index: "#", ...args: T[]): number; -/** - * @luaIterator - * @tupleReturn - */ -type LuaTupleIterator = Iterable & { " LuaTupleIterator": never }; - -declare function ipairs(t: Record): LuaTupleIterator<[number, T]>; +declare function ipairs(t: Record): LuaIterable, Record>; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 76e8b4632..e8873746a 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -118,6 +118,10 @@ export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( "the '@tupleReturn' annotation." ); +export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory( + "LuaIterable with a LuaMultiReturn return value type must be destructured." +); + export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( "Accessors in object literal are not supported." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 391993f8a..efcd7d810 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -1,10 +1,11 @@ import * as ts from "typescript"; -import * as path from "path"; +import { TransformationContext } from "../context"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", RangeFunction = "RangeFunction", + IterableType = "IterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -43,74 +44,66 @@ export enum ExtensionKind { LengthOperatorMethodType = "LengthOperatorMethodType", } -const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { - $multi: ExtensionKind.MultiFunction, - $range: ExtensionKind.RangeFunction, +const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { + [ExtensionKind.MultiFunction]: "$multi", + [ExtensionKind.RangeFunction]: "$range", }; -const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { - LuaMultiReturn: ExtensionKind.MultiType, - LuaAddition: ExtensionKind.AdditionOperatorType, - LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, - LuaSubtraction: ExtensionKind.SubtractionOperatorType, - LuaSubtractionMethod: ExtensionKind.SubtractionOperatorMethodType, - LuaMultiplication: ExtensionKind.MultiplicationOperatorType, - LuaMultiplicationMethod: ExtensionKind.MultiplicationOperatorMethodType, - LuaDivision: ExtensionKind.DivisionOperatorType, - LuaDivisionMethod: ExtensionKind.DivisionOperatorMethodType, - LuaModulo: ExtensionKind.ModuloOperatorType, - LuaModuloMethod: ExtensionKind.ModuloOperatorMethodType, - LuaPower: ExtensionKind.PowerOperatorType, - LuaPowerMethod: ExtensionKind.PowerOperatorMethodType, - LuaFloorDivision: ExtensionKind.FloorDivisionOperatorType, - LuaFloorDivisionMethod: ExtensionKind.FloorDivisionOperatorMethodType, - LuaBitwiseAnd: ExtensionKind.BitwiseAndOperatorType, - LuaBitwiseAndMethod: ExtensionKind.BitwiseAndOperatorMethodType, - LuaBitwiseOr: ExtensionKind.BitwiseOrOperatorType, - LuaBitwiseOrMethod: ExtensionKind.BitwiseOrOperatorMethodType, - LuaBitwiseExclusiveOr: ExtensionKind.BitwiseExclusiveOrOperatorType, - LuaBitwiseExclusiveOrMethod: ExtensionKind.BitwiseExclusiveOrOperatorMethodType, - LuaBitwiseLeftShift: ExtensionKind.BitwiseLeftShiftOperatorType, - LuaBitwiseLeftShiftMethod: ExtensionKind.BitwiseLeftShiftOperatorMethodType, - LuaBitwiseRightShift: ExtensionKind.BitwiseRightShiftOperatorType, - LuaBitwiseRightShiftMethod: ExtensionKind.BitwiseRightShiftOperatorMethodType, - LuaConcat: ExtensionKind.ConcatOperatorType, - LuaConcatMethod: ExtensionKind.ConcatOperatorMethodType, - LuaLessThan: ExtensionKind.LessThanOperatorType, - LuaLessThanMethod: ExtensionKind.LessThanOperatorMethodType, - LuaGreaterThan: ExtensionKind.GreaterThanOperatorType, - LuaGreaterThanMethod: ExtensionKind.GreaterThanOperatorMethodType, - LuaNegation: ExtensionKind.NegationOperatorType, - LuaNegationMethod: ExtensionKind.NegationOperatorMethodType, - LuaBitwiseNot: ExtensionKind.BitwiseNotOperatorType, - LuaBitwiseNotMethod: ExtensionKind.BitwiseNotOperatorMethodType, - LuaLength: ExtensionKind.LengthOperatorType, - LuaLengthMethod: ExtensionKind.LengthOperatorMethodType, +const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { + [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", + [ExtensionKind.MultiType]: "__luaMultiReturnBrand", + [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", + [ExtensionKind.IterableType]: "__luaIterableBrand", + [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", + [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", + [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", + [ExtensionKind.SubtractionOperatorMethodType]: "__luaSubtractionMethodBrand", + [ExtensionKind.MultiplicationOperatorType]: "__luaMultiplicationBrand", + [ExtensionKind.MultiplicationOperatorMethodType]: "__luaMultiplicationMethodBrand", + [ExtensionKind.DivisionOperatorType]: "__luaDivisionBrand", + [ExtensionKind.DivisionOperatorMethodType]: "__luaDivisionMethodBrand", + [ExtensionKind.ModuloOperatorType]: "__luaModuloBrand", + [ExtensionKind.ModuloOperatorMethodType]: "__luaModuloMethodBrand", + [ExtensionKind.PowerOperatorType]: "__luaPowerBrand", + [ExtensionKind.PowerOperatorMethodType]: "__luaPowerMethodBrand", + [ExtensionKind.FloorDivisionOperatorType]: "__luaFloorDivisionBrand", + [ExtensionKind.FloorDivisionOperatorMethodType]: "__luaFloorDivisionMethodBrand", + [ExtensionKind.BitwiseAndOperatorType]: "__luaBitwiseAndBrand", + [ExtensionKind.BitwiseAndOperatorMethodType]: "__luaBitwiseAndMethodBrand", + [ExtensionKind.BitwiseOrOperatorType]: "__luaBitwiseOrBrand", + [ExtensionKind.BitwiseOrOperatorMethodType]: "__luaBitwiseOrMethodBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorType]: "__luaBitwiseExclusiveOrBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorMethodType]: "__luaBitwiseExclusiveOrMethodBrand", + [ExtensionKind.BitwiseLeftShiftOperatorType]: "__luaBitwiseLeftShiftBrand", + [ExtensionKind.BitwiseLeftShiftOperatorMethodType]: "__luaBitwiseLeftShiftMethodBrand", + [ExtensionKind.BitwiseRightShiftOperatorType]: "__luaBitwiseRightShiftBrand", + [ExtensionKind.BitwiseRightShiftOperatorMethodType]: "__luaBitwiseRightShiftMethodBrand", + [ExtensionKind.ConcatOperatorType]: "__luaConcatBrand", + [ExtensionKind.ConcatOperatorMethodType]: "__luaConcatMethodBrand", + [ExtensionKind.LessThanOperatorType]: "__luaLessThanBrand", + [ExtensionKind.LessThanOperatorMethodType]: "__luaLessThanMethodBrand", + [ExtensionKind.GreaterThanOperatorType]: "__luaGreaterThanBrand", + [ExtensionKind.GreaterThanOperatorMethodType]: "__luaGreaterThanMethodBrand", + [ExtensionKind.NegationOperatorType]: "__luaNegationBrand", + [ExtensionKind.NegationOperatorMethodType]: "__luaNegationMethodBrand", + [ExtensionKind.BitwiseNotOperatorType]: "__luaBitwiseNotBrand", + [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", + [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", + [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", }; -function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { - const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); - const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); - return extensionDirectory === sourceFileDirectory; +export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { + const typeBrand = extensionKindToTypeBrand[extensionKind]; + return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; } -export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { - const sourceFile = declaration.getSourceFile(); - if (isSourceFileFromLanguageExtensions(sourceFile)) { - if (ts.isFunctionDeclaration(declaration) && declaration.name?.text) { - const extensionKind = functionNameToExtensionKind[declaration.name.text]; - if (extensionKind) { - return extensionKind; - } - } - - if (ts.isTypeAliasDeclaration(declaration)) { - const extensionKind = typeNameToExtensionKind[declaration.name.text]; - if (extensionKind) { - return extensionKind; - } - } - - throw new Error("Unknown extension kind"); - } +export function isExtensionFunction( + context: TransformationContext, + symbol: ts.Symbol, + extensionKind: ExtensionKind +): boolean { + return ( + symbol.getName() === extensionKindToFunctionName[extensionKind] && + symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) + ); } diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts new file mode 100644 index 000000000..769e15093 --- /dev/null +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -0,0 +1,82 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; +import { transformArrayBindingElement } from "../variable-declaration"; +import { invalidMultiIterableWithoutDestructuring } from "../../utils/diagnostics"; +import { cast } from "../../../utils"; +import { isMultiReturnType } from "./multi"; + +export function isIterableType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.IterableType); +} + +export function returnsIterableType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + const type = signature?.getReturnType(); + return type ? isIterableType(type) : false; +} + +export function isIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { + const type = context.checker.getTypeAtLocation(expression); + return isIterableType(type); +} + +function transformForOfMultiIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const luaIterator = context.transformExpression(statement.expression); + let identifiers: lua.Identifier[] = []; + + if (ts.isVariableDeclarationList(statement.initializer)) { + // Variables declared in for loop + // for ${initializer} in ${iterable} do + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (ts.isArrayBindingPattern(binding)) { + identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(binding)); + } + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Variables NOT declared in for loop - catch iterator values in temps and assign + // for ____value0 in ${iterable} do + // ${initializer} = ____value0 + identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) + ), + identifiers + ) + ); + } + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(statement.initializer)); + } + + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); + } + + return lua.createForInStatement(block, identifiers, [luaIterator], statement); +} + +export function transformForOfIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const type = context.checker.getTypeAtLocation(statement.expression); + if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { + return transformForOfMultiIterableStatement(context, statement, block); + } + + const luaIterator = context.transformExpression(statement.expression); + const identifier = transformForInitializer(context, statement.initializer, block); + return lua.createForInStatement(block, [identifier], [luaIterator], statement); +} diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 8ddb54c83..b292d9aa1 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -1,22 +1,16 @@ import * as ts from "typescript"; import * as extensions from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { invalidMultiFunctionUse } from "../../utils/diagnostics"; import { findFirstNodeAbove } from "../../utils/typescript"; - -const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; - -const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; +import { isIterableExpression } from "./iterable"; +import { invalidMultiFunctionUse } from "../../utils/diagnostics"; export function isMultiReturnType(type: ts.Type): boolean { - return type.aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; + return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); } export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { - const type = context.checker.getTypeAtLocation(expression.expression); - return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; + return isMultiFunctionNode(context, expression.expression); } export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { @@ -30,8 +24,8 @@ export function isMultiReturnCall(context: TransformationContext, expression: ts } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { - const type = context.checker.getTypeAtLocation(node); - return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.MultiFunction) : false; } export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { @@ -86,6 +80,11 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n return false; } + // LuaIterable in for...of + if (ts.isForOfStatement(node.parent) && isIterableExpression(context, node)) { + return false; + } + return true; } @@ -99,8 +98,7 @@ export function findMultiAssignmentViolations( if (!ts.isShorthandPropertyAssignment(element)) continue; const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); if (valueSymbol) { - const declaration = valueSymbol.valueDeclaration; - if (declaration && isMultiFunctionDeclaration(declaration)) { + if (extensions.isExtensionFunction(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { context.diagnostics.push(invalidMultiFunctionUse(element)); result.push(element); } diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index b217a26e8..dddecf338 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -49,10 +49,7 @@ const unaryOperatorMappings = new Map([ - ...binaryOperatorMappings.keys(), - ...unaryOperatorMappings.keys(), -]); +const operatorMapExtensions = [...binaryOperatorMappings.keys(), ...unaryOperatorMappings.keys()]; const bitwiseOperatorMapExtensions = new Set([ extensions.ExtensionKind.BitwiseAndOperatorType, @@ -84,25 +81,15 @@ function getOperatorMapExtensionKindForCall(context: TransformationContext, node if (!typeDeclaration) { return; } - const mapping = extensions.getExtensionKind(typeDeclaration); - if (mapping !== undefined && operatorMapExtensions.has(mapping)) { - return mapping; - } -} - -function isOperatorMapDeclaration(declaration: ts.Declaration) { - const typeDeclaration = getTypeDeclaration(declaration); - if (typeDeclaration) { - const extensionKind = extensions.getExtensionKind(typeDeclaration); - return extensionKind !== undefined ? operatorMapExtensions.has(extensionKind) : false; - } + const type = context.checker.getTypeFromTypeNode(typeDeclaration.type); + return operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); } function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { if (type.isUnionOrIntersection()) { return type.types.some(t => isOperatorMapType(context, t)); } else { - return type.symbol?.declarations?.some(isOperatorMapDeclaration); + return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); } } diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts index d68729c3c..00a3c249e 100644 --- a/src/transformation/visitors/language-extensions/range.ts +++ b/src/transformation/visitors/language-extensions/range.ts @@ -8,17 +8,13 @@ import { transformArguments } from "../call"; import { assert } from "../../../utils"; import { invalidRangeControlVariable } from "../../utils/diagnostics"; -const isRangeFunctionDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.RangeFunction; - export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { - const type = context.checker.getTypeAtLocation(expression.expression); - return type.symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; + return isRangeFunctionNode(context, expression.expression); } export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; + return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.RangeFunction) : false; } function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 047ed3535..e8241f40f 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -8,6 +8,7 @@ import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; +import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformArrayBindingElement } from "../variable-declaration"; import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; @@ -156,6 +157,8 @@ export const transformForOfStatement: FunctionVisitor = (node return transformRangeStatement(context, node, body); } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { return transformForRangeStatement(context, node, body); + } else if (isIterableExpression(context, node.expression)) { + return transformForOfIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { return transformForOfLuaIteratorStatement(context, node, body); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 7e7a7ddf8..f309874f7 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -12,6 +12,7 @@ import { shouldMultiReturnCallBeWrapped, isMultiFunctionCall, isMultiReturnType, + isInMultiReturnFunction, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; @@ -20,6 +21,8 @@ function transformExpressionsInReturn( node: ts.Expression, insideTryCatch: boolean ): lua.Expression[] { + const expressionType = context.checker.getTypeAtLocation(node); + if (ts.isCallExpression(node)) { // $multi(...) if (isMultiFunctionCall(context, node)) { @@ -40,6 +43,9 @@ function transformExpressionsInReturn( if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { return [wrapInTable(context.transformExpression(node))]; } + } else if (isInMultiReturnFunction(context, node) && isMultiReturnType(expressionType)) { + // Unpack objects typed as LuaMultiReturn + return [createUnpackCall(context, context.transformExpression(node), node)]; } if (!isInTupleReturnFunction(context, node)) { @@ -47,7 +53,6 @@ function transformExpressionsInReturn( } let results: lua.Expression[]; - const expressionType = context.checker.getTypeAtLocation(node); // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(node)) { diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap new file mode 100644 index 000000000..1f76110a4 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,24): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + local s + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,25): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; diff --git a/test/unit/language-extensions/iterable.spec.ts b/test/unit/language-extensions/iterable.spec.ts new file mode 100644 index 000000000..b6f7ab141 --- /dev/null +++ b/test/unit/language-extensions/iterable.spec.ts @@ -0,0 +1,552 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidMultiIterableWithoutDestructuring } from "../../../src/transformation/utils/diagnostics"; + +const iterableProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +describe("simple LuaIterable", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strs = ["a", "b", "c"]; + let i = 0; + return (() => strs[i++]) as any; + } + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable using state", () => { + const testIterable = ` + function iterator(this: void, strs: string[], lastStr: string) { + return strs[strs.indexOf(lastStr) + 1]; + } + const testIterable = (() => $multi(iterator, ["a", "b", "c"], "")) as (() => LuaIterable); + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let [iter, state, val] = testIterable(); + while (true) { + val = iter(state, val); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with array value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => strsArray[i++]) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with LuaMultiReturn value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable> { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => { + const strs = strsArray[i++]; + if (strs) { + return $multi(...strs); + } + }) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const [x, y] = iter(); + if (!x) { + break; + } + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test.each(["for (const s of testIterable()) {}", "let s; for (s of testIterable()) {}"])( + "invalid LuaIterable without destructuring (%p)", + statement => { + util.testFunction` + ${testIterable} + ${statement} + ` + .setOptions(iterableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiIterableWithoutDestructuring.code]); + } + ); +}); + +describe("LuaIterable property", () => { + const testIterable = ` + class IterableTester { + public strs = ["a", "b", "c"]; + + public get values(): LuaIterable { + let i = 0; + return (() => this.strs[i++]) as any; + } + } + const tester = new IterableTester(); + `; + const testResults = ["a", "b", "c"]; + + test("basic usage", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of tester.values) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of tester.values) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return tester.values; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = tester.values; return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => tester.values; + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = tester.values; + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index ff1fd403a..0b99cf4dc 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -130,15 +130,37 @@ test("allow $multi call in ArrowFunction body", () => { .expectToEqual(1); }); +test("forward $multi call", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { return foo(); } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .setOptions(multiProjectOptions) + .expectToEqual([1, 2]); +}); + +test("forward $multi call indirect", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { const m = foo(); return m; } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .setOptions(multiProjectOptions) + .expectToEqual([1, 2]); +}); + test("forward $multi call in ArrowFunction body", () => { util.testFunction` - const foo = () => $multi(1); + const foo = () => $multi(1, 2); const call = () => foo(); - const [result] = call(); - return result; + const [resultA, resultB] = call(); + return [resultA, resultB]; ` .setOptions(multiProjectOptions) - .expectToEqual(1); + .expectToEqual([1, 2]); }); test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { From 0a5bd20a115e64db02186c6e9d84a30ecf918718 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 20 Feb 2021 19:00:34 +0100 Subject: [PATCH 41/91] 0.38.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70e4a7f8c..4791e9650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index b09cef649..078637493 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "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/", From e90fc31b1db83b7423710a73aa1feced265d43d8 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 21 Feb 2021 13:53:55 -0700 Subject: [PATCH 42/91] Lua table extensions (#991) * Lua table extensions * addressing feedback Co-authored-by: Tom --- language-extensions/index.d.ts | 78 ++++++++++ src/transformation/utils/diagnostics.ts | 8 + .../utils/language-extensions.ts | 10 ++ src/transformation/utils/typescript/index.ts | 12 ++ src/transformation/visitors/call.ts | 19 +++ src/transformation/visitors/class/new.ts | 5 + .../visitors/expression-statement.ts | 5 + src/transformation/visitors/identifier.ts | 6 + .../visitors/language-extensions/operators.ts | 36 +---- .../visitors/language-extensions/table.ts | 80 ++++++++++ .../__snapshots__/table.spec.ts.snap | 64 ++++++++ test/unit/language-extensions/table.spec.ts | 137 ++++++++++++++++++ 12 files changed, 429 insertions(+), 31 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/table.ts create mode 100644 test/unit/language-extensions/__snapshots__/table.spec.ts.snap create mode 100644 test/unit/language-extensions/table.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 79067b1cd..e5d3096a3 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -430,3 +430,81 @@ declare type LuaLength = ((operand: TOperand) => TReturn) & L * @param TReturn The resulting (return) type of the operation. */ declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key]`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGet = ((table: TTable, key: TKey) => TValue) & + LuaExtension<"__luaTableGetBrand">; + +/** + * Calls to methods with this type are translated to `table[key]`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGetMethod = ((key: TKey) => TValue) & + LuaExtension<"__luaTableGetMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = value`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSet = (( + table: TTable, + key: TKey, + value: TValue +) => void) & + LuaExtension<"__luaTableSetBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = value`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & + LuaExtension<"__luaTableSetMethodBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare interface LuaTable { + length: LuaLengthMethod; + get: LuaTableGetMethod; + set: LuaTableSetMethod; +} + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare type LuaTableConstructor = (new () => LuaTable) & + LuaExtension<"__luaTableNewBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare const LuaTable: LuaTableConstructor; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index e8873746a..9b34e9547 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -174,6 +174,14 @@ export const invalidOperatorMappingUse = createErrorDiagnosticFactory( "This function must always be directly called and cannot be referred to." ); +export const invalidTableExtensionUse = createErrorDiagnosticFactory( + "This function must be called directly and cannot be referred to." +); + +export const invalidTableSetExpression = createErrorDiagnosticFactory( + "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." +); + export const 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. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index efcd7d810..cb17987ad 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -42,6 +42,11 @@ export enum ExtensionKind { BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", LengthOperatorType = "LengthOperatorType", LengthOperatorMethodType = "LengthOperatorMethodType", + TableNewType = "TableNewType", + TableGetType = "TableGetType", + TableGetMethodType = "TableGetMethodType", + TableSetType = "TableSetType", + TableSetMethodType = "TableSetMethodType", } const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { @@ -90,6 +95,11 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", + [ExtensionKind.TableNewType]: "__luaTableNewBrand", + [ExtensionKind.TableGetType]: "__luaTableGetBrand", + [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", + [ExtensionKind.TableSetType]: "__luaTableSetBrand", + [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", }; export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 394d67656..46b4992ea 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -79,3 +79,15 @@ export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); } + +export function getFunctionTypeForCall(context: TransformationContext, node: ts.CallExpression) { + const signature = context.checker.getResolvedSignature(node); + if (!signature || !signature.declaration) { + return; + } + const typeDeclaration = findFirstNodeAbove(signature.declaration, ts.isTypeAliasDeclaration); + if (!typeDeclaration) { + return; + } + return context.checker.getTypeFromTypeNode(typeDeclaration.type); +} diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index f29cbd4e9..7ea22eb34 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -13,6 +13,13 @@ import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; +import { + isTableGetCall, + isTableSetCall, + transformTableGetExpression, + transformTableSetExpression, +} from "./language-extensions/table"; +import { invalidTableSetExpression } from "../utils/diagnostics"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -214,6 +221,18 @@ export const transformCallExpression: FunctionVisitor = (node return transformOperatorMappingExpression(context, node); } + if (isTableGetCall(context, node)) { + return transformTableGetExpression(context, node); + } + + if (isTableSetCall(context, node)) { + context.diagnostics.push(invalidTableSetExpression(node)); + return createImmediatelyInvokedFunctionExpression( + [transformTableSetExpression(context, node)], + lua.createNilLiteral() + ); + } + if (ts.isPropertyAccessExpression(node.expression)) { const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index da1c2f124..bf3935b7d 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -5,6 +5,7 @@ import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; +import { isTableNewCall } from "../language-extensions/table"; import { transformLuaTableNewExpression } from "../lua-table"; const builtinErrorTypeNames = new Set([ @@ -53,6 +54,10 @@ export const transformNewExpression: FunctionVisitor = (node, return luaTableResult; } + if (isTableNewCall(context, node)) { + return lua.createTableExpression(undefined, node); + } + const name = context.transformExpression(node.expression); const signature = context.checker.getResolvedSignature(node); const params = node.arguments diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 890695be0..1932a6dc2 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; +import { isTableSetCall, transformTableSetExpression } from "./language-extensions/table"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -11,6 +12,10 @@ export const transformExpressionStatement: FunctionVisitor([ extensions.ExtensionKind.BitwiseNotOperatorMethodType, ]); -function getTypeDeclaration(declaration: ts.Declaration) { - return ts.isTypeAliasDeclaration(declaration) - ? declaration - : findFirstNodeAbove(declaration, ts.isTypeAliasDeclaration); -} - function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { - const signature = context.checker.getResolvedSignature(node); - if (!signature || !signature.declaration) { - return; - } - const typeDeclaration = getTypeDeclaration(signature.declaration); - if (!typeDeclaration) { - return; - } - const type = context.checker.getTypeFromTypeNode(typeDeclaration.type); - return operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); -} - -function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { - if (type.isUnionOrIntersection()) { - return type.types.some(t => isOperatorMapType(context, t)); - } else { - return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); - } -} - -function isOperatorMapIdentifier(context: TransformationContext, node: ts.Identifier) { - const type = context.checker.getTypeAtLocation(node); - return isOperatorMapType(context, type); + const type = getFunctionTypeForCall(context, node); + return type && operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); } export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { if (ts.isCallExpression(node)) { return getOperatorMapExtensionKindForCall(context, node) !== undefined; } else { - return isOperatorMapIdentifier(context, node); + const type = context.checker.getTypeAtLocation(node); + return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); } } diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts new file mode 100644 index 000000000..b1c26f2d9 --- /dev/null +++ b/src/transformation/visitors/language-extensions/table.ts @@ -0,0 +1,80 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { getFunctionTypeForCall } from "../../utils/typescript"; +import { assert } from "../../../utils"; + +const tableGetExtensions = [extensions.ExtensionKind.TableGetType, extensions.ExtensionKind.TableGetMethodType]; + +const tableSetExtensions = [extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType]; + +const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableGetExtensions, ...tableSetExtensions]; + +function getTableExtensionKindForCall( + context: TransformationContext, + node: ts.CallExpression, + validExtensions: extensions.ExtensionKind[] +) { + const type = getFunctionTypeForCall(context, node); + return type && validExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableExtensionIdentifier(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; +} + +export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; +} + +export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { + const type = context.checker.getTypeAtLocation(node.expression); + return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); +} + +export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + return lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + node + ); +} + +export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 2 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + return lua.createAssignmentStatement( + lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + node + ), + context.transformExpression(args[2]) + ); +} diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap new file mode 100644 index 000000000..9f6113df6 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -0,0 +1,64 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` +"foo = { + (function() + ({}).foo = 3 + return nil + end)() +}" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): code 1`] = ` +"foo = (function() + ({}).foo = 3 + return nil +end)()" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): code 1`] = `"foo = getTable(_G, 1, 2)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): code 1`] = `"foo = {getTable}"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): code 1`] = `"foo = tostring(getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): code 1`] = `"foo = getTable"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): code 1`] = `"foo(_G, getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): diagnostics 1`] = `"main.ts(3,88): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts new file mode 100644 index 000000000..8d3d0fde1 --- /dev/null +++ b/test/unit/language-extensions/table.spec.ts @@ -0,0 +1,137 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidTableExtensionUse, invalidTableSetExpression } from "../../../src/transformation/utils/diagnostics"; + +const tableProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +describe("LuaTableGet & LuaTableSet extensions", () => { + test("stand-alone function", () => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + declare const setTable: LuaTableSet<{}, string, number>; + const tbl = {}; + setTable(tbl, "foo", 3); + const result = getTable(tbl, "foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test("namespace function", () => { + util.testModule` + declare namespace Table { + export const get: LuaTableGet<{}, string, number>; + export const set: LuaTableSet<{}, string, number>; + } + const tbl = {}; + Table.set(tbl, "foo", 3); + const result = Table.get(tbl, "foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test("method", () => { + util.testModule` + interface Table { + get: LuaTableGetMethod; + set: LuaTableSetMethod; + } + const tbl = {} as Table; + tbl.set("foo", 3); + const result = tbl.get("foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test.each([ + "const foo: unknown = getTable;", + "const foo = `${getTable}`;", + "declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);", + "const foo = (getTable as any)(1, 2);", + "const foo = [getTable];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + ${statement} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); + + test.each([ + 'const foo = setTable({}, "foo", 3);', + 'const foo = `${setTable({}, "foo", 3)}`;', + 'declare function foo(arg: any): void; foo(setTable({}, "foo", 3));', + 'const foo = [setTable({}, "foo", 3)];', + ])("LuaTableSet invalid use as expression (%p)", expression => { + util.testModule` + declare const setTable: LuaTableSet<{}, string, number>; + ${expression} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableSetExpression.code]); + }); +}); + +describe("LuaTable extension interface", () => { + test("untyped table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("typed table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("object keyed table", () => { + util.testFunction` + interface Key { keyStr: string } + const key: Key = {keyStr: "foo"}; + const tbl = new LuaTable(); + tbl.set(key, 3); + return tbl.get(key); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("table length", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(1, "foo"); + tbl.set(3, "bar"); + return tbl.length(); + ` + .setOptions(tableProjectOptions) + .expectToEqual(1); + }); + + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( + "table immediate access (%p)", + statement => { + util.testFunction(statement).setOptions(tableProjectOptions).expectToHaveNoDiagnostics(); + } + ); +}); From 0299d71a0e89184f5628b2e77f617fa165e55494 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Mar 2021 19:14:01 +0100 Subject: [PATCH 43/91] Fixed unexpected lua error from Object.GetOwnPropertyDescriptors returning nil (#994) --- src/lualib/ObjectGetOwnPropertyDescriptors.ts | 2 +- test/unit/builtins/object.spec.ts | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts index 9adc0071e..04aee8b51 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptors.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -1,5 +1,5 @@ function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { const metatable = getmetatable(object); if (!metatable) return {}; - return rawget(metatable, "_descriptors"); + return rawget(metatable, "_descriptors") || {}; } diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index cc7e380d6..c6c89a8a8 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -211,3 +211,27 @@ describe("Object.getOwnPropertyDescriptors", () => { `.expectToMatchJsResult(); }); }); + +describe("delete from object", () => { + test("delete from object", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/993 + test("delete from object with metatable", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + setmetatable(obj, {}); + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); +}); From 22e60190aa46685e9b0d1a2592e6a52bf2eb5a07 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 4 Mar 2021 21:11:30 +0100 Subject: [PATCH 44/91] Use WASM version of Lua instead of fengari for testing (#996) * Use tstl/lua-wasm-bindings instead of fengari * Removed extra comma * Added missing semicolon * Fix an issue with Lua json encoder not detecting actual Lua Ininfity / NaN * Fixed test cases Most of the tests failed due to incorrect iteration order And unexpected JS/Lua differences * Removed fengari from lockfile * Revert NaN change * Removed unused import * Fixed small mistake * Change Lua vm version from 5.4 to 5.3 * Removed error filter comment and TODO --- jest.config.js | 2 +- package-lock.json | 73 ++---- package.json | 2 +- test/tsconfig.json | 3 +- test/types/fengari.d.ts | 347 ----------------------------- test/unit/builtins/array.spec.ts | 11 +- test/unit/builtins/numbers.spec.ts | 13 +- test/unit/builtins/object.spec.ts | 12 +- test/unit/loops.spec.ts | 17 +- test/util.ts | 49 ++-- 10 files changed, 78 insertions(+), 451 deletions(-) delete mode 100644 test/types/fengari.d.ts diff --git a/jest.config.js b/jest.config.js index 09d82545f..2d390c93d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,7 +17,7 @@ module.exports = { preset: "ts-jest", globals: { "ts-jest": { - tsConfig: "/test/tsconfig.json", + tsconfig: "/test/tsconfig.json", diagnostics: { warnOnly: !isCI }, }, }, diff --git a/package-lock.json b/package-lock.json index 4791e9650..59d842844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,12 +27,12 @@ "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", - "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", + "lua-wasm-bindings": "^0.1.4", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -1460,7 +1460,6 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -3568,8 +3567,7 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -4439,17 +4437,6 @@ "bser": "2.1.1" } }, - "node_modules/fengari": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", - "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", - "dev": true, - "dependencies": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" - } - }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -6219,7 +6206,6 @@ "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-serializer": "^26.0.0", "jest-util": "^26.0.1", @@ -8808,6 +8794,12 @@ "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", "dev": true }, + "node_modules/lua-wasm-bindings": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", + "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "dev": true + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -9668,15 +9660,6 @@ "node": ">=4" } }, - "node_modules/readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -10542,12 +10525,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -10564,6 +10541,11 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, "engines": { "node": ">=0.10.0" } @@ -15318,17 +15300,6 @@ "bser": "2.1.1" } }, - "fengari": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", - "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", - "dev": true, - "requires": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" - } - }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -18856,6 +18827,12 @@ "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", "dev": true }, + "lua-wasm-bindings": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", + "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -19528,12 +19505,6 @@ } } }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", - "dev": true - }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -20254,12 +20225,6 @@ "extend-shallow": "^3.0.0" } }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", diff --git a/package.json b/package.json index 078637493..573394f5a 100644 --- a/package.json +++ b/package.json @@ -56,12 +56,12 @@ "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", - "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", + "lua-wasm-bindings": "^0.1.4", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" diff --git a/test/tsconfig.json b/test/tsconfig.json index 2c06244c7..86d7c9359 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "rootDir": "..", "types": ["node", "jest"], - "baseUrl": ".", - "paths": { "*": ["types/*"] } + "baseUrl": "." }, "include": [".", "../src"], "exclude": [ diff --git a/test/types/fengari.d.ts b/test/types/fengari.d.ts deleted file mode 100644 index 8b13b169d..000000000 --- a/test/types/fengari.d.ts +++ /dev/null @@ -1,347 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/class-name-casing */ - -export const FENGARI_AUTHORS: string; -export const FENGARI_COPYRIGHT: string; -export const FENGARI_RELEASE: string; -export const FENGARI_VERSION: string; -export const FENGARI_VERSION_MAJOR: string; -export const FENGARI_VERSION_MINOR: string; -export const FENGARI_VERSION_NUM: number; -export const FENGARI_VERSION_RELEASE: string; -export namespace lauxlib { - const LUA_ERRFILE: number; - const LUA_FILEHANDLE: Uint8Array; - const LUA_LOADED_TABLE: Uint8Array; - const LUA_NOREF: number; - const LUA_PRELOAD_TABLE: Uint8Array; - const LUA_REFNIL: number; - class luaL_Buffer { - L: any; - b: any; - n: any; - } - function luaL_addchar(B: any, c: any): void; - function luaL_addlstring(B: any, s: any, l: any): void; - function luaL_addsize(B: any, s: any): void; - function luaL_addstring(B: any, s: any): void; - function luaL_addvalue(B: any): void; - function luaL_argcheck(L: any, cond: any, arg: any, extramsg: any): void; - function luaL_argerror(L: any, arg: any, extramsg: any): any; - function luaL_buffinit(L: any, B: any): void; - function luaL_buffinitsize(L: any, B: any, sz: any): any; - function luaL_callmeta(L: any, obj: any, event: any): any; - function luaL_checkany(L: any, arg: any): void; - function luaL_checkinteger(L: any, arg: any): any; - function luaL_checklstring(L: any, arg: any): any; - function luaL_checknumber(L: any, arg: any): any; - function luaL_checkoption(L: any, arg: any, def: any, lst: any): any; - function luaL_checkstack(L: any, space: any, msg: any): void; - function luaL_checkstring(L: any, arg: any): any; - function luaL_checktype(L: any, arg: any, t: any): void; - function luaL_checkudata(L: any, ud: any, tname: any): any; - function luaL_checkversion(L: any): void; - function luaL_checkversion_(L: any, ver: any, sz: any): void; - function luaL_dofile(L: any, filename: any): any; - function luaL_dostring(L: any, s: any): any; - function luaL_error(L: any, fmt: any, argp: any): any; - function luaL_execresult(L: any, e: any): any; - function luaL_fileresult(L: any, stat: any, fname: any, e: any): any; - function luaL_getmetafield(L: any, obj: any, event: any): any; - function luaL_getmetatable(L: any, n: any): any; - function luaL_getsubtable(L: any, idx: any, fname: any): any; - function luaL_gsub(L: any, s: any, p: any, r: any): any; - function luaL_len(L: any, idx: any): any; - function luaL_loadbuffer(L: any, s: any, sz: any, n: any): any; - function luaL_loadbufferx(L: any, buff: any, size: any, name: any, mode: any): any; - function luaL_loadfile(L: any, filename: any): any; - function luaL_loadfilex(L: any, filename: any, mode: any): any; - function luaL_loadstring(L: any, s: any): any; - function luaL_newlib(L: any, l: any): void; - function luaL_newlibtable(L: any): void; - function luaL_newmetatable(L: any, tname: any): any; - function luaL_newstate(): any; - function luaL_opt(L: any, f: any, n: any, d: any): any; - function luaL_optinteger(L: any, arg: any, def: any): any; - function luaL_optlstring(L: any, arg: any, def: any): any; - function luaL_optnumber(L: any, arg: any, def: any): any; - function luaL_optstring(L: any, arg: any, def: any): any; - function luaL_prepbuffer(B: any): any; - function luaL_prepbuffsize(B: any, sz: any): any; - function luaL_pushresult(B: any): void; - function luaL_pushresultsize(B: any, sz: any): void; - function luaL_ref(L: any, t: any): any; - function luaL_requiref(L: any, modname: any, openf: any, glb: any): void; - function luaL_setfuncs(L: any, l: any, nup: any): void; - function luaL_setmetatable(L: any, tname: any): void; - function luaL_testudata(L: any, ud: any, tname: any): any; - function luaL_tolstring(L: any, idx: any): any; - function luaL_traceback(L: any, L1: any, msg: any, level: any): void; - function luaL_typename(L: any, i: any): any; - function luaL_unref(L: any, t: any, ref: any): void; - function luaL_where(L: any, level: any): void; - function lua_writestringerror(...args: any[]): void; -} -export namespace lua { - const LUA_AUTHORS: string; - const LUA_COPYRIGHT: string; - const LUA_ERRERR: number; - const LUA_ERRGCMM: number; - const LUA_ERRMEM: number; - const LUA_ERRRUN: number; - const LUA_ERRSYNTAX: number; - const LUA_HOOKCALL: number; - const LUA_HOOKCOUNT: number; - const LUA_HOOKLINE: number; - const LUA_HOOKRET: number; - const LUA_HOOKTAILCALL: number; - const LUA_MASKCALL: number; - const LUA_MASKCOUNT: number; - const LUA_MASKLINE: number; - const LUA_MASKRET: number; - const LUA_MINSTACK: number; - const LUA_MULTRET: number; - const LUA_NUMTAGS: number; - const LUA_OK: number; - const LUA_OPADD: number; - const LUA_OPBAND: number; - const LUA_OPBNOT: number; - const LUA_OPBOR: number; - const LUA_OPBXOR: number; - const LUA_OPDIV: number; - const LUA_OPEQ: number; - const LUA_OPIDIV: number; - const LUA_OPLE: number; - const LUA_OPLT: number; - const LUA_OPMOD: number; - const LUA_OPMUL: number; - const LUA_OPPOW: number; - const LUA_OPSHL: number; - const LUA_OPSHR: number; - const LUA_OPSUB: number; - const LUA_OPUNM: number; - const LUA_REGISTRYINDEX: number; - const LUA_RELEASE: string; - const LUA_RIDX_GLOBALS: number; - const LUA_RIDX_LAST: number; - const LUA_RIDX_MAINTHREAD: number; - const LUA_SIGNATURE: Uint8Array; - const LUA_TBOOLEAN: number; - const LUA_TFUNCTION: number; - const LUA_TLIGHTUSERDATA: number; - const LUA_TNIL: number; - const LUA_TNONE: number; - const LUA_TNUMBER: number; - const LUA_TSTRING: number; - const LUA_TTABLE: number; - const LUA_TTHREAD: number; - const LUA_TUSERDATA: number; - const LUA_VERSION: string; - const LUA_VERSION_MAJOR: string; - const LUA_VERSION_MINOR: string; - const LUA_VERSION_NUM: number; - const LUA_VERSION_RELEASE: string; - const LUA_YIELD: number; - class lua_Debug { - event: any; - name: any; - namewhat: any; - what: any; - source: any; - currentline: any; - linedefined: any; - lastlinedefined: any; - nups: any; - nparams: any; - isvararg: any; - istailcall: any; - short_src: any; - i_ci: any; - } - function lua_absindex(L: any, idx: any): any; - function lua_arith(L: any, op: any): void; - function lua_atnativeerror(L: any, errorf: any): any; - function lua_atpanic(L: any, panicf: any): any; - function lua_call(L: any, n: any, r: any): void; - function lua_callk(L: any, nargs: any, nresults: any, ctx: any, k: any): void; - function lua_checkstack(L: any, n: any): any; - function lua_close(L: any): void; - function lua_compare(L: any, index1: any, index2: any, op: any): any; - function lua_concat(L: any, n: any): void; - function lua_copy(L: any, fromidx: any, toidx: any): void; - function lua_createtable(L: any, narray: any, nrec: any): void; - function lua_dump(L: any, writer: any, data: any, strip: any): any; - function lua_error(L: any): void; - function lua_gc(): void; - function lua_getallocf(): any; - function lua_getextraspace(): any; - function lua_getfield(L: any, idx: any, k: any): any; - function lua_getglobal(L: any, name: any): any; - function lua_gethook(L: any): any; - function lua_gethookcount(L: any): any; - function lua_gethookmask(L: any): any; - function lua_geti(L: any, idx: any, n: any): any; - function lua_getinfo(L: any, what: any, ar: any): any; - function lua_getlocal(L: any, ar: any, n: any): any; - function lua_getmetatable(L: any, objindex: any): any; - function lua_getstack(L: any, level: any, ar: any): any; - function lua_gettable(L: any, idx: any): any; - function lua_gettop(L: any): any; - function lua_getupvalue(L: any, funcindex: any, n: any): any; - function lua_getuservalue(L: any, idx: any): any; - function lua_insert(L: any, idx: any): void; - function lua_isboolean(L: any, n: any): any; - function lua_iscfunction(L: any, idx: any): any; - function lua_isfunction(L: any, idx: any): any; - function lua_isinteger(L: any, idx: any): any; - function lua_islightuserdata(L: any, idx: any): any; - function lua_isnil(L: any, n: any): any; - function lua_isnone(L: any, n: any): any; - function lua_isnoneornil(L: any, n: any): any; - function lua_isnumber(L: any, idx: any): any; - function lua_isproxy(p: any, L: any): any; - function lua_isstring(L: any, idx: any): any; - function lua_istable(L: any, idx: any): any; - function lua_isthread(L: any, idx: any): any; - function lua_isuserdata(L: any, idx: any): any; - function lua_isyieldable(L: any): any; - function lua_len(L: any, idx: any): void; - function lua_load(L: any, reader: any, data: any, chunkname: any, mode: any): any; - function lua_newstate(): any; - function lua_newtable(L: any): void; - function lua_newthread(L: any): any; - function lua_newuserdata(L: any, size: any): any; - function lua_next(L: any, idx: any): any; - function lua_pcall(L: any, n: any, r: any, f: any): any; - function lua_pcallk(L: any, nargs: any, nresults: any, errfunc: any, ctx: any, k: any): any; - function lua_pop(L: any, n: any): void; - function lua_pushboolean(L: any, b: any): void; - function lua_pushcclosure(L: any, fn: any, n: any): void; - function lua_pushcfunction(L: any, fn: any): void; - function lua_pushfstring(L: any, fmt: any, argp: any): any; - function lua_pushglobaltable(L: any): void; - function lua_pushinteger(L: any, n: any): void; - function lua_pushjsclosure(L: any, fn: any, n: any): void; - function lua_pushjsfunction(L: any, fn: any): void; - function lua_pushlightuserdata(L: any, p: any): void; - function lua_pushliteral(L: any, s: any): any; - function lua_pushlstring(L: any, s: any, len: any): any; - function lua_pushnil(L: any): void; - function lua_pushnumber(L: any, n: any): void; - function lua_pushstring(L: any, s: any): any; - function lua_pushthread(L: any): any; - function lua_pushvalue(L: any, idx: any): void; - function lua_pushvfstring(L: any, fmt: any, argp: any): any; - function lua_rawequal(L: any, index1: any, index2: any): any; - function lua_rawget(L: any, idx: any): any; - function lua_rawgeti(L: any, idx: any, n: any): any; - function lua_rawgetp(L: any, idx: any, p: any): any; - function lua_rawlen(L: any, idx: any): any; - function lua_rawset(L: any, idx: any): void; - function lua_rawseti(L: any, idx: any, n: any): void; - function lua_rawsetp(L: any, idx: any, p: any): void; - function lua_register(L: any, n: any, f: any): void; - function lua_remove(L: any, idx: any): void; - function lua_replace(L: any, idx: any): void; - function lua_resume(L: any, from: any, nargs: any): any; - function lua_rotate(L: any, idx: any, n: any): void; - const lua_setallof: any; - function lua_setfield(L: any, idx: any, k: any): void; - function lua_setglobal(L: any, name: any): void; - function lua_sethook(L: any, func: any, mask: any, count: any): void; - function lua_seti(L: any, idx: any, n: any): void; - function lua_setlocal(L: any, ar: any, n: any): any; - function lua_setmetatable(L: any, objindex: any): any; - function lua_settable(L: any, idx: any): void; - function lua_settop(L: any, idx: any): void; - function lua_setupvalue(L: any, funcindex: any, n: any): any; - function lua_setuservalue(L: any, idx: any): void; - function lua_status(L: any): any; - function lua_stringtonumber(L: any, s: any): any; - function lua_toboolean(L: any, idx: any): any; - function lua_tocfunction(L: any, idx: any): any; - function lua_todataview(L: any, idx: any): any; - function lua_tointeger(L: any, idx: any): any; - function lua_tointegerx(L: any, idx: any): any; - function lua_tojsstring(L: any, idx: any): any; - function lua_tolstring(L: any, idx: any): any; - function lua_tonumber(L: any, idx: any): any; - function lua_tonumberx(L: any, idx: any): any; - function lua_topointer(L: any, idx: any): any; - function lua_toproxy(L: any, idx: any): any; - function lua_tostring(L: any, idx: any): LuaString; - function lua_tothread(L: any, idx: any): any; - function lua_touserdata(L: any, idx: any): any; - function lua_type(L: any, idx: any): any; - function lua_typename(L: any, t: any): any; - function lua_upvalueid(L: any, fidx: any, n: any): any; - function lua_upvalueindex(i: any): any; - function lua_upvaluejoin(L: any, fidx1: any, n1: any, fidx2: any, n2: any): void; - function lua_version(L: any): any; - function lua_xmove(from: any, to: any, n: any): void; - function lua_yield(L: any, n: any): void; - function lua_yieldk(L: any, nresults: any, ctx: any, k: any): any; -} -export namespace luaconf { - const LUAI_MAXSTACK: number; - const LUAL_BUFFERSIZE: number; - const LUA_COMPAT_FLOATSTRING: boolean; - const LUA_DIRSEP: string; - const LUA_EXEC_DIR: string; - const LUA_IDSIZE: number; - const LUA_INTEGER_FMT: string; - const LUA_INTEGER_FRMLEN: string; - const LUA_JSDIR: string; - const LUA_JSPATH_DEFAULT: Uint8Array; - const LUA_LDIR: string; - const LUA_MAXINTEGER: number; - const LUA_MININTEGER: number; - const LUA_NUMBER_FMT: string; - const LUA_NUMBER_FRMLEN: string; - const LUA_PATH_DEFAULT: Uint8Array; - const LUA_PATH_MARK: string; - const LUA_PATH_SEP: string; - const LUA_SHRDIR: string; - const LUA_VDIR: string; - function frexp(value: any): any; - function ldexp(mantissa: any, exponent: any): any; - function lua_getlocaledecpoint(): any; - function lua_integer2str(n: any): any; - function lua_number2str(n: any): any; - function lua_numbertointeger(n: any): any; - function luai_apicheck(l: any, e: any): void; -} -export namespace lualib { - const LUA_BITLIBNAME: string; - const LUA_COLIBNAME: string; - const LUA_DBLIBNAME: string; - const LUA_FENGARILIBNAME: string; - const LUA_IOLIBNAME: string; - const LUA_LOADLIBNAME: string; - const LUA_MATHLIBNAME: string; - const LUA_OSLIBNAME: string; - const LUA_STRLIBNAME: string; - const LUA_TABLIBNAME: string; - const LUA_UTF8LIBNAME: string; - const LUA_VERSUFFIX: string; - function luaL_openlibs(L: any): void; - function lua_assert(c: any): void; - function luaopen_coroutine(L: any): any; - function luaopen_debug(L: any): any; - function luaopen_fengari(L: any): any; - function luaopen_io(L: any): any; - function luaopen_math(L: any): any; - function luaopen_os(L: any): any; - function luaopen_package(L: any): any; - function luaopen_string(L: any): any; - function luaopen_table(L: any): any; - function luaopen_utf8(L: any): any; -} - -export type LuaString = number[]; - -export function luastring_eq(a: any, b: any): any; -export function luastring_indexOf(s: any, v: any, i: any): any; -export function luastring_of(): any; -export function to_jsstring(value: LuaString, from?: any, to?: any, replacement_char?: any): string; -export function to_luastring(str: string, cache?: any): LuaString; -export function to_uristring(a: any): any; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 584f686bb..770387aea 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -160,12 +160,21 @@ describe("array.length", () => { util.testExpression`[1, 2, 3].length = ${length}`.expectToEqual(length); }); - test.each([-1, -7, 0.1, NaN, Infinity, -Infinity])("throws on invalid values (%p)", length => { + test.each([-1, -7, 0.1])("throws on invalid values (%p)", length => { util.testFunction` [1, 2, 3].length = ${length}; `.expectToEqual(new util.ExecutionError(`invalid array length: ${length}`)); }); + test.each([NaN, Infinity, -Infinity])("throws on invalid special values (%p)", length => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaSpecialValueString = util.testExpression`(${length}).toString()`.getLuaExecutionResult(); + util.testFunction` + [1, 2, 3].length = ${length}; + `.expectToEqual(new util.ExecutionError(`invalid array length: ${luaSpecialValueString}`)); + }); + test("in array destructuring", () => { util.testFunction` const array = [0, 1, 2]; diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 0ae65efb3..f58209c31 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -56,8 +56,17 @@ test.each(toStringPairs)("(%p).toString(%p)", (value, radix) => { util.testExpressionTemplate`(${value}).toString(${radix})`.expectToMatchJsResult(); }); -test.each([NaN, Infinity, -Infinity])("%p.toString(2)", value => { - util.testExpressionTemplate`(${value}).toString(2)`.expectToMatchJsResult(); +test.each([ + [NaN, "(0/0)"], + [Infinity, "(1/0)"], + [-Infinity, "(-(1/0))"], +])("%p.toString(2)", (value, luaNativeSpecialNum) => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaNativeSpecialNumString = util.testExpression`${luaNativeSpecialNum}.toString()`.getLuaExecutionResult(); + // Cannot use expectToMatchJsResult because this actually wont be the same in JS in Lua + // TODO fix this in lualib/NumberToString.ts + util.testExpressionTemplate`(${value}).toString(2)`.expectToEqual(luaNativeSpecialNumString); }); test.each(cases)("isNaN(%p)", value => { diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index c6c89a8a8..fb0fe26ba 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -11,15 +11,21 @@ test.each([ }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { - util.testExpressionTemplate`Object.entries(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.entries(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.keys (%p)", obj => { - util.testExpressionTemplate`Object.keys(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.keys(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: "def" }, { abc: 3, def: "xyz" }])("Object.values (%p)", obj => { - util.testExpressionTemplate`Object.values(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.values(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each(["[]", '[["a", 1], ["b", 2]]', '[["a", 1], ["a", 2]]', 'new Map([["foo", "bar"]])'])( diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index c644776e5..8e9c22373 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -573,7 +573,7 @@ test("do...while double-negation", () => { }); test("for...in with pre-defined variable", () => { - util.testFunction` + const testBuilder = util.testFunction` const obj = { x: "y", foo: "bar" }; let x = ""; @@ -582,16 +582,23 @@ test("for...in with pre-defined variable", () => { result.push(x); } return result; - `.expectToMatchJsResult(); + `; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test("for...in with pre-defined variable keeps last value", () => { - util.testFunction` - const obj = { x: "y", foo: "bar" }; + const keyX = "x"; + const keyFoo = "foo"; + + const result = util.testFunction` + const obj = { ${keyX}: "y", ${keyFoo}: "bar" }; let x = ""; for (x in obj) { } return x; - `.expectToMatchJsResult(); + `.getLuaExecutionResult(); + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect([keyX, keyFoo]).toContain(result); }); diff --git a/test/util.ts b/test/util.ts index 67cfcef57..a93b54995 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,7 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; +import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.53"; +import { LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -10,32 +11,8 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -export function toByteCode(luaCode: string) { - const L = lauxlib.luaL_newstate(); - - if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); - - const writer = (_: any, newBytes: Uint8Array, size: number, data: number[]) => { - data.push(...newBytes.slice(0, size)); - return 0; - }; - - const data: number[] = []; - - const dumpExitCode = lua.lua_dump(L, writer, data, false); - - if (dumpExitCode !== 0) { - throw Error("Unable to dump byte code"); - } - - return Uint8Array.from(data); -} - const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const jsonLibByteCode = toByteCode(jsonLib); - const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const luaLibByteCode = toByteCode(luaLib); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -369,7 +346,7 @@ export abstract class TestBuilder { // Json lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, jsonLibByteCode); + lauxlib.luaL_loadstring(L, jsonLib); lua.lua_setfield(L, -2, "json"); // Lua lib if ( @@ -378,7 +355,7 @@ export abstract class TestBuilder { ) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, luaLibByteCode); + lauxlib.luaL_loadstring(L, luaLib); lua.lua_setfield(L, -2, "lualib_bundle"); } @@ -392,7 +369,7 @@ export abstract class TestBuilder { if (transpiledExtraFile?.lua) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(transpiledExtraFile.lua)); + lauxlib.luaL_loadstring(L, transpiledExtraFile.lua); lua.lua_setfield(L, -2, fileName.replace(".ts", "")); } }); @@ -404,20 +381,22 @@ return JSON.stringify((function() ${this.getLuaCodeWithWrapper(mainFile)} end)());`; - const status = lauxlib.luaL_dostring(L, to_luastring(wrappedMainCode)); + const status = lauxlib.luaL_dostring(L, wrappedMainCode); - if (status === lua.LUA_OK) { + if (status === LUA_OK) { if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + const result = eval(`(${lua.lua_tostring(L, -1)})`); + lua.lua_close(L); return result === null ? undefined : result; } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + const returnType = lua.lua_typename(L, lua.lua_type(L, -1)); + lua.lua_close(L); throw new Error(`Unsupported Lua return type: ${returnType}`); } } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + const luaStackString = lua.lua_tostring(L, -1); + const message = luaStackString.replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + lua.lua_close(L); return new ExecutionError(message); } } From f6a92c09275696eedc61e43463ac62a98b01da3a Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Fri, 5 Mar 2021 18:45:15 +0100 Subject: [PATCH 45/91] Remove phantom, metaExtension, extension, pureAbstract (#998) And replace the deprecation warning with an error Progress on #953 --- src/transformation/utils/diagnostics.ts | 30 +-- .../visitors/binary-expression/index.ts | 6 +- src/transformation/visitors/class/index.ts | 208 +++++------------- .../visitors/class/members/fields.ts | 5 +- .../visitors/class/members/method.ts | 15 +- src/transformation/visitors/class/new.ts | 6 +- src/transformation/visitors/class/utils.ts | 9 +- src/transformation/visitors/modules/import.ts | 10 +- src/transformation/visitors/namespace.ts | 7 +- .../__snapshots__/transformation.spec.ts.snap | 37 ---- .../transformation/classExtension1.ts | 4 - .../transformation/classExtension2.ts | 7 - .../transformation/classExtension3.ts | 9 - .../transformation/classExtension4.ts | 6 - .../transformation/classPureAbstract.ts | 3 - .../transformation/namespacePhantom.ts | 4 - .../__snapshots__/deprecated.spec.ts.snap | 34 ++- .../__snapshots__/extension.spec.ts.snap | 68 ------ .../__snapshots__/metaExtension.spec.ts.snap | 23 -- test/unit/annotations/deprecated.spec.ts | 14 +- test/unit/annotations/extension.spec.ts | 35 --- test/unit/annotations/metaExtension.spec.ts | 50 ----- 22 files changed, 113 insertions(+), 477 deletions(-) delete mode 100644 test/translation/transformation/classExtension1.ts delete mode 100644 test/translation/transformation/classExtension2.ts delete mode 100644 test/translation/transformation/classExtension3.ts delete mode 100644 test/translation/transformation/classExtension4.ts delete mode 100644 test/translation/transformation/classPureAbstract.ts delete mode 100644 test/translation/transformation/namespacePhantom.ts delete mode 100644 test/unit/annotations/__snapshots__/extension.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap delete mode 100644 test/unit/annotations/extension.spec.ts delete mode 100644 test/unit/annotations/metaExtension.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 9b34e9547..4086ee0f2 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -58,30 +58,6 @@ export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const extensionCannotConstruct = createErrorDiagnosticFactory( - "Cannot construct classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionCannotExtend = createErrorDiagnosticFactory( - "Cannot extend classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionCannotExport = createErrorDiagnosticFactory( - "Cannot export classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionInvalidInstanceOf = createErrorDiagnosticFactory( - "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionAndMetaExtensionConflict = createErrorDiagnosticFactory( - "Cannot use both '@extension' and '@metaExtension' annotations on the same class." -); - -export const metaExtensionMissingExtends = createErrorDiagnosticFactory( - "'@metaExtension' annotation requires the extension of the metatable class." -); - export const invalidForRangeCall = createErrorDiagnosticFactory( (message: string) => `Invalid @forRange call: ${message}.` ); @@ -182,6 +158,12 @@ export const invalidTableSetExpression = createErrorDiagnosticFactory( "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); +export const 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. ` + diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 001591c01..d9e4746e0 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; +import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -109,10 +109,6 @@ export const transformBinaryExpression: FunctionVisitor = ( const rhsType = context.checker.getTypeAtLocation(node.right); const annotations = getTypeAnnotations(rhsType); - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionInvalidInstanceOf(node)); - } - if (annotations.has(AnnotationKind.LuaTable)) { context.diagnostics.push(luaTableInvalidInstanceOf(node)); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index d9da80cf7..8b40eadcd 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -3,19 +3,10 @@ import * as lua from "../../../LuaAST"; import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { - annotationDeprecated, - extensionAndMetaExtensionConflict, - extensionCannotExport, - extensionCannotExtend, - luaTableCannotBeExtended, - luaTableMustBeAmbient, - metaExtensionMissingExtends, -} from "../../utils/diagnostics"; +import { annotationRemoved, luaTableCannotBeExtended, luaTableMustBeAmbient } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, - getIdentifierExportScope, hasDefaultExportModifier, isSymbolExported, } from "../../utils/export"; @@ -28,7 +19,6 @@ import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { popScope, pushScope, ScopeType } from "../../utils/scope"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; -import { transformPropertyName } from "../literal"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; @@ -90,25 +80,11 @@ function transformClassLikeDeclaration( const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); - // Find out if this class is extension of existing class - const extensionDirective = annotations.get(AnnotationKind.Extension); - const isExtension = extensionDirective !== undefined; - const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); - - if (isExtension) { - context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.Extension)); + if (annotations.has(AnnotationKind.Extension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.Extension)); } - if (isMetaExtension) { - context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.MetaExtension)); - } - - if (isExtension && isMetaExtension) { - context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); - } - - if ((isExtension || isMetaExtension) && getIdentifierExportScope(context, className) !== undefined) { - // Cannot export extension classes - context.diagnostics.push(extensionCannotExport(classDeclaration)); + if (annotations.has(AnnotationKind.MetaExtension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.MetaExtension)); } // Get type that is extended @@ -122,14 +98,6 @@ function transformClassLikeDeclaration( checkForLuaLibType(context, extendedType); } - if (!(isExtension || isMetaExtension) && extendedType) { - // Non-extensions cannot extend extension classes - const extendsAnnotations = getTypeAnnotations(extendedType); - if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotExtend(classDeclaration)); - } - } - // You cannot extend LuaTable classes if (extendedType) { const annotations = getTypeAnnotations(extendedType); @@ -150,43 +118,6 @@ function transformClassLikeDeclaration( const result: lua.Statement[] = []; - // Overwrite the original className with the class we are overriding for extensions - if (isMetaExtension) { - if (extendedType) { - const extendsName = lua.createStringLiteral(extendedType.symbol.name); - className = lua.createIdentifier("__meta__" + extendsName.value); - - // local className = debug.getregistry()["extendsName"] - const assignDebugCallIndex = lua.createVariableDeclarationStatement( - className, - lua.createTableIndexExpression( - lua.createCallExpression( - lua.createTableIndexExpression( - lua.createIdentifier("debug"), - lua.createStringLiteral("getregistry") - ), - [] - ), - extendsName - ), - classDeclaration - ); - - result.push(assignDebugCallIndex); - } else { - context.diagnostics.push(metaExtensionMissingExtends(classDeclaration)); - } - } - - if (extensionDirective !== undefined) { - const [extensionName] = extensionDirective.args; - if (extensionName) { - className = lua.createIdentifier(extensionName); - } else if (extendedType) { - className = lua.createIdentifier(extendedType.symbol.name); - } - } - let localClassName: lua.Identifier; if (isUnsafeName(className.text)) { localClassName = lua.createIdentifier( @@ -200,82 +131,60 @@ function transformClassLikeDeclaration( localClassName = className; } - if (!isExtension && !isMetaExtension) { - result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - } else { - for (const f of instanceFields) { - const fieldName = transformPropertyName(context, f.name); - - const value = f.initializer !== undefined ? context.transformExpression(f.initializer) : undefined; + result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - // className["fieldName"] - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); - - // className["fieldName"] = value; - const assignClassField = lua.createAssignmentStatement(classField, value); + // Find first constructor with body + const constructor = classDeclaration.members.find( + (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + ); - result.push(assignClassField); - } - } + if (constructor) { + // Add constructor plus initialization of instance fields + const constructorResult = transformConstructorDeclaration( + context, + constructor, + localClassName, + instanceFields, + classDeclaration + ); - // Find first constructor with body - if (!isExtension && !isMetaExtension) { - const constructor = classDeclaration.members.find( - (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + if (constructorResult) result.push(constructorResult); + } else if (!extendedType) { + // Generate a constructor if none was defined in a base class + const constructorResult = transformConstructorDeclaration( + context, + ts.createConstructor([], [], [], ts.createBlock([], true)), + localClassName, + instanceFields, + classDeclaration ); - if (constructor) { - // Add constructor plus initialization of instance fields - const constructorResult = transformConstructorDeclaration( - context, - constructor, - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if (!extendedType) { - // Generate a constructor if none was defined in a base class - const constructorResult = transformConstructorDeclaration( - context, - ts.createConstructor([], [], [], ts.createBlock([], true)), - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if (instanceFields.length > 0) { - // Generate a constructor if none was defined in a class with instance fields that need initialization - // localClassName.prototype.____constructor = function(self, ...) - // baseClassName.prototype.____constructor(self, ...) - // ... - const constructorBody = transformClassInstanceFields(context, instanceFields); - const superCall = lua.createExpressionStatement( - lua.createCallExpression( - lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), - lua.createStringLiteral("____constructor") - ), - [createSelfIdentifier(), lua.createDotsLiteral()] - ) - ); - constructorBody.unshift(superCall); - const constructorFunction = lua.createFunctionExpression( - lua.createBlock(constructorBody), - [createSelfIdentifier()], - lua.createDotsLiteral(), - lua.FunctionExpressionFlags.Declaration - ); - result.push( - lua.createAssignmentStatement( - createConstructorName(localClassName), - constructorFunction, - classDeclaration - ) - ); - } + if (constructorResult) result.push(constructorResult); + } else if (instanceFields.length > 0) { + // Generate a constructor if none was defined in a class with instance fields that need initialization + // localClassName.prototype.____constructor = function(self, ...) + // baseClassName.prototype.____constructor(self, ...) + // ... + const constructorBody = transformClassInstanceFields(context, instanceFields); + const superCall = lua.createExpressionStatement( + lua.createCallExpression( + lua.createTableIndexExpression( + context.transformExpression(ts.createSuper()), + lua.createStringLiteral("____constructor") + ), + [createSelfIdentifier(), lua.createDotsLiteral()] + ) + ); + constructorBody.unshift(superCall); + const constructorFunction = lua.createFunctionExpression( + lua.createBlock(constructorBody), + [createSelfIdentifier()], + lua.createDotsLiteral(), + lua.FunctionExpressionFlags.Declaration + ); + result.push( + lua.createAssignmentStatement(createConstructorName(localClassName), constructorFunction, classDeclaration) + ); } // Transform accessors @@ -290,18 +199,17 @@ function transformClassLikeDeclaration( } } - const noPrototype = isExtension || isMetaExtension; const decorationStatements: lua.Statement[] = []; for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { - const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + const expression = createPropertyDecoratingExpression(context, member, localClassName); if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } else if (ts.isMethodDeclaration(member)) { - const statement = transformMethodDeclaration(context, member, localClassName, noPrototype); + const statement = transformMethodDeclaration(context, member, localClassName); if (statement) result.push(statement); if (member.body) { - const statement = createMethodDecoratingExpression(context, member, localClassName, noPrototype); + const statement = createMethodDecoratingExpression(context, member, localClassName); if (statement) decorationStatements.push(statement); } } else if (ts.isPropertyDeclaration(member)) { @@ -309,7 +217,7 @@ function transformClassLikeDeclaration( const statement = transformStaticPropertyDeclaration(context, member, localClassName); if (statement) decorationStatements.push(statement); } - const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + const expression = createPropertyDecoratingExpression(context, member, localClassName); if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } } diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 5d07033dd..980c6f851 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -9,12 +9,11 @@ import { transformMemberExpressionOwnerName } from "./method"; export function createPropertyDecoratingExpression( context: TransformationContext, node: ts.PropertyDeclaration | ts.AccessorDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Expression | undefined { if (!node.decorators) return; const propertyName = transformPropertyName(context, node.name); - const propertyOwnerTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const propertyOwnerTable = transformMemberExpressionOwnerName(node, className); return createDecoratingExpression( context, node.kind, diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 24cd77f44..c902ea8de 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -11,10 +11,9 @@ import { isNonNull } from "../../../../utils"; export function transformMemberExpressionOwnerName( node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Expression { - return isStaticNode(node) || noPrototype ? lua.cloneIdentifier(className) : createPrototypeName(className); + return isStaticNode(node) ? lua.cloneIdentifier(className) : createPrototypeName(className); } export function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression { @@ -28,13 +27,12 @@ export function transformMethodName(context: TransformationContext, node: ts.Met export function transformMethodDeclaration( context: TransformationContext, node: ts.MethodDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Statement | undefined { // Don't transform methods without body (overload declarations) if (!node.body) return; - const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); @@ -48,10 +46,9 @@ export function transformMethodDeclaration( export function createMethodDecoratingExpression( context: TransformationContext, node: ts.MethodDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Statement | undefined { - const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); const parameterDecorators = node.parameters diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index bf3935b7d..1a9c5e8aa 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; @@ -70,10 +70,6 @@ export const transformNewExpression: FunctionVisitor = (node, const annotations = getTypeAnnotations(type); - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotConstruct(node)); - } - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 88388adf8..aea06680a 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationDeprecated } from "../../utils/diagnostics"; +import { annotationRemoved } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -20,13 +20,12 @@ export function getExtendedNode( const superType = context.checker.getTypeAtLocation(extendsClause.types[0]); const annotations = getTypeAnnotations(superType); - if (!annotations.has(AnnotationKind.PureAbstract)) { - return extendsClause.types[0]; - } if (annotations.has(AnnotationKind.PureAbstract)) { - context.diagnostics.push(annotationDeprecated(extendsClause, AnnotationKind.PureAbstract)); + context.diagnostics.push(annotationRemoved(extendsClause, AnnotationKind.PureAbstract)); } + + return extendsClause.types[0]; } export function getExtendedType( diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 34fa216d6..d36bb0509 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -3,7 +3,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getSymbolAnnotations, getTypeAnnotations } from "../../utils/annotations"; +import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; import { createSafeName } from "../../utils/safe-names"; @@ -60,13 +60,7 @@ export function createModuleRequire( } function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(importNode)); - - return ( - context.resolver.isReferencedAliasDeclaration(importNode) && - !annotations.has(AnnotationKind.Extension) && - !annotations.has(AnnotationKind.MetaExtension) - ); + return context.resolver.isReferencedAliasDeclaration(importNode); } function transformImportSpecifier( diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 3316ace4b..0244ac21c 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationDeprecated } from "../utils/diagnostics"; +import { annotationRemoved } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, @@ -53,9 +53,8 @@ const currentNamespaces = new WeakMap = (node, context) => { const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body - if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Phantom)); - return context.transformStatements(node.body.statements); + if (annotations.has(AnnotationKind.Phantom)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Phantom)); } const currentNamespace = currentNamespaces.get(context); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index a299f2640..7fd968b00 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -24,38 +24,6 @@ escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \ nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. ((\\"Level 1: \\\\n\\\\t\\\\t \\" .. ((\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\"" `; -exports[`Transformation (classExtension1) 1`] = ` -"function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension2) 1`] = ` -"function TestClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension3) 1`] = ` -"function RenamedTestClass.myFunction(self) -end -function RenamedMyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension4) 1`] = ` -"MyClass.test = \\"test\\" -MyClass.testP = \\"testP\\" -function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classPureAbstract) 1`] = ` -"require(\\"lualib_bundle\\"); -ClassB = __TS__Class() -ClassB.name = \\"ClassB\\" -function ClassB.prototype.____constructor(self) -end" -`; - exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 @@ -262,11 +230,6 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; -exports[`Transformation (namespacePhantom) 1`] = ` -"function nsMember(self) -end" -`; - exports[`Transformation (returnDefault) 1`] = ` "function myFunc(self) return diff --git a/test/translation/transformation/classExtension1.ts b/test/translation/transformation/classExtension1.ts deleted file mode 100644 index 5df5bdeac..000000000 --- a/test/translation/transformation/classExtension1.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @extension */ -class MyClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension2.ts b/test/translation/transformation/classExtension2.ts deleted file mode 100644 index 11145e9d5..000000000 --- a/test/translation/transformation/classExtension2.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** @extension */ -class TestClass {} - -/** @extension */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension3.ts b/test/translation/transformation/classExtension3.ts deleted file mode 100644 index 3fa37f05e..000000000 --- a/test/translation/transformation/classExtension3.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** @extension RenamedTestClass */ -class TestClass { - public myFunction() {} -} - -/** @extension RenamedMyClass */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension4.ts b/test/translation/transformation/classExtension4.ts deleted file mode 100644 index 8cb996079..000000000 --- a/test/translation/transformation/classExtension4.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @extension */ -class MyClass { - public test: string = "test"; - private testP: string = "testP"; - public myFunction() {} -} diff --git a/test/translation/transformation/classPureAbstract.ts b/test/translation/transformation/classPureAbstract.ts deleted file mode 100644 index d9a661160..000000000 --- a/test/translation/transformation/classPureAbstract.ts +++ /dev/null @@ -1,3 +0,0 @@ -/** @pureAbstract */ -declare class ClassA {} -class ClassB extends ClassA {} diff --git a/test/translation/transformation/namespacePhantom.ts b/test/translation/transformation/namespacePhantom.ts deleted file mode 100644 index 2f003c28e..000000000 --- a/test/translation/transformation/namespacePhantom.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @phantom */ -namespace myNamespace { - function nsMember() {} -} diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 5be0a22b4..3b1d5e2af 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -1,12 +1,22 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`extension deprecation: code 1`] = `""`; +exports[`extension removed: code 1`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; -exports[`extension deprecation: code 2`] = `"local __meta__A = debug.getregistry().A"`; +exports[`extension removed: code 2`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; -exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; +exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@extension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; -exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; +exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; exports[`forRange deprecation: code 1`] = ` "for i = 1, 10 do @@ -15,19 +25,21 @@ end" exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; -exports[`phantom deprecation: code 1`] = ` -"function nsMember(self) +exports[`phantom removed: code 1`] = ` +"A = A or ({}) +do + local function nsMember(self) + end end" `; -exports[`phantom deprecation: diagnostics 1`] = `"main.ts(3,9): warning TSTL: '@phantom' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; +exports[`phantom removed: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@phantom' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; -exports[`pureAbstract deprecation: code 1`] = ` +exports[`pureAbstract removed: code 1`] = ` "require(\\"lualib_bundle\\"); ClassB = __TS__Class() ClassB.name = \\"ClassB\\" -function ClassB.prototype.____constructor(self) -end" +__TS__ClassExtends(ClassB, ClassA)" `; -exports[`pureAbstract deprecation: diagnostics 1`] = `"main.ts(4,22): warning TSTL: '@pureAbstract' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; +exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap deleted file mode 100644 index 606d21635..000000000 --- a/test/unit/annotations/__snapshots__/extension.spec.ts.snap +++ /dev/null @@ -1,68 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Class construct extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -b = __TS__New(B)" -`; - -exports[`Class construct extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class construct extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -b = __TS__New(B)" -`; - -exports[`Class construct extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class extends extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class extends extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`instanceof extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`instanceof extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap deleted file mode 100644 index ad3f2ac51..000000000 --- a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DontAllowInstantiation: code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta___LOADED = debug.getregistry()._LOADED -e = __TS__New(Ext)" -`; - -exports[`DontAllowInstantiation: diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`IncorrectUsage: code 1`] = ` -"function LoadedExt.test(self) - return 5 -end" -`; - -exports[`IncorrectUsage: diagnostics 1`] = ` -"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class. -main.ts(3,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information." -`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 4fe836014..072ff6372 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -1,29 +1,29 @@ -import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; +import { annotationDeprecated, annotationRemoved } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; -test.each(["extension", "metaExtension"])("extension deprecation", extensionType => { +test.each(["extension", "metaExtension"])("extension removed", extensionType => { util.testModule` declare class A {} /** @${extensionType} **/ class B extends A {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("phantom deprecation", () => { +test("phantom removed", () => { util.testModule` /** @phantom **/ namespace A { function nsMember() {} } - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("pureAbstract deprecation", () => { +test("pureAbstract removed", () => { util.testModule` /** @pureAbstract */ declare class ClassA {} class ClassB extends ClassA {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); test("forRange deprecation", () => { diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts deleted file mode 100644 index 27093801b..000000000 --- a/test/unit/annotations/extension.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - annotationDeprecated, - extensionCannotConstruct, - extensionCannotExtend, - extensionInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - class C extends B {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotExtend.code]); -}); - -test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - const b = new B(); - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); -}); - -test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - declare const foo: any; - const result = foo instanceof B; - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionInvalidInstanceOf.code]); -}); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts deleted file mode 100644 index b0fa56578..000000000 --- a/test/unit/annotations/metaExtension.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - annotationDeprecated, - extensionCannotConstruct, - metaExtensionMissingExtends, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test("MetaExtension", () => { - const tsHeader = ` - declare class _LOADED {} - declare namespace debug { - function getregistry(): any; - } - /** @metaExtension */ - class LoadedExt extends _LOADED { - public static test() { - return 5; - } - } - `; - - // Can't use expectToMatchJsResult because above is not valid TS/JS - util.testModule` - export default debug.getregistry()["_LOADED"].test(); - ` - .setTsHeader(tsHeader) - .ignoreDiagnostics([annotationDeprecated.code]) - .setReturnExport("default") - .expectToEqual(5); -}); - -test("IncorrectUsage", () => { - util.testModule` - /** @metaExtension */ - class LoadedExt { - public static test() { - return 5; - } - } - `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code, annotationDeprecated.code]); -}); - -test("DontAllowInstantiation", () => { - util.testModule` - declare class _LOADED {} - /** @metaExtension */ - class Ext extends _LOADED {} - const e = new Ext(); - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); -}); From 5dffb6b8e4e84c37327fc7be4b4e482bc161c8b2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 5 Mar 2021 22:22:25 +0100 Subject: [PATCH 46/91] Official support for Lua 5.4 --- src/CompilerOptions.ts | 1 + test/cli/parse.spec.ts | 1 + .../__snapshots__/expressions.spec.ts.snap | 100 ++++++++++++++++++ test/unit/builtins/math.spec.ts | 1 + test/unit/expressions.spec.ts | 14 +++ .../language-extensions/operators.spec.ts | 2 +- test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 6 +- test/util.ts | 4 +- 9 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 889a5837a..439b29652 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -49,6 +49,7 @@ export enum LuaTarget { Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", + Lua54 = "5.4", LuaJIT = "JIT", } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 6b6349f9b..cb441ca2f 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -221,6 +221,7 @@ describe("tsconfig", () => { ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], + ["luaTarget", "5.4", { luaTarget: tstl.LuaTarget.Lua54 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], ["luaBundle", "foo", { luaBundle: "foo" }], diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index b743ed0c8..03bb46230 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -335,6 +335,87 @@ ____exports.__result = a | b return ____exports" `; +exports[`Bitop [5.4] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = ~a +return ____exports" +`; + +exports[`Bitop [5.4] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a & b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = a & b +return ____exports" +`; + +exports[`Bitop [5.4] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a << b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a<>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Bitop [5.4] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a ~ b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = a ~ b +return ____exports" +`; + +exports[`Bitop [5.4] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a | b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = a | b +return ____exports" +`; + exports[`Bitop [JIT] ("~a") 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) @@ -553,3 +634,22 @@ return ____exports" `; exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index faaeacbcd..8267cd0b3 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -34,6 +34,7 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); test("Math.atan2(4, 5)", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index fd6c8ab0d..9a874577f 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -77,6 +77,13 @@ test.each(supportedInAll)("Bitop [5.3] (%p)", input => { .expectLuaToMatchSnapshot(); }); +test.each(supportedInAll)("Bitop [5.4] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) @@ -84,6 +91,13 @@ test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); +test.each(unsupportedIn53)("Unsupported bitop 5.4 (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); +}); + test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( "Binary expressions ordering parentheses (%p)", input => { diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index 4559ff7e6..c84f8aac9 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -6,7 +6,7 @@ import { LuaTarget } from "../../../src"; import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; const operatorsProjectOptions: tstl.CompilerOptions = { - luaTarget: LuaTarget.Lua53, + luaTarget: LuaTarget.Lua54, types: [path.resolve(__dirname, "../../../language-extensions")], }; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 8e9c22373..987f53628 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -534,6 +534,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, + [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, }); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 3384b60fb..831b68842 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -77,7 +77,8 @@ describe("in function call", () => { [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); }); @@ -88,7 +89,8 @@ describe("in array literal", () => { [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); test("of array literal /w OmittedExpression", () => { diff --git a/test/util.ts b/test/util.ts index a93b54995..616d6cde9 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.53"; +import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.54"; import { LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; @@ -109,7 +109,7 @@ export abstract class TestBuilder { } private options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua53, + luaTarget: tstl.LuaTarget.Lua54, noHeader: true, skipLibCheck: true, target: ts.ScriptTarget.ES2017, From 079f215c1aa95cb2550a6101de94f0385210cfbb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 5 Mar 2021 22:36:37 +0100 Subject: [PATCH 47/91] Renamed unsupportedIn53 variable --- test/unit/expressions.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 9a874577f..71c014fda 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -46,8 +46,8 @@ test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions }); const supportedInAll = ["~a", "a&b", "a&=b", "a|b", "a|=b", "a^b", "a^=b", "a<>>b", "a>>>=b"]; -const unsupportedIn53 = ["a>>b", "a>>=b"]; -const allBinaryOperators = [...supportedInAll, ...unsupportedIn53]; +const unsupportedIn53And54 = ["a>>b", "a>>=b"]; +const allBinaryOperators = [...supportedInAll, ...unsupportedIn53And54]; test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception util.testExpression(input) @@ -84,14 +84,14 @@ test.each(supportedInAll)("Bitop [5.4] (%p)", input => { .expectLuaToMatchSnapshot(); }); -test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { +test.each(unsupportedIn53And54)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); -test.each(unsupportedIn53)("Unsupported bitop 5.4 (%p)", input => { +test.each(unsupportedIn53And54)("Unsupported bitop 5.4 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() From b84686ffc7c5b00bbc517041f094b4b4b569eea4 Mon Sep 17 00:00:00 2001 From: Yan Soares Couto Date: Sat, 6 Mar 2021 17:19:48 +0000 Subject: [PATCH 48/91] Fix destructuring assignment of multiReturn (closes #995) (#997) * Fix destructuring assignment of multiReturn (closes #995) Added a test. * Rename test and add test for null return * Splitting tests --- .../visitors/variable-declaration.ts | 10 ++++--- .../__snapshots__/multi.spec.ts.snap | 4 ++- test/unit/language-extensions/multi.spec.ts | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 12f6717c4..d9f1624c1 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -6,7 +6,7 @@ import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; +import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; @@ -158,9 +158,11 @@ export function transformBindingVariableDeclaration( // Contain the expression in a temporary variable table = lua.createAnonymousIdentifier(); if (initializer) { - statements.push( - lua.createVariableDeclarationStatement(table, context.transformExpression(initializer)) - ); + let expression = context.transformExpression(initializer); + if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + expression = wrapInTable(expression); + } + statements.push(lua.createVariableDeclarationStatement(table, expression)); } } statements.push(...transformBindingPattern(context, bindingPattern, table)); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index a280fe331..b2b679d30 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -69,7 +69,9 @@ exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"mai exports[`invalid $multi call (const {} = $multi();): code 1`] = ` "local ____ = { - ____(_G) + { + ____(_G) + } }" `; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 0b99cf4dc..5d59aa4d0 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -24,6 +24,33 @@ test("multi example use case", () => { .expectToEqual({ a: "foo", b: 5 }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/995 +test("Destructuring assignment of LuaMultiReturn", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return $multi(1, 2, 3); + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: 1, b: [2, 3] }); +}); + +test("Destructuring assignment of LuaMultiReturn returning nil", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return; + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: undefined, b: [] }); +}); + test.each<[string, any]>([ ["$multi()", undefined], ["$multi(true)", true], From 0d22c0d9c4b9e6e40a8998acd6296944a2a0c102 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 6 Mar 2021 10:21:10 -0700 Subject: [PATCH 49/91] Vararg Update (#992) * wip vararg extension * vararg spread optimization working with handling for hoisting * refactoring and tests * deprecation test * updates from feedback * clarity for isOptimizableVarargSpread Co-authored-by: Tom --- language-extensions/index.d.ts | 6 + src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/Generator.ts | 4 +- src/lualib/New.ts | 2 +- src/lualib/declarations/tstl.d.ts | 3 - src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 9 +- src/transformation/utils/lua-ast.ts | 2 + src/transformation/utils/scope.ts | 42 ++- src/transformation/utils/symbols.ts | 7 +- src/transformation/utils/transform.ts | 22 ++ .../visitors/binary-expression/assignments.ts | 63 ++-- .../visitors/binary-expression/compound.ts | 58 ++-- .../visitors/binary-expression/index.ts | 12 +- src/transformation/visitors/call.ts | 96 +++--- src/transformation/visitors/class/index.ts | 21 +- src/transformation/visitors/function.ts | 22 +- src/transformation/visitors/identifier.ts | 7 + src/transformation/visitors/index.ts | 3 +- .../visitors/language-extensions/multi.ts | 4 +- .../visitors/language-extensions/range.ts | 2 +- .../visitors/language-extensions/vararg.ts | 16 + src/transformation/visitors/spread.ts | 82 +++++ src/transformation/visitors/template.ts | 26 +- test/unit/__snapshots__/spread.spec.ts.snap | 127 ++++++++ .../__snapshots__/deprecated.spec.ts.snap | 10 + test/unit/annotations/deprecated.spec.ts | 11 + test/unit/annotations/vararg.spec.ts | 7 +- .../__snapshots__/multi.spec.ts.snap | 36 +-- .../__snapshots__/vararg.spec.ts.snap | 37 +++ test/unit/language-extensions/vararg.spec.ts | 38 +++ test/unit/spread.spec.ts | 301 ++++++++++++++++++ 34 files changed, 914 insertions(+), 172 deletions(-) create mode 100644 src/transformation/utils/transform.ts create mode 100644 src/transformation/visitors/language-extensions/vararg.ts create mode 100644 src/transformation/visitors/spread.ts create mode 100644 test/unit/__snapshots__/spread.spec.ts.snap create mode 100644 test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap create mode 100644 test/unit/language-extensions/vararg.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index e5d3096a3..ad3692a97 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -34,6 +34,12 @@ declare type LuaMultiReturn = T & LuaExtension<"__luaMultiRetur declare const $range: ((start: number, limit: number, step?: number) => Iterable) & LuaExtension<"__luaRangeFunctionBrand">; +/** + * Transpiles to the global vararg (`...`) + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + */ +declare const $vararg: string[] & LuaExtension<"__luaVarargConstantBrand">; + /** * Represents a Lua-style iterator which is returned from a LuaIterable. * For simple iterators (with no state), this is just a function. diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index edb6825e6..c8ea2de50 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduce( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: T[] ): T { const len = arr.length; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 8e5336f61..a0d5933d2 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduceRight( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: T[] ): T { const len = arr.length; diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 1b0bf9cff..0fae685e8 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { +function __TS__ArraySplice(this: void, list: T[], ...args: unknown[]): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index a71740761..1573f5ec3 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -8,7 +8,7 @@ function __TS__GeneratorIterator(this: GeneratorIterator) { return this; } -function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { +function __TS__GeneratorNext(this: GeneratorIterator, ...args: any[]) { const co = this.____coroutine; if (coroutine.status(co) === "dead") return { done: true }; @@ -19,7 +19,7 @@ function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { } function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { - return function (this: void, ...args: Vararg): GeneratorIterator { + return function (this: void, ...args: any[]): GeneratorIterator { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil diff --git a/src/lualib/New.ts b/src/lualib/New.ts index 507ba120c..8b33ec837 100644 --- a/src/lualib/New.ts +++ b/src/lualib/New.ts @@ -1,4 +1,4 @@ -function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { +function __TS__New(this: void, target: LuaClass, ...args: any[]): any { const instance: any = setmetatable({}, target.prototype); instance.____constructor(...args); return instance; diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 4a718a31a..f68237190 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,8 +1,5 @@ /** @noSelfInFile */ -/** @vararg */ -type Vararg = T & { __luaVararg?: never }; - interface Metatable { _descriptors?: Record; __index?: any; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 4086ee0f2..422a93cac 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -64,6 +64,10 @@ export const invalidForRangeCall = createErrorDiagnosticFactory( export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); +export const invalidVarargUse = createErrorDiagnosticFactory( + "$vararg can only be used in a spread element ('...$vararg') in global scope." +); + export const invalidRangeControlVariable = createErrorDiagnosticFactory( "For loop using $range must declare a single control variable." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index cb17987ad..2991204c2 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -5,6 +5,7 @@ export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", RangeFunction = "RangeFunction", + VarargConstant = "VarargConstant", IterableType = "IterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", @@ -49,15 +50,17 @@ export enum ExtensionKind { TableSetMethodType = "TableSetMethodType", } -const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { +const extensionKindToValueName: { [T in ExtensionKind]?: string } = { [ExtensionKind.MultiFunction]: "$multi", [ExtensionKind.RangeFunction]: "$range", + [ExtensionKind.VarargConstant]: "$vararg", }; const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", [ExtensionKind.MultiType]: "__luaMultiReturnBrand", [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", + [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", [ExtensionKind.IterableType]: "__luaIterableBrand", [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", @@ -107,13 +110,13 @@ export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): bo return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; } -export function isExtensionFunction( +export function isExtensionValue( context: TransformationContext, symbol: ts.Symbol, extensionKind: ExtensionKind ): boolean { return ( - symbol.getName() === extensionKindToFunctionName[extensionKind] && + symbol.getName() === extensionKindToValueName[extensionKind] && symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) ); } diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 91e81bc9a..5f3a21e4a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -62,6 +62,8 @@ export function getNumberLiteralValue(expression?: lua.Expression) { return undefined; } +// Prefer use of transformToImmediatelyInvokedFunctionExpression to maintain correct scope. If you use this directly, +// ensure you push/pop a function scope appropriately to avoid incorrect vararg optimization. export function createImmediatelyInvokedFunctionExpression( statements: lua.Statement[], result: lua.Expression | lua.Expression[], diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 2c9f267dd..200b65860 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { assert, getOrUpdate, isNonNull } from "../../utils"; import { TransformationContext } from "../context"; import { getSymbolInfo } from "./symbols"; -import { getFirstDeclarationInFile } from "./typescript"; +import { findFirstNodeAbove, getFirstDeclarationInFile } from "./typescript"; export enum ScopeType { File = 1 << 0, @@ -24,6 +24,7 @@ interface FunctionDefinitionInfo { export interface Scope { type: ScopeType; id: number; + node?: ts.Node; referencedSymbols?: Map; variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; @@ -91,6 +92,45 @@ export function popScope(context: TransformationContext): Scope { return scope; } +function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { + return symbol?.declarations.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); +} + +// Checks for references to local functions which haven't been defined yet, +// and thus will be hoisted above the current position. +export function hasReferencedUndefinedLocalFunction(context: TransformationContext, scope: Scope) { + if (!scope.referencedSymbols || !scope.node) { + return false; + } + for (const [symbolId, nodes] of scope.referencedSymbols) { + const type = context.checker.getTypeAtLocation(nodes[0]); + if ( + !scope.functionDefinitions?.has(symbolId) && + type.getCallSignatures().length > 0 && + isDeclaredInScope(type.symbol, scope.node) + ) { + return true; + } + } + return false; +} + +export function hasReferencedSymbol(context: TransformationContext, scope: Scope, symbol: ts.Symbol) { + if (!scope.referencedSymbols) { + return; + } + for (const nodes of scope.referencedSymbols.values()) { + if (nodes.some(node => context.checker.getSymbolAtLocation(node) === symbol)) { + return true; + } + } + return false; +} + +export function isFunctionScopeWithDefinition(scope: Scope): scope is Scope & { node: ts.SignatureDeclaration } { + return scope.node !== undefined && ts.isFunctionLike(scope.node); +} + export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { const scope = peekScope(context); let result = statements; diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index c99b41a25..f800eea86 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; +import { isOptimizedVarArgSpread } from "../visitors/spread"; import { markSymbolAsReferencedInCurrentScopes } from "./scope"; const symbolIdCounters = new WeakMap(); @@ -44,7 +45,11 @@ export function trackSymbolReference( symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); } - markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + // If isOptimizedVarArgSpread returns true, the identifier will not appear in the resulting Lua. + // Only the optimized ellipses (...) will be used. + if (!isOptimizedVarArgSpread(context, symbol, identifier)) { + markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + } return symbolId; } diff --git a/src/transformation/utils/transform.ts b/src/transformation/utils/transform.ts new file mode 100644 index 000000000..215a018d5 --- /dev/null +++ b/src/transformation/utils/transform.ts @@ -0,0 +1,22 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { castArray } from "../../utils"; +import { TransformationContext } from "../context"; +import { createImmediatelyInvokedFunctionExpression } from "./lua-ast"; +import { ScopeType, pushScope, popScope } from "./scope"; + +export interface ImmediatelyInvokedFunctionParameters { + statements: lua.Statement | lua.Statement[]; + result: lua.Expression | lua.Expression[]; +} + +export function transformToImmediatelyInvokedFunctionExpression( + context: TransformationContext, + transformFunction: () => ImmediatelyInvokedFunctionParameters, + tsOriginal?: ts.Node +): lua.CallExpression { + pushScope(context, ScopeType.Function); + const { statements, result } = transformFunction(); + popScope(context); + return createImmediatelyInvokedFunctionExpression(castArray(statements), result, tsOriginal); +} diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index df99a2a7d..0b1b7fe70 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -5,13 +5,18 @@ import { TransformationContext } from "../../context"; import { isTupleReturnCall } from "../../utils/annotations"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; +import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -68,6 +73,25 @@ export function transformAssignment( ]; } +function transformDestructuredAssignmentExpression( + context: TransformationContext, + expression: ts.DestructuringAssignment +): ImmediatelyInvokedFunctionParameters { + const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + + let right = context.transformExpression(expression.right); + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { + right = wrapInTable(right); + } + + const statements = [ + lua.createVariableDeclarationStatement(rootIdentifier, right), + ...transformDestructuringAssignment(context, expression, rootIdentifier), + ]; + + return { statements, result: rootIdentifier }; +} + export function transformAssignmentExpression( context: TransformationContext, expression: ts.AssignmentExpression @@ -89,19 +113,11 @@ export function transformAssignmentExpression( } if (isDestructuringAssignment(expression)) { - const rootIdentifier = lua.createAnonymousIdentifier(expression.left); - - let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { - right = wrapInTable(right); - } - - const statements = [ - lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier), - ]; - - return createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformDestructuredAssignmentExpression(context, expression), + expression + ); } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { @@ -120,6 +136,7 @@ export function transformAssignmentExpression( indexParameter, valueParameter, ]); + pushScope(context, ScopeType.Function); const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { @@ -134,15 +151,19 @@ export function transformAssignmentExpression( } const args = [objExpression, indexExpression, context.transformExpression(expression.right)]; + popScope(context); return lua.createCallExpression(iife, args, expression); } else { - // Simple assignment - // (function() ${left} = ${right}; return ${left} end)() - const left = context.transformExpression(expression.left); - const right = context.transformExpression(expression.right); - return createImmediatelyInvokedFunctionExpression( - transformAssignment(context, expression.left, right), - left, + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + // Simple assignment + // (function() ${left} = ${right}; return ${left} end)() + const left = context.transformExpression(expression.left); + const right = context.transformExpression(expression.right); + const statements = transformAssignment(context, expression.left, right); + return { statements, result: left }; + }, expression ); } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 3b92ade58..7a11454c8 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -2,7 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; import { transformBinaryOperation } from "../binary-expression"; import { transformAssignment } from "./assignments"; @@ -75,15 +78,14 @@ export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; -export function transformCompoundAssignmentExpression( +export function transformCompoundAssignment( context: TransformationContext, expression: ts.Expression, - // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -): lua.CallExpression { +): ImmediatelyInvokedFunctionParameters { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const right = context.transformExpression(rhs); @@ -116,11 +118,7 @@ export function transformCompoundAssignmentExpression( assignStatement = lua.createAssignmentStatement(accessExpression, tmp); } // return ____tmp - return createImmediatelyInvokedFunctionExpression( - [objAndIndexDeclaration, tmpDeclaration, assignStatement], - tmp, - expression - ); + return { statements: [objAndIndexDeclaration, tmpDeclaration, assignStatement], result: tmp }; } else if (isPostfix) { // Postfix expressions need to cache original value in temp // local ____tmp = ${left}; @@ -130,11 +128,7 @@ export function transformCompoundAssignmentExpression( const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); const operatorExpression = transformBinaryOperation(context, tmpIdentifier, right, operator, expression); const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____tmp = ${left} ${replacementOperator} ${right}; @@ -146,27 +140,39 @@ export function transformCompoundAssignmentExpression( const assignStatements = transformAssignment(context, lhs, tmpIdentifier); if (isSetterSkippingCompoundAssignmentOperator(operator)) { - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs)], - tmpIdentifier, - expression - ); + const statements = [ + tmpDeclaration, + ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs), + ]; + return { statements, result: tmpIdentifier }; } - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { // Simple expressions // ${left} = ${right}; return ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); - const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression(assignStatements, left, expression); + const statements = transformAssignment(context, lhs, operatorExpression); + return { statements, result: left }; } } +export function transformCompoundAssignmentExpression( + context: TransformationContext, + expression: ts.Expression, + // TODO: Change type to ts.LeftHandSideExpression? + lhs: ts.Expression, + rhs: ts.Expression, + operator: CompoundAssignmentToken, + isPostfix: boolean +): lua.CallExpression { + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix), + expression + ); +} + export function transformCompoundAssignmentStatement( context: TransformationContext, node: ts.Node, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index d9e4746e0..26e90ad67 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; -import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; +import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; @@ -16,6 +16,7 @@ import { unwrapCompoundAssignmentToken, } from "./compound"; import { assert } from "../../../utils"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -121,9 +122,12 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.CommaToken: { - return createImmediatelyInvokedFunctionExpression( - context.transformStatements(ts.createExpressionStatement(node.left)), - context.transformExpression(node.right), + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ + statements: context.transformStatements(ts.createExpressionStatement(node.left)), + result: context.transformExpression(node.right), + }), node ); } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 7ea22eb34..75f73db88 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,16 +2,16 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; -import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; +import { isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; -import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; +import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { isTableGetCall, @@ -20,6 +20,10 @@ import { transformTableSetExpression, } from "./language-extensions/table"; import { invalidTableSetExpression } from "../utils/diagnostics"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../utils/transform"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -113,10 +117,32 @@ export function transformArguments( return parameters; } +function transformElementAccessCall( + context: TransformationContext, + left: ts.PropertyAccessExpression | ts.ElementAccessExpression, + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature +): ImmediatelyInvokedFunctionParameters { + const transformedArguments = transformArguments(context, args, signature, ts.factory.createIdentifier("____self")); + + // Cache left-side if it has effects + // (function() local ____self = context; return ____self[argument](parameters); end)() + const argument = ts.isElementAccessExpression(left) + ? transformElementAccessArgument(context, left) + : lua.createStringLiteral(left.name.text); + const selfIdentifier = lua.createIdentifier("____self"); + const callContext = context.transformExpression(left.expression); + const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); + const index = lua.createTableIndexExpression(selfIdentifier, argument); + const callExpression = lua.createCallExpression(index, transformedArguments); + return { statements: selfAssignment, result: callExpression }; +} + export function transformContextualCallExpression( context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, - transformedArguments: lua.Expression[] + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature ): lua.Expression { const left = ts.isCallExpression(node) ? node.expression : node.tag; if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { @@ -126,32 +152,25 @@ export function transformContextualCallExpression( return lua.createMethodCallExpression( table, lua.createIdentifier(left.name.text, left.name), - transformedArguments, + transformArguments(context, args, signature), node ); } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { - const callContext = context.transformExpression(left.expression); if (isExpressionWithEvaluationEffect(left.expression)) { - // Inject context parameter - transformedArguments.unshift(lua.createIdentifier("____self")); - - // Cache left-side if it has effects - // (function() local ____self = context; return ____self[argument](parameters); end)() - const argument = ts.isElementAccessExpression(left) - ? transformElementAccessArgument(context, left) - : lua.createStringLiteral(left.name.text); - const selfIdentifier = lua.createIdentifier("____self"); - const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); - const index = lua.createTableIndexExpression(selfIdentifier, argument); - const callExpression = lua.createCallExpression(index, transformedArguments); - return createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformElementAccessCall(context, left, args, signature), + node + ); } else { + const callContext = context.transformExpression(left.expression); const expression = context.transformExpression(left); + const transformedArguments = transformArguments(context, args, signature); return lua.createCallExpression(expression, [callContext, ...transformedArguments]); } } else if (ts.isIdentifier(left)) { - const callContext = context.isStrict ? lua.createNilLiteral() : lua.createIdentifier("_G"); - transformedArguments.unshift(callContext); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); + const transformedArguments = transformArguments(context, args, signature, callContext); const expression = context.transformExpression(left); return lua.createCallExpression(expression, transformedArguments, node); } else { @@ -168,17 +187,17 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal return lua.createCallExpression(context.transformExpression(node.expression), parameters); } - const parameters = transformArguments(context, node.arguments, signature); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // table:name() - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { const table = context.transformExpression(node.expression.expression); // table.name() const name = node.expression.name.text; const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); + const parameters = transformArguments(context, node.arguments, signature); return lua.createCallExpression(callPath, parameters, node); } } @@ -186,13 +205,13 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); - const parameters = transformArguments(context, node.arguments, signature); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // A contextual parameter must be given to this call expression - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { // No context const expression = context.transformExpression(node.expression); + const parameters = transformArguments(context, node.arguments, signature); return lua.createCallExpression(expression, parameters); } } @@ -227,9 +246,10 @@ export const transformCallExpression: FunctionVisitor = (node if (isTableSetCall(context, node)) { context.diagnostics.push(invalidTableSetExpression(node)); - return createImmediatelyInvokedFunctionExpression( - [transformTableSetExpression(context, node)], - lua.createNilLiteral() + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableSetExpression(context, node), result: lua.createNilLiteral() }), + node ); } @@ -272,21 +292,3 @@ export const transformCallExpression: FunctionVisitor = (node const callExpression = lua.createCallExpression(callPath, parameters, node); return wrapResult ? wrapInTable(callExpression) : callExpression; }; - -// TODO: Currently it's also used as an array member -export const transformSpreadElement: FunctionVisitor = (node, context) => { - const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) return innerExpression; - if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; - - if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { - return lua.createDotsLiteral(node); - } - - const type = context.checker.getTypeAtLocation(node.expression); - if (isArrayType(context, type)) { - return createUnpackCall(context, innerExpression, node); - } - - return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); -}; diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 8b40eadcd..9963c09f4 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -10,13 +10,9 @@ import { hasDefaultExportModifier, isSymbolExported, } from "../../utils/export"; -import { - createImmediatelyInvokedFunctionExpression, - createSelfIdentifier, - unwrapVisitorResult, -} from "../../utils/lua-ast"; +import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; -import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; @@ -50,11 +46,14 @@ export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, context: TransformationContext ): lua.Expression { - pushScope(context, ScopeType.Function); - const { statements, name } = transformClassLikeDeclaration(expression, context); - popScope(context); - - return createImmediatelyInvokedFunctionExpression(unwrapVisitorResult(statements), name, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + const { statements, name } = transformClassLikeDeclaration(expression, context); + return { statements: unwrapVisitorResult(statements), result: name }; + }, + expression + ); } const classSuperInfos = new WeakMap(); diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index d3fb88a5a..cb1d29bfd 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isVarargType } from "../utils/annotations"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { @@ -38,7 +37,7 @@ function transformParameterDefaultValueDeclaration( return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); } -function isRestParameterReferenced(context: TransformationContext, identifier: lua.Identifier, scope: Scope): boolean { +function isRestParameterReferenced(identifier: lua.Identifier, scope: Scope): boolean { if (!identifier.symbolId) { return true; } @@ -46,11 +45,7 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return false; } const references = scope.referencedSymbols.get(identifier.symbolId); - if (!references) { - return false; - } - // Ignore references to @vararg types in spread elements - return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); + return references !== undefined && references.length > 0; } export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { @@ -99,7 +94,7 @@ export function transformFunctionBodyHeader( } // Push spread operator here - if (spreadIdentifier && isRestParameterReferenced(context, spreadIdentifier, bodyScope)) { + if (spreadIdentifier && isRestParameterReferenced(spreadIdentifier, bodyScope)) { const spreadTable = wrapInTable(lua.createDotsLiteral()); headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -114,9 +109,11 @@ export function transformFunctionBody( context: TransformationContext, parameters: ts.NodeArray, body: ts.ConciseBody, - spreadIdentifier?: lua.Identifier + spreadIdentifier?: lua.Identifier, + node?: ts.FunctionLikeDeclaration ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); + scope.node = node; const bodyStatements = transformFunctionBodyContent(context, body); const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); @@ -195,7 +192,8 @@ export function transformFunctionToExpression( context, node.parameters, node.body, - spreadIdentifier + spreadIdentifier, + node ); const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), @@ -236,6 +234,10 @@ export function transformFunctionLikeDeclaration( // Only wrap if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); + // We cannot use transformToImmediatelyInvokedFunctionExpression() here because we need to transpile + // the function first to determine if it's self-referencing. Fortunately, this does not cause issues + // with var-arg optimization because the IIFE is just wrapping another function which will already push + // another scope. return createImmediatelyInvokedFunctionExpression( [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], lua.cloneIdentifier(nameIdentifier) diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 5905f1485..191319160 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -8,6 +8,7 @@ import { invalidMultiFunctionUse, invalidOperatorMappingUse, invalidRangeUse, + invalidVarargUse, invalidTableExtensionUse, } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; @@ -18,6 +19,7 @@ import { isMultiFunctionNode } from "./language-extensions/multi"; import { isOperatorMapping } from "./language-extensions/operators"; import { isRangeFunctionNode } from "./language-extensions/range"; import { isTableExtensionIdentifier } from "./language-extensions/table"; +import { isVarargConstantNode } from "./language-extensions/vararg"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -38,6 +40,11 @@ export function transformIdentifier(context: TransformationContext, identifier: return lua.createAnonymousIdentifier(identifier); } + if (isVarargConstantNode(context, identifier)) { + context.diagnostics.push(invalidVarargUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 48469a84b..b9983ae31 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -4,7 +4,8 @@ import { transformElementAccessExpression, transformPropertyAccessExpression, tr import { transformBinaryExpression } from "./binary-expression"; import { transformBlock } from "./block"; import { transformBreakStatement, transformContinueStatement } from "./break-continue"; -import { transformCallExpression, transformSpreadElement } from "./call"; +import { transformCallExpression } from "./call"; +import { transformSpreadElement } from "./spread"; import { transformClassAsExpression, transformClassDeclaration, diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index b292d9aa1..85b3c6a29 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -25,7 +25,7 @@ export function isMultiReturnCall(context: TransformationContext, expression: ts export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.MultiFunction) : false; + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.MultiFunction) : false; } export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { @@ -98,7 +98,7 @@ export function findMultiAssignmentViolations( if (!ts.isShorthandPropertyAssignment(element)) continue; const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); if (valueSymbol) { - if (extensions.isExtensionFunction(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { + if (extensions.isExtensionValue(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { context.diagnostics.push(invalidMultiFunctionUse(element)); result.push(element); } diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts index 00a3c249e..43f297a9a 100644 --- a/src/transformation/visitors/language-extensions/range.ts +++ b/src/transformation/visitors/language-extensions/range.ts @@ -14,7 +14,7 @@ export function isRangeFunction(context: TransformationContext, expression: ts.C export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.RangeFunction) : false; + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.RangeFunction) : false; } function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { diff --git a/src/transformation/visitors/language-extensions/vararg.ts b/src/transformation/visitors/language-extensions/vararg.ts new file mode 100644 index 000000000..99eea82a9 --- /dev/null +++ b/src/transformation/visitors/language-extensions/vararg.ts @@ -0,0 +1,16 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { Scope, ScopeType } from "../../utils/scope"; + +export function isGlobalVarargConstant(context: TransformationContext, symbol: ts.Symbol, scope: Scope) { + return ( + scope.type === ScopeType.File && + extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) + ); +} + +export function isVarargConstantNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) : false; +} diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts new file mode 100644 index 000000000..ca5e2fb85 --- /dev/null +++ b/src/transformation/visitors/spread.ts @@ -0,0 +1,82 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { createUnpackCall } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { + findScope, + hasReferencedSymbol, + hasReferencedUndefinedLocalFunction, + isFunctionScopeWithDefinition, + ScopeType, +} from "../utils/scope"; +import { isArrayType } from "../utils/typescript"; +import { returnsMultiType } from "./language-extensions/multi"; +import { annotationDeprecated } from "../utils/diagnostics"; +import { isGlobalVarargConstant } from "./language-extensions/vararg"; + +export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { + if (!ts.isSpreadElement(identifier.parent)) { + return false; + } + + // Walk up, stopping at any scope types which could stop optimization + const scope = findScope(context, ScopeType.Function | ScopeType.Try | ScopeType.Catch | ScopeType.File); + if (!scope) { + return; + } + + // $vararg global constant + if (isGlobalVarargConstant(context, symbol, scope)) { + return true; + } + + // Scope must be a function scope associated with a real ts function + if (!isFunctionScopeWithDefinition(scope)) { + return false; + } + + // Identifier must be a vararg in the local function scope's parameters + const isSpreadParameter = (p: ts.ParameterDeclaration) => + p.dotDotDotToken && ts.isIdentifier(p.name) && context.checker.getSymbolAtLocation(p.name) === symbol; + if (!scope.node.parameters.some(isSpreadParameter)) { + return false; + } + + // De-optimize if already referenced outside of a spread, as the array may have been modified + if (hasReferencedSymbol(context, scope, symbol)) { + return false; + } + + // De-optimize if a function is being hoisted from below to above, as it may have modified the array + if (hasReferencedUndefinedLocalFunction(context, scope)) { + return false; + } + return true; +} + +// TODO: Currently it's also used as an array member +export const transformSpreadElement: FunctionVisitor = (node, context) => { + if (ts.isIdentifier(node.expression)) { + if (isVarargType(context, node.expression)) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Vararg)); + return lua.createDotsLiteral(node); + } + const symbol = context.checker.getSymbolAtLocation(node.expression); + if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { + return lua.createDotsLiteral(node); + } + } + + const innerExpression = context.transformExpression(node.expression); + if (isTupleReturnCall(context, node.expression)) return innerExpression; + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; + + const type = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, type)) { + return createUnpackCall(context, innerExpression, node); + } + + return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); +}; diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 1b714d765..9f9a19b33 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -65,29 +65,35 @@ export const transformTaggedTemplateExpression: FunctionVisitor lua.createTableFieldExpression(lua.createStringLiteral(text))) + const rawStringsArray = ts.factory.createArrayLiteralExpression( + rawStrings.map(text => ts.factory.createStringLiteral(text)) ); - const stringTableLiteral = lua.createTableExpression([ - ...strings.map(partialString => lua.createTableFieldExpression(lua.createStringLiteral(partialString))), - lua.createTableFieldExpression(rawStringsTable, lua.createStringLiteral("raw")), + const stringObject = ts.factory.createObjectLiteralExpression([ + ...strings.map((partialString, i) => + ts.factory.createPropertyAssignment( + ts.factory.createNumericLiteral(i + 1), + ts.factory.createStringLiteral(partialString) + ) + ), + ts.factory.createPropertyAssignment("raw", rawStringsArray), ]); + expressions.unshift(stringObject); + // Evaluate if there is a self parameter to be used. const signature = context.checker.getResolvedSignature(expression); const signatureDeclaration = signature?.getDeclaration(); const useSelfParameter = signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; - // Argument evaluation. - const callArguments = transformArguments(context, expressions, signature); - callArguments.unshift(stringTableLiteral); - if (useSelfParameter) { - return transformContextualCallExpression(context, expression, callArguments); + return transformContextualCallExpression(context, expression, expressions, signature); } + // Argument evaluation. + const callArguments = transformArguments(context, expressions, signature); + const leftHandSideExpression = context.transformExpression(expression.tag); return lua.createCallExpression(leftHandSideExpression, callArguments); }; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap new file mode 100644 index 000000000..f16bc746a --- /dev/null +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -0,0 +1,127 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`vararg spread optimization $multi 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function multi(self, ...) + return ... + end + local function test(self, ...) + return select( + 2, + multi(nil, ...) + ) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization basic use 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization block statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + local result + do + result = pick(nil, ...) + end + return result + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization body-less arrow function 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(____, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization 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 if statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + if true then + return pick(nil, ...) + end + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization loop statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + repeat + do + return pick(nil, ...) + end + until not false + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 3b1d5e2af..750b0596f 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -43,3 +43,13 @@ __TS__ClassExtends(ClassB, ClassA)" `; exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; + +exports[`vararg deprecation: code 1`] = ` +"function foo(self, ...) +end +function vararg(self, ...) + foo(_G, ...) +end" +`; + +exports[`vararg deprecation: diagnostics 1`] = `"main.ts(6,17): warning TSTL: '@vararg' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 072ff6372..9c81b2176 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -33,3 +33,14 @@ test("forRange deprecation", () => { for (const i of forRange(1, 10)) {} `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); }); + +test("vararg deprecation", () => { + util.testModule` + /** @vararg */ + type VarArg = T & { readonly __brand: unique symbol }; + function foo(...args: any[]) {} + function vararg(...args: VarArg) { + foo(...args); + } + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts index 1635ef13a..1b80e73db 100644 --- a/test/unit/annotations/vararg.spec.ts +++ b/test/unit/annotations/vararg.spec.ts @@ -1,3 +1,4 @@ +import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const varargDeclaration = ` @@ -19,6 +20,7 @@ test("@vararg", () => { ` .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .ignoreDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -30,7 +32,9 @@ test("@vararg array access", () => { return c.join("") + b[0]; } return foo("A", "B", "C", "D"); - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("@vararg global", () => { @@ -41,5 +45,6 @@ test("@vararg global", () => { ` .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .ignoreDiagnostics([annotationDeprecated.code]) .expectToEqual({ result: "ABCD" }); }); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index b2b679d30..36b928202 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -4,8 +4,7 @@ exports[`disallow LuaMultiReturn non-numeric access: code 1`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end return select( \\"forEach\\", @@ -19,8 +18,7 @@ exports[`disallow LuaMultiReturn non-numeric access: code 2`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end return ({ multi(nil) @@ -96,8 +94,7 @@ exports[`invalid $multi implicit cast: diagnostics 1`] = `"main.ts(3,20): error exports[`invalid direct $multi function use (const [a = 1] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil) if a == nil then @@ -112,8 +109,7 @@ exports[`invalid direct $multi function use (const [a = 1] = $multi()): diagnost exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil, 2) if a == nil then @@ -128,8 +124,7 @@ exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): diagnos exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil) ____exports.a = a @@ -141,8 +136,7 @@ exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil, 1) ____exports.a = a @@ -154,8 +148,7 @@ exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local _ = nil local a = ____(nil, 1) @@ -168,8 +161,7 @@ exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): d exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local ar = {1} local a = ____( @@ -185,8 +177,7 @@ exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi( exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a local ____ = { @@ -203,8 +194,7 @@ exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a do @@ -226,8 +216,7 @@ exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); fal exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a do @@ -245,8 +234,7 @@ exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2 exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a if (function() diff --git a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap new file mode 100644 index 000000000..819cc27a0 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$vararg invalid use ("const l = $vararg.length"): code 1`] = `"l = #____"`; + +exports[`$vararg invalid use ("const l = $vararg.length"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("const x = $vararg;"): code 1`] = `"x = ____"`; + +exports[`$vararg invalid use ("const x = $vararg;"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): code 1`] = ` +"for ____, x in ipairs(____) do +end" +`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): code 1`] = ` +"function f(self, s) +end +f(_G, ____)" +`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): diagnostics 1`] = `"main.ts(2,38): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): code 1`] = ` +"function foo(self, ...) +end +function bar(self) + foo( + _G, + table.unpack(____) + ) +end" +`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): diagnostics 1`] = `"main.ts(2,68): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; diff --git a/test/unit/language-extensions/vararg.spec.ts b/test/unit/language-extensions/vararg.spec.ts new file mode 100644 index 000000000..f92cc0f96 --- /dev/null +++ b/test/unit/language-extensions/vararg.spec.ts @@ -0,0 +1,38 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidVarargUse } from "../../../src/transformation/utils/diagnostics"; + +const varargProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test.each([ + 'const result = [...$vararg].join("")', + 'let result: string; { result = [...$vararg].join(""); }', + 'let result: string; if (true) { result = [...$vararg].join(""); }', + 'let result: string; do { result = [...$vararg].join(""); } while (false);', +])("$vararg valid use (%p)", statement => { + util.testModule` + ${statement} + export { result }; + ` + .setOptions(varargProjectOptions) + .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .expectToEqual({ result: "ABCD" }); +}); + +test.each([ + "const x = $vararg;", + "for (const x of $vararg) {}", + "const l = $vararg.length", + "function f(s: string[]) {} f($vararg);", + "function foo(...args: string[]) {} function bar() { foo(...$vararg); }", +])("$vararg invalid use (%p)", statement => { + util.testModule` + ${statement} + ` + .setOptions(varargProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]); +}); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 831b68842..344205ddb 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -1,3 +1,4 @@ +import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import { formatCode } from "../util"; @@ -130,3 +131,303 @@ describe("in object literal", () => { `.expectToMatchJsResult(); }); }); + +describe("vararg spread optimization", () => { + test("basic use", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return pick(...args); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("body-less arrow function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = (...args: string[]) => pick(...args); + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("if statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + if (true) { + return pick(...args); + } + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("loop statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + do { + return pick(...args); + } while (false); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("block statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let result: string; + { + result = pick(...args); + } + return result; + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("finally clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + } finally { + return pick(...args); + } + } + return test("a" ,"b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("$multi", () => { + util.testFunction` + function multi(...args: string[]) { + return $multi(...args); + } + function test(...args: string[]) { + return multi(...args)[1]; + } + return test("a" ,"b", "c"); + ` + .setOptions({ types: [path.resolve(__dirname, "../../language-extensions")] }) + .expectLuaToMatchSnapshot() + .expectToEqual("b"); + }); +}); + +describe("vararg spread de-optimization", () => { + test("array modification", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + args[1] = "foobar"; + return pick(...args); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + hoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in secondary hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + function triggersHoisted() { hoisted(); } + triggersHoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); +}); + +describe("vararg spread in IIFE", () => { + test("comma operator", () => { + util.testFunction` + function dummy() { return "foobar"; } + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return (dummy(), pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: string; + return (x = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("destructured assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return [args[1]]; } + function test(...args: string[]) { + let x: string; + return ([x] = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("property-access assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: {val?: string} = {}; + return (x.val = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("binary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = 1; + return x += pick(...args); + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("postfix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return x[pick(...args)]++; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("prefix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return ++x[pick(...args)]; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("try clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + return pick(...args) + } catch {} + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("catch clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + return pick(...args) + } + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("class expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + const fooClass = class Foo { foo = pick(...args); }; + return new fooClass().foo; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("self-referencing function expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = function testName(...args: string[]) { + return \`\${typeof testName}:\${pick(...args)}\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (access args)", () => { + util.testFunction` + const obj = { $method: () => obj.arg, arg: "foobar" }; + function getObj(...args: string[]) { obj.arg = args[1]; return obj; } + function test(...args: string[]) { + return getObj(...args).$method(); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (method args)", () => { + util.testFunction` + const obj = { $pick: (...args: string[]) => args[1] }; + function getObj() { return obj; } + function test(...args: string[]) { + return getObj().$pick(...args); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("tagged template method indirect access", () => { + util.testFunction` + const obj = { $tag: (t: TemplateStringsArray, ...args: string[]) => args[1] }; + function getObj() { return obj; } + function pick(...args: string[]): string { return args[1]; } + function test(...args: string[]) { + return getObj().$tag\`FOO\${pick(...args)}BAR\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); +}); From 3b950d44466cafe777958b087cad0454b0031986 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sat, 6 Mar 2021 22:49:11 +0100 Subject: [PATCH 50/91] Add actual multi version tests (#1001) * Add actual multi version tests Test now select the appropriate Lua runtime based on luaTarget option This works for all supported Lua versions except JIT * Updated testeachversion calls * Revert continue test multiversion tests * Added missing expectToMatchJsResult in spread tests * Throw if JIT is used in tests --- package-lock.json | 14 +++++++------- package.json | 2 +- test/unit/builtins/math.spec.ts | 9 +++++++-- test/unit/conditionals.spec.ts | 3 --- test/unit/spread.spec.ts | 16 ++++++++-------- test/util.ts | 26 ++++++++++++++++++++++++-- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59d842844..9fecaff4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.1.4", + "lua-wasm-bindings": "^0.2.1", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -8795,9 +8795,9 @@ "dev": true }, "node_modules/lua-wasm-bindings": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", - "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", + "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", "dev": true }, "node_modules/make-dir": { @@ -18828,9 +18828,9 @@ "dev": true }, "lua-wasm-bindings": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", - "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", + "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", "dev": true }, "make-dir": { diff --git a/package.json b/package.json index 573394f5a..61452f116 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.1.4", + "lua-wasm-bindings": "^0.2.1", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 8267cd0b3..dd928c68d 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -37,6 +37,11 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); -test("Math.atan2(4, 5)", () => { - util.testExpression`Math.atan2(4, 5)`.expectToMatchJsResult(); +util.testEachVersion("Math.atan2(4, 5)", () => util.testExpression`Math.atan2(4, 5)`, { + [tstl.LuaTarget.Universal]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.LuaJIT]: false, + [tstl.LuaTarget.Lua51]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), }); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 890c6dc71..1df76d6a1 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -368,9 +368,6 @@ test.each([ { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, ])("Ternary operator (%p)", ({ input, options }) => { util.testFunction` const literalValue = "literal"; diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 344205ddb..a395ef2bd 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -74,11 +74,11 @@ describe("in function call", () => { return foo(...array); `, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); @@ -86,11 +86,11 @@ describe("in function call", () => { describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); diff --git a/test/util.ts b/test/util.ts index 616d6cde9..b553ef359 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,7 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.54"; -import { LUA_OK } from "lua-wasm-bindings/dist/lua"; +import { LauxLib, Lua, LuaLib, LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -17,6 +16,27 @@ const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bu // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; +function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; lua: Lua; lualib: LuaLib } { + if (target === tstl.LuaTarget.Lua51) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.51"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua52) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.52"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua53) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.53"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.LuaJIT) { + throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!"); + } + + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54"); + return { lauxlib, lua, lualib }; +} + export function assert(value: any, message?: string | Error): asserts value { nativeAssert(value, message); } @@ -339,6 +359,8 @@ export abstract class TestBuilder { // Main file const mainFile = this.getMainLuaCodeChunk(); + const { lauxlib, lua, lualib } = getLuaBindingsForVersion(this.options.luaTarget ?? tstl.LuaTarget.Lua54); + const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); From fe5a5cc822ecdba31f473ccfa58005fbbd40c2ec Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Mar 2021 16:19:20 +0100 Subject: [PATCH 51/91] CHANGELOG 0.39.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae1502099..fefbd8362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.39.0 + +- **[Breaking]** Removed support for `@phantom`, `@metaExtension`, `@extension`, `@pureAbstract` compiler annotations. As of this version **these will no longer function!** For help upgrading your code see [the deprecated annotation docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#deprecated). +- Added official support for **Lua 5.4**. +- Added the `LuaTable` language extension. This allows the use of barebones Lua tables for key-value storage, without suffering from JS's forced string indexes. For more information see [the LuaTable docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types). +- Deprecated `@vararg`. Instead, tstl will figure out itself when use of the Lua ellipsis token (`...`) is appropriate. Also language extension `$vararg` was added to force use of the ellipsis token. See [the docs](https://typescripttolua.github.io/docs/advanced/language-extensions#vararg-constant) for more information. +- Added `trailingComments` and `leadingComments` fields to statements in the Lua AST. These can be modified by plugins to emit comments in the output lua. For an example see [the add-comments test plugin](https://github.com/TypeScriptToLua/TypeScriptToLua/blob/master/test/transpile/plugins/add-comments.ts). + +Under the hood: + +- Tests are now run on a WebAssembly-compiled version of official Lua releases. This means we can now execute test Lua on all Lua versions (except LuaJIT). Shoutout to [Fengari](https://github.com/fengari-lua/fengari) for serving us well for a long time. + ## 0.38.0 - **[Breaking]** Renamed `MultiReturn` to `LuaMultiReturn` to be consistent with other language extensions all starting with Lua-. From a6399982d8f5f9f1402aa9cd50dc1418ca271842 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Mar 2021 16:30:47 +0100 Subject: [PATCH 52/91] 0.39.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fecaff4c..e04a792e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 61452f116..02a0c665a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.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/", From 759090a3aabc744f81883bb0d39929ecc740258c Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 7 Mar 2021 17:48:31 +0100 Subject: [PATCH 53/91] Bump lua-wasm-bindings version (#1002) Fixed an issue were errors would be printed for 5.1 tests even though the tests passed. --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e04a792e3..8dbf1d54d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.2.1", + "lua-wasm-bindings": "^0.2.2", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -8795,9 +8795,9 @@ "dev": true }, "node_modules/lua-wasm-bindings": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", - "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", "dev": true }, "node_modules/make-dir": { @@ -18828,9 +18828,9 @@ "dev": true }, "lua-wasm-bindings": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", - "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", + "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": { diff --git a/package.json b/package.json index 02a0c665a..677789323 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.2.1", + "lua-wasm-bindings": "^0.2.2", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" From 29dba98fe906972f2c29a5d15954b44ed95c255f Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 25 Mar 2021 19:22:30 +0100 Subject: [PATCH 54/91] Replaced deprecated factory functions (#1008) * Replaced deprecated factory functions Also enabled some eslint rules & fixed violations * Caught to more deprecated function calls * Fixed typo --- .eslintrc.js | 51 +++++++++++-------- src/LuaLib.ts | 2 + src/LuaPrinter.ts | 2 +- .../visitors/binary-expression/compound.ts | 8 +-- .../visitors/binary-expression/index.ts | 6 +-- src/transformation/visitors/call.ts | 8 +-- src/transformation/visitors/class/index.ts | 4 +- src/transformation/visitors/literal.ts | 4 +- src/transformation/visitors/loops/for.ts | 4 +- src/transformation/visitors/loops/utils.ts | 2 +- src/transformation/visitors/modules/export.ts | 11 ++-- .../visitors/unary-expression.ts | 12 ++--- .../visitors/variable-declaration.ts | 2 +- src/transpilation/transformers.ts | 6 +-- test/cli/parse.spec.ts | 1 + test/transpile/transformers/fixtures.ts | 8 +-- .../transformers/transformers.spec.ts | 1 + .../invalidFunctionAssignments.spec.ts | 16 +++--- test/unit/hoisting.spec.ts | 4 +- 19 files changed, 85 insertions(+), 67 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index fb8ec7488..dabc1db41 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -130,6 +130,8 @@ module.exports = { "no-useless-return": ["error"], "import/no-default-export": "error", + // TODO currently only works for direct imports (useless for now) https://github.com/benmosher/eslint-plugin-import/issues/1729 + // "import/no-deprecated": "error", "jest/expect-expect": "off", "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], @@ -154,31 +156,33 @@ module.exports = { "@typescript-eslint/no-require-imports": "off", "@typescript-eslint/no-unnecessary-condition": "off", "@typescript-eslint/prefer-for-of": "error", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1265 - // "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", "@typescript-eslint/prefer-readonly": "off", "@typescript-eslint/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], "@typescript-eslint/require-array-sort-compare": "off", "@typescript-eslint/camelcase": "off", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1712 - // "@typescript-eslint/naming-convention": [ - // "error", - // { - // selector: "default", - // format: ["camelCase"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "variable", - // format: ["camelCase", "UPPER_CASE"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "typeLike", - // format: ["PascalCase"], - // }, - // ], + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "default", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "variable", + format: ["camelCase", "UPPER_CASE"], + leadingUnderscore: "allow", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "enumMember", + format: ["PascalCase"], + }, + ], }, }, { @@ -187,6 +191,13 @@ module.exports = { "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], "@typescript-eslint/no-throw-literal": "off", "@typescript-eslint/prefer-optional-chain": "off", + "@typescript-eslint/naming-convention": "off", + }, + }, + { + files: "language-extensions/index.d.ts", + rules: { + "@typescript-eslint/naming-convention": "off", }, }, { diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7168d0067..06742022d 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -87,6 +87,7 @@ export enum LuaLibFeature { Unpack = "Unpack", } +/* eslint-disable @typescript-eslint/naming-convention */ const luaLibDependencies: Partial> = { ArrayConcat: [LuaLibFeature.ArrayIsArray], ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], @@ -108,6 +109,7 @@ const luaLibDependencies: Partial> = { StringSplit: [LuaLibFeature.StringSubstring], SymbolRegistry: [LuaLibFeature.Symbol], }; +/* eslint-enable @typescript-eslint/naming-convention */ export function loadLuaLibFeatures(features: Iterable, emitHost: EmitHost): string { let result = ""; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 912ab33f5..b1cfb7f46 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -272,7 +272,7 @@ export class LuaPrinter { } } }); - return result || false; + return result ?? false; } protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 7a11454c8..febd7681e 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -22,15 +22,15 @@ export function parseAccessExpressionWithEvaluationEffects( const type = context.checker.getTypeAtLocation(node.expression); if (isArrayType(context, type)) { // Offset arrays by one - const oneLit = ts.createNumericLiteral("1"); - const exp = ts.createParen(node.argumentExpression); - const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); + const oneLit = ts.factory.createNumericLiteral("1"); + const exp = ts.factory.createParenthesizedExpression(node.argumentExpression); + const addExp = ts.factory.createBinaryExpression(exp, ts.SyntaxKind.PlusToken, oneLit); return [node.expression, addExp]; } else { return [node.expression, node.argumentExpression]; } } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { - return [node.expression, ts.createStringLiteral(node.name.text)]; + return [node.expression, ts.factory.createStringLiteral(node.name.text)]; } return []; diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 26e90ad67..5ed023618 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -125,7 +125,7 @@ export const transformBinaryExpression: FunctionVisitor = ( return transformToImmediatelyInvokedFunctionExpression( context, () => ({ - statements: context.transformStatements(ts.createExpressionStatement(node.left)), + statements: context.transformStatements(ts.factory.createExpressionStatement(node.left)), result: context.transformExpression(node.right), }), node @@ -159,8 +159,8 @@ export function transformBinaryExpressionStatement( return transformAssignmentStatement(context, expression as ts.AssignmentExpression); } else if (operator === ts.SyntaxKind.CommaToken) { const statements = [ - ...context.transformStatements(ts.createExpressionStatement(expression.left)), - ...context.transformStatements(ts.createExpressionStatement(expression.right)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.left)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.right)), ]; return lua.createDoStatement(statements, expression); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 75f73db88..306968010 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -183,7 +183,7 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression(context.transformExpression(node.expression), parameters); } @@ -267,11 +267,11 @@ export const transformCallExpression: FunctionVisitor = (node // Handle super calls properly if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression( lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), + context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), parameters @@ -285,7 +285,7 @@ export const transformCallExpression: FunctionVisitor = (node if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { parameters = transformArguments(context, node.arguments, signature); } else { - const callContext = context.isStrict ? ts.createNull() : ts.createIdentifier("_G"); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); parameters = transformArguments(context, node.arguments, signature, callContext); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 9963c09f4..4c0e05eee 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -152,7 +152,7 @@ function transformClassLikeDeclaration( // Generate a constructor if none was defined in a base class const constructorResult = transformConstructorDeclaration( context, - ts.createConstructor([], [], [], ts.createBlock([], true)), + ts.factory.createConstructorDeclaration([], [], [], ts.factory.createBlock([], true)), localClassName, instanceFields, classDeclaration @@ -168,7 +168,7 @@ function transformClassLikeDeclaration( const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), + context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), [createSelfIdentifier(), lua.createDotsLiteral()] diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 36c7e48c6..8fa85e4e4 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -38,7 +38,7 @@ export function createShorthandIdentifier( const name = isUnsafeName ? createSafeName(propertyName) : propertyName; - let identifier = context.transformExpression(ts.createIdentifier(name)); + let identifier = context.transformExpression(ts.factory.createIdentifier(name)); lua.setNodeOriginal(identifier, propertyIdentifier); if (valueSymbol !== undefined && lua.isIdentifier(identifier)) { identifier.symbolId = getSymbolIdOfSymbol(context, valueSymbol); @@ -137,7 +137,7 @@ const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => - ts.isOmittedExpression(e) ? ts.createIdentifier("undefined") : e + ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e ); const values = flattenSpreadExpressions(context, filteredElements).map(e => lua.createTableFieldExpression(e)); diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index f81a62199..98864082e 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -13,7 +13,7 @@ export const transformForStatement: FunctionVisitor = (statemen // local initializer = value result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { - result.push(...context.transformStatements(ts.createExpressionStatement(statement.initializer))); + result.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.initializer))); } } @@ -25,7 +25,7 @@ export const transformForStatement: FunctionVisitor = (statemen const body: lua.Statement[] = transformLoopBody(context, statement); if (statement.incrementor) { - body.push(...context.transformStatements(ts.createExpressionStatement(statement.incrementor))); + body.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.incrementor))); } // while (condition) do ... end diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 8ee86f4ea..a7402b653 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -36,7 +36,7 @@ export function getVariableDeclarationBinding( checkVariableDeclarationList(context, node); if (node.declarations.length === 0) { - return ts.createIdentifier("____"); + return ts.factory.createIdentifier("____"); } return node.declarations[0].name; diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 0fa5d9ee4..955f56866 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -129,12 +129,15 @@ function transformExportSpecifiersFrom( exportSpecifiers: ts.ExportSpecifier[] ): lua.Statement { // First transpile as import clause - const importClause = ts.createImportClause( + const importClause = ts.factory.createImportClause( + false, undefined, - ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) + ts.factory.createNamedImports( + exportSpecifiers.map(s => ts.factory.createImportSpecifier(s.propertyName, s.name)) + ) ); - const importDeclaration = ts.createImportDeclaration( + const importDeclaration = ts.factory.createImportDeclaration( statement.decorators, statement.modifiers, importClause, @@ -142,7 +145,7 @@ function transformExportSpecifiersFrom( ); // Wrap in block to prevent imports from hoisting out of `do` statement - const [block] = transformScopeBlock(context, ts.createBlock([importDeclaration]), ScopeType.Block); + const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); const result = block.statements; // Now the module is imported, add the imports to the export table diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index 76b0e4941..5960c2200 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -25,7 +25,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } else if (ts.isPostfixUnaryExpression(expression)) { @@ -37,7 +37,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } @@ -50,7 +50,7 @@ export const transformPostfixUnaryExpression: FunctionVisitor = () => node => { const transformSourceFile: ts.Transformer = node => { - const empty = ts.createNotEmittedStatement(undefined!); + const empty = ts.factory.createNotEmittedStatement(undefined!); ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); - return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); + return ts.factory.updateSourceFile(node, [empty, ...node.statements], node.isDeclarationFile); }; return ts.isBundle(node) - ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) + ? ts.factory.updateBundle(node, node.sourceFiles.map(transformSourceFile)) : transformSourceFile(node); }; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index cb441ca2f..06ed05f75 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -158,6 +158,7 @@ describe("tsconfig", () => { }); test("should parse options case-sensitively", () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const result = parseConfigFileContent({ tstl: { NoHeader: true } }); expect(result.errors).toHaveDiagnostics(); diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index c998d6efc..a69829d5d 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -9,7 +9,7 @@ export const program = (program: ts.Program, options: { value: any }): ts.Transf export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(value)); + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); }); export const checker = ( @@ -20,13 +20,13 @@ export const checker = ( if (!ts.isReturnStatement(node) || !node.expression) return; const type = checker.getTypeAtLocation(node.expression); if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; - return ts.updateReturn(node, ts.createLiteral(value)); + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); }); export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); export const compilerOptions = ( @@ -35,6 +35,6 @@ export const compilerOptions = ( assert(options.plugins?.length === 1); return visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); }; diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts index e166198bd..02290d9d1 100644 --- a/test/transpile/transformers/transformers.spec.ts +++ b/test/transpile/transformers/transformers.spec.ts @@ -23,6 +23,7 @@ test("transformer resolution error", () => { .expectToHaveDiagnostics(); }); +// This tests plugin transformers by transforming the `return false` statement to a `return true` statement. describe("factory types", () => { test.each(["program", "config", "checker", "raw", "compilerOptions"] as const)("%s", type => { util.testFunction` diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 7d678496b..cd12b4ba8 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -10,7 +10,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function variable declaration (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} const fn: ${functionType} = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], @@ -23,7 +23,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function assignment (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: ${functionType}; fn = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( @@ -35,7 +35,7 @@ test.each(invalidTestFunctionAssignments)( test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: typeof ${testFunction.value}; fn = ${castedFunction}; `.expectDiagnosticsToMatchSnapshot( @@ -48,7 +48,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: ${functionType}); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -68,7 +68,7 @@ test("Invalid lua lib function argument", () => { test.each(invalidTestFunctionCasts)("Invalid function argument with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: typeof ${testFunction.value}); takesFunction(${castedFunction}); `.expectDiagnosticsToMatchSnapshot( @@ -81,7 +81,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function generic argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: T); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -95,7 +95,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function return (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): ${functionType} { return ${testFunction.value}; } @@ -110,7 +110,7 @@ test.each(invalidTestFunctionCasts)( "Invalid function return with cast (%p)", (testFunction, castedFunction, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): typeof ${testFunction.value} { return ${castedFunction}; } diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 9caefb300..144460067 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -107,9 +107,9 @@ test("Hoisting with synthetic source file node", () => { .setCustomTransformers({ before: [ () => sourceFile => - ts.updateSourceFileNode( + ts.factory.updateSourceFile( sourceFile, - [ts.createNotEmittedStatement(undefined!), ...sourceFile.statements], + [ts.factory.createNotEmittedStatement(undefined!), ...sourceFile.statements], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, From c09f98cd4ebcbc5bf07a662a11a7f771939dcac3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 25 Mar 2021 20:56:29 +0100 Subject: [PATCH 55/91] 0.39.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dbf1d54d..2c8f86ac9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 677789323..7a701c557 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "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/", From f3dea4271a4dae65cc2e4644ab44d2108a2094ce Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 2 Apr 2021 18:41:08 +0200 Subject: [PATCH 56/91] Use ts.getParseTreeNode before getSourceFile to handle transformer output (#1010) * Use getParseTreeNode before getSourceFile * npm audit fix --- package-lock.json | 29 +++++++++++--------- src/LuaAST.ts | 8 ++++-- src/transformation/utils/typescript/index.ts | 3 +- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c8f86ac9..72ffc8c45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1460,6 +1460,7 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -3567,7 +3568,8 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -6206,6 +6208,7 @@ "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-serializer": "^26.0.0", "jest-util": "^26.0.1", @@ -8762,9 +8765,9 @@ } }, "node_modules/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.memoize": { @@ -11549,9 +11552,9 @@ "dev": true }, "node_modules/y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "node_modules/yargs": { @@ -18795,9 +18798,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.memoize": { @@ -21039,9 +21042,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yargs": { diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 661500e4a..2f0d2e880 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -174,10 +174,12 @@ export function setNodeOriginal(node: T | undefined, tsOriginal: } function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { - if (sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { + const parseTreeNode = ts.getParseTreeNode(sourceNode) ?? sourceNode; + const sourceFile = parseTreeNode.getSourceFile(); + if (sourceFile !== undefined && parseTreeNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition( - sourceNode.getSourceFile(), - sourceNode.pos + sourceNode.getLeadingTriviaWidth() + sourceFile, + parseTreeNode.pos + parseTreeNode.getLeadingTriviaWidth() ); return { line, column: character }; diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 46b4992ea..6d7bfa68c 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -32,7 +32,8 @@ export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.Sour } function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { - const sourceFile = declaration.getSourceFile(); + const parseTreeNode = ts.getParseTreeNode(declaration) ?? declaration; + const sourceFile = parseTreeNode.getSourceFile(); if (!sourceFile) { return false; } From c0d7936598fef6b37ea6d1c9efcc8818b3eb1afb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 2 Apr 2021 19:01:46 +0200 Subject: [PATCH 57/91] 0.39.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72ffc8c45..683dd5035 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 7a701c557..790013fa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "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/", From d86ef928d9965fc4e9e79413f3b10a444ae7b113 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 28 Apr 2021 08:52:36 +0200 Subject: [PATCH 58/91] Fix missing stringaccess lualib dependency (#1015) --- src/LuaLib.ts | 2 +- test/unit/builtins/string.spec.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 06742022d..dc4501d86 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -106,7 +106,7 @@ const luaLibDependencies: Partial> = { WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], - StringSplit: [LuaLibFeature.StringSubstring], + StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], SymbolRegistry: [LuaLibFeature.Symbol], }; /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 5e1790573..c31ef012f 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -200,6 +200,13 @@ test("string.split inline", () => { .expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1009 +test("string.split inline empty separator", () => { + util.testExpression`"a, b, c".split("")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, From a617fafa1463a71e00874f7ca229b6cb657723d9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 28 Apr 2021 20:59:48 +0200 Subject: [PATCH 59/91] Fixed invalid switch statement lua when default was not the last case (#1016) * Made switch default case always last * Actually fixed switch statement this time * Added extra default fallthrough test --- src/transformation/visitors/switch.ts | 9 +- ...onals.spec.ts.snap => switch.spec.ts.snap} | 0 test/unit/conditionals.spec.ts | 297 -------------- test/unit/switch.spec.ts | 363 ++++++++++++++++++ 4 files changed, 369 insertions(+), 300 deletions(-) rename test/unit/__snapshots__/{conditionals.spec.ts.snap => switch.spec.ts.snap} (100%) create mode 100644 test/unit/switch.spec.ts diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 99ff3df7d..a82ff0bf0 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -18,10 +18,13 @@ export const transformSwitchStatement: FunctionVisitor = (st let statements: lua.Statement[] = []; - const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); - // Starting from the back, concatenating ifs into one big if/elseif statement - const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => { + const concatenatedIf = statement.caseBlock.clauses.reduceRight((previousCondition, clause, index) => { + if (ts.isDefaultClause(clause)) { + // Skip default clause here (needs to be included to ensure index lines up with index later) + return previousCondition; + } + // If the clause condition holds, go to the correct label const condition = lua.createBinaryExpression( switchVariable, diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap similarity index 100% rename from test/unit/__snapshots__/conditionals.spec.ts.snap rename to test/unit/__snapshots__/switch.spec.ts.snap diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 1df76d6a1..c9717d0c0 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,4 @@ import * as tstl from "../../src"; -import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each([0, 1])("if (%p)", inp => { @@ -52,302 +51,6 @@ test.each([0, 1, 2, 3])("ifelseifelse (%p)", inp => { `.expectToMatchJsResult(); }); -test.each([0, 1, 2, 3])("switch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - case 1: - result = 1; - break; - case 2: - result = 2; - case 3: - case 4: - result = 4; - break; - case 5: - result = 5; - case 6: - result += 10; - break; - case 7: - result = 7; - default: - result = -2; - break; - } - - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: - result = 0; - break; - case 1: - switch(${inp} as number) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - default: - result = -3; - break; - } - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch cases scope", () => { - util.testFunction` - switch (0 as number) { - case 0: - let foo: number | undefined = 1; - case 1: - foo = 2; - case 2: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("variable in nested scope does not interfere with case scope", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: { - let foo = 1; - } - - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("switch using variable re-declared in cases", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: - let foo = true; - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - let x = 0; - result = 0; - break; - } - case 1: { - let x = 1; - result = x; - } - case 2: { - let x = 2; - result = x; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { - util.testFunction` - switch (${inp}) { - case 0: - return 0; - break; - case 1: - return 1; - case 2: - return 2; - break; - } - - return -1; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - - if (result == 1) break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: { - result = 0; - - for (let i = 0; i < 5; i++) { - result++; - - if (i >= 2) { - break; - } - } - } - case 1: { - result++; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch uses elseif", () => { - test("array", () => { - util.testFunction` - let result: number = -1; - - switch (2 as number) { - case 0: { - result = 200; - break; - } - - case 1: { - result = 100; - break; - } - - case 2: { - result = 1; - break; - } - } - - return result; - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); -}); - -test("switch not allowed in 5.1", () => { - util.testFunction` - switch ("abc") {} - ` - .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); -}); - test.each([ { input: "true ? 'a' : 'b'" }, { input: "false ? 'a' : 'b'" }, diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts new file mode 100644 index 000000000..dd3e2a09c --- /dev/null +++ b/test/unit/switch.spec.ts @@ -0,0 +1,363 @@ +import * as tstl from "../../src"; +import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test.each([0, 1, 2, 3])("switch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + case 1: + result = 1; + break; + case 2: + result = 2; + case 3: + case 4: + result = 4; + break; + case 5: + result = 5; + case 6: + result += 10; + break; + case 7: + result = 7; + default: + result = -2; + break; + } + + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: + result = 0; + break; + case 1: + switch(${inp} as number) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + default: + result = -3; + break; + } + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch cases scope", () => { + util.testFunction` + switch (0 as number) { + case 0: + let foo: number | undefined = 1; + case 1: + foo = 2; + case 2: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("variable in nested scope does not interfere with case scope", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: { + let foo = 1; + } + + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("switch using variable re-declared in cases", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: + let foo = true; + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + let x = 0; + result = 0; + break; + } + case 1: { + let x = 1; + result = x; + } + case 2: { + let x = 2; + result = x; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { + util.testFunction` + switch (${inp}) { + case 0: + return 0; + break; + case 1: + return 1; + case 2: + return 2; + break; + } + + return -1; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + + if (result == 1) break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: { + result = 0; + + for (let i = 0; i < 5; i++) { + result++; + + if (i >= 2) { + break; + } + } + } + case 1: { + result++; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch uses elseif", () => { + test("array", () => { + util.testFunction` + let result: number = -1; + + switch (2 as number) { + case 0: { + result = 200; + break; + } + + case 1: { + result = 100; + break; + } + + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); +}); + +test("switch not allowed in 5.1", () => { + util.testFunction` + switch ("abc") {} + ` + .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/967 +test("switch default case not last - first", () => { + util.testFunction` + switch (3 as number) { + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch default case not last - second", () => { + util.testFunction` + switch (3 as number) { + case 4: + return "also wrong"; + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch fallthrough enters default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + case 3: + out.push("3"); + default: + out.push("default"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough does not enter earlier default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough stops after default", () => { + util.testFunction` + const out = []; + switch (4 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); From b26dac0469ba30c07557722ea6fb8487e022f1b3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 3 May 2021 21:57:50 +0200 Subject: [PATCH 60/91] Fix namespace and module resulting in invalid Lua when modified with TS transformer plugin (#1014) * Failing test * Fixed bug #1013 * Fix prettier * Switched transformer plugin to TS instead of JS --- src/transformation/visitors/namespace.ts | 2 +- test/transpile/plugins/plugins.spec.ts | 20 ++++++++++++++++++++ test/transpile/plugins/transformer-plugin.ts | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/transpile/plugins/transformer-plugin.ts diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 0244ac21c..7ee32adac 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -76,7 +76,7 @@ export const transformModuleDeclaration: FunctionVisitor = const isFirstDeclaration = symbol === undefined || (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && - node === symbol.declarations.find(ts.isModuleDeclaration)); + ts.getOriginalNode(node) === symbol.declarations.find(ts.isModuleDeclaration)); if (isNonModuleMergeable) { // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 46988dae0..eaaee3dca 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -40,3 +40,23 @@ test("statement comments", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "add-comments.ts") }] }) .expectLuaToMatchSnapshot(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1013 +test.each(["namespace", "module"])("%s with TS transformer plugin", moduleOrNamespace => { + util.testModule` + import { ns } from "module"; + export const result = ns.returnsBool(); + ` + .addExtraFile( + "module.ts", + ` + export ${moduleOrNamespace} ns { + export function returnsBool() { + return false; + } + } + ` + ) + .setOptions({ plugins: [{ transform: path.join(__dirname, "transformer-plugin.ts") }] }) + .expectNoExecutionError(); +}); diff --git a/test/transpile/plugins/transformer-plugin.ts b/test/transpile/plugins/transformer-plugin.ts new file mode 100644 index 000000000..8b338723c --- /dev/null +++ b/test/transpile/plugins/transformer-plugin.ts @@ -0,0 +1,15 @@ +/** + * This is a TS tranformer plugin that replaces any return statement to 'return true'. + */ +import * as ts from "typescript"; + +const replaceNode = (node: ts.Node) => { + if (ts.isReturnStatement(node)) { + return ts.factory.createReturnStatement(ts.factory.createTrue()); + } +}; +const createTransformer = () => (context: ts.TransformationContext) => { + const visit = (node: ts.Node): ts.Node => replaceNode(node) ?? ts.visitEachChild(node, visit, context); + return (file: ts.SourceFile) => ts.visitNode(file, visit); +}; +exports.default = createTransformer; From 9ac496c24e9c5ca1d9531c95e6f3c40a61ff7ec3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 3 May 2021 22:05:37 +0200 Subject: [PATCH 61/91] 0.39.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 683dd5035..3f1cbb4f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 790013fa5..5cce58d65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "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/", From 2ff677ce9263c2f2e43d9fd44cc49d85388c0cb9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 21 May 2021 15:50:17 +0200 Subject: [PATCH 62/91] deduped and audited package-lock (#1022) --- package-lock.json | 7344 +++++++++++++++++++++------------------------ 1 file changed, 3482 insertions(+), 3862 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f1cbb4f4..a4be60bc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,12 +42,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.12.13" } }, "node_modules/@babel/core": { @@ -77,80 +77,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/core/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "node_modules/@babel/core/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/core/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "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", @@ -161,14 +87,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" } }, @@ -182,23 +107,23 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.14.2" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-member-expression-to-functions": { @@ -234,40 +159,6 @@ "lodash": "^4.17.13" } }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", @@ -295,78 +186,6 @@ "@babel/types": "^7.9.6" } }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/helper-simple-access": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", @@ -378,18 +197,18 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "node_modules/@babel/helpers": { @@ -403,86 +222,14 @@ "@babel/types": "^7.9.6" } }, - "node_modules/@babel/helpers/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@babel/helpers/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, @@ -549,9 +296,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -651,41 +398,39 @@ } }, "node_modules/@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "node_modules/@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" } }, "node_modules/@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "dependencies": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, @@ -752,21 +497,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/core": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", @@ -806,15 +536,16 @@ } }, "node_modules/@jest/core/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -822,13 +553,13 @@ } }, "node_modules/@jest/core/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -837,13 +568,14 @@ } }, "node_modules/@jest/core/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -851,16 +583,31 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/core/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@jest/core/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/@jest/core/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -868,12 +615,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/core/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -889,79 +639,74 @@ } }, "node_modules/@jest/core/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/core/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -979,18 +724,18 @@ } }, "node_modules/@jest/core/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -998,25 +743,26 @@ } }, "node_modules/@jest/core/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -1024,51 +770,61 @@ } }, "node_modules/@jest/core/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/core/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -1107,20 +863,14 @@ "node": ">=8" } }, - "node_modules/@jest/core/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/@jest/core/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -1129,9 +879,9 @@ } }, "node_modules/@jest/core/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1154,21 +904,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/fake-timers": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", @@ -1185,21 +920,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/globals": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", @@ -1215,43 +935,46 @@ } }, "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1259,10 +982,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/globals/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1270,12 +1008,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/globals/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -1291,79 +1032,74 @@ } }, "node_modules/@jest/globals/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1372,12 +1108,13 @@ } }, "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -1393,40 +1130,47 @@ } }, "node_modules/@jest/globals/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/@jest/globals/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/globals/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1460,7 +1204,6 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -1475,15 +1218,16 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -1491,13 +1235,13 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1506,13 +1250,14 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1520,10 +1265,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/reporters/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1531,6 +1291,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/escape-string-regexp": { @@ -1542,24 +1305,19 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/reporters/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1568,18 +1326,18 @@ } }, "node_modules/@jest/reporters/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -1587,36 +1345,61 @@ } }, "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/reporters/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jest/reporters/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" } }, + "node_modules/@jest/reporters/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/reporters/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -1655,15 +1438,6 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "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", @@ -1674,9 +1448,9 @@ } }, "node_modules/@jest/reporters/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1699,12 +1473,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/source-map/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "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", @@ -1729,21 +1497,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/test-sequencer": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", @@ -1761,15 +1514,16 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -1777,13 +1531,13 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1792,13 +1546,14 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1806,10 +1561,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/test-sequencer/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/test-sequencer/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1817,6 +1587,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/test-sequencer/node_modules/escape-string-regexp": { @@ -1828,24 +1601,19 @@ "node": ">=8" } }, - "node_modules/@jest/test-sequencer/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1854,25 +1622,47 @@ } }, "node_modules/@jest/test-sequencer/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/@jest/test-sequencer/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@jest/test-sequencer/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/test-sequencer/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1908,13 +1698,14 @@ } }, "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1922,10 +1713,19 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1933,14 +1733,11 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/transform/node_modules/jest-regex-util": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", @@ -1951,16 +1748,17 @@ } }, "node_modules/@jest/transform/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" @@ -1976,9 +1774,9 @@ } }, "node_modules/@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2084,12 +1882,6 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -2141,9 +1933,9 @@ } }, "node_modules/@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*", @@ -2151,13 +1943,13 @@ } }, "node_modules/@types/jest": { - "version": "25.1.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", - "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "dependencies": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, "node_modules/@types/json-schema": { @@ -2235,7 +2027,7 @@ "node": "^8.10.0 || ^10.13.0 || >=11.10.1" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "node_modules/@typescript-eslint/experimental-utils": { "version": "2.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", @@ -2248,59 +2040,28 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/experimental-utils": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", - "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.23.0", - "eslint-scope": "^5.0.0" }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/@typescript-eslint/parser": { @@ -2338,10 +2099,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -2372,9 +2136,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", - "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -2387,6 +2151,15 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { @@ -2398,18 +2171,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", @@ -2424,9 +2185,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "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" @@ -2439,9 +2200,9 @@ "dev": true }, "node_modules/acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2509,22 +2270,24 @@ } }, "node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -2716,13 +2479,14 @@ } }, "node_modules/babel-jest/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -2730,10 +2494,19 @@ "node": ">= 10.14.2" } }, + "node_modules/babel-jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/babel-jest/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -2741,14 +2514,11 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/babel-jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -3280,12 +3050,20 @@ } }, "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -3418,9 +3196,9 @@ } }, "node_modules/diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true, "engines": { "node": ">= 8.3" @@ -3568,8 +3346,7 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -3864,9 +3641,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { "node": ">=4" @@ -3999,18 +3776,6 @@ "node": ">=6.0.0" } }, - "node_modules/espree/node_modules/acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -4173,84 +3938,6 @@ "node": ">= 8.3" } }, - "node_modules/expect/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4578,12 +4265,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/fs-extra/node_modules/graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4606,8 +4287,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -4737,9 +4417,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "node_modules/growly": { @@ -4775,7 +4455,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -4865,9 +4544,9 @@ } }, "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/html-encoding-sniffer": { @@ -5086,6 +4765,17 @@ "is-ci": "bin.js" } }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -5451,13 +5141,14 @@ } }, "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5465,10 +5156,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-changed-files/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5476,6 +5176,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-changed-files/node_modules/cross-spawn": { @@ -5493,9 +5196,9 @@ } }, "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -5510,18 +5213,24 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-changed-files/node_modules/is-stream": { @@ -5647,13 +5356,14 @@ } }, "node_modules/jest-config/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5661,10 +5371,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-config/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-config/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5672,18 +5391,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-config/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-config/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -5699,18 +5415,18 @@ } }, "node_modules/jest-config/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -5718,51 +5434,61 @@ } }, "node_modules/jest-config/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-config/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-config/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-config/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -5801,25 +5527,16 @@ "node": ">=8" } }, - "node_modules/jest-config/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "dependencies": { "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { "node": ">= 8.3" @@ -5853,45 +5570,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-each/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-environment-jsdom": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", @@ -5910,43 +5588,46 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5954,10 +5635,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5965,6 +5661,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { @@ -5976,24 +5675,19 @@ "node": ">=8" } }, - "node_modules/jest-environment-jsdom/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6002,37 +5696,60 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-environment-jsdom/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-environment-jsdom/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6058,43 +5775,46 @@ } }, "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6102,10 +5822,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-node/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6113,6 +5848,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-environment-node/node_modules/escape-string-regexp": { @@ -6124,24 +5862,19 @@ "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6150,37 +5883,60 @@ } }, "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-environment-node/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-environment-node/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-environment-node/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6190,33 +5946,33 @@ } }, "node_modules/jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true, "engines": { "node": ">= 8.3" } }, "node_modules/jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "engines": { "node": ">= 10.14.2" @@ -6226,13 +5982,14 @@ } }, "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6240,10 +5997,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6251,45 +6017,37 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-haste-map/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "node_modules/jest-haste-map/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } }, "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-haste-map/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/jest-jasmine2": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", @@ -6319,15 +6077,16 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -6335,43 +6094,45 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -6380,13 +6141,14 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6394,16 +6156,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-jasmine2/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6411,12 +6188,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-jasmine2/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -6432,95 +6212,90 @@ } }, "node_modules/jest-jasmine2/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-jasmine2/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-jasmine2/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6529,12 +6304,13 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -6550,18 +6326,18 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -6569,25 +6345,26 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -6595,51 +6372,61 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-jasmine2/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -6667,6 +6454,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-jasmine2/node_modules/read-pkg/node_modules/type-fest": { @@ -6678,20 +6468,14 @@ "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-jasmine2/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -6700,9 +6484,9 @@ } }, "node_modules/jest-jasmine2/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6725,13 +6509,14 @@ } }, "node_modules/jest-leak-detector/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6739,10 +6524,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-leak-detector/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6750,42 +6544,51 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", "dev": true, "dependencies": { "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { "node": ">= 8.3" @@ -6810,61 +6613,33 @@ "node": ">= 8.3" } }, - "node_modules/jest-message-util/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-message-util/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-mock": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@jest/types": "^25.5.0" }, "engines": { "node": ">= 8.3" } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true, "engines": { "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, "node_modules/jest-regex-util": { @@ -6911,13 +6686,14 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6925,16 +6701,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-resolve-dependencies/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-resolve-dependencies/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6942,12 +6733,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-resolve-dependencies/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -6963,79 +6757,74 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7053,18 +6842,18 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7072,25 +6861,26 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -7098,51 +6888,61 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-resolve-dependencies/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-resolve-dependencies/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7170,6 +6970,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve-dependencies/node_modules/read-pkg/node_modules/type-fest": { @@ -7181,20 +6984,14 @@ "node": ">=8" } }, - "node_modules/jest-resolve-dependencies/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-resolve-dependencies/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -7203,9 +7000,9 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7214,40 +7011,22 @@ "node": ">=10" } }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-resolve/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-resolve/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve/node_modules/read-pkg": { @@ -7288,15 +7067,6 @@ "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runner": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", @@ -7328,15 +7098,16 @@ } }, "node_modules/jest-runner/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -7344,43 +7115,45 @@ } }, "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -7389,13 +7162,14 @@ } }, "node_modules/jest-runner/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -7403,10 +7177,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-runner/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-runner/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-runner/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7414,6 +7203,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runner/node_modules/escape-string-regexp": { @@ -7425,24 +7217,19 @@ "node": ">=8" } }, - "node_modules/jest-runner/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7451,30 +7238,31 @@ } }, "node_modules/jest-runner/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7482,36 +7270,61 @@ } }, "node_modules/jest-runner/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" } }, + "node_modules/jest-runner/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-runner/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7550,19 +7363,10 @@ "node": ">=8" } }, - "node_modules/jest-runner/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runner/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7612,15 +7416,16 @@ } }, "node_modules/jest-runtime/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -7628,43 +7433,45 @@ } }, "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -7673,13 +7480,14 @@ } }, "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -7687,16 +7495,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-runtime/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7704,12 +7527,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runtime/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -7725,79 +7551,74 @@ } }, "node_modules/jest-runtime/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-runtime/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7806,12 +7627,13 @@ } }, "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -7827,18 +7649,18 @@ } }, "node_modules/jest-runtime/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7846,25 +7668,26 @@ } }, "node_modules/jest-runtime/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -7872,51 +7695,61 @@ } }, "node_modules/jest-runtime/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-runtime/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-runtime/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-runtime/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7955,20 +7788,14 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runtime/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -7977,9 +7804,9 @@ } }, "node_modules/jest-runtime/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7989,23 +7816,18 @@ } }, "node_modules/jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "dependencies": { + "@types/node": "*", "graceful-fs": "^4.2.4" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-serializer/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-snapshot": { "version": "25.5.1", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", @@ -8032,90 +7854,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-snapshot/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8141,27 +7879,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-util/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-util/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-validate": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", @@ -8180,13 +7897,14 @@ } }, "node_modules/jest-validate/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8194,19 +7912,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-validate/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-validate/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8214,32 +7944,41 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-watcher": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", @@ -8258,15 +7997,16 @@ } }, "node_modules/jest-watcher/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -8274,13 +8014,13 @@ } }, "node_modules/jest-watcher/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -8289,13 +8029,14 @@ } }, "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8303,10 +8044,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-watcher/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8314,6 +8070,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-watcher/node_modules/escape-string-regexp": { @@ -8325,24 +8084,19 @@ "node": ">=8" } }, - "node_modules/jest-watcher/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-watcher/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -8351,25 +8105,47 @@ } }, "node_modules/jest-watcher/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-watcher/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-watcher/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-watcher/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -8379,28 +8155,30 @@ } }, "node_modules/jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "dependencies": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10.13.0" } }, "node_modules/jest/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -8408,13 +8186,13 @@ } }, "node_modules/jest/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -8423,13 +8201,14 @@ } }, "node_modules/jest/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8437,10 +8216,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8448,6 +8242,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest/node_modules/escape-string-regexp": { @@ -8459,12 +8256,6 @@ "node": ">=8" } }, - "node_modules/jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest/node_modules/jest-cli": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", @@ -8493,17 +8284,18 @@ } }, "node_modules/jest/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -8512,25 +8304,47 @@ } }, "node_modules/jest/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -8613,10 +8427,10 @@ "node": ">=4" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "node_modules/json-schema": { @@ -8788,7 +8602,19 @@ "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/lua-types": { @@ -8876,16 +8702,16 @@ } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/mime-db": { @@ -9050,11 +8876,14 @@ } }, "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -9299,15 +9128,18 @@ } }, "node_modules/p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -9421,12 +9253,15 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true, "engines": { "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pify": { @@ -9493,12 +9328,12 @@ } }, "node_modules/pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "dependencies": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -9564,9 +9399,9 @@ } }, "node_modules/react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "node_modules/read-pkg": { @@ -9826,11 +9661,15 @@ "dev": true }, "node_modules/resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dependencies": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-cwd": { @@ -10554,12 +10393,24 @@ } }, "node_modules/stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/static-extend": { @@ -10610,9 +10461,9 @@ } }, "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", @@ -10698,9 +10549,9 @@ } }, "node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" @@ -10968,122 +10819,104 @@ } }, "node_modules/ts-jest/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/@types/jest": { - "version": "26.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", - "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "node_modules/ts-jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "dependencies": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "@types/istanbul-lib-report": "*" } }, - "node_modules/ts-jest/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "node_modules/ts-jest/node_modules/@types/jest": { + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, - "engines": { - "node": ">= 8.3" + "dependencies": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" } }, - "node_modules/ts-jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/ts-jest/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "node_modules/ts-jest/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 8.3" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ts-jest/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "node_modules/ts-jest/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", - "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "node_modules/ts-jest/node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { - "@jest/types": "^26.3.0", - "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/@jest/types": { + "node_modules/ts-jest/node_modules/jest-get-type": { "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/ts-jest/node_modules/jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=10" + "node": ">= 10.14.2" } }, "node_modules/ts-jest/node_modules/mkdirp": { @@ -11099,25 +10932,34 @@ } }, "node_modules/ts-jest/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" + "node": ">= 10" } }, + "node_modules/ts-jest/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -11152,15 +10994,18 @@ "dev": true }, "node_modules/tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "dependencies": { "tslib": "^1.8.1" }, "engines": { "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, "node_modules/tunnel-agent": { @@ -11557,6 +11402,12 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", @@ -11604,12 +11455,12 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.12.13" } }, "@babel/core": { @@ -11636,74 +11487,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -11713,14 +11496,13 @@ } }, "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", "dev": true, "requires": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { @@ -11733,23 +11515,23 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.14.2" } }, "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { @@ -11783,36 +11565,6 @@ "@babel/template": "^7.8.6", "@babel/types": "^7.9.0", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-optimise-call-expression": { @@ -11840,71 +11592,6 @@ "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" - }, - "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-simple-access": { @@ -11918,18 +11605,18 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "@babel/helpers": { @@ -11941,81 +11628,16 @@ "@babel/template": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" - }, - "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -12072,9 +11694,9 @@ } }, "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -12168,41 +11790,39 @@ } }, "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, @@ -12252,20 +11872,6 @@ "jest-message-util": "^25.5.0", "jest-util": "^25.5.0", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/core": { @@ -12304,52 +11910,69 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12357,9 +11980,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -12369,67 +11992,62 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } @@ -12441,81 +12059,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -12547,25 +12173,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12582,20 +12202,6 @@ "@jest/fake-timers": "^25.5.0", "@jest/types": "^25.5.0", "jest-mock": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/fake-timers": { @@ -12609,20 +12215,6 @@ "jest-mock": "^25.5.0", "jest-util": "^25.5.0", "lolex": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/globals": { @@ -12637,45 +12229,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12683,9 +12293,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -12695,78 +12305,74 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -12776,34 +12382,41 @@ "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12845,46 +12458,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12897,69 +12527,83 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -12991,15 +12635,6 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -13007,9 +12642,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -13028,12 +12663,6 @@ "source-map": "^0.6.0" }, "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -13052,20 +12681,6 @@ "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/test-sequencer": { @@ -13082,46 +12697,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13134,45 +12766,59 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -13204,33 +12850,37 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-regex-util": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", @@ -13238,16 +12888,17 @@ "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "source-map": { @@ -13259,9 +12910,9 @@ } }, "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13355,12 +13006,6 @@ "@babel/types": "^7.3.0" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -13412,9 +13057,9 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*", @@ -13422,13 +13067,13 @@ } }, "@types/jest": { - "version": "25.1.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", - "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "requires": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, "@types/json-schema": { @@ -13495,67 +13140,35 @@ "version": "2.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "2.31.0", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - } - }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.31.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" } }, "@typescript-eslint/experimental-utils": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", - "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.23.0", - "eslint-scope": "^5.0.0" + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } } }, "@typescript-eslint/parser": { @@ -13587,10 +13200,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -13611,9 +13227,9 @@ "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", - "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", "dev": true, "requires": { "debug": "^4.1.1", @@ -13630,15 +13246,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } } } }, @@ -13653,9 +13260,9 @@ }, "dependencies": { "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "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 } } @@ -13667,9 +13274,9 @@ "dev": true }, "acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-globals": { @@ -13722,19 +13329,18 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -13883,32 +13489,36 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true } } }, @@ -14363,12 +13973,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -14470,9 +14080,9 @@ "dev": true }, "diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true }, "dir-glob": { @@ -14931,9 +14541,9 @@ } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { @@ -14945,14 +14555,6 @@ "acorn": "^7.1.1", "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true - } } }, "esprima": { @@ -15080,68 +14682,6 @@ "jest-matcher-utils": "^25.5.0", "jest-message-util": "^25.5.0", "jest-regex-util": "^25.2.6" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - } } }, "extend": { @@ -15409,14 +14949,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - } } }, "fs.realpath": { @@ -15435,8 +14967,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -15538,9 +15069,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "growly": { @@ -15570,7 +15101,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -15640,9 +15170,9 @@ } }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { @@ -15816,6 +15346,14 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -16088,46 +15626,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16140,12 +15695,6 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-cli": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", @@ -16168,38 +15717,58 @@ } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16219,21 +15788,31 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16252,9 +15831,9 @@ } }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -16269,9 +15848,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -16375,37 +15954,41 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-regex-util": { @@ -16415,58 +15998,65 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -16497,28 +16087,19 @@ "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, "jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "requires": { "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, "jest-docblock": { @@ -16541,38 +16122,6 @@ "jest-get-type": "^25.2.6", "jest-util": "^25.5.0", "pretty-format": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - } } }, "jest-environment-jsdom": { @@ -16590,45 +16139,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16641,54 +16208,69 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16710,45 +16292,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@types/istanbul-lib-report": "*" } }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16761,54 +16361,69 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16817,80 +16432,83 @@ } }, "jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true }, "jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "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" + "micromatch": "^4.0.2" } } } @@ -16921,76 +16539,95 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16998,9 +16635,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -17010,91 +16647,87 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -17104,81 +16737,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17210,25 +16851,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17247,21 +16882,31 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17269,35 +16914,41 @@ } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, "jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", "dev": true, "requires": { "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, "jest-message-util": { @@ -17314,26 +16965,6 @@ "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-mock": { @@ -17343,27 +16974,14 @@ "dev": true, "requires": { "@jest/types": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", - "dev": true + "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": "25.2.6", @@ -17388,33 +17006,15 @@ "slash": "^3.0.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -17448,15 +17048,6 @@ "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, @@ -17472,27 +17063,43 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17500,9 +17107,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -17512,67 +17119,62 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } @@ -17584,81 +17186,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17690,25 +17300,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17744,70 +17348,89 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17820,78 +17443,93 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17923,19 +17561,10 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17978,76 +17607,95 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18055,9 +17703,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -18067,78 +17715,74 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -18148,81 +17792,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -18254,25 +17906,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -18281,20 +17927,13 @@ } }, "jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { @@ -18320,72 +17959,6 @@ "semver": "^6.3.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -18405,26 +17978,6 @@ "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-validate": { @@ -18442,27 +17995,37 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18470,22 +18033,28 @@ } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, @@ -18504,46 +18073,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18556,45 +18142,59 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -18603,11 +18203,12 @@ } }, "jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } @@ -18674,10 +18275,10 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { @@ -18824,6 +18425,15 @@ "@sinonjs/commons": "^1.7.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "lua-types": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", @@ -18896,13 +18506,13 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime-db": { @@ -19042,11 +18652,14 @@ }, "dependencies": { "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, - "optional": true + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "which": { "version": "2.0.2", @@ -19235,9 +18848,9 @@ "dev": true }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "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" @@ -19327,9 +18940,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, "pify": { @@ -19375,12 +18988,12 @@ "dev": true }, "pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -19431,9 +19044,9 @@ "dev": true }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "read-pkg": { @@ -19639,10 +19252,11 @@ "dev": true }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -20246,10 +19860,21 @@ } }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } }, "static-extend": { "version": "0.1.2", @@ -20289,9 +19914,9 @@ } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -20353,9 +19978,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -20570,103 +20195,83 @@ }, "dependencies": { "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" } }, "@types/jest": { - "version": "26.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", - "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" } }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", - "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "micromatch": "^4.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "mkdirp": { @@ -20676,22 +20281,31 @@ "dev": true }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -20715,9 +20329,9 @@ "dev": true }, "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -21047,6 +20661,12 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "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": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", From 1945d93d2150c39cd67b87c0a5437024cb6e2d5d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 10 Jun 2021 17:42:37 +0200 Subject: [PATCH 63/91] Update TS and ESLint (#1027) * Upgrade to TS 4.3 * Upgrade eslint * npm audit fix * Fixed build issue * Fixed issue with benchmark json type --- .eslintrc.js | 153 +- benchmark/src/memory_benchmark.ts | 2 +- .../src/memory_benchmarks/graph_cylce.ts | 2 +- benchmark/src/util.ts | 2 +- language-extensions/index.d.ts | 22 +- package-lock.json | 2312 +++++++++-------- package.json | 8 +- src/LuaAST.ts | 2 +- src/LuaPrinter.ts | 2 +- src/cli/tsconfig.ts | 4 +- src/lualib/ArrayToObject.ts | 2 +- src/lualib/Decorate.ts | 13 +- src/lualib/DecorateParam.ts | 13 +- src/lualib/Error.ts | 2 +- src/lualib/ObjectAssign.ts | 1 + src/lualib/ObjectDefineProperty.ts | 2 +- src/lualib/WeakMap.ts | 2 +- src/lualib/WeakSet.ts | 2 +- src/lualib/declarations/debug.d.ts | 2 +- src/lualib/declarations/global.d.ts | 8 +- src/lualib/declarations/luatable.d.ts | 2 +- src/transformation/utils/annotations.ts | 18 +- src/transformation/utils/export.ts | 2 +- .../utils/language-extensions.ts | 2 +- src/transformation/utils/safe-names.ts | 2 +- src/transformation/utils/scope.ts | 2 +- src/transformation/visitors/call.ts | 6 +- src/transformation/visitors/namespace.ts | 4 +- src/utils.ts | 1 + test/setup.ts | 2 +- 30 files changed, 1416 insertions(+), 1181 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index dabc1db41..52df969ff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,70 +1,3 @@ -// https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js -const typescriptBase = { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "error", - { - types: { - Function: null, - CallableFunction: { fixWith: "(...args: any[]) => any" }, - NewableFunction: { fixWith: "new (...args: any[]) => any" }, - }, - }, - ], - camelcase: "off", - "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], - "@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/consistent-type-assertions": [ - "error", - { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, - ], - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/explicit-member-accessibility": ["error", { overrides: { constructors: "no-public" } }], - "@typescript-eslint/generic-type-naming": ["error", "^(T([A-Z][A-Za-z]*)?|U|P|K|V)$"], - "@typescript-eslint/interface-name-prefix": "error", - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-extra-non-null-assertion": "error", - "@typescript-eslint/no-extraneous-class": "error", - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-misused-promises": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-require-imports": "error", - "@typescript-eslint/no-this-alias": "error", - "no-throw-literal": "off", - "@typescript-eslint/no-throw-literal": "error", - "no-constant-condition": "off", - "@typescript-eslint/no-unnecessary-condition": ["error", { ignoreRhs: true, allowConstantLoopConditions: true }], - "@typescript-eslint/no-unnecessary-qualifier": "error", - "@typescript-eslint/no-unnecessary-type-arguments": "error", - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": "error", - "@typescript-eslint/prefer-function-type": "error", - "@typescript-eslint/prefer-includes": "error", - "@typescript-eslint/prefer-optional-chain": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/prefer-readonly": "error", - "@typescript-eslint/prefer-string-starts-ends-with": "error", - "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], - quotes: "off", - "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], - "@typescript-eslint/require-array-sort-compare": "error", - "@typescript-eslint/require-await": "error", - "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], - "@typescript-eslint/return-await": "error", - "@typescript-eslint/triple-slash-reference": "error", - "@typescript-eslint/unified-signatures": "error", -}; - module.exports = { extends: ["plugin:jest/recommended", "plugin:jest/style"], parserOptions: { @@ -149,7 +82,74 @@ module.exports = { files: "**/*.ts", extends: ["plugin:@typescript-eslint/base"], rules: { - ...typescriptBase, + // https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-types": [ + "error", + { + types: { + Function: null, + CallableFunction: { fixWith: "(...args: any[]) => any" }, + NewableFunction: { fixWith: "new (...args: any[]) => any" }, + }, + }, + ], + camelcase: "off", + "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], + "@typescript-eslint/consistent-type-assertions": [ + "error", + { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, + ], + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { overrides: { constructors: "no-public" } }, + ], + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "error", + "no-throw-literal": "off", + "@typescript-eslint/no-throw-literal": "error", + "no-constant-condition": "off", + "@typescript-eslint/no-unnecessary-condition": [ + "error", + { ignoreRhs: true, allowConstantLoopConditions: true }, + ], + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-readonly": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + quotes: "off", + "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], + "@typescript-eslint/require-array-sort-compare": "error", + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", + // end of https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js "@typescript-eslint/array-type": ["error", { default: "array-simple" }], "@typescript-eslint/ban-types": ["error", { types: { null: null } }], "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], @@ -182,6 +182,23 @@ module.exports = { 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, + }, + }, ], }, }, diff --git a/benchmark/src/memory_benchmark.ts b/benchmark/src/memory_benchmark.ts index 10934757a..51f8031be 100644 --- a/benchmark/src/memory_benchmark.ts +++ b/benchmark/src/memory_benchmark.ts @@ -1,7 +1,7 @@ import { BenchmarkKind, MemoryBenchmarkResult, ComparisonInfo, MemoryBenchmarkCategory } from "./benchmark_types"; import { toFixed, json, calculatePercentageChange } from "./util"; -export function runMemoryBenchmark(benchmarkFunction: Function): MemoryBenchmarkResult { +export function runMemoryBenchmark(benchmarkFunction: () => void): MemoryBenchmarkResult { const result: MemoryBenchmarkResult = { kind: BenchmarkKind.Memory, benchmarkName: "NO_NAME", diff --git a/benchmark/src/memory_benchmarks/graph_cylce.ts b/benchmark/src/memory_benchmarks/graph_cylce.ts index c78812dc5..c75372d07 100644 --- a/benchmark/src/memory_benchmarks/graph_cylce.ts +++ b/benchmark/src/memory_benchmarks/graph_cylce.ts @@ -1,4 +1,4 @@ -type Graph = Map; +type Graph = Map; function range(start: number, end: number): number[] { if (start > end) return []; diff --git a/benchmark/src/util.ts b/benchmark/src/util.ts index d1c9fcc1d..bd1c0a10f 100644 --- a/benchmark/src/util.ts +++ b/benchmark/src/util.ts @@ -12,7 +12,7 @@ export function calculatePercentageChange(oldValue: number, newValue: number): n export const isWindows = package.config.startsWith("\\"); export const json: { - decode: (this: void, str: string) => {}; + decode: (this: void, str: string) => Record | unknown[]; encode: (this: void, val: any) => string; } = require("json"); diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index ad3692a97..761d6a68e 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,3 +1,7 @@ +type AnyTable = Record; +// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/consistent-type-definitions +type AnyNotNil = {}; + /** * Indicates a type is a language extension provided by TypescriptToLua. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -445,7 +449,10 @@ declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLen * @param TKey The type of the key to use to access the table. * @param TValue The type of the value stored in the table. */ -declare type LuaTableGet = ((table: TTable, key: TKey) => TValue) & +declare type LuaTableGet = (( + table: TTable, + key: TKey +) => TValue) & LuaExtension<"__luaTableGetBrand">; /** @@ -455,7 +462,7 @@ declare type LuaTableGet = ((tab * @param TKey The type of the key to use to access the table. * @param TValue The type of the value stored in the table. */ -declare type LuaTableGetMethod = ((key: TKey) => TValue) & +declare type LuaTableGetMethod = ((key: TKey) => TValue) & LuaExtension<"__luaTableGetMethodBrand">; /** @@ -466,7 +473,7 @@ declare type LuaTableGetMethod = ((key: TKey) => TValue * @param TKey The type of the key to use to access the table. * @param TValue The type of the value to assign to the table. */ -declare type LuaTableSet = (( +declare type LuaTableSet = (( table: TTable, key: TKey, value: TValue @@ -480,7 +487,7 @@ declare type LuaTableSet = (( * @param TKey The type of the key to use to access the table. * @param TValue The type of the value to assign to the table. */ -declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; /** @@ -490,7 +497,7 @@ declare type LuaTableSetMethod = ((key: TKey, value: TV * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare interface LuaTable { +declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; @@ -503,7 +510,10 @@ declare interface LuaTable { * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare type LuaTableConstructor = (new () => LuaTable) & +declare type LuaTableConstructor = (new () => LuaTable< + TKey, + TValue +>) & LuaExtension<"__luaTableNewBrand">; /** diff --git a/package-lock.json b/package-lock.json index a4be60bc2..93b27be93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": ">=4.0.2" + "typescript": "~4.3.2" }, "bin": { "tstl": "dist/tstl.js" @@ -22,9 +22,9 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^4.1.0", - "eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", "fs-extra": "^8.1.0", @@ -456,6 +456,69 @@ "node": ">=0.1.95" } }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -584,9 +647,9 @@ } }, "node_modules/@jest/core/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -983,9 +1046,9 @@ } }, "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1266,9 +1329,9 @@ } }, "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1562,9 +1625,9 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1714,9 +1777,9 @@ } }, "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1789,12 +1852,12 @@ } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -1802,21 +1865,21 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -1953,9 +2016,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "node_modules/@types/minimatch": { @@ -2013,18 +2076,128 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", - "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", + "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/experimental-utils": "4.26.1", + "@typescript-eslint/scope-manager": "4.26.1", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" + "lodash": "^4.17.21", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", + "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/experimental-utils": { @@ -2049,53 +2222,58 @@ "eslint": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/@typescript-eslint/parser": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", + "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "debug": "^4.3.1" }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", - "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", - "debug": "^4.1.1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", - "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/parser/node_modules/semver": { @@ -2114,25 +2292,33 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", - "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", + "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0" + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", - "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", + "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { @@ -2172,16 +2358,20 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", - "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", + "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/types": "4.26.1", "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { @@ -2222,10 +2412,13 @@ } }, "node_modules/acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, "node_modules/acorn-walk": { "version": "7.1.1", @@ -2248,6 +2441,15 @@ "uri-js": "^4.2.2" } }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", @@ -2418,12 +2620,12 @@ } }, "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/asynckit": { @@ -2495,9 +2697,9 @@ } }, "node_modules/babel-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -2811,12 +3013,6 @@ "node": ">=10" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -2850,24 +3046,6 @@ "node": ">=0.10.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -3283,6 +3461,18 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3370,46 +3560,48 @@ } }, "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -3417,7 +3609,10 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-import-resolver-node": { @@ -3616,12 +3811,12 @@ } }, "node_modules/eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "engines": { @@ -3629,15 +3824,18 @@ } }, "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/eslint-visitor-keys": { @@ -3649,131 +3847,216 @@ "node": ">=4" } }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=8" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/eslint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=6.5.0" + "node": ">=8" } }, - "node_modules/eslint/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/eslint/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": { - "semver": "bin/semver.js" + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/eslint/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, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=4" + "node": ">= 8" } }, "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "engines": { - "node": ">=6.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/esprima": { @@ -3790,29 +4073,47 @@ } }, "node_modules/esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.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.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", @@ -3969,20 +4270,6 @@ "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -4074,15 +4361,15 @@ ] }, "node_modules/fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -4109,9 +4396,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4126,28 +4413,16 @@ "bser": "2.1.1" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { @@ -4176,35 +4451,22 @@ } }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "node_modules/for-in": { @@ -4370,9 +4632,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" @@ -4391,9 +4653,9 @@ } }, "node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "dependencies": { "array-union": "^2.1.0", @@ -4405,6 +4667,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby/node_modules/ignore": { @@ -4675,30 +4940,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -4917,12 +5158,6 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "node_modules/is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "node_modules/is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -5157,9 +5392,9 @@ } }, "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5372,9 +5607,9 @@ } }, "node_modules/jest-config/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5636,9 +5871,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5823,9 +6058,9 @@ } }, "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5998,9 +6233,9 @@ } }, "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6157,9 +6392,9 @@ } }, "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6525,9 +6760,9 @@ } }, "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6702,9 +6937,9 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7178,9 +7413,9 @@ } }, "node_modules/jest-runner/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7496,9 +7731,9 @@ } }, "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7913,9 +8148,9 @@ } }, "node_modules/jest-validate/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8045,9 +8280,9 @@ } }, "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8217,9 +8452,9 @@ } }, "node_modules/jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8584,18 +8819,36 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "node_modules/lodash.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 }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "node_modules/lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -8787,30 +9040,12 @@ "node": ">=0.10.0" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -9100,15 +9335,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", @@ -9398,6 +9624,26 @@ "node": ">=0.6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -9654,6 +9900,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -9688,30 +9943,17 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -9752,34 +9994,27 @@ "node": "6.* || >= 7.*" } }, - "node_modules/run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "dependencies": { - "is-promise": "^2.1.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" + "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { @@ -10073,53 +10308,20 @@ } }, "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" + "node": ">=10" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/snapdragon": { @@ -10540,12 +10742,15 @@ } }, "node_modules/strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -10580,69 +10785,43 @@ "dev": true }, "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/table/node_modules/ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/terminal-link": { "version": "2.1.1", @@ -10683,24 +10862,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -10835,9 +10996,9 @@ } }, "node_modules/ts-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -11066,9 +11227,9 @@ } }, "node_modules/typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", + "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11351,18 +11512,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -11376,12 +11525,24 @@ } }, "node_modules/ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "dev": true, "engines": { "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xml-name-validator": { @@ -11842,6 +12003,52 @@ "minimist": "^1.2.0" } }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "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" + } + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "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 + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -11949,9 +12156,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -12268,9 +12475,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -12497,9 +12704,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -12736,9 +12943,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -12863,9 +13070,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -12922,28 +13129,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "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.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "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.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -13077,9 +13284,9 @@ } }, "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "@types/minimatch": { @@ -13137,15 +13344,74 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", - "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", + "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/experimental-utils": "4.26.1", + "@typescript-eslint/scope-manager": "4.26.1", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" + "lodash": "^4.17.21", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", + "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "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 + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/experimental-utils": { @@ -13158,45 +13424,33 @@ "@typescript-eslint/typescript-estree": "2.31.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } } }, "@typescript-eslint/parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", - "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", + "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", - "debug": "^4.1.1" + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "debug": "^4.3.1" }, "dependencies": { "@typescript-eslint/typescript-estree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", - "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, "semver": { @@ -13211,19 +13465,19 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", - "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", + "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0" + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1" } }, "@typescript-eslint/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", - "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", + "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", "dev": true }, "@typescript-eslint/typescript-estree": { @@ -13250,12 +13504,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", - "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", + "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/types": "4.26.1", "eslint-visitor-keys": "^2.0.0" }, "dependencies": { @@ -13290,10 +13544,11 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.1.1", @@ -13313,6 +13568,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", @@ -13443,9 +13704,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "asynckit": { @@ -13502,9 +13763,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -13770,12 +14031,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -13805,21 +14060,6 @@ } } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -14153,6 +14393,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -14221,134 +14470,185 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } }, - "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==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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": { - "color-convert": "^1.9.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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 + }, + "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 + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "type-fest": "^0.20.2" } }, - "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==", + "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": { - "color-name": "1.1.3" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "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" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "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 }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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 }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": { - "ansi-regex": "^4.1.0" + "prelude-ls": "^1.2.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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 + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" } } } @@ -14522,19 +14822,19 @@ } }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -14547,14 +14847,14 @@ "dev": true }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { @@ -14564,21 +14864,37 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -14711,17 +15027,6 @@ } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -14794,15 +15099,15 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -14826,9 +15131,9 @@ "dev": true }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -14843,22 +15148,13 @@ "bser": "2.1.1" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -14881,31 +15177,19 @@ } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "for-in": { @@ -15032,9 +15316,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -15047,9 +15331,9 @@ "dev": true }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -15272,27 +15556,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - } - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -15460,12 +15723,6 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -15665,9 +15922,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -15801,9 +16058,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -15967,9 +16224,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -16178,9 +16435,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -16331,9 +16588,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -16473,9 +16730,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -16604,9 +16861,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -16895,9 +17152,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -17076,9 +17333,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -17413,9 +17670,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -17672,9 +17929,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -18008,9 +18265,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -18112,9 +18369,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -18404,18 +18661,36 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.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 + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -18572,27 +18847,12 @@ } } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "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 }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -18829,12 +19089,6 @@ "word-wrap": "~1.2.3" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", @@ -19043,6 +19297,12 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -19245,6 +19505,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -19281,16 +19547,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -19318,28 +19574,13 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, - "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "tslib": "^1.9.0" + "queue-microtask": "^1.2.2" } }, "safe-buffer": { @@ -19589,46 +19830,14 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, "snapdragon": { @@ -19972,9 +20181,9 @@ "dev": true }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { @@ -20003,54 +20212,36 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true } } }, @@ -20087,21 +20278,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -20208,9 +20384,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "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": "*" @@ -20383,9 +20559,9 @@ } }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==" + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", + "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" }, "union-value": { "version": "1.0.1", @@ -20616,15 +20792,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -20638,10 +20805,11 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", - "dev": true + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index 5cce58d65..5fac9629f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": ">=4.0.2" + "typescript": "~4.3.2" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -51,9 +51,9 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^4.1.0", - "eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", "fs-extra": "^8.1.0", diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 2f0d2e880..1ac86d3f5 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -806,7 +806,7 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr return ( expression.body.statements?.length === 1 && isReturnStatement(expression.body.statements[0]) && - (expression.body.statements[0] as ReturnStatement).expressions !== undefined && + expression.body.statements[0].expressions !== undefined && (expression.flags & FunctionExpressionFlags.Inline) !== 0 ); } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index b1cfb7f46..e2a6eafe6 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -150,7 +150,7 @@ export class LuaPrinter { const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included - this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" + `${this.options.sourceRoot.replace(/[\\/]+$/, "")}/` : ""; const rootSourceNode = this.printFile(file); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index bec7c2d31..bc6fb5ae9 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -12,7 +12,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic return undefined; } - const searchPath = normalizeSlashes(ts.sys.getCurrentDirectory()); + const searchPath = normalizeSlashes(process.cwd()); return ts.findConfigFile(searchPath, ts.sys.fileExists); } @@ -21,7 +21,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic } // TODO: Unlike tsc, this resolves `.` to absolute path - const fileOrDirectory = normalizeSlashes(path.resolve(ts.sys.getCurrentDirectory(), project)); + const fileOrDirectory = normalizeSlashes(path.resolve(process.cwd(), project)); if (ts.sys.directoryExists(fileOrDirectory)) { const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); if (ts.sys.fileExists(configFileName)) { diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts index 385906f0a..460a77250 100644 --- a/src/lualib/ArrayToObject.ts +++ b/src/lualib/ArrayToObject.ts @@ -1,4 +1,4 @@ -function __TS__ArrayToObject(this: void, array: any[]): object { +function __TS__ArrayToObject(this: void, array: T[]): Record { const object: Record = {}; for (let i = 0; i < array.length; i += 1) { object[i] = array[i]; diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index e5cad0218..816721da7 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,7 +1,18 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -function __TS__Decorate(this: void, decorators: Function[], target: any, key?: any, desc?: any): {} { +type Decorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; +function __TS__Decorate( + this: void, + decorators: Array>, + target: TTarget, + key?: TKey, + desc?: any +): TTarget { let result = target; for (let i = decorators.length; i >= 0; i--) { diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index ed0c28309..4e11f3e54 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -1,3 +1,12 @@ -function __TS__DecorateParam(this: void, paramIndex: number, decorator: Function): {} { - return (target: Function, key?: string) => decorator(target, key, paramIndex); +type ParamDecorator = ( + target: TTarget, + key: TKey, + index: number +) => TTarget; +function __TS__DecorateParam( + this: void, + paramIndex: number, + decorator: ParamDecorator +): Decorator { + return (target: TTarget, key?: TKey) => decorator(target, key, paramIndex); } diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index d44a3b9eb..197ff816b 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -3,7 +3,7 @@ interface ErrorType { new (...args: any[]): Error; } -function __TS__GetErrorStack(constructor: Function): string { +function __TS__GetErrorStack(constructor: () => any): string { let level = 1; while (true) { const info = debug.getinfo(level, "f"); diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index da49d9eb0..bcf521c07 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,4 +1,5 @@ // https://tc39.github.io/ecma262/#sec-object.assign +// eslint-disable-next-line @typescript-eslint/ban-types function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { if (to === undefined) { return to; diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index 68297c420..e9aa599d5 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,5 +1,5 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty(this: void, target: any, key: any, desc: PropertyDescriptor): object { +function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { const luaKey = typeof key === "number" ? key + 1 : key; const value = rawget(target, luaKey); diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 772f7bb58..7b7df1e99 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -WeakMap = class WeakMap { +WeakMap = class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index ebc950a5a..670b3c695 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -WeakSet = class WeakSet { +WeakSet = class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts index a451fe07f..2333f95d4 100644 --- a/src/lualib/declarations/debug.d.ts +++ b/src/lualib/declarations/debug.d.ts @@ -6,7 +6,7 @@ declare function error(...args: any[]): never; declare namespace debug { function traceback(...args: any[]): string; - interface FunctionInfo { + interface FunctionInfo any = () => any> { func: T; name?: string; namewhat: "global" | "local" | "method" | "field" | ""; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 117438817..488586275 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,6 +1,10 @@ /* eslint-disable no-var */ /** @noSelfInFile */ +type AnyTable = Record; +// eslint-disable-next-line +type AnyNotNil = {}; + declare var __TS__sourcemap: Record | undefined; declare var __TS__originalTraceback: | ((this: void, thread?: any, message?: string, level?: number) => string) @@ -13,8 +17,8 @@ declare function tonumber(value: any, base?: number): number | undefined; declare function type( value: any ): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; -declare function setmetatable(table: T, metatable: any): T; -declare function getmetatable(table: T): any; +declare function setmetatable(table: T, metatable: any): T; +declare function getmetatable(table: T): any; declare function rawget(table: T, key: K): T[K]; declare function rawset(table: T, key: K, val: T[K]): void; /** @tupleReturn */ diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts index 63805d283..b802153c8 100644 --- a/src/lualib/declarations/luatable.d.ts +++ b/src/lualib/declarations/luatable.d.ts @@ -1,5 +1,5 @@ /** @LuaTable */ -declare class LuaTable { +declare class LuaTable { public readonly length: number; public set(key: K, value: V | undefined): void; public get(key: K): V | undefined; diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index bd9d052ab..212f30416 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -35,7 +35,7 @@ export type AnnotationsMap = Map; function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void { for (const tag of source.getJsDocTags()) { - const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []); + const annotation = createAnnotation(tag.name, tag.text?.map(p => p.text) ?? []); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -62,7 +62,7 @@ export function getNodeAnnotations(node: ts.Node): AnnotationsMap { for (const tag of ts.getJSDocTags(node)) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -80,7 +80,7 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { if (jsDoc) { for (const tag of jsDoc.flatMap(x => x.tags ?? [])) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -178,3 +178,15 @@ export function isForRangeType(context: TransformationContext, node: ts.Node): b const type = context.checker.getTypeAtLocation(node); return getTypeAnnotations(type).has(AnnotationKind.ForRange); } + +export function getTagArgsFromComment(tag: ts.JSDocTag): string[] { + if (tag.comment) { + if (typeof tag.comment === "string") { + return tag.comment.split(" "); + } else { + return tag.comment.map(part => part.text); + } + } + + return []; +} diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index d11109427..1edee936c 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -96,7 +96,7 @@ export function getExportedSymbolsFromScope( export function getDependenciesOfSymbol(context: TransformationContext, originalSymbol: ts.Symbol): ts.Symbol[] { return getExportedSymbolsFromScope(context, context.sourceFile).filter(exportSymbol => exportSymbol.declarations - .filter(ts.isExportSpecifier) + ?.filter(ts.isExportSpecifier) .map(context.checker.getExportSpecifierLocalTargetSymbol) .includes(originalSymbol) ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 2991204c2..8b999ae56 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -117,6 +117,6 @@ export function isExtensionValue( ): boolean { return ( symbol.getName() === extensionKindToValueName[extensionKind] && - symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) + symbol.declarations?.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) === true ); } diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index c072135f4..877196ba4 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -72,7 +72,7 @@ export function hasUnsafeSymbolName( symbol: ts.Symbol, tsOriginal: ts.Identifier ): boolean { - const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d)); + const isAmbient = symbol.declarations?.some(d => isAmbientNode(d)) ?? false; // Catch ambient declarations of identifiers with bad names if (isAmbient && checkName(context, symbol.name, tsOriginal)) { diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 200b65860..72b267e2a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -93,7 +93,7 @@ export function popScope(context: TransformationContext): Scope { } function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { - return symbol?.declarations.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); + return symbol?.declarations?.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); } // Checks for references to local functions which haven't been defined yet, diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 306968010..9fa17711a 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -109,8 +109,10 @@ export function transformArguments( for (const [index, param] of params.entries()) { const signatureParameter = signature.parameters[index]; const paramType = context.checker.getTypeAtLocation(param); - const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); - validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + if (signatureParameter.valueDeclaration !== undefined) { + const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + } } } diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 7ee32adac..d41aefd75 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -75,8 +75,8 @@ export const transformModuleDeclaration: FunctionVisitor = // - declared as a class or function at all (TS requires these to be before module, unless module is empty) const isFirstDeclaration = symbol === undefined || - (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && - ts.getOriginalNode(node) === symbol.declarations.find(ts.isModuleDeclaration)); + (!symbol.declarations?.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && + ts.getOriginalNode(node) === symbol.declarations?.find(ts.isModuleDeclaration)); if (isNonModuleMergeable) { // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' diff --git a/src/utils.ts b/src/utils.ts index 1244068a4..72e6ee168 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,6 +50,7 @@ export function formatPathToLuaPath(filePath: string): string { type NoInfer = [T][T extends any ? 0 : never]; export function getOrUpdate( + // eslint-disable-next-line @typescript-eslint/ban-types map: Map | (K extends object ? WeakMap : never), key: K, getDefaultValue: () => NoInfer diff --git a/test/setup.ts b/test/setup.ts index 6d92e3332..de78ad24b 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -5,7 +5,7 @@ import * as tstl from "../src"; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { - // eslint-disable-next-line @typescript-eslint/generic-type-naming + // eslint-disable-next-line @typescript-eslint/naming-convention interface Matchers { toHaveDiagnostics(expected?: number[]): R; } From 0dd7008374e81cf90465ae1c4dcc6895e0aed585 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 10 Jun 2021 17:53:07 +0200 Subject: [PATCH 64/91] 0.39.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 93b27be93..575c0ee9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 5fac9629f..3bbbfefe7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "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/", From 9cbc04fa7ee861116c400789b88b03603f44924c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 10:18:30 +0200 Subject: [PATCH 65/91] Fixed typo in language extension and add a step to test procedure to make sure this does not happen again (#1029) --- language-extensions/index.d.ts | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 761d6a68e..bcd609a27 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -487,7 +487,7 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; /** diff --git a/package.json b/package.json index 3bbbfefe7..7e65103ab 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,13 @@ "scripts": { "build": "tsc && npm run build-lualib", "build-lualib": "node build-lualib.js", - "pretest": "npm run lint && npm run build-lualib", + "pretest": "npm run lint && npm run check:language-extensions && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint . --ext .js,.ts", "fix:prettier": "prettier --write .", + "check:language-extensions": "tsc language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, From bd17ed78290bf81903250fe2621cf2ee521fc165 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 12 Jun 2021 10:24:47 +0200 Subject: [PATCH 66/91] 0.39.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 575c0ee9f..6211e0e84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 7e65103ab..b608ec87f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "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/", From ffde3904440711629af06e8ba127de4042fa4f41 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 14:55:07 +0200 Subject: [PATCH 67/91] Implement array.entries() (#1031) * Implement array.entries * Added extra test for indirect use of array.entries() * Added destructuring test for array.entries * Fix prettier --- src/LuaLib.ts | 1 + src/lualib/ArrayEntries.ts | 14 ++++++++++++++ src/transformation/builtins/array.ts | 2 ++ test/unit/builtins/array.spec.ts | 29 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 src/lualib/ArrayEntries.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index dc4501d86..d98b78044 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -3,6 +3,7 @@ import { EmitHost } from "./transpilation"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", + ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", diff --git a/src/lualib/ArrayEntries.ts b/src/lualib/ArrayEntries.ts new file mode 100644 index 000000000..7d12f1347 --- /dev/null +++ b/src/lualib/ArrayEntries.ts @@ -0,0 +1,14 @@ +// https://262.ecma-international.org/10.0/#sec-array.prototype.entries +function __TS__ArrayEntries(this: void, array: T[]): IterableIterator<[number, T]> { + let key = 0; + return { + [Symbol.iterator](): IterableIterator<[number, T]> { + return this; + }, + next(): IteratorResult<[number, T]> { + const result = { done: array[key] === undefined, value: [key, array[key]] as [number, T] }; + key++; + return result; + }, + }; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index a04e0e98b..d8bd4dd3b 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -36,6 +36,8 @@ export function transformArrayPrototypeCall( switch (expressionName) { case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); + case "entries": + return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); case "push": return transformLuaLibFunction(context, LuaLibFeature.ArrayPush, node, caller, ...params); case "reverse": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 770387aea..037ebe2a7 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -594,6 +594,35 @@ describe.each(["reduce", "reduceRight"])("array.%s", reduce => { }); }); +test.each([{ array: [] }, { array: ["a", "b", "c"] }, { array: [{ foo: "foo" }, { bar: "bar" }] }])( + "array.entries (%p)", + ({ array }) => { + util.testFunction` + const array = ${util.formatCode(array)}; + const result = []; + for (const [i, v] of array.entries()) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); + } +); + +test("array.entries indirect use", () => { + util.testFunction` + const entries = ["a", "b", "c"].entries(); + const result = []; + for (const [i, v] of entries) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); +}); + +test("array.entries destructured", () => { + util.testExpression`[...["a", "b", "c"].entries()]`.expectToMatchJsResult(); +}); + const genericChecks = [ "function generic(array: T)", "function generic(array: T)", From bfb89e9e8c4678c9c86028066fc9881d388d69d4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 14:55:17 +0200 Subject: [PATCH 68/91] Implemented LuaTableHas and LuaTableDelete (#1030) * Add tests for luatable has * Implement LuaTable has * LuaTableDelete declaration and tests * Implemented LuaTableDelete --- language-extensions/index.d.ts | 40 ++++ src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 8 + src/transformation/visitors/call.ts | 19 +- .../visitors/expression-statement.ts | 11 +- .../visitors/language-extensions/table.ts | 85 ++++++++- .../__snapshots__/table.spec.ts.snap | 63 +++++++ test/unit/language-extensions/table.spec.ts | 175 +++++++++++++++++- 8 files changed, 395 insertions(+), 10 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index bcd609a27..dbd9a1cd8 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -490,6 +490,44 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; +/** + * Calls to functions with this type are translated to `table[key] ~= nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHas = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableHasBrand">; + +/** + * Calls to methods with this type are translated to `table[key] ~= nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHasMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableHasMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDelete = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteMethodBrand">; + /** * A convenience type for working directly with a Lua table. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -501,6 +539,8 @@ declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; + has: LuaTableHasMethod; + delete: LuaTableDeleteMethod; } /** diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 422a93cac..f25707443 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -158,6 +158,10 @@ export const invalidTableExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); +export const invalidTableDeleteExpression = createErrorDiagnosticFactory( + "Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." +); + export const invalidTableSetExpression = createErrorDiagnosticFactory( "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 8b999ae56..3861cbf57 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -44,8 +44,12 @@ export enum ExtensionKind { LengthOperatorType = "LengthOperatorType", LengthOperatorMethodType = "LengthOperatorMethodType", TableNewType = "TableNewType", + TableDeleteType = "TableDeleteType", + TableDeleteMethodType = "TableDeleteMethodType", TableGetType = "TableGetType", TableGetMethodType = "TableGetMethodType", + TableHasType = "TableHasType", + TableHasMethodType = "TableHasMethodType", TableSetType = "TableSetType", TableSetMethodType = "TableSetMethodType", } @@ -99,8 +103,12 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", [ExtensionKind.TableNewType]: "__luaTableNewBrand", + [ExtensionKind.TableDeleteType]: "__luaTableDeleteBrand", + [ExtensionKind.TableDeleteMethodType]: "__luaTableDeleteMethodBrand", [ExtensionKind.TableGetType]: "__luaTableGetBrand", [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", + [ExtensionKind.TableHasType]: "__luaTableHasBrand", + [ExtensionKind.TableHasMethodType]: "__luaTableHasMethodBrand", [ExtensionKind.TableSetType]: "__luaTableSetBrand", [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", }; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 9fa17711a..709ce1175 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -14,12 +14,16 @@ import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { + isTableDeleteCall, isTableGetCall, + isTableHasCall, isTableSetCall, + transformTableDeleteExpression, transformTableGetExpression, + transformTableHasExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { invalidTableSetExpression } from "../utils/diagnostics"; +import { invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, @@ -242,10 +246,23 @@ export const transformCallExpression: FunctionVisitor = (node return transformOperatorMappingExpression(context, node); } + if (isTableDeleteCall(context, node)) { + context.diagnostics.push(invalidTableDeleteExpression(node)); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableDeleteExpression(context, node), result: lua.createNilLiteral() }), + node + ); + } + if (isTableGetCall(context, node)) { return transformTableGetExpression(context, node); } + if (isTableHasCall(context, node)) { + return transformTableHasExpression(context, node); + } + if (isTableSetCall(context, node)) { context.diagnostics.push(invalidTableSetExpression(node)); return transformToImmediatelyInvokedFunctionExpression( diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 1932a6dc2..ac020976f 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,7 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { isTableSetCall, transformTableSetExpression } from "./language-extensions/table"; +import { + isTableDeleteCall, + isTableSetCall, + transformTableDeleteExpression, + transformTableSetExpression, +} from "./language-extensions/table"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -12,6 +17,10 @@ export const transformExpressionStatement: FunctionVisitor extensions.isExtensionType(type, extensionKind)); } +export function isTableDeleteCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableDeleteExtensions) !== undefined; +} + export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; } +export function isTableHasCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableHasExtensions) !== undefined; +} + export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; } @@ -38,6 +59,27 @@ export function isTableNewCall(context: TransformationContext, node: ts.NewExpre return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); } +export function transformTableDeleteExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableDeleteExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] = nil + return lua.createAssignmentStatement( + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + lua.createNilLiteral(), + node + ); +} + export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); assert(extensionKind); @@ -47,9 +89,11 @@ export function transformTableGetExpression(context: TransformationContext, node args.length === 1 && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { + // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } + // arg0[arg1] return lua.createTableIndexExpression( context.transformExpression(args[0]), context.transformExpression(args[1]), @@ -57,6 +101,34 @@ export function transformTableGetExpression(context: TransformationContext, node ); } +export function transformTableHasExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableHasExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] + const tableIndexExpression = lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]) + ); + + // arg0[arg1] ~= nil + return lua.createBinaryExpression( + tableIndexExpression, + lua.createNilLiteral(), + lua.SyntaxKind.InequalityOperator, + node + ); +} + export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); assert(extensionKind); @@ -66,15 +138,14 @@ export function transformTableSetExpression(context: TransformationContext, node args.length === 2 && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { + // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } + // arg0[arg1] = arg2 return lua.createAssignmentStatement( - lua.createTableIndexExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - node - ), - context.transformExpression(args[2]) + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + context.transformExpression(args[2]), + node ); } diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 9f6113df6..f8e3a895d 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -1,5 +1,48 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` +"foo = { + (function() + ({}).foo = nil + return nil + end)() +}" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): code 1`] = ` +"foo = (function() + ({}).foo = nil + return nil +end)()" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` "foo = { (function() @@ -62,3 +105,23 @@ exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): code 1`] = `"foo(_G, getTable)"`; exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): diagnostics 1`] = `"main.ts(3,88): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): code 1`] = `"foo = tableHas(_G, 1, 2)"`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): code 1`] = `"foo = {tableHas}"`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): code 1`] = `"foo = tostring(tableHas)"`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): code 1`] = `"foo = tableHas"`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): code 1`] = `"foo(_G, tableHas)"`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): diagnostics 1`] = `"main.ts(3,80): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 8d3d0fde1..8d0437fb0 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -1,7 +1,11 @@ import * as path from "path"; import * as util from "../../util"; import * as tstl from "../../../src"; -import { invalidTableExtensionUse, invalidTableSetExpression } from "../../../src/transformation/utils/diagnostics"; +import { + invalidTableDeleteExpression, + invalidTableExtensionUse, + invalidTableSetExpression, +} from "../../../src/transformation/utils/diagnostics"; const tableProjectOptions: tstl.CompilerOptions = { types: [path.resolve(__dirname, "../../../language-extensions")], @@ -84,6 +88,151 @@ describe("LuaTableGet & LuaTableSet extensions", () => { }); }); +describe("LuaTableHas extension", () => { + test("LuaTableHas standalone function", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const hasFoo = tableHas(table, "foo"); + export const hasBaz = tableHas(table, "baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas nested expression", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const result = \`table has foo: \${tableHas(table, "foo")}\`; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ result: "table has foo: true" }); + }); + + test("LuaTableHas namespace function", () => { + util.testModule` + declare namespace Table { + export const tableHas: LuaTableHas<{}, string>; + } + const table = { foo: "bar" }; + + export const hasFoo = Table.tableHas(table, "foo"); + export const hasBaz = Table.tableHas(table, "baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithHas { + has: LuaTableHasMethod; + set: LuaTableSetMethod; + } + const table = {} as TableWithHas; + table.set("foo", 42); + + export const hasFoo = table.has("foo"); + export const hasBaz = table.has("baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas as statement", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + let count = 0; + function getKey() { + count++; + return "foo"; + } + + // The result is not captured, but the expression will be evaulated + tableHas(table, getKey()); + + export const numCalls = count; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ numCalls: 1 }); + }); + + test.each([ + "const foo: unknown = tableHas;", + "const foo = `${tableHas}`;", + "declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);", + "const foo = (tableHas as any)(1, 2);", + "const foo = [tableHas];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + ${statement} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); +}); + +describe("LuaTableDelete extension", () => { + test("LuaTableDelete standalone function", () => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + + export const table = { foo: "bar", baz: "baz" }; + tableDelete(table, "foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableDelete namespace function", () => { + util.testModule` + declare namespace Table { + export const tableDelete: LuaTableDelete<{}, string>; + } + + export const table = { foo: "bar", baz: "baz" }; + Table.tableDelete(table, "foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithDelete { + delete: LuaTableDeleteMethod; + set: LuaTableSetMethod; + } + export const table = {} as TableWithDelete; + table.set("foo", 42); + table.set("bar", 12); + table.delete("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { bar: 12 } }); + }); + + test.each([ + 'const foo = tableDelete({}, "foo");', + 'const foo = `${tableDelete({}, "foo")}`;', + 'declare function foo(arg: any): void; foo(tableDelete({}, "foo"));', + 'const foo = [tableDelete({}, "foo")];', + ])("LuaTableDelete invalid use as expression (%p)", expression => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + ${expression} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableDeleteExpression.code]); + }); +}); + describe("LuaTable extension interface", () => { test("untyped table", () => { util.testFunction` @@ -128,6 +277,30 @@ describe("LuaTable extension interface", () => { .expectToEqual(1); }); + test("table has", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(3, "foo"); + return [tbl.has(1), tbl.has(3)]; + ` + .setOptions(tableProjectOptions) + .expectToEqual([false, true]); + }); + + test("table delete", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + tbl.set("bar", 3); + tbl.set("baz", 5); + tbl.delete("bar"); + tbl.delete("foo"); + return tbl; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ baz: 5 }); + }); + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( "table immediate access (%p)", statement => { From 5b673302e661795aebe3ecc846fdb5c5d3d92a8f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 13 Jun 2021 22:48:48 +0200 Subject: [PATCH 69/91] Fixed language extensions LuaTable keys required to be tables (#1034) * Fixed another mistake in language extensions where luatable keys were accidentally required to be tables * update snapshot names --- language-extensions/index.d.ts | 2 +- .../__snapshots__/table.spec.ts.snap | 46 +++++++++++++++++++ test/unit/language-extensions/table.spec.ts | 23 ++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index dbd9a1cd8..30eb70009 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -535,7 +535,7 @@ declare type LuaTableDeleteMethod = ((key: TKey) => bool * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare interface LuaTable { +declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index f8e3a895d..5deed95c3 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -1,5 +1,51 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'null' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'number | undefined' does not satisfy the constraint 'AnyNotNil'. + Type 'undefined' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'string | null' does not satisfy the constraint 'AnyNotNil'. + Type 'null' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'undefined' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; + exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` "foo = { (function() diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 8d0437fb0..e6d485a04 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -254,6 +254,29 @@ describe("LuaTable extension interface", () => { .expectToEqual(3); }); + // Test to catch issue from https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1033 + test("typed table in type declaration", () => { + util.testFunction` + function fill(tbl: LuaTable) { + tbl.set("foo", 3); + return tbl; + } + return fill(new LuaTable()).get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test.each([["null"], ["undefined"], ["number | undefined"], ["string | null"], ["unknown"]])( + "LuaTable in strict mode does not accept key type that could be nil (%p)", + keyType => { + util.testExpression`new LuaTable<${keyType}, unknown>()` + .setOptions({ ...tableProjectOptions, strict: true }) + .expectToHaveDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + } + ); + test("object keyed table", () => { util.testFunction` interface Key { keyStr: string } From 57fbef1a90d7ef5cee7e9e314549acaeafa61d3d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 13 Jun 2021 22:54:45 +0200 Subject: [PATCH 70/91] 0.39.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6211e0e84..5b210730c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index b608ec87f..0fc954467 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "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/", From 5abb60ba6dbb619862c619781c672038a8e3f153 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 14 Jun 2021 18:50:30 +0200 Subject: [PATCH 71/91] Remove deprecated annotations (#1032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed luaIterator, vararg, luaTable and forRange annotations * Fixed change missed in conflict resolve * Removed unused import * Remove unused diagnostics * Fixed deprecation tests working because tbl.new instead of get/set * Prettier 💅 --- src/lualib/declarations/luatable.d.ts | 6 - src/transformation/utils/diagnostics.ts | 30 --- src/transformation/visitors/access.ts | 52 ++--- .../visitors/binary-expression/assignments.ts | 8 +- .../visitors/binary-expression/index.ts | 7 - src/transformation/visitors/call.ts | 16 +- src/transformation/visitors/class/index.ts | 15 +- src/transformation/visitors/class/new.ts | 16 +- .../visitors/expression-statement.ts | 15 +- src/transformation/visitors/identifier.ts | 12 +- src/transformation/visitors/loops/for-of.ts | 124 +---------- src/transformation/visitors/lua-table.ts | 158 -------------- src/transformation/visitors/spread.ts | 5 +- .../__snapshots__/deprecated.spec.ts.snap | 66 +++++- .../__snapshots__/forRange.spec.ts.snap | 89 -------- .../__snapshots__/luaIterator.spec.ts.snap | 15 -- .../__snapshots__/luaTable.spec.ts.snap | 197 ------------------ test/unit/annotations/deprecated.spec.ts | 67 +++++- test/unit/annotations/forRange.spec.ts | 98 --------- test/unit/annotations/luaIterator.spec.ts | 191 ----------------- test/unit/annotations/luaTable.spec.ts | 151 -------------- test/unit/annotations/vararg.spec.ts | 50 ----- test/unit/loops.spec.ts | 48 ----- 23 files changed, 178 insertions(+), 1258 deletions(-) delete mode 100644 src/lualib/declarations/luatable.d.ts delete mode 100644 src/transformation/visitors/lua-table.ts delete mode 100644 test/unit/annotations/__snapshots__/forRange.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/luaTable.spec.ts.snap delete mode 100644 test/unit/annotations/forRange.spec.ts delete mode 100644 test/unit/annotations/luaIterator.spec.ts delete mode 100644 test/unit/annotations/luaTable.spec.ts delete mode 100644 test/unit/annotations/vararg.spec.ts diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts deleted file mode 100644 index b802153c8..000000000 --- a/src/lualib/declarations/luatable.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @LuaTable */ -declare class LuaTable { - public readonly length: number; - public set(key: K, value: V | undefined): void; - public get(key: K): V | undefined; -} diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index f25707443..ef699c07c 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -58,10 +58,6 @@ export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const invalidForRangeCall = createErrorDiagnosticFactory( - (message: string) => `Invalid @forRange call: ${message}.` -); - export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); export const invalidVarargUse = createErrorDiagnosticFactory( @@ -72,32 +68,6 @@ export const invalidRangeControlVariable = createErrorDiagnosticFactory( "For loop using $range must declare a single control variable." ); -export const luaTableMustBeAmbient = createErrorDiagnosticFactory( - "Classes with the '@luaTable' annotation must be ambient." -); - -export const luaTableCannotBeExtended = createErrorDiagnosticFactory( - "Cannot extend classes with the '@luaTable' annotation." -); - -export const luaTableInvalidInstanceOf = createErrorDiagnosticFactory( - "The instanceof operator cannot be used with a '@luaTable' class." -); - -export const luaTableCannotBeAccessedDynamically = createErrorDiagnosticFactory( - "@luaTable cannot be accessed dynamically." -); - -export const luaTableForbiddenUsage = createErrorDiagnosticFactory( - (description: string) => `Invalid @luaTable usage: ${description}.` -); - -export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( - "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + - "You must use a destructuring statement to catch results from a lua iterator with " + - "the '@tupleReturn' annotation." -); - export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory( "LuaIterable with a LuaMultiReturn return value type must be destructured." ); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index d33c5c5c6..a41c4462f 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,13 +3,12 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; +import { annotationRemoved, invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { returnsMultiType } from "./language-extensions/multi"; -import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; export function transformElementAccessArgument( context: TransformationContext, @@ -27,8 +26,6 @@ export function transformElementAccessArgument( } export const transformElementAccessExpression: FunctionVisitor = (node, context) => { - validateLuaTableElementAccessExpression(context, node); - const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return constEnumValue; @@ -59,53 +56,50 @@ export const transformElementAccessExpression: FunctionVisitor = ( - expression, - context -) => { - if (ts.isOptionalChain(expression)) { - context.diagnostics.push(optionalChainingNotSupported(expression)); +export const transformPropertyAccessExpression: FunctionVisitor = (node, context) => { + const property = node.name.text; + const type = context.checker.getTypeAtLocation(node.expression); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } - const constEnumValue = tryGetConstEnumValue(context, expression); - if (constEnumValue) { - return constEnumValue; + if (ts.isOptionalChain(node)) { + context.diagnostics.push(optionalChainingNotSupported(node)); } - const luaTableResult = transformLuaTablePropertyAccessExpression(context, expression); - if (luaTableResult) { - return luaTableResult; + const constEnumValue = tryGetConstEnumValue(context, node); + if (constEnumValue) { + return constEnumValue; } - const builtinResult = transformBuiltinPropertyAccessExpression(context, expression); + const builtinResult = transformBuiltinPropertyAccessExpression(context, node); if (builtinResult) { return builtinResult; } - if (ts.isCallExpression(expression.expression) && returnsMultiType(context, expression.expression)) { - context.diagnostics.push(invalidMultiReturnAccess(expression)); + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) { + context.diagnostics.push(invalidMultiReturnAccess(node)); } - const property = expression.name.text; - const type = context.checker.getTypeAtLocation(expression.expression); - - const annotations = getTypeAnnotations(type); // Do not output path for member only enums if (annotations.has(AnnotationKind.CompileMembersOnly)) { - if (ts.isPropertyAccessExpression(expression.expression)) { + if (ts.isPropertyAccessExpression(node.expression)) { // in case of ...x.enum.y transform to ...x.y return lua.createTableIndexExpression( - context.transformExpression(expression.expression.expression), + context.transformExpression(node.expression.expression), lua.createStringLiteral(property), - expression + node ); } else { - return lua.createIdentifier(property, expression); + return lua.createIdentifier(property, node); } } - const callPath = context.transformExpression(expression.expression); - return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), expression); + const callPath = context.transformExpression(node.expression); + return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), node); }; export const transformQualifiedName: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 0b1b7fe70..c8a1cd907 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -9,7 +9,6 @@ import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; -import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; import { popScope, pushScope, ScopeType } from "../../utils/scope"; @@ -23,9 +22,7 @@ export function transformAssignmentLeftHandSideExpression( node: ts.Expression ): lua.AssignmentLeftHandSideExpression { const symbol = context.checker.getSymbolAtLocation(node); - const left = ts.isPropertyAccessExpression(node) - ? transformLuaTablePropertyAccessInAssignment(context, node) ?? context.transformExpression(node) - : context.transformExpression(node); + const left = context.transformExpression(node); return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) ? createExportedIdentifier(context, left) @@ -140,9 +137,6 @@ export function transformAssignmentExpression( const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { - // Called only for validation - transformLuaTablePropertyAccessInAssignment(context, expression.left); - // Property access indexExpression = lua.createStringLiteral(expression.left.name.text); } else { diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 5ed023618..0b4533a4a 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -1,8 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -108,11 +106,6 @@ export const transformBinaryExpression: FunctionVisitor = ( const lhs = context.transformExpression(node.left); const rhs = context.transformExpression(node.right); const rhsType = context.checker.getTypeAtLocation(node.right); - const annotations = getTypeAnnotations(rhsType); - - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableInvalidInstanceOf(node)); - } if (isStandardLibraryType(context, rhsType, "ObjectConstructor")) { return transformLuaLibFunction(context, LuaLibFeature.InstanceOfObject, node, lhs); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 709ce1175..f7a1b004e 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { AnnotationKind, getTypeAnnotations, isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -10,7 +10,6 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; -import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { @@ -23,7 +22,7 @@ import { transformTableHasExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; +import { annotationRemoved, invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, @@ -223,11 +222,6 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre } export const transformCallExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableCallExpression(context, node); - if (luaTableResult) { - return luaTableResult; - } - const isTupleReturn = isTupleReturnCall(context, node); const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); @@ -273,6 +267,12 @@ export const transformCallExpression: FunctionVisitor = (node } if (ts.isPropertyAccessExpression(node.expression)) { + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const annotations = getTypeAnnotations(ownerType); + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); + } + const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 4c0e05eee..98d74f84a 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationRemoved, luaTableCannotBeExtended, luaTableMustBeAmbient } from "../../utils/diagnostics"; +import { annotationRemoved } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, @@ -13,7 +13,6 @@ import { import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; -import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; @@ -97,18 +96,6 @@ function transformClassLikeDeclaration( checkForLuaLibType(context, extendedType); } - // You cannot extend LuaTable classes - if (extendedType) { - const annotations = getTypeAnnotations(extendedType); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeExtended(extendedTypeNode!)); - } - } - - if (annotations.has(AnnotationKind.LuaTable) && !isAmbientNode(classDeclaration)) { - context.diagnostics.push(luaTableMustBeAmbient(classDeclaration)); - } - // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 1a9c5e8aa..721cc26e5 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,11 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; -import { transformLuaTableNewExpression } from "../lua-table"; const builtinErrorTypeNames = new Set([ "Error", @@ -49,9 +48,12 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type } export const transformNewExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableNewExpression(context, node); - if (luaTableResult) { - return luaTableResult; + const type = context.checker.getTypeAtLocation(node); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } if (isTableNewCall(context, node)) { @@ -64,12 +66,8 @@ export const transformNewExpression: FunctionVisitor = (node, ? transformArguments(context, node.arguments, signature) : [lua.createBooleanLiteral(true)]; - const type = context.checker.getTypeAtLocation(node); - checkForLuaLibType(context, type); - const annotations = getTypeAnnotations(type); - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index ac020976f..228307f25 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -8,21 +8,17 @@ import { transformTableDeleteExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableExpressionStatement(context, node); - if (luaTableResult) { - return luaTableResult; - } + const expression = node.expression; - if (ts.isCallExpression(node.expression) && isTableDeleteCall(context, node.expression)) { - return transformTableDeleteExpression(context, node.expression); + if (ts.isCallExpression(expression) && isTableDeleteCall(context, expression)) { + return transformTableDeleteExpression(context, expression); } - if (ts.isCallExpression(node.expression) && isTableSetCall(context, node.expression)) { - return transformTableSetExpression(context, node.expression); + if (ts.isCallExpression(expression) && isTableSetCall(context, expression)) { + return transformTableSetExpression(context, expression); } const unaryExpressionResult = transformUnaryExpressionStatement(context, node); @@ -35,7 +31,6 @@ export const transformExpressionStatement: FunctionVisitor !isNumberType(context, context.checker.getTypeAtLocation(a)))) { - context.diagnostics.push(invalidForRangeCall(statement.expression, "arguments must be numbers")); - } - - const controlVariable = getControlVariable() ?? lua.createAnonymousIdentifier(); - function getControlVariable(): lua.Identifier | undefined { - if (!ts.isVariableDeclarationList(statement.initializer)) { - context.diagnostics.push( - invalidForRangeCall(statement.initializer, "loop must declare it's own control variable") - ); - return; - } - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (!ts.isIdentifier(binding)) { - context.diagnostics.push(invalidForRangeCall(statement.initializer, "destructuring cannot be used")); - return; - } - - if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { - context.diagnostics.push( - invalidForRangeCall(statement.expression, "function must return Iterable") - ); - } - - return transformIdentifier(context, binding); - } - - const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( - context, - callArguments, - context.checker.getResolvedSignature(statement.expression) - ); - - return lua.createForStatement(block, controlVariable, start, limit, step, statement); -} - -function transformForOfLuaIteratorStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - const luaIterator = context.transformExpression(statement.expression); - const type = context.checker.getTypeAtLocation(statement.expression); - const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); - let identifiers: lua.Identifier[] = []; - - if (tupleReturn) { - // LuaIterator + TupleReturn - - if (ts.isVariableDeclarationList(statement.initializer)) { - // Variables declared in for loop - // for ${initializer} in ${iterable} do - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (ts.isArrayBindingPattern(binding)) { - identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(binding)); - } - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____value0 in ${iterable} do - // ${initializer} = ____value0 - - identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); - if (identifiers.length > 0) { - block.statements.unshift( - lua.createAssignmentStatement( - statement.initializer.elements.map(e => - cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) - ), - identifiers - ) - ); - } - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); - } - } else { - // LuaIterator (no TupleReturn) - - identifiers.push(transformForInitializer(context, statement.initializer, block)); - } - - if (identifiers.length === 0) { - identifiers.push(lua.createAnonymousIdentifier()); - } - - return lua.createForInStatement(block, identifiers, [luaIterator], statement); -} +import { transformForInitializer, transformLoopBody } from "./utils"; function transformForOfArrayStatement( context: TransformationContext, @@ -156,11 +44,11 @@ export const transformForOfStatement: FunctionVisitor = (node if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { return transformRangeStatement(context, node, body); } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { - return transformForRangeStatement(context, node, body); + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.ForRange)); } else if (isIterableExpression(context, node.expression)) { return transformForOfIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { - return transformForOfLuaIteratorStatement(context, node, body); + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { return transformForOfArrayStatement(context, node, body); } else { diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts deleted file mode 100644 index 300837c1e..000000000 --- a/src/transformation/visitors/lua-table.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../LuaAST"; -import { TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { luaTableCannotBeAccessedDynamically, luaTableForbiddenUsage, unsupportedProperty } from "../utils/diagnostics"; -import { transformArguments } from "./call"; - -const parseLuaTableExpression = (context: TransformationContext, node: ts.PropertyAccessExpression) => - [context.transformExpression(node.expression), node.name.text] as const; - -function validateLuaTableCall( - context: TransformationContext, - node: ts.Node, - methodName: string, - callArguments: ts.NodeArray -): void { - for (const argument of callArguments) { - if (ts.isSpreadElement(argument)) { - context.diagnostics.push(luaTableForbiddenUsage(argument, "Arguments cannot be spread")); - return; - } - } - - switch (methodName) { - case "get": - if (callArguments.length !== 1) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 1 arguments, but got ${callArguments.length}`) - ); - } - break; - - case "set": - if (callArguments.length !== 2) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 2 arguments, but got ${callArguments.length}`) - ); - } - break; - } -} - -export function transformLuaTableExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - - if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, expression.expression); - validateLuaTableCall(context, expression, methodName, expression.arguments); - const signature = context.checker.getResolvedSignature(expression); - const params = transformArguments(context, expression.arguments, signature); - - switch (methodName) { - case "get": - return lua.createVariableDeclarationStatement( - lua.createAnonymousIdentifier(expression), - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - expression - ); - case "set": - return lua.createAssignmentStatement( - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - [params[1] ?? lua.createNilLiteral()], - expression - ); - default: - context.diagnostics.push(unsupportedProperty(expression.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTableCallExpression( - context: TransformationContext, - node: ts.CallExpression -): lua.Expression | undefined { - if (!ts.isPropertyAccessExpression(node.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); - validateLuaTableCall(context, node, methodName, node.arguments); - const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - - switch (methodName) { - case "get": - return lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), node); - default: - context.diagnostics.push(unsupportedProperty(node.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTablePropertyAccessExpression( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function transformLuaTablePropertyAccessInAssignment( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.AssignmentLeftHandSideExpression | undefined { - if (!ts.isPropertyAccessExpression(node)) return; - - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - context.diagnostics.push(luaTableForbiddenUsage(node, "A LuaTable object's length cannot be re-assigned")); - return lua.createTableIndexExpression(luaTable, lua.createStringLiteral(propertyName), node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function validateLuaTableElementAccessExpression( - context: TransformationContext, - node: ts.ElementAccessExpression -): void { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeAccessedDynamically(node)); - } -} - -export function transformLuaTableNewExpression( - context: TransformationContext, - node: ts.NewExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - if (node.arguments && node.arguments.length > 0) { - context.diagnostics.push( - luaTableForbiddenUsage(node, "No parameters are allowed when constructing a LuaTable object") - ); - } - - return lua.createTableExpression(); -} diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index ca5e2fb85..d9da3ce44 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -13,7 +13,7 @@ import { } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; import { returnsMultiType } from "./language-extensions/multi"; -import { annotationDeprecated } from "../utils/diagnostics"; +import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { @@ -60,8 +60,7 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: export const transformSpreadElement: FunctionVisitor = (node, context) => { if (ts.isIdentifier(node.expression)) { if (isVarargType(context, node.expression)) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Vararg)); - return lua.createDotsLiteral(node); + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Vararg)); } const symbol = context.checker.getSymbolAtLocation(node.expression); if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 750b0596f..d612bc478 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -1,5 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTable deprecation warning property access set: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:set(\\"foo\\", 0) +end +return ____exports" +`; + +exports[`LuaTable deprecation warning property access set: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning constructor: code 1`] = ` +"require(\\"lualib_bundle\\"); +____table = __TS__New(Table)" +`; + +exports[`LuaTable removed warning constructor: diagnostics 1`] = `"main.ts(11,15): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access get: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:get(\\"foo\\") +end +return ____exports" +`; + +exports[`LuaTable removed warning property access get: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access length: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl.length +end +return ____exports" +`; + +exports[`LuaTable removed warning property access length: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + exports[`extension removed: code 1`] = ` "require(\\"lualib_bundle\\"); B = __TS__Class() @@ -18,12 +55,29 @@ exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@exte exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; -exports[`forRange deprecation: code 1`] = ` -"for i = 1, 10 do -end" +exports[`forRange removed: code 1`] = `""`; + +exports[`forRange removed: diagnostics 1`] = `"main.ts(4,25): error TSTL: '@forRange' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; + +exports[`luaiterator removed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local arr = {\\"a\\", \\"b\\", \\"c\\"} + local function luaIter(self) + local i = 0 + return function() return arr[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] end + end + local result = \\"\\" + return result +end +return ____exports" `; -exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; +exports[`luaiterator removed: diagnostics 1`] = `"main.ts(10,23): error TSTL: '@luaIterator' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luaiterator for more information."`; exports[`phantom removed: code 1`] = ` "A = A or ({}) @@ -44,7 +98,7 @@ __TS__ClassExtends(ClassB, ClassA)" exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; -exports[`vararg deprecation: code 1`] = ` +exports[`vararg removed: code 1`] = ` "function foo(self, ...) end function vararg(self, ...) @@ -52,4 +106,4 @@ function vararg(self, ...) end" `; -exports[`vararg deprecation: diagnostics 1`] = `"main.ts(6,17): warning TSTL: '@vararg' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; +exports[`vararg removed: diagnostics 1`] = `"main.ts(6,17): error TSTL: '@vararg' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap deleted file mode 100644 index e752d0782..000000000 --- a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap +++ /dev/null @@ -1,89 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`invalid usage argument count ([]): code 1`] = ` -"for i = 0, 0 do -end" -`; - -exports[`invalid usage argument count ([]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 0."`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): code 1`] = ` -"for i = 1, 2, 3 do -end" -`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 4."`; - -exports[`invalid usage argument count ([1]): code 1`] = ` -"for i = 1, 0 do -end" -`; - -exports[`invalid usage argument count ([1]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 1."`; - -exports[`invalid usage argument types: code 1`] = ` -"for i = \\"foo\\", 2 do -end" -`; - -exports[`invalid usage argument types: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: arguments must be numbers."`; - -exports[`invalid usage non-ambient declaration: code 1`] = ` -"function luaRange(self) -end" -`; - -exports[`invalid usage non-ambient declaration: diagnostics 1`] = `"main.ts(3,22): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage non-declared loop variable: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage non-declared loop variable: diagnostics 1`] = `"main.ts(7,18): error TSTL: Invalid @forRange call: loop must declare it's own control variable."`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): code 1`] = ` -"call = nil -call(_G, luaRange)" -`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): diagnostics 1`] = `"main.ts(6,49): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): code 1`] = `"range = luaRange(_G, 1, 10)"`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): diagnostics 1`] = `"main.ts(6,27): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): code 1`] = ` -"for ____, i in ipairs( - { - table.unpack( - luaRange(_G, 1, 10) - ) - } -) do -end" -`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): diagnostics 1`] = `"main.ts(6,33): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): code 1`] = `"array = {0, luaRange, 1}"`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = `"luaRange(nil, 0, 0, 0)"`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): diagnostics 1`] = `"main.ts(6,13): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage return type: code 1`] = ` -"for i = 1, 10 do -end" -`; - -exports[`invalid usage return type: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: function must return Iterable."`; - -exports[`invalid usage variable destructuring: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage variable destructuring: diagnostics 1`] = `"main.ts(6,18): error TSTL: Invalid @forRange call: destructuring cannot be used."`; diff --git a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap b/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap deleted file mode 100644 index 24761ca3a..000000000 --- a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`forof lua iterator tuple-return single existing variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single existing variable: diagnostics 1`] = `"main.ts(9,14): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; - -exports[`forof lua iterator tuple-return single variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single variable: diagnostics 1`] = `"main.ts(8,18): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; diff --git a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap b/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap deleted file mode 100644 index fae2b1f20..000000000 --- a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap +++ /dev/null @@ -1,197 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Ext = __TS__Class() -Ext.name = \\"Ext\\" -__TS__ClassExtends(Ext, Table)" -`; - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,19): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Ext = __TS__Class() - Ext.name = \\"Ext\\" - __TS__ClassExtends(Ext, Table) - return Ext -end)()" -`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,29): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot isolate LuaTable method ("get"): code 1`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): code 2`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): code 1`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): code 2`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot set LuaTable length: code 1`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: code 2`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot set LuaTable length: diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 1`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 2`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 1`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 2`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 1`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 2`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): code 1`] = ` -"require(\\"lualib_bundle\\"); -__TS__InstanceOf(tbl, Table)" -`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): diagnostics 1`] = `"main.ts(11,1): error TSTL: The instanceof operator cannot be used with a '@luaTable' class."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 1`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 2`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 1`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 2`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 1`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 2`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 1`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 2`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 1`] = `"main.ts(11,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 2`] = `"main.ts(13,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 1`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 2`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 1`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 2`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 1`] = `"main.ts(11,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 2`] = `"main.ts(13,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 1`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 2`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Table = __TS__Class() -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Table = __TS__Class() - Table.name = \\"Table\\" - function Table.prototype.____constructor(self) - end - return Table -end)()" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): diagnostics 1`] = `"main.ts(1,28): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local ____exports = {} -____exports.Table = __TS__Class() -local Table = ____exports.Table -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end -return ____exports" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 1`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 2`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 1`] = `"main.ts(11,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 2`] = `"main.ts(13,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTables cannot be constructed with arguments: code 1`] = `"____table = {}"`; - -exports[`LuaTables cannot be constructed with arguments: diagnostics 1`] = `"main.ts(11,15): error TSTL: Invalid @luaTable usage: No parameters are allowed when constructing a LuaTable object."`; - -exports[`LuaTables cannot have other members: code 1`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 2`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 3`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: code 4`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: diagnostics 1`] = `"main.ts(11,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 2`] = `"main.ts(13,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 3`] = `"main.ts(11,13): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 4`] = `"main.ts(13,13): error TSTL: LuaTable.other is unsupported."`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 9c81b2176..2f0edb105 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -1,4 +1,4 @@ -import { annotationDeprecated, annotationRemoved } from "../../../src/transformation/utils/diagnostics"; +import { annotationRemoved } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test.each(["extension", "metaExtension"])("extension removed", extensionType => { @@ -26,15 +26,15 @@ test("pureAbstract removed", () => { `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("forRange deprecation", () => { +test("forRange removed", () => { util.testModule` /** @forRange */ declare function forRange(start: number, limit: number, step?: number): number[]; for (const i of forRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("vararg deprecation", () => { +test("vararg removed", () => { util.testModule` /** @vararg */ type VarArg = T & { readonly __brand: unique symbol }; @@ -42,5 +42,62 @@ test("vararg deprecation", () => { function vararg(...args: VarArg) { foo(...args); } - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("luaiterator removed", () => { + util.testFunction` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +const tableLibClass = ` +/** @luaTable */ +declare class Table { + length: number; + constructor(notAllowed?: any); + set(key?: K, value?: V, notAllowed?: any): void; + get(key?: K, notAllowed?: any): V; + other(): void; +} +declare let tbl: Table; +`; + +test("LuaTable removed warning constructor", () => { + util.testModule("const table = new Table();") + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access length", () => { + util.testFunction` + return tbl.length; + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access get", () => { + util.testFunction` + return tbl.get("foo"); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable deprecation warning property access set", () => { + util.testFunction` + return tbl.set("foo", 0); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts deleted file mode 100644 index 35dc285b1..000000000 --- a/test/unit/annotations/forRange.spec.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { annotationDeprecated, invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` - /** @forRange */ - declare function luaRange(${args}): ${returns}; -`; - -test.each([ - { args: [1, 10], results: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { args: [1, 10, 2], results: [1, 3, 5, 7, 9] }, - { args: [10, 1, -1], results: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, - { args: [10, 1, -2], results: [10, 8, 6, 4, 2] }, -])("usage in for...of loop", ({ args, results }) => { - util.testModule` - ${createForRangeDeclaration()} - export const results: number[] = []; - - for (const i of luaRange(${args})) { - results.push(i); - } - ` - .setReturnExport("results") - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToEqual(results); -}); - -describe("invalid usage", () => { - test("non-ambient declaration", () => { - util.testModule` - /** @forRange */ - function luaRange() {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { - util.testModule` - ${createForRangeDeclaration("...args: number[]")} - for (const i of luaRange(${args})) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("non-declared loop variable", () => { - util.testModule` - ${createForRangeDeclaration()} - let i: number; - for (i of luaRange(1, 10, 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("argument types", () => { - util.testModule` - ${createForRangeDeclaration("i: string, j: number")} - for (const i of luaRange("foo", 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("variable destructuring", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "number[][]")} - for (const [i] of luaRange(1, 10, 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("return type", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "string[]")} - for (const i of luaRange(1, 10)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each([ - "const range = luaRange(1, 10);", - "luaRange.call(null, 0, 0, 0);", - "let array = [0, luaRange, 1];", - "const call = undefined as any; call(luaRange);", - "for (const i of [...luaRange(1, 10)]) {}", - ])("reference (%p)", statement => { - util.testModule` - ${createForRangeDeclaration()} - ${statement} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); -}); diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts deleted file mode 100644 index b1efc62ca..000000000 --- a/test/unit/annotations/luaIterator.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import * as util from "../../util"; -import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; - -test("forof lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof array lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Array {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof lua iterator with existing variable", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - let e: string; - for (e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof lua iterator destructuring", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator destructuring with existing variables", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return with existing variables", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return single variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - for (let x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof lua iterator tuple-return single existing variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - let x: [string, string]; - for (x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof forwarded lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - function iter() { return arr[i++]; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let a of forward()) { result += a; } - return result; - `.expectToEqual("abc"); -}); - -test("forof forwarded lua iterator with tupleReturn", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let [a, b] of forward()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts deleted file mode 100644 index 0f9cbbf36..000000000 --- a/test/unit/annotations/luaTable.spec.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { - luaTableCannotBeAccessedDynamically, - luaTableCannotBeExtended, - luaTableForbiddenUsage, - luaTableMustBeAmbient, - unsupportedProperty, - luaTableInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const tableLibClass = ` -/** @luaTable */ -declare class Table { - length: number; - constructor(notAllowed?: any); - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} -declare let tbl: Table; -`; - -const tableLibInterface = ` -/** @luaTable */ -declare interface Table { - length: number; - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} - -/** @luaTable */ -declare const Table: new (notAllowed?: any) => Table; -declare let tbl: Table; -`; - -test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule("const table = new Table(true);") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); -}); - -test.each([tableLibClass, tableLibInterface])( - "LuaTable set() cannot be used in a LuaTable call expression", - tableLib => { - util.testModule('const exp = tbl.set("value", 5)') - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); - } -); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule("tbl.other()").setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule("let x = tbl.other()") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass])("LuaTable new", tableLib => { - expect(util.testFunction("tbl = new Table();").setTsHeader(tableLib).getMainLuaCodeChunk()).toContain("tbl = {}"); -}); - -test.each([tableLibClass])("LuaTable length", tableLib => { - util.testFunction` - tbl = new Table(); - return tbl.length; - ` - .setTsHeader(tableLib) - .expectToEqual(0); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule("tbl.length = 2;") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); -}); - -test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { - test.each([ - "tbl.get()", - 'tbl.get("field", "field2")', - "tbl.set()", - 'tbl.set("field")', - 'tbl.set("field", 0, 1)', - 'tbl.set(...(["field", 0] as const))', - 'tbl.set("field", ...([0] as const))', - ])("Forbidden LuaTable use (%p)", invalidCode => { - util.testModule(invalidCode) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); - }); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( - "Cannot extend LuaTable class (%p)", - code => { - util.testModule(code) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); - } - ); -}); - -test.each([ - "/** @luaTable */ class Table {}", - "/** @luaTable */ export class Table {}", - "/** @luaTable */ const c = class Table {}", -])("LuaTable classes must be ambient (%p)", code => { - util.testModule(code).expectDiagnosticsToMatchSnapshot([luaTableMustBeAmbient.code]); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { - util.testModule(code).setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); - }); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpression on a LuaTable", tableLib => { - test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( - "Cannot use ElementAccessExpression on a LuaTable (%p)", - code => { - util.testModule(code) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableCannotBeAccessedDynamically.code]); - } - ); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { - test.each(["set", "get"])("Cannot isolate LuaTable method (%p)", propertyName => { - util.testModule(`${tableLib} let property = tbl.${propertyName}`).expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); - }); -}); - -test.each([tableLibClass])("LuaTable functional tests", tableLib => { - test.each<[string, any]>([ - ['const t = new Table(); t.set("field", "value"); return t.get("field");', "value"], - ['const t = new Table(); t.set("field", 0); return t.get("field");', 0], - ["const t = new Table(); t.set(1, true); return t.length", 1], - ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], - ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], - ])("LuaTable test (%p)", (code, expectedReturnValue) => { - util.testFunction(code).setTsHeader(tableLib).expectToEqual(expectedReturnValue); - }); -}); diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts deleted file mode 100644 index 1b80e73db..000000000 --- a/test/unit/annotations/vararg.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const varargDeclaration = ` - /** @vararg */ - type LuaVararg = A & { __luaVararg?: never }; -`; - -test("@vararg", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join(""); - } - function bar(a: unknown, ...b: LuaVararg) { - return foo(a, ...b); - } - return bar("A", "B", "C", "D"); - ` - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("@vararg array access", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join("") + b[0]; - } - return foo("A", "B", "C", "D"); - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("@vararg global", () => { - util.testModule` - ${varargDeclaration} - declare const arg: LuaVararg; - export const result = [...arg].join(""); - ` - .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToEqual({ result: "ABCD" }); -}); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 987f53628..a3d4db239 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -465,54 +465,6 @@ describe("for...of empty destructuring", () => { return i; `.expectToMatchJsResult(); }); - - test("luaIterator", () => { - const luaResult = util.testFunction` - const arr = [["a"], ["b"], ["c"]]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let it = 0; - return (() => arr[it++]) as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `.getLuaExecutionResult(); - // Can't use expectToMatchJsResult because above is not valid TS/JS - expect(luaResult).toBe(3); - }); - - test("luaIterator+tupleReturn", () => { - const luaResult = util.testFunction` - const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let it = 0; - /** @tupleReturn */ - function iter() { - const e = arr[it++]; - if (e) { - return e; - } - } - return iter as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `.getLuaExecutionResult(); - // Can't use expectToMatchJsResult because above is not valid TS/JS - expect(luaResult).toBe(3); - }); }; describe("declaration", () => declareTests("const ")); From 691c9cc7bde8dfd89f44e61cf0777e4bdfbd3fcd Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 14 Jun 2021 18:51:26 +0200 Subject: [PATCH 72/91] Module resolution from node_modules (#1011) * Create test project with node_modules * testProject test util * Fix typos in module resolution test * Base case module resolution * Replace requires in source maps too * Fixed incorrect path behavior * More tests * add module resolution with sourceDir node_modules * Get all module-resolution testcases to work * Restrict resolver to only lua files * All tests working * Added more in-project dependency checks to sourceDir test * Fixed problem with lua sibling files * Also resolve JSON modules * Add debug to resolution test to try to figure out why CI is failing * fix test runner path preloading * Revert "Add debug to resolution test to try to figure out why CI is failing" This reverts commit 7b8bd80e2bc961037384863bf836b0c982b3372d. * Changed resolution failure from error to warning * move json.lua from dist to src in benchmark * Use commit version instead of master to compile benchmark scripts * Added module resolution test project with lua sources * Add library compilation mode * renamed compilemode to buildmode * clean up resolve * Fix tests * Removed old project test runner * PR comments * Remove file casing test * Resolution + library mode combined test * remove out path logic from printer * Fixed bundle entry point require not being resolved correctly * Add header to bundle * Made couldNotResolveRequire an error instead of warning * updated couldnotResolveRequire snapshot --- .eslintignore | 1 + .github/workflows/ci.yml | 8 +- .vscode/launch.json | 17 ++ benchmark/{dist => src}/json.lua | 0 package-lock.json | 46 ++- package.json | 1 + src/CompilerOptions.ts | 6 + src/LuaPrinter.ts | 24 +- src/cli/parse.ts | 8 +- src/transformation/utils/diagnostics.ts | 4 - src/transformation/visitors/modules/import.ts | 34 +-- src/transpilation/bundle.ts | 42 ++- src/transpilation/diagnostics.ts | 15 +- src/transpilation/index.ts | 2 +- src/transpilation/output-collector.ts | 3 +- src/transpilation/resolve.ts | 231 ++++++++++++++ src/transpilation/transpile.ts | 9 +- src/transpilation/transpiler.ts | 71 ++++- src/transpilation/utils.ts | 1 + test/cli/parse.spec.ts | 6 + test/translation/transformation.spec.ts | 3 +- .../__snapshots__/directories.spec.ts.snap | 8 - .../__snapshots__/project.spec.ts.snap | 12 +- test/transpile/bundle.spec.ts | 11 +- test/transpile/directories.spec.ts | 1 - .../baseurl/src/lib/nested/file.ts | 3 - .../transpile/directories/baseurl/src/main.ts | 3 - test/transpile/module-resolution.spec.ts | 282 ++++++++++++++++++ .../project-with-dependency-chain/main.ts | 4 + .../node_modules/dependency1/index.d.ts | 3 + .../node_modules/dependency1/index.lua | 7 + .../node_modules/dependency1/otherfile.lua | 5 + .../node_modules/dependency2/index.lua | 5 + .../node_modules/dependency3/index.lua | 3 + .../tsconfig.json | 10 + .../lua_sources/otherluaFile.d.ts | 2 + .../lua_sources/otherluaFile.lua | 3 + .../project-with-lua-sources/luafile.d.ts | 2 + .../project-with-lua-sources/luafile.lua | 3 + .../project-with-lua-sources/main.ts | 5 + .../project-with-lua-sources/tsconfig.json | 9 + .../lua-global-without-decls.d.ts | 4 + .../lua-module-without-decls.d.ts | 9 + .../project-with-node-modules/main.ts | 39 +++ .../lua-global-with-decls/baz.d.ts | 1 + .../lua-global-with-decls/baz.lua | 3 + .../lua-global-with-decls/index.d.ts | 3 + .../lua-global-with-decls/index.lua | 6 + .../lua-global-without-decls/baz.lua | 3 + .../lua-global-without-decls/index.lua | 6 + .../lua-module-with-decls/baz.d.ts | 2 + .../lua-module-with-decls/baz.lua | 5 + .../lua-module-with-decls/index.d.ts | 3 + .../lua-module-with-decls/index.lua | 8 + .../lua-module-with-dependency/index.d.ts | 2 + .../lua-module-with-dependency/index.lua | 7 + .../lua-module-without-decls/baz.lua | 5 + .../lua-module-without-decls/index.lua | 8 + .../project-with-node-modules/tsconfig.json | 12 + .../node_modules/dependency1/index.d.ts | 2 + .../node_modules/dependency1/index.lua | 5 + .../node_modules/dependency2/index.lua | 5 + .../node_modules/dependency3/index.lua | 3 + .../project-with-sourceDir/src/main.ts | 9 + .../src/subdir/otherfile.ts | 5 + .../src/subdir/otherfile2.ts | 3 + .../src/subdir/subdirofsubdir/nestedfile.ts | 9 + .../project-with-sourceDir/tsconfig.json | 10 + .../dependency1-ts/d1otherfile.ts | 3 + .../dependency1-ts/index.ts | 5 + .../dependency1-ts/tsconfig.json | 9 + .../dependency2-ts/d2otherfile.ts | 3 + .../dependency2-ts/main.ts | 5 + .../dependency2-ts/tsconfig.json | 9 + .../project-with-tstl-library-modules/main.ts | 8 + .../tsconfig.json | 1 + test/transpile/project.spec.ts | 15 +- test/transpile/run.ts | 10 - test/unit/bundle.spec.ts | 10 + test/unit/file.spec.ts | 14 + .../functions/noImplicitSelfOption.spec.ts | 6 +- .../__snapshots__/resolution.spec.ts.snap | 4 +- test/unit/modules/modules.spec.ts | 3 +- test/unit/modules/resolution.spec.ts | 5 +- test/unit/printer/sourcemaps.spec.ts | 24 +- test/util.ts | 75 +++-- 86 files changed, 1102 insertions(+), 197 deletions(-) create mode 100644 .vscode/launch.json rename benchmark/{dist => src}/json.lua (100%) create mode 100644 src/transpilation/resolve.ts delete mode 100644 test/transpile/directories/baseurl/src/lib/nested/file.ts delete mode 100644 test/transpile/directories/baseurl/src/main.ts create mode 100644 test/transpile/module-resolution.spec.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/main.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua create mode 100644 test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/luafile.lua create mode 100644 test/transpile/module-resolution/project-with-lua-sources/main.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/main.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/main.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 707cb8140..492195f96 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ /test/cli/errors /test/cli/watch /test/transpile/directories +/test/transpile/module-resolution/*/node_modules /test/transpile/outFile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13df095ec..968cd9b87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,14 +76,14 @@ jobs: run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark # Run master benchmark first and output to commit benchmark data - name: Build benchmark Lua 5.3 master - run: node ../dist/tstl.js -p tsconfig.53.json + run: node ../../commit/dist/tstl.js -p tsconfig.53.json working-directory: master/benchmark - name: Run benchmark Lua 5.3 master id: benchmark-lua-master run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json working-directory: master/benchmark/dist - name: Build benchmark LuaJIT master - run: node ../dist/tstl.js -p tsconfig.jit.json + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json working-directory: master/benchmark - name: Run benchmark LuaJIT master id: benchmark-jit-master @@ -91,14 +91,14 @@ jobs: working-directory: master/benchmark/dist # Run commit benchmark and compare with master - name: Build benchmark Lua 5.3 commit - run: node ../dist/tstl.js -p tsconfig.53.json + run: node ../../commit/dist/tstl.js -p tsconfig.53.json working-directory: commit/benchmark - name: Run benchmark Lua 5.3 commit id: benchmark-lua-commit run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json working-directory: commit/benchmark/dist - name: Build benchmark LuaJIT commit - run: node ../dist/tstl.js -p tsconfig.jit.json + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json working-directory: commit/benchmark - name: Run benchmark LuaJIT commit id: benchmark-jit-commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..a50a68074 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug current jest test", + "type": "node", + "request": "launch", + "env": { "CI": "true" }, + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/jest", + "args": ["--runInBand", "--no-cache", "--runTestsByPath", "${relativeFile}"], + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/benchmark/dist/json.lua b/benchmark/src/json.lua similarity index 100% rename from benchmark/dist/json.lua rename to benchmark/src/json.lua diff --git a/package-lock.json b/package-lock.json index 5b210730c..43137cbae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.39.6", "license": "MIT", "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", "typescript": "~4.3.2" @@ -3461,6 +3462,18 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -4684,8 +4697,7 @@ "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "node_modules/growly": { "version": "1.3.0", @@ -10585,11 +10597,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -10823,6 +10830,14 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "engines": { + "node": ">=6" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -14393,6 +14408,15 @@ "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -15355,8 +15379,7 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "growly": { "version": "1.3.0", @@ -20245,6 +20268,11 @@ } } }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", diff --git a/package.json b/package.json index 0fc954467..fc3604e49 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "node": ">=12.13.0" }, "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", "typescript": "~4.3.2" diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 439b29652..e06adc1f3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -25,6 +25,7 @@ export interface LuaPluginImport { } export type CompilerOptions = OmitIndexSignature & { + buildMode?: BuildMode; noImplicitSelf?: boolean; noHeader?: boolean; luaBundle?: string; @@ -53,6 +54,11 @@ export enum LuaTarget { LuaJIT = "JIT", } +export enum BuildMode { + Default = "default", + Library = "library", +} + export const isBundleEnabled = (options: CompilerOptions) => options.luaBundle !== undefined && options.luaBundleEntry !== undefined; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e2a6eafe6..390b62977 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,4 +1,3 @@ -import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -6,7 +5,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, normalizeSlashes, trimExtension } from "./utils"; +import { intersperse, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -25,6 +24,8 @@ const escapeStringMap: Record = { export const escapeString = (value: string) => `"${value.replace(escapeStringRegExp, char => escapeStringMap[char])}"`; +export const tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + /** * Checks that a name is valid for use in lua function declaration syntax: * @@ -124,22 +125,7 @@ export class LuaPrinter { constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { this.options = program.getCompilerOptions(); - - if (this.options.outDir) { - const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName); - if (this.options.sourceRoot) { - // When sourceRoot is specified, just use relative path inside rootDir - this.sourceFile = relativeFileName; - } else { - // Calculate relative path from rootDir to outDir - const outputPath = path.resolve(this.options.outDir, relativeFileName); - this.sourceFile = path.relative(path.dirname(outputPath), fileName); - } - // We want forward slashes, even in windows - this.sourceFile = normalizeSlashes(this.sourceFile); - } else { - this.sourceFile = path.basename(fileName); // File will be in same dir as source - } + this.sourceFile = fileName; } public print(file: lua.File): PrintResult { @@ -201,7 +187,7 @@ export class LuaPrinter { let header = file.trivia; if (!this.options.noHeader) { - header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + header += tstlHeader; } const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index fff0ef0d0..d29bf4e83 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; +import { BuildMode, CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; import * as cliDiagnostics from "./diagnostics"; export interface ParsedCommandLine extends ts.ParsedCommandLine { @@ -24,6 +24,12 @@ interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; export const optionDeclarations: CommandLineOption[] = [ + { + name: "buildMode", + description: "'default' or 'library'. Compiling as library will not resolve external dependencies.", + type: "enum", + choices: Object.values(BuildMode), + }, { name: "luaBundle", description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index ef699c07c..fcc37b6f0 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -94,10 +94,6 @@ export const invalidAmbientIdentifierName = createErrorDiagnosticFactory( (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` ); -export const unresolvableRequirePath = createErrorDiagnosticFactory( - (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` -); - export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index d36bb0509..d8daba8c9 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; @@ -10,36 +9,13 @@ import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { unresolvableRequirePath } from "../../utils/diagnostics"; -const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => - !relativePath.startsWith(".") && options.baseUrl - ? path.resolve(options.baseUrl, relativePath) - : path.resolve(directoryPath, relativePath); - -function getImportPath(context: TransformationContext, relativePath: string, node: ts.Node): string { - const { options, sourceFile } = context; - const { fileName } = sourceFile; - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absoluteImportPath = path.format( - path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) - ); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - if (absoluteImportPath.includes(absoluteRootDirPath)) { - return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); - } else { - context.diagnostics.push(unresolvableRequirePath(node, relativePath)); - return relativePath; - } -} - -function shouldResolveModulePath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { +function isNoResolutionPath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier); - if (!moduleOwnerSymbol) return true; + if (!moduleOwnerSymbol) return false; const annotations = getSymbolAnnotations(moduleOwnerSymbol); - return !annotations.has(AnnotationKind.NoResolution); + return annotations.has(AnnotationKind.NoResolution); } export function createModuleRequire( @@ -49,8 +25,8 @@ export function createModuleRequire( ): lua.CallExpression { const params: lua.Expression[] = []; if (ts.isStringLiteral(moduleSpecifier)) { - const modulePath = shouldResolveModulePath(context, moduleSpecifier) - ? getImportPath(context, moduleSpecifier.text.replace(/"/g, ""), moduleSpecifier) + const modulePath = isNoResolutionPath(context, moduleSpecifier) + ? `@NoResolution:${moduleSpecifier.text}` : moduleSpecifier.text; params.push(lua.createStringLiteral(modulePath)); diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index c696c6900..31d58b27b 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -2,13 +2,14 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; -import { escapeString } from "../LuaPrinter"; +import { escapeString, tstlHeader } from "../LuaPrinter"; import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; -import { EmitFile, EmitHost, ProcessedFile } from "./utils"; +import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; +import { EmitFile, ProcessedFile } from "./utils"; -const createModulePath = (baseDir: string, pathToResolve: string) => - escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); +const createModulePath = (pathToResolve: string, program: ts.Program) => + escapeString(formatPathToLuaPath(trimExtension(getEmitPathRelativeToOutDir(pathToResolve, program)))); // Override `require` to read from ____modules table. const requireOverride = ` @@ -32,42 +33,37 @@ local function require(file) end `; -export function getBundleResult( - program: ts.Program, - emitHost: EmitHost, - files: ProcessedFile[] -): [ts.Diagnostic[], EmitFile] { +export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile] { const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; const bundleFile = cast(options.luaBundle, isNonNull); const entryModule = cast(options.luaBundleEntry, isNonNull); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; - const projectRootDir = options.configFilePath - ? path.dirname(options.configFilePath) - : emitHost.getCurrentDirectory(); - // Resolve project settings relative to project file. - const resolvedEntryModule = path.resolve(projectRootDir, entryModule); - const outputPath = normalizeSlashes(path.resolve(projectRootDir, bundleFile)); + const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); + const outputPath = normalizeSlashes(path.resolve(getEmitOutDir(program), bundleFile)); - if (!files.some(f => f.fileName === resolvedEntryModule)) { + if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); - return [diagnostics, { outputPath, code: "" }]; } // For each file: [""] = function() end, - const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(outDir, f.fileName))); + const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program))); // Create ____modules table containing all entries from moduleTableEntries const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(outDir, resolvedEntryModule)})\n`; + const entryPoint = `return require(${createModulePath(entryModule, program)})\n`; + + const sourceChunks = [requireOverride, moduleTable, entryPoint]; + + if (!options.noHeader) { + sourceChunks.unshift(tstlHeader); + } - const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); + const bundleNode = joinSourceChunks(sourceChunks); const { code, map } = bundleNode.toStringWithSourceMap(); return [ @@ -83,7 +79,7 @@ export function getBundleResult( function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { const tableEntryHead = `[${modulePath}] = function() `; - const tableEntryTail = "end,\n"; + const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); } diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index d0e609677..bfae6b140 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -1,8 +1,19 @@ import * as ts from "typescript"; import { createSerialDiagnosticFactory } from "../utils"; -const createDiagnosticFactory = (getMessage: (...args: TArgs) => string) => - createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args) })); +const createDiagnosticFactory = ( + getMessage: (...args: TArgs) => string, + category: ts.DiagnosticCategory = ts.DiagnosticCategory.Error +) => createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args), category })); + +export const couldNotResolveRequire = createDiagnosticFactory( + (requirePath: string, containingFile: string) => + `Could not resolve require path '${requirePath}' in file ${containingFile}.` +); + +export const couldNotReadDependency = createDiagnosticFactory( + (dependency: string) => `Could not read content of resolved dependency ${dependency}.` +); export const toLoadItShouldBeTranspiled = createDiagnosticFactory( (kind: string, transform: string) => diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 608b42818..59e83233a 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -45,7 +45,7 @@ const libCache: { [key: string]: ts.SourceFile } = {}; /** @internal */ export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { const compilerHost: ts.CompilerHost = { - fileExists: () => true, + fileExists: fileName => fileName in input || ts.sys.fileExists(fileName), getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", getDefaultLibFileName: ts.getDefaultLibFileName, diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts index d18137c5a..866c1f79a 100644 --- a/src/transpilation/output-collector.ts +++ b/src/transpilation/output-collector.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import { intersection, union } from "../utils"; export interface TranspiledFile { + outPath: string; sourceFiles: ts.SourceFile[]; lua?: string; luaSourceMap?: string; @@ -18,7 +19,7 @@ export function createEmitOutputCollector() { const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); if (!file) { - file = { sourceFiles: [...sourceFiles] }; + file = { outPath: fileName, sourceFiles: [...sourceFiles] }; files.push(file); } else { file.sourceFiles = union(file.sourceFiles, sourceFiles); diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts new file mode 100644 index 000000000..3eca25e2e --- /dev/null +++ b/src/transpilation/resolve.ts @@ -0,0 +1,231 @@ +import * as path from "path"; +import * as resolve from "enhanced-resolve"; +import * as ts from "typescript"; +import * as fs from "fs"; +import { EmitHost, ProcessedFile } from "./utils"; +import { SourceNode } from "source-map"; +import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./transpiler"; +import { formatPathToLuaPath, trimExtension } from "../utils"; +import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; +import { BuildMode } from "../CompilerOptions"; + +const resolver = resolve.ResolverFactory.createResolver({ + extensions: [".lua"], + enforceExtension: true, // Resolved file must be a lua file + fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, + useSyncFileSystemCalls: true, +}); + +interface ResolutionResult { + resolvedFiles: ProcessedFile[]; + diagnostics: ts.Diagnostic[]; +} + +export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { + const outFiles: ProcessedFile[] = [...files]; + const diagnostics: ts.Diagnostic[] = []; + + // Resolve dependencies for all processed files + for (const file of files) { + const resolutionResult = resolveFileDependencies(file, program, emitHost); + outFiles.push(...resolutionResult.resolvedFiles); + diagnostics.push(...resolutionResult.diagnostics); + } + + return { resolvedFiles: outFiles, diagnostics }; +} + +function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { + const dependencies: ProcessedFile[] = []; + const diagnostics: ts.Diagnostic[] = []; + + for (const required of findRequiredPaths(file.code)) { + // Do no resolve lualib + if (required === "lualib_bundle") { + continue; + } + + // Do not resolve noResolution paths + if (required.startsWith("@NoResolution:")) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + continue; + } + + // Try to resolve the import starting from the directory `file` is in + const fileDir = path.dirname(file.fileName); + const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); + if (resolvedDependency) { + // Figure out resolved require path and dependency output path + const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); + + if (shouldRewriteRequires(resolvedDependency, program)) { + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); + } + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + if (shouldIncludeDependency(resolvedDependency, program)) { + // If dependency resolved successfully, read its content + const dependencyContent = emitHost.readFile(resolvedDependency); + if (dependencyContent === undefined) { + diagnostics.push(couldNotReadDependency(resolvedDependency)); + continue; + } + + const dependency = { + fileName: resolvedDependency, + code: dependencyContent, + }; + const nestedDependencies = resolveFileDependencies(dependency, program, emitHost); + dependencies.push(dependency, ...nestedDependencies.resolvedFiles); + diagnostics.push(...nestedDependencies.diagnostics); + } + } else { + // Could not resolve dependency, add a diagnostic and make some fallback path + diagnostics.push(couldNotResolveRequire(required, path.relative(getProjectRoot(program), file.fileName))); + + const fallbackRequire = fallbackResolve(required, getSourceDir(program), fileDir); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); + } + } + return { resolvedFiles: dependencies, diagnostics }; +} + +function resolveDependency( + fileDirectory: string, + dependency: string, + program: ts.Program, + emitHost: EmitHost +): string | undefined { + // Check if file is a file in the project + const resolvedPath = path.join(fileDirectory, dependency); + + if (isProjectFile(resolvedPath, program)) { + // JSON files need their extension as part of the import path, caught by this branch + return resolvedPath; + } + + const resolvedFile = resolvedPath + ".ts"; + if (isProjectFile(resolvedFile, program)) { + return resolvedFile; + } + + const projectIndexPath = path.resolve(resolvedPath, "index.ts"); + if (isProjectFile(projectIndexPath, program)) { + return projectIndexPath; + } + + // Check if this is a sibling of a required lua file + const luaFilePath = path.resolve(fileDirectory, dependency + ".lua"); + if (emitHost.fileExists(luaFilePath)) { + return luaFilePath; + } + + // Not a TS file in our project sources, use resolver to check if we can find dependency + try { + const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); + if (resolveResult) { + return resolveResult; + } + } catch (e) { + // resolveSync errors if it fails to resolve + } + + return undefined; +} + +function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { + return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); +} + +function shouldIncludeDependency(resolvedDependency: string, program: ts.Program) { + // Never include lua files (again) that are transpiled from project sources + if (!hasSourceFileInProject(resolvedDependency, program)) { + // Always include lua files not in node_modules (internal lua sources) + if (!isNodeModulesFile(resolvedDependency)) { + return true; + } else { + // Only include node_modules files if not in library mode + return !isBuildModeLibrary(program); + } + } + return false; +} + +function isBuildModeLibrary(program: ts.Program) { + return program.getCompilerOptions().buildMode === BuildMode.Library; +} + +function findRequiredPaths(code: string): string[] { + // Find all require("") paths in a lua code string + const paths: string[] = []; + const pattern = /require\("(.+)"\)/g; + // eslint-disable-next-line @typescript-eslint/ban-types + let match: RegExpExecArray | null; + while ((match = pattern.exec(code))) { + paths.push(match[1]); + } + + return paths; +} + +function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + file.code = file.code.replace(`require("${originalRequire}")`, `require("${requirePath}")`); +} + +function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + if (file.sourceMapNode) { + replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire}"`, `"${requirePath}"`); + } +} + +function replaceInSourceMap(node: SourceNode, parent: SourceNode, require: string, resolvedRequire: string): boolean { + if ((!node.children || node.children.length === 0) && node.toString() === require) { + parent.children = [new SourceNode(node.line, node.column, node.source, [resolvedRequire])]; + return true; // Stop after finding the first occurrence + } + + if (node.children) { + for (const c of node.children) { + if (replaceInSourceMap(c, node, require, resolvedRequire)) { + return true; // Occurrence found in one of the children + } + } + } + + return false; // Did not find the require +} + +function isNodeModulesFile(filePath: string): boolean { + return path + .normalize(filePath) + .split(path.sep) + .some(p => p === "node_modules"); +} + +function isProjectFile(file: string, program: ts.Program): boolean { + return program.getSourceFile(file) !== undefined; +} + +function hasSourceFileInProject(filePath: string, program: ts.Program) { + const pathWithoutExtension = trimExtension(filePath); + return ( + isProjectFile(pathWithoutExtension + ".ts", program) || isProjectFile(pathWithoutExtension + ".json", program) + ); +} + +// Transform an import path to a lua require that is probably not correct, but can be used as fallback when regular resolution fails +function fallbackResolve(required: string, sourceRootDir: string, fileDir: string): string { + return formatPathToLuaPath( + path + .normalize(path.join(path.relative(sourceRootDir, fileDir), required)) + .split(path.sep) + .filter(s => s !== "." && s !== "..") + .join(path.sep) + ); +} diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index cbc77c13c..0d3071f73 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -65,9 +65,12 @@ export function getProgramTranspileResult( diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { const printResult = printer(program, emitHost, sourceFile.fileName, file); - const sourceRootDir = program.getCommonSourceDirectory(); - const fileName = path.resolve(sourceRootDir, sourceFile.fileName); - transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst: file, ...printResult }); + transpiledFiles.push({ + sourceFiles: [sourceFile], + fileName: path.normalize(sourceFile.fileName), + luaAst: file, + ...printResult, + }); } }; diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 205b6b2db..7b5eb0f3f 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -4,6 +4,7 @@ import { isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; +import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; import { EmitFile, EmitHost, ProcessedFile } from "./utils"; @@ -33,6 +34,7 @@ export class Transpiler { writeFile, emitOptions ); + const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); const options = program.getCompilerOptions(); @@ -53,28 +55,79 @@ export class Transpiler { files: ProcessedFile[] ): { emitPlan: EmitFile[] } { const options = program.getCompilerOptions(); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); if (lualibRequired) { - const fileName = normalizeSlashes(path.resolve(rootDir, "lualib_bundle.lua")); + // 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")); files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); } + // Resolve imported modules and modify output Lua requires + const resolutionResult = resolveDependencies(program, files, this.emitHost); + diagnostics.push(...resolutionResult.diagnostics); + let emitPlan: EmitFile[]; if (isBundleEnabled(options)) { - const [bundleDiagnostics, bundleFile] = getBundleResult(program, this.emitHost, files); + const [bundleDiagnostics, bundleFile] = getBundleResult(program, resolutionResult.resolvedFiles); diagnostics.push(...bundleDiagnostics); emitPlan = [bundleFile]; } else { - emitPlan = files.map(file => { - const pathInOutDir = path.resolve(outDir, path.relative(rootDir, file.fileName)); - const outputPath = normalizeSlashes(trimExtension(pathInOutDir) + ".lua"); - return { ...file, outputPath }; - }); + emitPlan = resolutionResult.resolvedFiles.map(file => ({ + ...file, + outputPath: getEmitPath(file.fileName, program), + })); } return { emitPlan }; } } + +export function getEmitPath(file: string, program: ts.Program): string { + const relativeOutputPath = getEmitPathRelativeToOutDir(file, program); + const outDir = getEmitOutDir(program); + + return path.join(outDir, relativeOutputPath); +} + +export function getEmitPathRelativeToOutDir(fileName: string, program: ts.Program): string { + const sourceDir = getSourceDir(program); + // Default output path is relative path in source dir + let emitPathSplits = path.relative(sourceDir, fileName).split(path.sep); + + // If source is in a parent directory of source dir, move it into the source dir + emitPathSplits = emitPathSplits.filter(s => s !== ".."); + + // To avoid overwriting lua sources in node_modules, emit into lua_modules + if (emitPathSplits[0] === "node_modules") { + emitPathSplits[0] = "lua_modules"; + } + + // Make extension lua + emitPathSplits[emitPathSplits.length - 1] = trimExtension(emitPathSplits[emitPathSplits.length - 1]) + ".lua"; + + return path.join(...emitPathSplits); +} + +export function getSourceDir(program: ts.Program): string { + const rootDir = program.getCompilerOptions().rootDir; + if (rootDir && rootDir.length > 0) { + return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir); + } + return program.getCommonSourceDirectory(); +} + +export function getEmitOutDir(program: ts.Program): string { + const outDir = program.getCompilerOptions().outDir; + if (outDir && outDir.length > 0) { + return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir); + } + return program.getCommonSourceDirectory(); +} + +export function getProjectRoot(program: ts.Program): string { + // Try to get the directory the tsconfig is in + const tsConfigPath = program.getCompilerOptions().configFilePath; + // If no tsconfig is known, use common source directory + return tsConfigPath ? path.dirname(tsConfigPath) : program.getCommonSourceDirectory(); +} diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 099dfd400..a4acdfbb4 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -8,6 +8,7 @@ import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; export interface EmitHost { + fileExists(path: string): boolean; getCurrentDirectory(): string; readFile(path: string): string | undefined; writeFile: ts.WriteFileCallback; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 06ed05f75..f66b97766 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -105,6 +105,9 @@ describe("command line", () => { ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], @@ -213,6 +216,9 @@ describe("tsconfig", () => { ["sourceMapTraceback", false, { sourceMapTraceback: false }], ["sourceMapTraceback", true, { sourceMapTraceback: true }], + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 4e0d7dd9d..42a4b4355 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -2,6 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as tstl from "../../src"; import { annotationDeprecated } from "../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../src/transpilation/diagnostics"; import * as util from "../util"; const fixturesPath = path.join(__dirname, "./transformation"); @@ -14,7 +15,7 @@ const fixtures = fs test.each(fixtures)("Transformation (%s)", (_name, content) => { util.testModule(content) .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) - .ignoreDiagnostics([annotationDeprecated.code]) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index 901d885f4..eaf179a6c 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -1,13 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should be able to resolve ({"name": "baseurl", "options": [Object]}) 1`] = ` -Array [ - "directories/baseurl/out/lualib_bundle.lua", - "directories/baseurl/out/src/lib/nested/file.lua", - "directories/baseurl/out/src/main.lua", -] -`; - exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` Array [ "directories/basic/src/lib/file.lua", diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 4db30085f..623480405 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -3,27 +3,23 @@ exports[`should transpile 1`] = ` Array [ Object { - "name": "project/otherFile.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "otherFile.lua", + "lua": "local ____exports = {} function ____exports.getNumber(self) return getAPIValue() end return ____exports ", - "writeByteOrderMark": false, }, Object { - "name": "project/index.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "index.lua", + "lua": "local ____exports = {} local ____otherFile = require(\\"otherFile\\") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) setAPIValue(myNumber * 5) return ____exports ", - "writeByteOrderMark": false, }, ] `; diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 0ccab7c70..69c86406e 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -1,20 +1,19 @@ import * as path from "path"; import * as util from "../util"; -import { transpileProjectResult } from "./run"; const projectDir = path.join(__dirname, "bundle"); const inputProject = path.join(projectDir, "tsconfig.json"); test("should transpile into one file", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(inputProject); + const { diagnostics, transpiledFiles } = util.testProject(inputProject).getLuaResult(); expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toHaveLength(1); + expect(transpiledFiles).toHaveLength(1); - const { name, text } = emittedFiles[0]; + const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(name).toBe("bundle/bundle.lua"); + expect(outPath.endsWith("bundle/bundle.lua")).toBe(true); // Verify exported module by executing // Use an empty TS string because we already transpiled the TS project - util.testModule("").setLuaHeader(text).expectToEqual({ myNumber: 3 }); + util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); }); diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 9141199e5..1c0bba994 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -13,7 +13,6 @@ test.each([ { name: "basic", options: { outDir: "out" } }, { name: "basic", options: { rootDir: "src" } }, { name: "basic", options: { rootDir: "src", outDir: "out" } }, - { name: "baseurl", options: { baseUrl: "./src/lib", rootDir: ".", outDir: "./out" } }, ])("should be able to resolve (%p)", ({ name, options: compilerOptions }) => { const projectPath = path.join(__dirname, "directories", name); jest.spyOn(process, "cwd").mockReturnValue(projectPath); diff --git a/test/transpile/directories/baseurl/src/lib/nested/file.ts b/test/transpile/directories/baseurl/src/lib/nested/file.ts deleted file mode 100644 index 4248a042b..000000000 --- a/test/transpile/directories/baseurl/src/lib/nested/file.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function test() { - return 1; -} diff --git a/test/transpile/directories/baseurl/src/main.ts b/test/transpile/directories/baseurl/src/main.ts deleted file mode 100644 index 1665f4e08..000000000 --- a/test/transpile/directories/baseurl/src/main.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { test } from "nested/file"; - -test(); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts new file mode 100644 index 000000000..c386e2d33 --- /dev/null +++ b/test/transpile/module-resolution.spec.ts @@ -0,0 +1,282 @@ +import * as path from "path"; +import * as tstl from "../../src"; +import * as util from "../util"; +import * as ts from "typescript"; +import { transpileProject } from "../../src"; + +describe("basic module resolution", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); + + const projectWithNodeModules = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")); + + test("can resolve global dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().globalWithDeclarationsResults).toEqual({ + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }); + }); + + test("can resolve global dependencies with hand-written declarations", () => { + // No declarations in the node_modules directory, but written by hand in project dir + expect(projectWithNodeModules.getLuaExecutionResult().globalWithoutDeclarationsResults).toEqual({ + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }); + }); + + test("can resolve module dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDeclarationsResults).toEqual({ + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }); + }); + + test("can resolve module dependencies with hand-written declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithoutDeclarationsResults).toEqual({ + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }); + }); + + test("can resolve package depencency with a dependency on another package", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDependencyResult).toEqual( + "Calling dependency: foo from lua module with decls" + ); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ + globalWithDeclarationsResults: { + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }, + globalWithoutDeclarationsResults: { + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }, + moduleWithDeclarationsResults: { + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }, + moduleWithDependencyResult: "Calling dependency: foo from lua module with decls", + moduleWithoutDeclarationsResults: { + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }, + }); + }); +}); + +describe("module resolution with chained dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("can resolve dependencies in chain", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .expectToEqual(expectedResult); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); + + test("works with different module setting", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ module: ts.ModuleKind.ESNext }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution with outDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("emits files in outDir", () => { + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(5); + expect(outPaths).toContain(path.join("tstl-out", "main.lua")); + // Note: outputs to lua_modules + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "otherfile.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency2", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency3", "index.lua")); + }); + + test("emits bundle in outDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ outDir: "tstl-out", luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(1); + expect(outPaths).toContain(path.join("tstl-out", "bundle.lua")); + }); +}); + +describe("module resolution with sourceDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-sourceDir"); + const expectedResult = { + result: "dependency3", + functionInSubDir: "non-node_modules import", + functionReExportedFromSubDir: "nested func result", + nestedFunctionInSubDirOfSubDir: "nested func result", + nestedFunctionUsingFunctionFromParentDir: "nested func: non-node_modules import 2", + }; + + test("can resolve dependencies with sourceDir", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "src", "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution project with lua sources", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + const expectedResult = { + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution in library mode", () => { + test("result does not contain resolved paths", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ buildMode: tstl.BuildMode.Library }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); + + test("project works in library mode because no external dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out", buildMode: tstl.BuildMode.Library }) + .expectToEqual({ + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }) + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); + + test("bundle works in library mode because no external dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + const mainFile = path.join(projectPath, "main.ts"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ buildMode: tstl.BuildMode.Library, luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }) + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); +}); + +describe("module resolution project with dependencies built by tstl library mode", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-modules"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + transpileProject(path.join(projectPath, "dependency2-ts", "tsconfig.json")); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + dependency2MainResult: "dependency 2 main", + dependency2OtherFileResult: "Dependency 2 func: my string argument", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); diff --git a/test/transpile/module-resolution/project-with-dependency-chain/main.ts b/test/transpile/module-resolution/project-with-dependency-chain/main.ts new file mode 100644 index 000000000..cda66cd55 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/main.ts @@ -0,0 +1,4 @@ +import * as dependency1 from "dependency1"; + +export const result = dependency1.f1(); +export const result2 = dependency1.otherFileFromDependency1(); diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..5155e72c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function f1(): string; +export declare function otherFileFromDependency1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua new file mode 100644 index 000000000..80cae6fb8 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua @@ -0,0 +1,7 @@ +local dependency2 = require("dependency2") +local otherfile = require("otherfile") + +return { + f1 = function() return dependency2.f2() end, + otherFileFromDependency1 = otherfile.someFunc +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..871964bf7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua @@ -0,0 +1,5 @@ +return { + someFunc = function() + return "someFunc from otherfile.lua" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts new file mode 100644 index 000000000..6166280f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcFromSubDir(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua new file mode 100644 index 000000000..a23007078 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua @@ -0,0 +1,3 @@ +return { + funcFromSubDir = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts new file mode 100644 index 000000000..6294675a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcInLuaFile(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.lua b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua new file mode 100644 index 000000000..56e61090f --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua @@ -0,0 +1,3 @@ +return { + funcInLuaFile = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/main.ts b/test/transpile/module-resolution/project-with-lua-sources/main.ts new file mode 100644 index 000000000..d4c19b440 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/main.ts @@ -0,0 +1,5 @@ +import { funcInLuaFile } from "./luafile"; +import { funcFromSubDir } from "./lua_sources/otherluaFile"; + +export const funcFromLuaFile = funcInLuaFile(); +export const funcFromSubDirLuaFile = funcFromSubDir(); diff --git a/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json new file mode 100644 index 000000000..a07455ed7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "outDir": "tstl-out" + } +} diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts new file mode 100644 index 000000000..4d1c1db1b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ +declare function fooGlobalWithoutDecls(): string; +declare function barGlobalWithoutDecls(param: string): string; +declare function bazGlobalWithoutDecls(): string; diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts new file mode 100644 index 000000000..9ccfc9bfe --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts @@ -0,0 +1,9 @@ +/** @noSelfInFile */ +declare module "lua-module-without-decls" { + function foo(this: void): string; + function bar(this: void, param: string): string; +} + +declare module "lua-module-without-decls/baz" { + function baz(this: void): string; +} diff --git a/test/transpile/module-resolution/project-with-node-modules/main.ts b/test/transpile/module-resolution/project-with-node-modules/main.ts new file mode 100644 index 000000000..8d9332190 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/main.ts @@ -0,0 +1,39 @@ +import "lua-global-with-decls"; +import "lua-global-with-decls/baz"; + +import "lua-global-without-decls"; +import "lua-global-without-decls/baz"; + +import * as moduleWithDeclarations from "lua-module-with-decls"; +import * as moduleWithDeclarationsBaz from "lua-module-with-decls/baz"; + +import * as moduleWithoutDeclarations from "lua-module-without-decls"; +import * as moduleWithoutDeclarationsBaz from "lua-module-without-decls/baz"; + +import * as moduleWithDependency from "lua-module-with-dependency"; + +export const globalWithDeclarationsResults = { + foo: fooGlobal(), + bar: barGlobal("global with declarations!"), + baz: bazGlobal(), +}; + +export const globalWithoutDeclarationsResults = { + foo: fooGlobalWithoutDecls(), + bar: barGlobalWithoutDecls("global without declarations!"), + baz: bazGlobalWithoutDecls(), +}; + +export const moduleWithDeclarationsResults = { + foo: moduleWithDeclarations.foo(), + bar: moduleWithDeclarations.bar("module with declarations!"), + baz: moduleWithDeclarationsBaz.baz(), +}; + +export const moduleWithoutDeclarationsResults = { + foo: moduleWithoutDeclarations.foo(), + bar: moduleWithoutDeclarations.bar("module without declarations!"), + baz: moduleWithoutDeclarationsBaz.baz(), +}; + +export const moduleWithDependencyResult = moduleWithDependency.callDependency(); diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts new file mode 100644 index 000000000..23f55b1ad --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts @@ -0,0 +1 @@ +declare function bazGlobal(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua new file mode 100644 index 000000000..952807f1a --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobal() + return "baz from lua global with decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts new file mode 100644 index 000000000..1339056b5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +declare function fooGlobal(): string; +declare function barGlobal(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua new file mode 100644 index 000000000..d10edd189 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobal() + return "foo from lua global with decls" +end +function barGlobal(param) + return "bar from lua global with decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua new file mode 100644 index 000000000..02980e662 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobalWithoutDecls() + return "baz from lua global without decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua new file mode 100644 index 000000000..46dd970a0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobalWithoutDecls() + return "foo from lua global without decls" +end +function barGlobalWithoutDecls(param) + return "bar from lua global without decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts new file mode 100644 index 000000000..5f46a6ce2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function baz(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua new file mode 100644 index 000000000..f4e16a0d7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module with decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts new file mode 100644 index 000000000..aa83ce4a6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function foo(): string; +export declare function bar(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua new file mode 100644 index 000000000..0c5d47fe6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module with decls" + end, + bar = function(param) + return "bar from lua module with decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts new file mode 100644 index 000000000..381596acd --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelf */ +export declare function callDependency(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua new file mode 100644 index 000000000..9bc475e5b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua @@ -0,0 +1,7 @@ +local dependency = require("lua-module-with-decls") + +return { + callDependency = function() + return "Calling dependency: " .. dependency.foo() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua new file mode 100644 index 000000000..7358f341b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module without decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua new file mode 100644 index 000000000..e73581589 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module without decls" + end, + bar = function(param) + return "bar from lua module without decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/tsconfig.json b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json new file mode 100644 index 000000000..935b64af6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..761d6bc02 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function f1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua new file mode 100644 index 000000000..dcf28d6fd --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua @@ -0,0 +1,5 @@ +local dependency2 = require("dependency2") + +return { + f1 = function() return dependency2.f2() end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/main.ts b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts new file mode 100644 index 000000000..9014f7b62 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts @@ -0,0 +1,9 @@ +import * as dependency1 from "dependency1"; +import { func, nestedFunc } from "./subdir/otherfile"; +import { nestedFunc as nestedFuncOriginal, nestedFuncUsingParent } from "./subdir/subdirofsubdir/nestedfile"; + +export const result = dependency1.f1(); +export const functionInSubDir = func(); +export const functionReExportedFromSubDir = nestedFunc(); +export const nestedFunctionInSubDirOfSubDir = nestedFuncOriginal(); +export const nestedFunctionUsingFunctionFromParentDir = nestedFuncUsingParent(); diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts new file mode 100644 index 000000000..c12dee955 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts @@ -0,0 +1,5 @@ +export function func() { + return "non-node_modules import"; +} + +export { nestedFunc } from "./subdirofsubdir/nestedfile"; diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts new file mode 100644 index 000000000..1132c2ea1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts @@ -0,0 +1,3 @@ +export function func2() { + return "non-node_modules import 2"; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts new file mode 100644 index 000000000..d316f023e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts @@ -0,0 +1,9 @@ +import { func2 } from "../otherfile2"; + +export function nestedFunc() { + return "nested func result"; +} + +export function nestedFuncUsingParent() { + return `nested func: ${func2()}`; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json new file mode 100644 index 000000000..200df2468 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "src" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts @@ -0,0 +1,3 @@ +export function dependency1OtherFileFunc() { + return "dependency1OtherFileFunc in dependency1/d1otherfile"; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts new file mode 100644 index 000000000..fc1cdddec --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts @@ -0,0 +1,5 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json new file mode 100644 index 000000000..5fcb76fbe --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency1", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts new file mode 100644 index 000000000..63e34f8b6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts @@ -0,0 +1,3 @@ +export function dependency2OtherFileFunc(this: void, arg: string) { + return `Dependency 2 func: ${arg}`; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts new file mode 100644 index 000000000..03b90c231 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts @@ -0,0 +1,5 @@ +export function dependency2Main() { + return "dependency 2 main"; +} + +export * from "./d2otherfile"; diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json new file mode 100644 index 000000000..f77b336a2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency2", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts new file mode 100644 index 000000000..c1286088a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts @@ -0,0 +1,8 @@ +import { dependency1IndexFunc } from "dependency1"; +import { dependency1OtherFileFunc } from "dependency1/d1otherfile"; +import { dependency2Main, dependency2OtherFileFunc } from "dependency2/main"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); +export const dependency2MainResult = dependency2Main(); +export const dependency2OtherFileResult = dependency2OtherFileFunc("my string argument"); diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index 6f262dada..965c834d7 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,8 +1,15 @@ import * as path from "path"; -import { transpileProjectResult } from "./run"; +import * as util from "../util"; test("should transpile", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(path.join(__dirname, "project", "tsconfig.json")); - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toMatchSnapshot(); + const projectDir = path.join(__dirname, "project"); + const { transpiledFiles } = util + .testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect( + transpiledFiles.map(f => ({ filePath: path.relative(projectDir, f.outPath), lua: f.lua })) + ).toMatchSnapshot(); }); diff --git a/test/transpile/run.ts b/test/transpile/run.ts index 8890d7a18..a24a76b9f 100644 --- a/test/transpile/run.ts +++ b/test/transpile/run.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../../src"; -import { parseConfigFileWithSystem } from "../../src/cli/tsconfig"; import { normalizeSlashes } from "../../src/utils"; export function transpileFilesResult(rootNames: string[], options: tstl.CompilerOptions) { @@ -16,12 +15,3 @@ export function transpileFilesResult(rootNames: string[], options: tstl.Compiler return { diagnostics, emittedFiles }; } - -export function transpileProjectResult(configFileName: string) { - const parseResult = parseConfigFileWithSystem(configFileName); - if (parseResult.errors.length > 0) { - return { diagnostics: parseResult.errors, emittedFiles: [] }; - } - - return transpileFilesResult(parseResult.fileNames, parseResult.options); -} diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index d28f4bf25..f961dddb0 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -59,6 +59,16 @@ test("entry point in directory", () => { .expectToEqual({ value: true }); }); +test("entry point in rootDir", () => { + util.testModule` + export { value } from "./module"; + ` + .setMainFileName("src/main.ts") + .addExtraFile("src/module.ts", "export const value = true") + .setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToEqual({ value: true }); +}); + test("LuaLibImportKind.Require", () => { util.testBundle` export const result = [1, 2]; diff --git a/test/unit/file.spec.ts b/test/unit/file.spec.ts index 3a810dc60..12a136408 100644 --- a/test/unit/file.spec.ts +++ b/test/unit/file.spec.ts @@ -10,6 +10,20 @@ describe("JSON", () => { .setMainFileName("main.json") .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); }); + + test("JSON modules can be imported", () => { + util.testModule` + import * as jsonData from "./jsonModule.json"; + export const result = jsonData; + ` + .addExtraFile("jsonModule.json", '{ "jsonField1": "hello, this is JSON", "jsonField2": ["a", "b", "c"] }') + .expectToEqual({ + result: { + jsonField1: "hello, this is JSON", + jsonField2: ["a", "b", "c"], + }, + }); + }); }); describe("shebang", () => { diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index f61e37cb2..2da1d9722 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -1,3 +1,4 @@ +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test("enables noSelfInFile behavior for functions", () => { @@ -31,10 +32,13 @@ test("generates declaration files with @noSelfInFile", () => { const fooDeclaration = fooBuilder.getLuaResult().transpiledFiles.find(f => f.declaration)?.declaration; util.assert(fooDeclaration !== undefined); + expect(fooDeclaration).toContain("@noSelfInFile"); + util.testModule` - import { bar } from "./foo.d"; + import { bar } from "./foo"; const test: (this: void) => void = bar; ` .addExtraFile("foo.d.ts", fooDeclaration) + .ignoreDiagnostics([couldNotResolveRequire.code]) // no foo implementation in the project to create foo.lua .expectToHaveNoDiagnostics(); }); diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index d4228141d..4db74c57f 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -2,9 +2,9 @@ exports[`doesn't resolve paths out of root dir: code 1`] = ` "local ____exports = {} -local module = require(\\"../module\\") +local module = require(\\"module\\") local ____ = module return ____exports" `; -exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"src/main.ts(2,33): error TSTL: Cannot create require path. Module '../module' does not exist within --rootDir."`; +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve require path '../module' in file main.ts."`; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index dd3d1dd7a..ffdc36ce9 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -58,8 +58,7 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ import { foo } from "./${name}"; export { foo }; ` - .disableSemanticCheck() - .setLuaHeader('setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })') + .addExtraFile(`${name}.ts`, 'export const foo = "bar";') .setReturnExport("foo") .expectToEqual("bar"); } diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 541c28c56..791ae06b5 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { unresolvableRequirePath } from "../../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; @@ -69,6 +69,7 @@ test.each([ module; ` .setMainFileName(filePath) + .addExtraFile(`${usedPath}.ts`, "") .setOptions(options) .tap(expectToRequire(expected)); }); @@ -81,7 +82,7 @@ test("doesn't resolve paths out of root dir", () => { .setMainFileName("src/main.ts") .setOptions({ rootDir: "./src" }) .disableSemanticCheck() - .expectDiagnosticsToMatchSnapshot([unresolvableRequirePath.code]); + .expectDiagnosticsToMatchSnapshot([couldNotResolveRequire.code]); }); test.each([ diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 84a6596a6..371c50df9 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,5 +1,6 @@ import { Position, SourceMapConsumer } from "source-map"; import * as tstl from "../../../src"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test.each([ @@ -144,7 +145,11 @@ test.each([ ], }, ])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { - const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); + const file = util + .testModule(code) + .ignoreDiagnostics([couldNotResolveRequire.code]) + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.luaSourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { @@ -157,32 +162,25 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {}, mapSource: "foo.ts", fullSource: "foo.ts" }, + { fileName: "/proj/foo.ts", config: {} }, { fileName: "/proj/src/foo.ts", config: { outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../../src/sub/foo.ts", - fullSource: "../../src/sub/foo.ts", }, { fileName: "/proj/src/sub/main.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - mapSource: "sub/main.ts", - fullSource: "bin/sub/main.ts", + fullSource: "bin/proj/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, mapSource, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { const file = util.testModule` const foo = "foo" ` @@ -192,11 +190,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(mapSource); + expect(sourceMap.sources[0]).toBe(fileName); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource); + expect(consumer.sources[0]).toBe(fullSource ?? fileName); }); test.each([ diff --git a/test/util.ts b/test/util.ts index b553ef359..39259e784 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { LauxLib, Lua, LuaLib, LUA_OK } from "lua-wasm-bindings/dist/lua"; +import { LauxLib, Lua, LuaLib, LuaState, LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -9,6 +9,8 @@ import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; +import { getEmitOutDir, transpileProject } from "../src"; +import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); @@ -128,7 +130,7 @@ export abstract class TestBuilder { return this; } - private options: tstl.CompilerOptions = { + protected options: tstl.CompilerOptions = { luaTarget: tstl.LuaTarget.Lua54, noHeader: true, skipLibCheck: true, @@ -148,7 +150,7 @@ export abstract class TestBuilder { protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { expect(this.hasProgram).toBe(false); - this.mainFileName = mainFileName; + this.mainFileName = normalizeSlashes(mainFileName); return this; } @@ -176,7 +178,10 @@ export abstract class TestBuilder { @memoize public getProgram(): ts.Program { this.hasProgram = true; - return tstl.createVirtualProgram({ ...this.extraFiles, [this.mainFileName]: this.getTsCode() }, this.options); + return tstl.createVirtualProgram( + { ...this.extraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, + this.options + ); } @memoize @@ -202,7 +207,10 @@ export abstract class TestBuilder { const { transpiledFiles } = this.getLuaResult(); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)); + : transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => normalizeSlashes(f.fileName) === this.mainFileName) + ); + expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; } @@ -259,9 +267,7 @@ export abstract class TestBuilder { public debug(): this { const transpiledFiles = this.getLuaResult().transpiledFiles; - const luaCode = transpiledFiles.map( - f => `[${f.sourceFiles.map(sf => sf.fileName).join(",")}]:\n${f.lua?.replace(/^/gm, " ")}` - ); + const luaCode = transpiledFiles.map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; @@ -366,35 +372,23 @@ export abstract class TestBuilder { // Load modules // Json - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, jsonLib); - lua.lua_setfield(L, -2, "json"); + this.packagePreloadLuaFile(L, lua, lauxlib, "json", jsonLib); // Lua lib if ( this.options.luaLibImport === tstl.LuaLibImportKind.Require || mainFile.includes('require("lualib_bundle")') ) { - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, luaLib); - lua.lua_setfield(L, -2, "lualib_bundle"); + this.packagePreloadLuaFile(L, lua, lauxlib, "lualib_bundle", luaLib); } - // Extra files + // Load all transpiled files into Lua's package cache const { transpiledFiles } = this.getLuaResult(); - - Object.keys(this.extraFiles).forEach(fileName => { - const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => f.fileName === fileName) - ); - if (transpiledExtraFile?.lua) { - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, transpiledExtraFile.lua); - lua.lua_setfield(L, -2, fileName.replace(".ts", "")); + for (const transpiledFile of transpiledFiles) { + if (transpiledFile.lua) { + const filePath = path.relative(getEmitOutDir(this.getProgram()), transpiledFile.outPath); + this.packagePreloadLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); } - }); + } // Execute Main const wrappedMainCode = ` @@ -423,6 +417,14 @@ 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 executeJs(): any { const { transpiledFiles } = this.getJsResult(); // Custom require for extra files. Really basic. Global support is hacky @@ -539,6 +541,22 @@ class ExpressionTestBuilder extends AccessorTestBuilder { } } +class ProjectTestBuilder extends ModuleTestBuilder { + constructor(private tsConfig: string) { + super(""); + this.setOptions({ configFilePath: this.tsConfig, ...tstl.parseConfigFileWithSystem(this.tsConfig) }); + } + + @memoize + public getLuaResult(): tstl.TranspileVirtualProjectResult { + // Override getLuaResult to use transpileProject with tsconfig.json instead + const collector = createEmitOutputCollector(); + const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile); + + return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; + } +} + const createTestBuilderFactory = ( builder: new (_tsCode: string) => T, serializeSubstitutions: boolean @@ -566,3 +584,4 @@ export const testFunction = createTestBuilderFactory(FunctionTestBuilder, false) export const testFunctionTemplate = createTestBuilderFactory(FunctionTestBuilder, true); export const testExpression = createTestBuilderFactory(ExpressionTestBuilder, false); export const testExpressionTemplate = createTestBuilderFactory(ExpressionTestBuilder, true); +export const testProject = createTestBuilderFactory(ProjectTestBuilder, false); From ca4428514cccf933ad031562fc7228a54f9eeed7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Jun 2021 21:11:35 +0200 Subject: [PATCH 73/91] Changelog 0.40.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefbd8362..12a8fda3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.40.0 + +- Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. +- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg) for instructions how to upgrade. +- Added support for `array.entries()`. +- Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info. +- Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua. + +- Fixed an issue where using TypeScript transformer plugins would cause invalid namespace and module code, as well as breaking hoisting. +- Fixed invalid switch statement output when the `default` clause was not the last clause in the switch. +- Fixed missing LuaLib dependency when using `string.split`. +- Fixed **lots** of bundling bugs and issues, also added the TypeScriptToLua header to the top of the bundle unless _noHeader_ is specified. + +Under the hood: + +- Various improvements to testing infrastructure for testing (virtual) projects with multiple files. + ## 0.39.0 - **[Breaking]** Removed support for `@phantom`, `@metaExtension`, `@extension`, `@pureAbstract` compiler annotations. As of this version **these will no longer function!** For help upgrading your code see [the deprecated annotation docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#deprecated). From c6e3555ae736db1ddc8c2e8c5b596cb437bf8322 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Jun 2021 21:18:22 +0200 Subject: [PATCH 74/91] 0.40.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43137cbae..002afb94a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index fc3604e49..5cba2dd38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.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/", From 1e539f0af1461396c9dafbce9957f076febda6cd Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Jun 2021 09:10:25 +0200 Subject: [PATCH 75/91] Also resolve tsx files (#1039) --- src/transpilation/resolve.ts | 29 ++++++++++--------- test/transpile/module-resolution.spec.ts | 15 ++++++++++ .../project-with-tsx/dir/index.tsx | 3 ++ .../project-with-tsx/main.tsx | 5 ++++ .../project-with-tsx/other.tsx | 3 ++ .../project-with-tsx/tsconfig.json | 5 ++++ 6 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-tsx/dir/index.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/main.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/other.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 3eca25e2e..a9b6b4e1a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -103,19 +103,18 @@ function resolveDependency( // Check if file is a file in the project const resolvedPath = path.join(fileDirectory, dependency); - if (isProjectFile(resolvedPath, program)) { - // JSON files need their extension as part of the import path, caught by this branch - return resolvedPath; - } - - const resolvedFile = resolvedPath + ".ts"; - if (isProjectFile(resolvedFile, program)) { - return resolvedFile; - } - - const projectIndexPath = path.resolve(resolvedPath, "index.ts"); - if (isProjectFile(projectIndexPath, program)) { - return projectIndexPath; + const possibleProjectFiles = [ + resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, + resolvedPath + ".ts", // Regular ts file + path.join(resolvedPath, "index.ts"), // Index ts file, + resolvedPath + ".tsx", // tsx file + path.join(resolvedPath, "index.tsx"), // tsx index + ]; + + for (const possibleFile of possibleProjectFiles) { + if (isProjectFile(possibleFile, program)) { + return possibleFile; + } } // Check if this is a sibling of a required lua file @@ -215,7 +214,9 @@ function isProjectFile(file: string, program: ts.Program): boolean { function hasSourceFileInProject(filePath: string, program: ts.Program) { const pathWithoutExtension = trimExtension(filePath); return ( - isProjectFile(pathWithoutExtension + ".ts", program) || isProjectFile(pathWithoutExtension + ".json", program) + isProjectFile(pathWithoutExtension + ".ts", program) || + isProjectFile(pathWithoutExtension + ".tsx", program) || + isProjectFile(pathWithoutExtension + ".json", program) ); } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index c386e2d33..6c5bff4a2 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -280,3 +280,18 @@ describe("module resolution project with dependencies built by tstl library mode .expectToEqual(expectedResult); }); }); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1037 +describe("module resolution with tsx", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tsx"); + + test("project with tsx files", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.tsx")) + .debug() + .expectToEqual({ + result: "hello from other.tsx", + indexResult: "hello from dir/index.tsx", + }); + }); +}); diff --git a/test/transpile/module-resolution/project-with-tsx/dir/index.tsx b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx new file mode 100644 index 000000000..20c981b8a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx @@ -0,0 +1,3 @@ +export function indexf() { + return "hello from dir/index.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/main.tsx b/test/transpile/module-resolution/project-with-tsx/main.tsx new file mode 100644 index 000000000..d17e2a7e4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/main.tsx @@ -0,0 +1,5 @@ +import { f } from "./other"; +import { indexf } from "./dir"; + +export const result = f(); +export const indexResult = indexf(); diff --git a/test/transpile/module-resolution/project-with-tsx/other.tsx b/test/transpile/module-resolution/project-with-tsx/other.tsx new file mode 100644 index 000000000..514705822 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/other.tsx @@ -0,0 +1,3 @@ +export function f() { + return "hello from other.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/tsconfig.json b/test/transpile/module-resolution/project-with-tsx/tsconfig.json new file mode 100644 index 000000000..b5fbd521b --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react" + } +} From 8d9c8afe27e707ef68f834088d92f9851c703a7e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Jun 2021 22:06:27 +0200 Subject: [PATCH 76/91] Fix getEmitOutDir not using project root if no outDir is provided (#1038) * Fix getEmitOutDir not using project root if no outDir is provided * Removed redundant tests --- CHANGELOG.md | 2 +- src/transpilation/bundle.ts | 4 +- src/transpilation/transpiler.ts | 4 +- test/transpile/bundle.spec.ts | 2 +- test/transpile/paths.spec.ts | 120 ++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 test/transpile/paths.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a8fda3b..1a81be4d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 0.40.0 - Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. -- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg) for instructions how to upgrade. +- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for instructions how to upgrade. - Added support for `array.entries()`. - Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info. - Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua. diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 31d58b27b..579e84ee1 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -3,7 +3,7 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; import { escapeString, tstlHeader } from "../LuaPrinter"; -import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; +import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; import { EmitFile, ProcessedFile } from "./utils"; @@ -42,7 +42,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t // Resolve project settings relative to project file. const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); - const outputPath = normalizeSlashes(path.resolve(getEmitOutDir(program), bundleFile)); + const outputPath = path.resolve(getEmitOutDir(program), bundleFile); if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 7b5eb0f3f..2dc5a9fc7 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -122,7 +122,9 @@ export function getEmitOutDir(program: ts.Program): string { if (outDir && outDir.length > 0) { return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir); } - return program.getCommonSourceDirectory(); + + // If no outDir is provided, emit in project root + return getProjectRoot(program); } export function getProjectRoot(program: ts.Program): string { diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 69c86406e..718e1b112 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -12,7 +12,7 @@ test("should transpile into one file", () => { const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(outPath.endsWith("bundle/bundle.lua")).toBe(true); + expect(outPath.endsWith(path.join("bundle", "bundle.lua"))).toBe(true); // Verify exported module by executing // Use an empty TS string because we already transpiled the TS project util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts new file mode 100644 index 000000000..33d4f6258 --- /dev/null +++ b/test/transpile/paths.spec.ts @@ -0,0 +1,120 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { getSourceDir } from "../../src"; +import * as util from "../util"; + +const cwd = process.cwd(); + +// Path for project tsconfig.json to resolve for +const configFilePath = path.join(cwd, "tsconfig.json"); + +describe("getSourceDir", () => { + test("with rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath, rootDir: "src" }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + expect(getSourceDir(program)).toBe(path.join(cwd, "src")); + }); + + test("without rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + // Common sources directory is project root + expect(normalize(getSourceDir(program))).toBe(cwd); + }); + + test("without rootDir in src dir", () => { + const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], { + configFilePath, + }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(path.join(cwd, "src")); + + // Common sources directory is src + expect(normalize(getSourceDir(program))).toBe(path.join(cwd, "src")); + }); +}); + +describe("getEmitPath", () => { + test("puts files next to input without options", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain("main.lua"); + expect(fileNames).toContain(path.join("dir", "extra.lua")); + }); + + test("puts files in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .setOptions({ outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "dir", "extra.lua")); + }); + + test("puts files from rootDir in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ rootDir: "src", outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "extra.lua")); + }); + + test("puts bundle relative to project root", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ configFilePath, rootDir: "src", luaBundle: "out/bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out", "bundle.lua")); + }); + + test("puts bundle relative to outdir", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ + configFilePath, + rootDir: "src", + outDir: "out1", + luaBundle: "out2/bundle.lua", + luaBundleEntry: "src/main.ts", + }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.lua")); + }); +}); + +function normalize(path: string) { + return path.endsWith("/") ? path.slice(0, path.length - 1) : path; +} From b847804b2a6fa84ffadf84755cf4a36dffee219f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 21 Jun 2021 22:15:59 +0200 Subject: [PATCH 77/91] 0.40.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 002afb94a..c3acb08d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 5cba2dd38..f96178a81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "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/", From 6c7c3366c2873f9770a127b1797cbc252edfd502 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 9 Jul 2021 03:13:26 +0800 Subject: [PATCH 78/91] optimizing varargs on functions passed as parameters (#1042) --- src/transformation/utils/scope.ts | 4 +++- test/unit/__snapshots__/spread.spec.ts.snap | 15 +++++++++++++++ test/unit/spread.spec.ts | 11 +++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 72b267e2a..dcb877db7 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -93,7 +93,9 @@ export function popScope(context: TransformationContext): Scope { } function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { - return symbol?.declarations?.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); + return symbol?.declarations?.some( + d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent) + ); } // Checks for references to local functions which haven't been defined yet, diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index f16bc746a..85d1c4ac3 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -66,6 +66,21 @@ 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 finally clause 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index a395ef2bd..e65ee7ee7 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -230,6 +230,17 @@ describe("vararg spread optimization", () => { .expectLuaToMatchSnapshot() .expectToEqual("b"); }); + + test("curry", () => { + util.testFunction` + function test(fn: (...args: A) => void, ...args: A) { + return fn(...args); + } + return test((arg: string) => arg, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); }); describe("vararg spread de-optimization", () => { From d79a2078d64336188f4708fef1b5c5cd9ee64ca5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 9 Jul 2021 10:04:17 +0200 Subject: [PATCH 79/91] Optional chaining (#1041) * Optional chaining * Added some more possibly undefined test cases * Added extra test and fixed bug * Removed double work from transformNullishCoalescingExpression * fix prettier --- src/LuaLib.ts | 3 + src/lualib/OptionalChainAccess.ts | 10 ++ src/lualib/OptionalFunctionCall.ts | 10 ++ src/lualib/OptionalMethodCall.ts | 14 ++ src/transformation/utils/diagnostics.ts | 2 - src/transformation/visitors/access.ts | 25 ++- .../visitors/binary-expression/index.ts | 17 +- src/transformation/visitors/call.ts | 95 ++++++++--- test/transpile/module-resolution.spec.ts | 1 - test/unit/optionalChaining.spec.ts | 161 +++++++++++++++++- 10 files changed, 296 insertions(+), 42 deletions(-) create mode 100644 src/lualib/OptionalChainAccess.ts create mode 100644 src/lualib/OptionalFunctionCall.ts create mode 100644 src/lualib/OptionalMethodCall.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index d98b78044..e1a8d9efd 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -57,6 +57,9 @@ export enum LuaLibFeature { ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", + OptionalChainAccess = "OptionalChainAccess", + OptionalFunctionCall = "OptionalFunctionCall", + OptionalMethodCall = "OptionalMethodCall", ParseFloat = "ParseFloat", ParseInt = "ParseInt", Set = "Set", diff --git a/src/lualib/OptionalChainAccess.ts b/src/lualib/OptionalChainAccess.ts new file mode 100644 index 000000000..7924aa282 --- /dev/null +++ b/src/lualib/OptionalChainAccess.ts @@ -0,0 +1,10 @@ +function __TS__OptionalChainAccess( + this: void, + table: Record, + key: TKey +): TReturn | undefined { + if (table) { + return table[key]; + } + return undefined; +} diff --git a/src/lualib/OptionalFunctionCall.ts b/src/lualib/OptionalFunctionCall.ts new file mode 100644 index 000000000..85b52a047 --- /dev/null +++ b/src/lualib/OptionalFunctionCall.ts @@ -0,0 +1,10 @@ +function __TS__OptionalFunctionCall( + this: void, + f: (this: void, ...args: [...TArgs]) => TReturn, + ...args: [...TArgs] +): TReturn | undefined { + if (f) { + return f(...args); + } + return undefined; +} diff --git a/src/lualib/OptionalMethodCall.ts b/src/lualib/OptionalMethodCall.ts new file mode 100644 index 000000000..8829e4a4d --- /dev/null +++ b/src/lualib/OptionalMethodCall.ts @@ -0,0 +1,14 @@ +function __TS__OptionalMethodCall( + this: void, + table: Record TReturn>, + methodName: string, + ...args: [...TArgs] +): TReturn | undefined { + if (table) { + const method = table[methodName]; + if (method) { + return method.call(table, ...args); + } + } + return undefined; +} diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index fcc37b6f0..16a0c7395 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -143,5 +143,3 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); - -export const optionalChainingNotSupported = createErrorDiagnosticFactory("Optional chaining is not supported yet."); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index a41c4462f..8b795426b 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationRemoved, invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; +import { annotationRemoved, invalidMultiReturnAccess } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; @@ -53,6 +53,10 @@ export const transformElementAccessExpression: FunctionVisitor = (node, context) => { const right = lua.createStringLiteral(node.right.text, node.right); const left = context.transformExpression(node.left); diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 0b4533a4a..ce73a7a70 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -54,7 +54,7 @@ export function transformBinaryOperation( if (operator === ts.SyntaxKind.QuestionQuestionToken) { assert(ts.isBinaryExpression(node)); - return transformNullishCoalescingExpression(context, node); + return transformNullishCoalescingExpression(context, node, left, right); } let luaOperator = simpleOperatorsToLua[operator]; @@ -162,7 +162,9 @@ export function transformBinaryExpressionStatement( function transformNullishCoalescingExpression( context: TransformationContext, - node: ts.BinaryExpression + node: ts.BinaryExpression, + transformedLeft: lua.Expression, + transformedRight: lua.Expression ): lua.Expression { const lhsType = context.checker.getTypeAtLocation(node.left); @@ -181,20 +183,15 @@ function transformNullishCoalescingExpression( // if ____ == nil then return rhs else return ____ end const ifStatement = lua.createIfStatement( nilComparison, - lua.createBlock([lua.createReturnStatement([context.transformExpression(node.right)])]), + lua.createBlock([lua.createReturnStatement([transformedRight])]), lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]) ); // (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs) return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [ - context.transformExpression(node.left), + transformedLeft, ]); } else { // lhs or rhs - return lua.createBinaryExpression( - context.transformExpression(node.left), - context.transformExpression(node.right), - lua.SyntaxKind.OrOperator, - node - ); + return lua.createBinaryExpression(transformedLeft, transformedRight, lua.SyntaxKind.OrOperator, node); } } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index f7a1b004e..ced618c4c 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -148,18 +148,29 @@ export function transformContextualCallExpression( node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray, signature?: ts.Signature -): lua.Expression { +): lua.CallExpression | lua.MethodCallExpression { const left = ts.isCallExpression(node) ? node.expression : node.tag; if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { // table:name() const table = context.transformExpression(left.expression); - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformArguments(context, args, signature), - node - ); + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + table, + lua.createStringLiteral(left.name.text, left.name), + ...transformArguments(context, args, signature) + ); + } else { + return lua.createMethodCallExpression( + table, + lua.createIdentifier(left.name.text, left.name), + transformArguments(context, args, signature), + node + ); + } } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { return transformToImmediatelyInvokedFunctionExpression( @@ -183,7 +194,10 @@ export function transformContextualCallExpression( } } -function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { +function transformPropertyCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { @@ -197,17 +211,22 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal // table:name() return transformContextualCallExpression(context, node, node.arguments, signature); } else { - const table = context.transformExpression(node.expression.expression); - // table.name() - const name = node.expression.name.text; - const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); + const callPath = context.transformExpression(node.expression); const parameters = transformArguments(context, node.arguments, signature); - return lua.createCallExpression(callPath, parameters, node); + + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction(context, LuaLibFeature.OptionalFunctionCall, node, callPath, ...parameters); + } else { + return lua.createCallExpression(callPath, parameters, node); + } } } -function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { +function transformElementCall( + context: TransformationContext, + node: ts.CallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { @@ -229,11 +248,12 @@ export const transformCallExpression: FunctionVisitor = (node const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); const wrapTupleReturn = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; - const wrapResult = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInTable = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInOptional = ts.isOptionalChain(node); const builtinResult = transformBuiltinCallExpression(context, node); if (builtinResult) { - return wrapResult ? wrapInTable(builtinResult) : builtinResult; + return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; } if (isOperatorMapping(context, node)) { @@ -274,12 +294,13 @@ export const transformCallExpression: FunctionVisitor = (node } const result = transformPropertyCall(context, node as PropertyCallExpression); - return wrapResult ? wrapInTable(result) : result; + // transformPropertyCall already wraps optional so no need to do so here + return wrapResultInTable ? wrapInTable(result) : result; } if (ts.isElementAccessExpression(node.expression)) { const result = transformElementCall(context, node); - return wrapResult ? wrapInTable(result) : result; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, result, node); } const signature = context.checker.getResolvedSignature(node); @@ -309,5 +330,41 @@ export const transformCallExpression: FunctionVisitor = (node } const callExpression = lua.createCallExpression(callPath, parameters, node); - return wrapResult ? wrapInTable(callExpression) : callExpression; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, callExpression, node); }; + +function wrapIfRequired( + context: TransformationContext, + shouldWrapInTable: boolean, + shouldWrapOptional: boolean, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.Node +): lua.Expression { + const wrappedOptional = shouldWrapOptional ? wrapOptionalCall(context, call, node) : call; + return shouldWrapInTable ? wrapInTable(wrappedOptional) : wrappedOptional; +} + +function wrapOptionalCall( + context: TransformationContext, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.Node +): lua.CallExpression { + if (lua.isMethodCallExpression(call)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + call.prefixExpression, + lua.createStringLiteral(call.name.text), + ...call.params + ); + } else { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalFunctionCall, + node, + call.expression, + ...call.params + ); + } +} diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 6c5bff4a2..872bd47c7 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -288,7 +288,6 @@ describe("module resolution with tsx", () => { test("project with tsx files", () => { util.testProject(path.join(projectPath, "tsconfig.json")) .setMainFileName(path.join(projectPath, "main.tsx")) - .debug() .expectToEqual({ result: "hello from other.tsx", indexResult: "hello from dir/index.tsx", diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 33d0802db..26deff810 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,9 +1,160 @@ -import { optionalChainingNotSupported } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; -test("Diagnostic optional chaining is not supported yet", () => { +test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` - let func = (value: number) => value != 0 ? {value} : undefined; - return func(1)?.value; - `.expectToHaveDiagnostics([optionalChainingNotSupported.code]); + const obj: any = ${value}; + return obj?.foo; + `.expectToMatchJsResult(); +}); + +test("long optional chain", () => { + util.testFunction` + const a = { b: { c: { d: { e: { f: "hello!"}}}}}; + return a.b?.c?.d.e.f; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])( + "nested optional chaining combined with coalescing (%p)", + value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar ?? "not found"; + `.expectToMatchJsResult(); + } +); + +test.each(["[1, 2, 3, 4]", "undefined"])("optional array access (%p)", value => { + util.testFunction` + const arr: number[] | undefined = ${value}; + return arr?.[2]; + `.expectToMatchJsResult(); +}); + +test.each(["[1, [2, [3, [4, 5]]]]", "[1, [2, [3, undefined]]] ", "[1, undefined]"])( + "optional element access nested (%p)", + value => { + util.testFunction` + const arr: [number, [number, [number, [number, number] | undefined]]] | [number, undefined] = ${value}; + return arr[1]?.[1][1]?.[0]; + `.expectToMatchJsResult(); + } +); + +test.each(["{ }", "{ a: { } }", "{ a: { b: [{ c: 10 }] } }"])( + "optional nested element access properties (%p)", + value => { + util.testFunction` + const obj: {a?: {b?: Array<{c: number }> } } = ${value}; + return [obj["a"]?.["b"]?.[0]?.["c"] ?? "not found", obj["a"]?.["b"]?.[2]?.["c"] ?? "not found"]; + `.expectToMatchJsResult(); + } +); + +test("optional element function calls", () => { + util.testFunction` + const obj: { value: string; foo?(this: void, v: number): number; bar?(this: void, v: number): number; } = { + value: "foobar", + foo: (v: number) => v + 10 + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.(5) ?? obj[fooKey]?.(15); + `.expectToMatchJsResult(); +}); + +test("optional element access method calls", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.("bar?") ?? obj[fooKey]?.("foo?"); + `.expectToMatchJsResult(); +}); + +test("no side effects", () => { + util.testFunction` + function getFoo(): { foo: number } | undefined { + return { foo: 42 }; + } + let barCalls = 0; + function getBar(): { bar: number } | undefined { + barCalls += 1; + return undefined; + } + const result = getFoo()?.foo ?? getBar()?.bar; + return { result, barCalls }; + `.expectToMatchJsResult(); +}); + +describe("optional chaining function calls", () => { + test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { + util.testFunction` + const f: (() => number) | undefined = ${value}; + return f?.(); + `.expectToMatchJsResult(); + }); + + test("methods present", () => { + util.testFunction` + const objWithMethods = { + foo() { + return 3; + }, + bar(this: void) { + return 5; + } + }; + + return [objWithMethods?.foo(), objWithMethods?.bar()]; + `.expectToMatchJsResult(); + }); + + test("object with method can be undefined", () => { + util.testFunction` + const objWithMethods: { foo: () => number, bar: (this: void) => number } | undefined = undefined; + return [objWithMethods?.foo() ?? "no foo", objWithMethods?.bar() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("nested optional method call", () => { + util.testFunction` + type typeWithOptional = { a?: { b: { c: () => number } } }; + + const objWithMethods: typeWithOptional = {}; + const objWithMethods2: typeWithOptional = { a: { b: { c: () => 4 } } }; + + return { + expectNil: objWithMethods.a?.b.c(), + expectFour: objWithMethods2.a?.b.c() + }; + `.expectToMatchJsResult(); + }); + + test("methods are undefined", () => { + util.testFunction` + const objWithMethods: { foo?: () => number, bar?: (this: void) => number } = {}; + return [objWithMethods.foo?.() ?? "no foo", objWithMethods.bar?.() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("optional method of optional method result", () => { + util.testFunction` + const obj: { a?: () => {b: {c?: () => number }}} = {}; + const obj2: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: {}})}; + const obj3: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: { c: () => 5 }})}; + + return [obj.a?.().b.c?.() ?? "nil", obj2.a?.().b.c?.() ?? "nil", obj3.a?.().b.c?.() ?? "nil"]; + `.expectToMatchJsResult(); + }); }); From 213b204c7702bae70c3eb71172e8c7cabb73eff0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 11 Jul 2021 10:49:15 +0200 Subject: [PATCH 80/91] Bundle librarymode error & tstlverbose CLI flag (#1043) * Disallow bundling with buildmode library * Add tstl verbose CLI flag * Add tstlverbose to CLI parser --- package-lock.json | 14 ++--- package.json | 2 +- src/CompilerOptions.ts | 15 +++--- src/cli/parse.ts | 5 ++ src/transformation/context/context.ts | 3 +- src/transpilation/diagnostics.ts | 5 ++ src/transpilation/resolve.ts | 19 ++++++- src/transpilation/transpile.ts | 17 ++++++ src/transpilation/transpiler.ts | 25 ++++++++- src/typescript-internal.d.ts | 3 ++ test/cli/parse.spec.ts | 2 + .../__snapshots__/project.spec.ts.snap | 20 +++++++ test/transpile/module-resolution.spec.ts | 19 ------- test/transpile/project.spec.ts | 20 +++++++ test/transpile/transformers/fixtures.ts | 52 ++++++++++--------- test/unit/__snapshots__/bundle.spec.ts.snap | 2 + test/unit/bundle.spec.ts | 8 ++- test/unit/modules/resolution.spec.ts | 10 ++-- test/util.ts | 38 +++++++------- 19 files changed, 191 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3acb08d1..0d5b08870 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.0.5", + "prettier": "^2.3.2", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" }, @@ -9554,9 +9554,9 @@ } }, "node_modules/prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -19259,9 +19259,9 @@ "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index f96178a81..a45f56929 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.0.5", + "prettier": "^2.3.2", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index e06adc1f3..0610d26b3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,13 +1,9 @@ import * as ts from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; -type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { - [K in keyof T]: infer U; -} - ? U - : never; - -type OmitIndexSignature> = Pick>; +type OmitIndexSignature = { + [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; +}; export interface TransformerImport { transform: string; @@ -35,6 +31,7 @@ export type CompilerOptions = OmitIndexSignature & { sourceMapTraceback?: boolean; luaPlugins?: LuaPluginImport[]; plugins?: Array; + tstlVerbose?: boolean; [option: string]: any; }; @@ -73,5 +70,9 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.usingLuaBundleWithInlineMightGenerateDuplicateCode()); } + if (options.luaBundle && options.buildMode === BuildMode.Library) { + diagnostics.push(diagnosticFactories.cannotBundleLibrary()); + } + return diagnostics; } diff --git a/src/cli/parse.ts b/src/cli/parse.ts index d29bf4e83..b7ed906e3 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -73,6 +73,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "List of TypeScriptToLua plugins.", type: "object", }, + { + name: "tstlVerbose", + description: "Provide verbose output useful for diagnosing problems.", + type: "boolean", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 4ee4515c4..4dbcf9e10 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -27,8 +27,7 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { export class TransformationContext { public readonly diagnostics: ts.Diagnostic[] = []; - public readonly checker: DiagnosticsProducingTypeChecker = (this - .program as any).getDiagnosticsProducingTypeChecker(); + public readonly checker: DiagnosticsProducingTypeChecker = this.program.getDiagnosticsProducingTypeChecker(); public readonly resolver: EmitResolver; public readonly options: CompilerOptions = this.program.getCompilerOptions(); diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index bfae6b140..4b57c329d 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -48,3 +48,8 @@ export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDi "Using 'luaBundle' with 'luaLibImport: \"inline\"' might generate duplicate code. " + "It is recommended to use 'luaLibImport: \"require\"'.", })); + +export const cannotBundleLibrary = createDiagnosticFactory( + () => + 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' +); diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index a9b6b4e1a..5334c0ca7 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -5,9 +5,9 @@ import * as fs from "fs"; import { EmitHost, ProcessedFile } from "./utils"; import { SourceNode } from "source-map"; import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./transpiler"; -import { formatPathToLuaPath, trimExtension } from "../utils"; +import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; -import { BuildMode } from "../CompilerOptions"; +import { BuildMode, CompilerOptions } from "../CompilerOptions"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], @@ -24,9 +24,14 @@ interface ResolutionResult { export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { const outFiles: ProcessedFile[] = [...files]; const diagnostics: ts.Diagnostic[] = []; + const options = program.getCompilerOptions() as CompilerOptions; // Resolve dependencies for all processed files for (const file of files) { + if (options.tstlVerbose) { + console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); + } + const resolutionResult = resolveFileDependencies(file, program, emitHost); outFiles.push(...resolutionResult.resolvedFiles); diagnostics.push(...resolutionResult.diagnostics); @@ -38,6 +43,7 @@ export function resolveDependencies(program: ts.Program, files: ProcessedFile[], function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { const dependencies: ProcessedFile[] = []; const diagnostics: ts.Diagnostic[] = []; + const options = program.getCompilerOptions() as CompilerOptions; for (const required of findRequiredPaths(file.code)) { // Do no resolve lualib @@ -57,6 +63,10 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH const fileDir = path.dirname(file.fileName); const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); if (resolvedDependency) { + if (options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + } + // Figure out resolved require path and dependency output path const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); @@ -100,6 +110,11 @@ function resolveDependency( program: ts.Program, emitHost: EmitHost ): string | undefined { + const options = program.getCompilerOptions() as CompilerOptions; + if (options.tstlVerbose) { + console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); + } + // Check if file is a file in the project const resolvedPath = path.join(fileDirectory, dependency); diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 0d3071f73..d78162fd8 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -27,6 +27,10 @@ export function getProgramTranspileResult( ): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; + if (options.tstlVerbose) { + console.log("Parsing project settings"); + } + const diagnostics = validateOptions(options); let transpiledFiles: ProcessedFile[] = []; @@ -57,13 +61,26 @@ export function getProgramTranspileResult( } const plugins = getPlugins(program, diagnostics, customPlugins); + + if (options.tstlVerbose) { + console.log(`Successfully loaded ${plugins.length} plugins`); + } + const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { + if (options.tstlVerbose) { + console.log(`Transforming ${sourceFile.fileName}`); + } + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { + if (options.tstlVerbose) { + console.log(`Printing ${sourceFile.fileName}`); + } + const printResult = printer(program, emitHost, sourceFile.fileName, file); transpiledFiles.push({ sourceFiles: [sourceFile], diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 2dc5a9fc7..b19790b37 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { isBundleEnabled } from "../CompilerOptions"; +import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; @@ -29,6 +29,7 @@ export class Transpiler { public emit(emitOptions: EmitOptions): EmitResult { const { program, writeFile = this.emitHost.writeFile } = emitOptions; + const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose; const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( this.emitHost, writeFile, @@ -37,15 +38,27 @@ export class Transpiler { const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); + if (verbose) { + console.log("Emitting output"); + } + const options = program.getCompilerOptions(); const emitBOM = options.emitBOM ?? false; for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) { + if (verbose) { + console.log(`Emitting ${normalizeSlashes(outputPath)}`); + } + writeFile(outputPath, code, emitBOM, undefined, sourceFiles); if (options.sourceMap && sourceMap !== undefined) { writeFile(outputPath + ".map", sourceMap, emitBOM, undefined, sourceFiles); } } + if (verbose) { + console.log("Emit finished!"); + } + return { diagnostics, emitSkipped: emitPlan.length === 0 }; } @@ -54,10 +67,18 @@ export class Transpiler { diagnostics: ts.Diagnostic[], files: ProcessedFile[] ): { emitPlan: EmitFile[] } { - const options = program.getCompilerOptions(); + const options = program.getCompilerOptions() as CompilerOptions; + + if (options.tstlVerbose) { + console.log("Constructing emit plan"); + } const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); if (lualibRequired) { + 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")); files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 7444d89d7..7bfd309ac 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -1,3 +1,5 @@ +import { DiagnosticsProducingTypeChecker } from "./transformation/context"; + export {}; declare module "typescript" { @@ -14,6 +16,7 @@ declare module "typescript" { interface Program { getCommonSourceDirectory(): string; + getDiagnosticsProducingTypeChecker(): DiagnosticsProducingTypeChecker; } interface CompilerOptions { diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index f66b97766..f157c9a21 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -104,6 +104,8 @@ describe("command line", () => { ["noHeader", "true", { noHeader: true }], ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + ["tstlVerbose", "true", { tstlVerbose: true }], + ["tstlVerbose", "false", { tstlVerbose: false }], ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 623480405..1effba209 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -1,5 +1,25 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should give verbose output 1`] = ` +Array [ + "Parsing project settings", + "Successfully loaded 0 plugins", + "Transforming /test/transpile/project/otherFile.ts", + "Printing /test/transpile/project/otherFile.ts", + "Transforming /test/transpile/project/index.ts", + "Printing /test/transpile/project/index.ts", + "Constructing emit plan", + "Resolving dependencies for /test/transpile/project/otherFile.ts", + "Resolving dependencies for /test/transpile/project/index.ts", + "Resolving \\"./otherFile\\" from /test/transpile/project", + "Resolved ./otherFile to /test/transpile/project/otherFile.ts", + "Emitting output", + "Emitting /test/transpile/project/otherFile.lua", + "Emitting /test/transpile/project/index.lua", + "Emit finished!", +] +`; + exports[`should transpile 1`] = ` Array [ Object { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 872bd47c7..b995e75a5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -230,25 +230,6 @@ describe("module resolution in library mode", () => { expect(file.lua).not.toContain('require("lua_modules'); } }); - - test("bundle works in library mode because no external dependencies", () => { - const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); - const mainFile = path.join(projectPath, "main.ts"); - - const { transpiledFiles } = util - .testProject(path.join(projectPath, "tsconfig.json")) - .setMainFileName(path.join(projectPath, "main.ts")) - .setOptions({ buildMode: tstl.BuildMode.Library, luaBundle: "bundle.lua", luaBundleEntry: mainFile }) - .expectToEqual({ - funcFromLuaFile: "lua file in subdir", - funcFromSubDirLuaFile: "lua file in subdir", - }) - .getLuaResult(); - - for (const file of transpiledFiles) { - expect(file.lua).not.toContain('require("lua_modules'); - } - }); }); describe("module resolution project with dependencies built by tstl library mode", () => { diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index 965c834d7..49234975b 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,4 +1,5 @@ import * as path from "path"; +import { normalizeSlashes } from "../../src/utils"; import * as util from "../util"; test("should transpile", () => { @@ -13,3 +14,22 @@ test("should transpile", () => { transpiledFiles.map(f => ({ filePath: path.relative(projectDir, f.outPath), lua: f.lua })) ).toMatchSnapshot(); }); + +test("should give verbose output", () => { + // Capture console logs + const consoleLogs: string[] = []; + const originalLog = console.log; + console.log = (...args: any[]) => { + consoleLogs.push(args.map(a => a.toString().replace(normalizeSlashes(process.cwd()), "")).join(",")); + }; + + const projectDir = path.join(__dirname, "project"); + util.testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .setOptions({ tstlVerbose: true }) + .expectToHaveNoDiagnostics(); + + console.log = originalLog; + + expect(consoleLogs).toMatchSnapshot(); +}); diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index a69829d5d..dff7667be 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -6,22 +6,25 @@ import { visitAndReplace } from "./utils"; export const program = (program: ts.Program, options: { value: any }): ts.TransformerFactory => checker(program.getTypeChecker(), options); -export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); - }); +export const config = + ({ value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); -export const checker = ( - checker: ts.TypeChecker, - { value }: { value: any } -): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || !node.expression) return; - const type = checker.getTypeAtLocation(node.expression); - if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; - return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); - }); +export const checker = + (checker: ts.TypeChecker, { value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || !node.expression) return; + const type = checker.getTypeAtLocation(node.expression); + if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { @@ -29,12 +32,13 @@ export const raw: ts.TransformerFactory = context => file => return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); -export const compilerOptions = ( - options: tstl.CompilerOptions -): ts.TransformerFactory => context => file => { - assert(options.plugins?.length === 1); - return visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); - }); -}; +export const compilerOptions = + (options: tstl.CompilerOptions): ts.TransformerFactory => + context => + file => { + assert(options.plugins?.length === 1); + return visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); + }); + }; diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 84c10f3d5..20d4ec657 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -2,6 +2,8 @@ exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; +exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle probjects with\\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; + exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; exports[`no entry point: diagnostics 1`] = `"error TSTL: 'luaBundleEntry' is required when 'luaBundle' is enabled."`; diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index f961dddb0..ddc678f34 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind } from "../../src"; +import { BuildMode, LuaLibImportKind } from "../../src"; import * as diagnosticFactories from "../../src/transpilation/diagnostics"; import * as util from "../util"; @@ -120,3 +120,9 @@ test("luaEntry doesn't exist", () => { .setEntryPoint("entry.ts") .expectDiagnosticsToMatchSnapshot([diagnosticFactories.couldNotFindBundleEntryPoint.code], true); }); + +test("bundling not allowed for buildmode library", () => { + util.testBundle`` + .setOptions({ buildMode: BuildMode.Library }) + .expectDiagnosticsToMatchSnapshot([diagnosticFactories.cannotBundleLibrary.code], true); +}); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 791ae06b5..b2c7194b5 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -3,10 +3,12 @@ import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; -const expectToRequire = (expected: string): util.TapCallback => builder => { - const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; - expect(requiredPath).toBe(expected); -}; +const expectToRequire = + (expected: string): util.TapCallback => + builder => { + const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; + expect(requiredPath).toBe(expected); + }; test.each([ { diff --git a/test/util.ts b/test/util.ts index 39259e784..b493f43e0 100644 --- a/test/util.ts +++ b/test/util.ts @@ -239,8 +239,9 @@ export abstract class TestBuilder { @memoize public getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); - const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) - ?.js; + const code = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === this.mainFileName) + )?.js; assert(code !== undefined); const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; @@ -557,25 +558,24 @@ class ProjectTestBuilder extends ModuleTestBuilder { } } -const createTestBuilderFactory = ( - builder: new (_tsCode: string) => T, - serializeSubstitutions: boolean -) => (...args: [string] | [TemplateStringsArray, ...any[]]): T => { - let tsCode: string; - if (typeof args[0] === "string") { - expect(serializeSubstitutions).toBe(false); - tsCode = args[0]; - } else { - let [raw, ...substitutions] = args; - if (serializeSubstitutions) { - substitutions = substitutions.map(s => formatCode(s)); - } +const createTestBuilderFactory = + (builder: new (_tsCode: string) => T, serializeSubstitutions: boolean) => + (...args: [string] | [TemplateStringsArray, ...any[]]): T => { + let tsCode: string; + if (typeof args[0] === "string") { + expect(serializeSubstitutions).toBe(false); + tsCode = args[0]; + } else { + let [raw, ...substitutions] = args; + if (serializeSubstitutions) { + substitutions = substitutions.map(s => formatCode(s)); + } - tsCode = String.raw(Object.assign([], { raw }), ...substitutions); - } + tsCode = String.raw(Object.assign([], { raw }), ...substitutions); + } - return new builder(tsCode); -}; + return new builder(tsCode); + }; export const testBundle = createTestBuilderFactory(BundleTestBuilder, false); export const testModule = createTestBuilderFactory(ModuleTestBuilder, false); From 1ab13ceaf028f01d6f7ce08b19332cecc14e6b73 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 11 Jul 2021 14:03:54 +0200 Subject: [PATCH 81/91] CHANGELOG 0.41.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a81be4d1..ce877a1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.41.0 + +- Added support for [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) `a?.b`, `a?.[b]` and `a?.()`. +- Added an error when trying to bundle a library (`"buildmode": "library"`) project. +- Added `--tstlVerbose` CLI flag to help with diagnosing problems. +- Fixed a bug where vararg (`...`) was not correctly optimized. +- Fixed .tsx files not correctly being resolved. +- Fixed a bug where files were emitted to the wrong location if no `outDir` was specified. + ## 0.40.0 - Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. From a879b971cc1605b70353d6c2b868d6036221896d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 11 Jul 2021 14:26:34 +0200 Subject: [PATCH 82/91] 0.41.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d5b08870..35fb97cf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index a45f56929..548b86ef2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.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/", From f034d9f322a380facea0b39490ffc26d3ff9a41d Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 17 Jul 2021 02:50:03 +0800 Subject: [PATCH 83/91] fixed vararg optimization logic (#1046) --- src/transformation/utils/scope.ts | 6 ++-- test/unit/__snapshots__/spread.spec.ts.snap | 33 +++++++++++++++++++++ test/unit/spread.spec.ts | 24 +++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index dcb877db7..53169765a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -92,9 +92,9 @@ export function popScope(context: TransformationContext): Scope { return scope; } -function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { +function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { return symbol?.declarations?.some( - d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent) + d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) ); } @@ -109,7 +109,7 @@ export function hasReferencedUndefinedLocalFunction(context: TransformationConte if ( !scope.functionDefinitions?.has(symbolId) && type.getCallSignatures().length > 0 && - isDeclaredInScope(type.symbol, scope.node) + isHoistableFunctionDeclaredInScope(type.symbol, scope.node) ) { return true; } diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index 85d1c4ac3..0b49fd80a 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -81,6 +81,24 @@ 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) @@ -105,6 +123,21 @@ 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) diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index e65ee7ee7..5d7ed93a7 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -241,6 +241,30 @@ describe("vararg spread optimization", () => { .expectLuaToMatchSnapshot() .expectToMatchJsResult(); }); + + test("curry with indirect type", () => { + util.testFunction` + function test(obj: {fn: (...args: A) => void}, ...args: A) { + const fn = obj.fn; + return fn(...args); + } + return test({fn: (arg: string) => arg}, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("function type declared inside scope", () => { + util.testFunction` + function test(...args: A) { + const fn: (...args: A) => A[0] = (...args) => args[0]; + return fn(...args); + } + test("foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); }); describe("vararg spread de-optimization", () => { From 987899c8acdaf14668d234a8470c9f29a33f7459 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sat, 31 Jul 2021 08:26:20 -0700 Subject: [PATCH 84/91] JSX support (#1052) * JSX support * Add jsx and jsxFrag pragma support * Remove unneeded flattenSpreadExpressions call. Typescript doesn't actually "spread out" jsx spread children, even though the syntax is supported. * Changes for PR. * Add license for functions copied from sucrase * Remove jsx snapshot test Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> --- src/CompilerOptions.ts | 5 + src/transformation/utils/annotations.ts | 2 + src/transformation/visitors/index.ts | 2 + src/transformation/visitors/jsx/jsx.ts | 264 +++++++++++++ src/transformation/visitors/jsx/xhtml.ts | 256 +++++++++++++ .../visitors/language-extensions/multi.ts | 2 +- src/transformation/visitors/literal.ts | 144 ++++--- src/transpilation/diagnostics.ts | 2 + test/unit/jsx.spec.ts | 361 ++++++++++++++++++ 9 files changed, 976 insertions(+), 62 deletions(-) create mode 100644 src/transformation/visitors/jsx/jsx.ts create mode 100644 src/transformation/visitors/jsx/xhtml.ts create mode 100644 test/unit/jsx.spec.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 0610d26b3..9fc232f68 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; type OmitIndexSignature = { @@ -74,5 +75,9 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.cannotBundleLibrary()); } + if (options.jsx && options.jsx !== JsxEmit.React) { + diagnostics.push(diagnosticFactories.unsupportedJsxEmit()); + } + return diagnostics; } diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 212f30416..d07df2808 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -17,6 +17,8 @@ export enum AnnotationKind { NoSelfInFile = "noSelfInFile", Vararg = "vararg", ForRange = "forRange", + Jsx = "jsx", + JsxFrag = "jsxFrag", } export interface Annotation { diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index b9983ae31..b05527364 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -40,6 +40,7 @@ import { transformTypeOfExpression } from "./typeof"; import { typescriptVisitors } from "./typescript"; import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; import { transformVariableStatement } from "./variable-declaration"; +import { jsxVisitors } from "./jsx/jsx"; const transformEmptyStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => @@ -48,6 +49,7 @@ const transformParenthesizedExpression: FunctionVisitor= charCodes.a && ch <= charCodes.z) || name.includes("-") || name.includes(":"); +} + +function transformTagName(name: ts.JsxTagNameExpression, context: TransformationContext): lua.Expression { + if (ts.isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { + return lua.createStringLiteral(ts.idText(name), name); + } else { + return context.transformExpression(name); + } +} + +function transformJsxChildren( + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression[] | undefined { + if (!children) return undefined; + + return children + .map(child => { + if (ts.isJsxText(child)) { + return processJsxText(child); + } + if (ts.isJsxExpression(child)) { + return child.expression; + } + return child; + }) + .filter(child => child !== undefined) + .map(child => context.transformExpression(child!)); +} + +function createJsxFactoryCall( + tagName: lua.Expression, + props: lua.Expression | undefined, + tsChildren: ts.NodeArray | undefined, + tsOriginal: ts.Node, + context: TransformationContext +): lua.Expression { + const transformedChildren = transformJsxChildren(tsChildren, context); + const jsxFactory = getJsxFactory(tsOriginal, context); + + const args = [tagName]; + if (props) { + args.push(props); + } + if (transformedChildren && transformedChildren.length > 0) { + if (!props) { + args.push(lua.createNilLiteral()); + } + args.push(...transformedChildren); + } + return lua.createCallExpression(jsxFactory, args, tsOriginal); +} + +function transformJsxOpeningLikeElement( + node: ts.JsxOpeningLikeElement, + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression { + const tagName = transformTagName(node.tagName, context); + const props = + node.attributes.properties.length !== 0 ? transformJsxAttributes(node.attributes, context) : undefined; + + return createJsxFactoryCall(tagName, props, children, node, context); +} + +const transformJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node.openingElement, node.children, context); +const transformSelfClosingJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node, undefined, context); +const transformJsxFragment: FunctionVisitor = (node, context) => { + const tagName = getJsxFragmentName(node, context); + return createJsxFactoryCall(tagName, undefined, node.children, node, context); +}; + +export const jsxVisitors: Visitors = { + [ts.SyntaxKind.JsxElement]: transformJsxElement, + [ts.SyntaxKind.JsxSelfClosingElement]: transformSelfClosingJsxElement, + [ts.SyntaxKind.JsxFragment]: transformJsxFragment, +}; diff --git a/src/transformation/visitors/jsx/xhtml.ts b/src/transformation/visitors/jsx/xhtml.ts new file mode 100644 index 000000000..814191df0 --- /dev/null +++ b/src/transformation/visitors/jsx/xhtml.ts @@ -0,0 +1,256 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export const XHTMLEntities: { [name: string]: string } = { + quot: "\u0022", + amp: "&", + apos: "\u0027", + lt: "<", + gt: ">", + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + fnof: "\u0192", + circ: "\u02C6", + tilde: "\u02DC", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + bull: "\u2022", + hellip: "\u2026", + permil: "\u2030", + prime: "\u2032", + Prime: "\u2033", + lsaquo: "\u2039", + rsaquo: "\u203A", + oline: "\u203E", + frasl: "\u2044", + euro: "\u20AC", + image: "\u2111", + weierp: "\u2118", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666", +}; diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 85b3c6a29..a433cd3f4 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -90,7 +90,7 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n export function findMultiAssignmentViolations( context: TransformationContext, - node: ts.ObjectLiteralExpression + node: ts.ObjectLiteralExpressionBase ): ts.Node[] { const result: ts.Node[] = []; diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 8fa85e4e4..75b4a3224 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { unsupportedAccessorInObjectLiteral, invalidMultiFunctionUse } from "../utils/diagnostics"; +import { invalidMultiFunctionUse, unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -11,6 +11,7 @@ import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; import { findMultiAssignmentViolations } from "./language-extensions/multi"; +import { formatJSXStringValueLiteral } from "./jsx/jsx"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -62,78 +63,99 @@ const transformNumericLiteralExpression: FunctionVisitor = ex return lua.createNumericLiteral(Number(expression.text), expression); }; -const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { - const violations = findMultiAssignmentViolations(context, expression); - if (violations.length > 0) { - context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); - return lua.createNilLiteral(expression); - } - - let properties: lua.TableFieldExpression[] = []; - const tableExpressions: lua.Expression[] = []; +const transformObjectLiteralExpressionOrJsxAttributes: FunctionVisitor = + (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } - for (const element of expression.properties) { - const name = element.name ? transformPropertyName(context, element.name) : undefined; + let properties: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; + + for (const element of expression.properties) { + const name = element.name ? transformPropertyName(context, element.name) : undefined; + + if (ts.isPropertyAssignment(element)) { + const expression = context.transformExpression(element.initializer); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isJsxAttribute(element)) { + const initializer = element.initializer; + let expression: lua.Expression; + if (initializer === undefined) { + expression = lua.createBooleanLiteral(true); + } else if (ts.isStringLiteral(initializer)) { + const text = formatJSXStringValueLiteral(initializer.text); + expression = lua.createStringLiteral(text, initializer); + } else if (ts.isJsxExpression(initializer)) { + expression = initializer.expression + ? context.transformExpression(initializer.expression) + : lua.createBooleanLiteral(true); + } else { + assertNever(initializer); + } + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + trackSymbolReference(context, valueSymbol, element.name); + } + + const identifier = createShorthandIdentifier(context, valueSymbol, element.name); + properties.push(lua.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { + const expression = transformFunctionLikeDeclaration(element, context); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element) || ts.isJsxSpreadAttribute(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + properties = []; + } + + const type = context.checker.getTypeAtLocation(element.expression); + let tableExpression: lua.Expression; + if (isArrayType(context, type)) { + tableExpression = transformLuaLibFunction( + context, + LuaLibFeature.ArrayToObject, + element.expression, + context.transformExpression(element.expression) + ); + } else { + tableExpression = context.transformExpression(element.expression); + } - if (ts.isPropertyAssignment(element)) { - const expression = context.transformExpression(element.initializer); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { - const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - trackSymbolReference(context, valueSymbol, element.name); + tableExpressions.push(tableExpression); + } else if (ts.isAccessor(element)) { + context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); + } else { + assertNever(element); } + } - const identifier = createShorthandIdentifier(context, valueSymbol, element.name); - properties.push(lua.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { - const expression = transformFunctionLikeDeclaration(element, context); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isSpreadAssignment(element)) { - // Create a table for preceding properties to preserve property order - // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (tableExpressions.length === 0) { + return lua.createTableExpression(properties, expression); + } else { if (properties.length > 0) { const tableExpression = lua.createTableExpression(properties, expression); tableExpressions.push(tableExpression); - properties = []; } - const type = context.checker.getTypeAtLocation(element.expression); - let tableExpression: lua.Expression; - if (isArrayType(context, type)) { - tableExpression = transformLuaLibFunction( - context, - LuaLibFeature.ArrayToObject, - element.expression, - context.transformExpression(element.expression) - ); - } else { - tableExpression = context.transformExpression(element.expression); + if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { + tableExpressions.unshift(lua.createTableExpression(undefined, expression)); } - tableExpressions.push(tableExpression); - } else if (ts.isAccessor(element)) { - context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); - } else { - assertNever(element); - } - } - - if (tableExpressions.length === 0) { - return lua.createTableExpression(properties, expression); - } else { - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); } - - if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { - tableExpressions.unshift(lua.createTableExpression(undefined, expression)); - } - - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); - } -}; + }; +const transformObjectLiteralExpression: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; +export const transformJsxAttributes: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; const transformArrayLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 4b57c329d..098d78740 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -53,3 +53,5 @@ export const cannotBundleLibrary = createDiagnosticFactory( () => 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' ); + +export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts new file mode 100644 index 000000000..5734b33ee --- /dev/null +++ b/test/unit/jsx.spec.ts @@ -0,0 +1,361 @@ +import * as util from "../util"; +import { TestBuilder } from "../util"; +import { JsxEmit } from "typescript"; + +// language=TypeScript +const reactLib = ` + export class Component { + static isClass = true + } + + namespace React { + const isLua = typeof Component === "object" + + export function createElement( + this: void, + type: any, + props?: any, + ...children: any[] + ) { + let typeStr: string + if (isLua) { + typeStr = + typeof type === "function" ? "<< function >>" : + typeof type === "object" ? \`<< class \${type.name} >>\` : + type + } else { + typeStr = typeof type === "function" ? (type.isClass ? \`<< class \${type.name} >>\` : "<< function >>") + : type + } + + return { + type: typeStr, + props, + children + }; + } + + export class Fragment extends Component { + } + } + export default React; +`; +// language=TypeScript +const jsxTypings = `declare namespace JSX { + interface IntrinsicElements { + a: any + b: any + foo: any + bar: any + div: any + "with-dash": any + } +} +`; + +function testJsx(...args: [string] | [TemplateStringsArray, ...any[]]): TestBuilder { + return util + .testFunction(...args) + .setOptions({ + jsx: JsxEmit.React, + }) + .setMainFileName("main.tsx") + .addExtraFile("react.ts", reactLib) + .addExtraFile("jsx.d.ts", jsxTypings) + .setTsHeader('import React, { Component } from "./react";'); +} + +describe("jsx", () => { + test("element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("self closing element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("element with dash name", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("custom element", () => { + testJsx` + function Foo() {} + return + `.expectToMatchJsResult(); + }); + test("fragment", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("fragment with children", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("esoteric component names", () => { + testJsx` + class _Foo extends Component {} + return <_Foo /> + `.expectToMatchJsResult(); + + testJsx` + class $ extends Component {} + return <$ /> + `.expectToMatchJsResult(); + + testJsx` + class é extends Component {} + return <é /> + `.expectToMatchJsResult(); + }); + test("nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("many nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("interpolated children", () => { + testJsx` + const x = 3 + return {x} + `.expectToMatchJsResult(); + }); + test("string prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("value prop", () => { + testJsx` + const x = 5 + return + `.expectToMatchJsResult(); + }); + test("quoted prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("shorthand prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("spaces in jsxText", () => { + testJsx` + return this + is somemultiline + text thing. + + + `.expectToMatchJsResult(); + }); + test("multiline string jsxText", () => { + testJsx` + return + foo bar + baz + + `.expectToMatchJsResult(); + }); + + test("access tag value", () => { + testJsx` + const a = { b(){} }; + return + `.expectToMatchJsResult(); + testJsx` + const a = { b: { c: { d(){} } } }; + return + `.expectToMatchJsResult(); + }); + + test("spread props", () => { + testJsx` + const x = {c: "d", e: "f"} + return + `.expectToMatchJsResult(); + testJsx` + const x = {c: "d", e: "no"} + return + `.expectToMatchJsResult(); + }); + + test("comment children", () => { + testJsx` + return + {/* comment */} + {/* another comment */} + + `.expectToMatchJsResult(); + testJsx` + return + + {/* comment */} + + + `.expectToMatchJsResult(); + }); + + test("multiline string prop value", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + testJsx` + return
+ `.expectToMatchJsResult(); + }); + + test("prop strings with entities", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + }); + test("jsxText with entities", () => { + testJsx` + return 9+10<21 + `.expectToMatchJsResult(); + }); + + test("Spread children", () => { + // doesn't actually "spread" (typescript's current behavior) + testJsx` + const children = [, ] + return {...children} + `.expectToMatchJsResult(); + }); + + test("complex", () => { + testJsx` + const x = 3 + const props = {one: "two", three: 4} + return + `.expectToMatchJsResult(); + }); + + // language=TypeScript + const customJsxLib = `export namespace MyLib { + export function myCreate( + this: void, + type: any, + props: any, + ...children: any[] + ) { + return { type: typeof type, props, children, myThing: true }; + } + + export function MyFragment() { + } + } + `; + + test("custom JSX factory", () => { + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .setOptions({ jsxFactory: "myCreate2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment factory", () => { + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyLib.MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";function MyFragment2(){};') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom JSX pragma", () => { + testJsx` + return c + ` + .setTsHeader('/** @jsx MyLib.myCreate */\nimport { MyLib } from "./myJsx";') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('/** @jsx myCreate2 */import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment pragma", () => { + testJsx` + return <>c + ` + .setTsHeader( + '/** @jsx MyLib.myCreate */\n/** @jsxFrag MyLib.MyFragment */\nimport { MyLib } from "./myJsx";' + ) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader( + "/** @jsx MyLib.myCreate */\n/** @jsxFrag MyFragment2 */\n" + + 'import { MyLib } from "./myJsx";function MyFragment2(){};' + ) + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + + test("forward declare components", () => { + testJsx` + const foo = + + function Foo(){} + + return foo + `.expectToMatchJsResult(); + }); + + test("invalid jsx config", () => { + testJsx(` + return + `) + .setOptions({ + jsx: JsxEmit.Preserve, + }) + .expectToHaveDiagnostics(); + }); +}); From 69a44a6dd3383d4609741e6ba42fc33805d7b243 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 3 Aug 2021 21:25:40 +0200 Subject: [PATCH 85/91] Fix crash when trying to assign to an optional chain (#1045) --- src/transformation/utils/diagnostics.ts | 4 ++++ .../visitors/binary-expression/assignments.ts | 6 ++++++ test/unit/optionalChaining.spec.ts | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 16a0c7395..dbbe9376a 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -143,3 +143,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); + +export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( + "The left-hand side of an assignment expression may not be an optional property access." +); diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index c8a1cd907..f6aa89d61 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -16,6 +16,7 @@ import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, } from "../../utils/transform"; +import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -36,6 +37,11 @@ export function transformAssignment( right: lua.Expression, parent?: ts.Expression ): lua.Statement[] { + if (ts.isOptionalChain(lhs)) { + context.diagnostics.push(notAllowedOptionalAssignment(lhs)); + return []; + } + if (isArrayLength(context, lhs)) { const arrayLengthAssignment = lua.createExpressionStatement( transformLuaLibFunction( diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 26deff810..cf24b6702 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,3 +1,4 @@ +import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { @@ -97,6 +98,15 @@ test("no side effects", () => { `.expectToMatchJsResult(); }); +// Test for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1044 +test("does not crash when incorrectly used in assignment (#1044)", () => { + const { diagnostics } = util.testFunction` + foo?.bar = "foo"; + `.getLuaResult(); + + expect(diagnostics.find(d => d.code === notAllowedOptionalAssignment.code)).toBeDefined(); +}); + describe("optional chaining function calls", () => { test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { util.testFunction` From cac1656bff3c95e101c1b2117bf8c2b02e65211f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 3 Aug 2021 22:21:51 +0200 Subject: [PATCH 86/91] Module resolution fixes (#1060) * Deduplicate resolved files * Add resolution context with cache * Fix problem resolving lua siblings * Added forgotten path.normalize * add ignored test node_modules .d.ts * Fix lua files in sources no longer correctly resolving * fix prettier * Fix lua source file resolution this time for real --- src/transpilation/resolve.ts | 189 +++++++++++++----- src/transpilation/utils.ts | 1 + test/transpile/module-resolution.spec.ts | 34 ++++ .../main.ts | 5 + .../node_modules/dependency1/index.d.ts | 4 + .../node_modules/dependency1/index.lua | 14 ++ .../node_modules/dependency1/otherfile.lua | 10 + .../dependency1/subdir/othersubdirfile.lua | 3 + .../dependency1/subdir/subdirfile.lua | 5 + .../node_modules/dependency1/util.lua | 3 + .../tsconfig.json | 10 + 11 files changed, 230 insertions(+), 48 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/main.ts create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 5334c0ca7..089191d53 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -21,29 +21,110 @@ interface ResolutionResult { diagnostics: ts.Diagnostic[]; } +class ResolutionContext { + private resultsCache = new Map(); + + constructor( + public readonly program: ts.Program, + public readonly options: CompilerOptions, + private readonly emitHost: EmitHost + ) {} + + public resolve(file: ProcessedFile, required: string): ResolutionResult { + const resolvedDependency = resolveDependency(file, required, this.program, this.emitHost); + if (resolvedDependency) { + if (this.options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + } + + // Figure out resolved require path and dependency output path + const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, this.program); + + if (shouldRewriteRequires(resolvedDependency, this.program)) { + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); + } + + // Check cache to prevent resolving nested dependencies double to break dependency loops + if (this.resultsCache.has(resolvedDependency)) { + if (this.options.tstlVerbose) { + console.log(`Resolution cache hit for ${normalizeSlashes(resolvedDependency)}`); + } + return this.resultsCache.get(resolvedDependency)!; + } + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + if (shouldIncludeDependency(resolvedDependency, this.program)) { + // If dependency resolved successfully, read its content + const dependencyContent = this.emitHost.readFile(resolvedDependency); + if (dependencyContent === undefined) { + return { resolvedFiles: [], diagnostics: [couldNotReadDependency(resolvedDependency)] }; + } + + const dependency = { + fileName: resolvedDependency, + code: dependencyContent, + }; + const nestedDependencies = resolveFileDependencies(dependency, this); + + // Cache result and return + const result = { + resolvedFiles: [dependency, ...nestedDependencies.resolvedFiles], + diagnostics: [...nestedDependencies.diagnostics], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } else { + const result = { + resolvedFiles: [], + diagnostics: [], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } + } else { + const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); + + return { + resolvedFiles: [], + diagnostics: [ + couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)), + ], + }; + } + } +} + export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { const outFiles: ProcessedFile[] = [...files]; const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; + const resolutionContext = new ResolutionContext(program, options, emitHost); + // Resolve dependencies for all processed files for (const file of files) { if (options.tstlVerbose) { console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); } - const resolutionResult = resolveFileDependencies(file, program, emitHost); + const resolutionResult = resolveFileDependencies(file, resolutionContext); outFiles.push(...resolutionResult.resolvedFiles); diagnostics.push(...resolutionResult.diagnostics); } - return { resolvedFiles: outFiles, diagnostics }; + return { resolvedFiles: deduplicateResolvedFiles(outFiles), diagnostics }; } -function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { +function deduplicateResolvedFiles(files: ProcessedFile[]): ProcessedFile[] { + return [...new Map(files.map(f => [f.fileName, f])).values()]; +} + +function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext): ResolutionResult { const dependencies: ProcessedFile[] = []; const diagnostics: ts.Diagnostic[] = []; - const options = program.getCompilerOptions() as CompilerOptions; for (const required of findRequiredPaths(file.code)) { // Do no resolve lualib @@ -60,57 +141,22 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH } // Try to resolve the import starting from the directory `file` is in - const fileDir = path.dirname(file.fileName); - const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); - if (resolvedDependency) { - if (options.tstlVerbose) { - console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); - } - - // Figure out resolved require path and dependency output path - const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); - - if (shouldRewriteRequires(resolvedDependency, program)) { - replaceRequireInCode(file, required, resolvedRequire); - replaceRequireInSourceMap(file, required, resolvedRequire); - } - - // If dependency is not part of project, add dependency to output and resolve its dependencies recursively - if (shouldIncludeDependency(resolvedDependency, program)) { - // If dependency resolved successfully, read its content - const dependencyContent = emitHost.readFile(resolvedDependency); - if (dependencyContent === undefined) { - diagnostics.push(couldNotReadDependency(resolvedDependency)); - continue; - } - - const dependency = { - fileName: resolvedDependency, - code: dependencyContent, - }; - const nestedDependencies = resolveFileDependencies(dependency, program, emitHost); - dependencies.push(dependency, ...nestedDependencies.resolvedFiles); - diagnostics.push(...nestedDependencies.diagnostics); - } - } else { - // Could not resolve dependency, add a diagnostic and make some fallback path - diagnostics.push(couldNotResolveRequire(required, path.relative(getProjectRoot(program), file.fileName))); - - const fallbackRequire = fallbackResolve(required, getSourceDir(program), fileDir); - replaceRequireInCode(file, required, fallbackRequire); - replaceRequireInSourceMap(file, required, fallbackRequire); - } + const resolvedDependency = context.resolve(file, required); + dependencies.push(...resolvedDependency.resolvedFiles); + diagnostics.push(...resolvedDependency.diagnostics); } return { resolvedFiles: dependencies, diagnostics }; } function resolveDependency( - fileDirectory: string, + requiringFile: ProcessedFile, dependency: string, program: ts.Program, emitHost: EmitHost ): string | undefined { const options = program.getCompilerOptions() as CompilerOptions; + + const fileDirectory = path.dirname(requiringFile.fileName); if (options.tstlVerbose) { console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); } @@ -132,10 +178,24 @@ function resolveDependency( } } + // Check if this is a lua file in the project sources + const possibleLuaProjectFiles = [ + resolvedPath + ".lua", // lua file in sources + path.join(resolvedPath, "index.lua"), // lua index file in sources + ]; + + for (const possibleFile of possibleLuaProjectFiles) { + if (emitHost.fileExists(possibleFile)) { + return possibleFile; + } + } + // Check if this is a sibling of a required lua file - const luaFilePath = path.resolve(fileDirectory, dependency + ".lua"); - if (emitHost.fileExists(luaFilePath)) { - return luaFilePath; + if (requiringFile.fileName.endsWith(".lua")) { + const luaFilePath = resolveLuaPath(fileDirectory, dependency, emitHost); + if (luaFilePath) { + return luaFilePath; + } } // Not a TS file in our project sources, use resolver to check if we can find dependency @@ -151,6 +211,39 @@ function resolveDependency( return undefined; } +function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost) { + const splitDependency = dependency.split("."); + if (splitDependency.length === 1) { + // If dependency has just one part (the file), look for a lua file with that name + const fileDirectory = walkUpFileTreeUntil(fromPath, dir => + emitHost.fileExists(path.join(dir, dependency) + ".lua") + ); + if (fileDirectory) { + return path.join(fileDirectory, dependency) + ".lua"; + } + } else { + // If dependency has multiple parts, look for the first directory of the require path, which must be in the lua root + const luaRoot = walkUpFileTreeUntil(fromPath, dir => + emitHost.directoryExists(path.join(dir, splitDependency[0])) + ); + if (luaRoot) { + return path.join(luaRoot, dependency.replace(".", path.sep)) + ".lua"; + } + } +} + +function walkUpFileTreeUntil(fromDirectory: string, predicate: (dir: string) => boolean) { + const currentDir = path.normalize(fromDirectory).split(path.sep); + while (currentDir.length > 0) { + const dir = currentDir.join(path.sep); + if (predicate(dir)) { + return dir; + } + currentDir.pop(); + } + return undefined; +} + function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); } diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index a4acdfbb4..4b0a9c24f 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -8,6 +8,7 @@ import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; export interface EmitHost { + directoryExists(path: string): boolean; fileExists(path: string): boolean; getCurrentDirectory(): string; readFile(path: string): string | undefined; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index b995e75a5..9f34407f3 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -275,3 +275,37 @@ describe("module resolution with tsx", () => { }); }); }); + +describe("dependency with complicated inner structure", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-complicated-dependency"); + const tsConfigPath = path.join(projectPath, "tsconfig.json"); + const mainFilePath = path.join(projectPath, "main.ts"); + + const expectedResult = { + otherFileResult: "someFunc from otherfile.lua", + otherFileUtil: "util", + utilResult: "util", + }; + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1055 + test("bundle should not contain duplicate files", () => { + const mainFile = path.join(projectPath, "main.ts"); + const { transpiledFiles } = util + .testProject(tsConfigPath) + .setMainFileName(mainFilePath) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + const lua = transpiledFiles[0].lua!; + // util is used in 2 places, but should only occur once in the bundle + const utilModuleOccurrences = (lua.match(/\["lua_modules\.dependency1\.util"\]/g) ?? []).length; + expect(utilModuleOccurrences).toBe(1); + }); + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1054 + test("should be able to resolve dependency files in subdirectories", () => { + util.testProject(tsConfigPath).setMainFileName(mainFilePath).expectToEqual(expectedResult); + }); +}); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts new file mode 100644 index 000000000..2149de5e4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -0,0 +1,5 @@ +import * as dependency1 from "dependency1"; + +export const otherFileResult = dependency1.otherFileFromDependency1(); +export const utilResult = dependency1.callUtil(); +export const otherFileUtil = dependency1.otherFileUtil(); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..3c72ec27b --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ +export declare function otherFileFromDependency1(): string; +export declare function callUtil(): string; +export declare function otherFileUtil(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua new file mode 100644 index 000000000..a4f17376c --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -0,0 +1,14 @@ +local otherfile = require("otherfile") +local util = require("util") +local subdirfile = require("subdir.subdirfile") +local othersubdirfile = require("subdir.othersubdirfile") + +return { + otherFileFromDependency1 = otherfile.someFunc, + callUtil = function() + return util.utilf() + end, + otherFileUtil = otherfile.callUtil, + subdirfileResult = subdirfile.subdirfileResult, + othersubdirfileResult = othersubdirfile.othersubdirfileResult +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..0fb8719ac --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua @@ -0,0 +1,10 @@ +local util = require("util") + +return { + someFunc = function() + return "someFunc from otherfile.lua" + end, + callUtil = function() + return util.utilf() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua new file mode 100644 index 000000000..45e5c985f --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua @@ -0,0 +1,3 @@ +return { + result = "result from other subdirectory file" +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua new file mode 100644 index 000000000..fe26400a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua @@ -0,0 +1,5 @@ +local othersubdirfile = require("subdir.othersubdirfile") +return { + subdirfileResult = "result from subdirectory file!", + othersubdirfileResult = othersubdirfile.result +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua new file mode 100644 index 000000000..e4e812406 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua @@ -0,0 +1,3 @@ +return { + utilf = function() return "util" end, +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} From 7b39ce3dd3d7c75350413d254924f2c98c0cad5d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 3 Aug 2021 22:28:54 +0200 Subject: [PATCH 87/91] 0.41.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35fb97cf6..3aa24f585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 548b86ef2..fc55ec87a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "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/", From 228d772cdf964a645fb4ca5e02bb87836d9a1457 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 20:35:04 +0200 Subject: [PATCH 88/91] More resolution fixes (#1064) * Fix files nested deeper in depedencies not correctly being resolved * Do not rewrite NoResolution imports in library build mode * Fix bundle require executing modules too often --- src/transpilation/bundle.ts | 6 +-- src/transpilation/resolve.ts | 13 ++++-- test/transpile/module-resolution.spec.ts | 43 ++++++++++++++++++- .../main.ts | 1 + .../node_modules/dependency1/index.d.ts | 3 +- .../node_modules/dependency1/index.lua | 4 +- .../subdir/subsubdir/subsubdirfile.lua | 3 ++ test/unit/bundle.spec.ts | 23 ++++++++++ 8 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 579e84ee1..78e03a7a6 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -18,11 +18,11 @@ local ____moduleCache = {} local ____originalRequire = require local function require(file) if ____moduleCache[file] then - return ____moduleCache[file] + return ____moduleCache[file].value end if ____modules[file] then - ____moduleCache[file] = ____modules[file]() - return ____moduleCache[file] + ____moduleCache[file] = { value = ____modules[file]() } + return ____moduleCache[file].value else if ____originalRequire then return ____originalRequire(file) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 089191d53..da74621aa 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -134,9 +134,14 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext // Do not resolve noResolution paths if (required.startsWith("@NoResolution:")) { - const path = required.replace("@NoResolution:", ""); - replaceRequireInCode(file, required, path); - replaceRequireInSourceMap(file, required, path); + // Remove @NoResolution prefix if not building in library mode + if (!isBuildModeLibrary(context.program)) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + } + + // Skip continue; } @@ -227,7 +232,7 @@ function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost emitHost.directoryExists(path.join(dir, splitDependency[0])) ); if (luaRoot) { - return path.join(luaRoot, dependency.replace(".", path.sep)) + ".lua"; + return path.join(luaRoot, dependency.replace(/\./g, path.sep)) + ".lua"; } } } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 9f34407f3..528b1f25d 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,7 +2,7 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; -import { transpileProject } from "../../src"; +import { BuildMode, transpileProject } from "../../src"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -284,6 +284,7 @@ describe("dependency with complicated inner structure", () => { const expectedResult = { otherFileResult: "someFunc from otherfile.lua", otherFileUtil: "util", + subsubresult: "result from subsub dir", utilResult: "util", }; @@ -309,3 +310,43 @@ describe("dependency with complicated inner structure", () => { util.testProject(tsConfigPath).setMainFileName(mainFilePath).expectToEqual(expectedResult); }); }); + +test("module resolution should not try to resolve @noResolution annotation", () => { + util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .expectToHaveNoDiagnostics(); +}); + +test("module resolution should not rewrite @NoResolution requires in library mode", () => { + const { transpiledFiles } = util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .setOptions({ buildMode: BuildMode.Library }) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); +}); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts index 2149de5e4..20bc696ea 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -3,3 +3,4 @@ import * as dependency1 from "dependency1"; export const otherFileResult = dependency1.otherFileFromDependency1(); export const utilResult = dependency1.callUtil(); export const otherFileUtil = dependency1.otherFileUtil(); +export const subsubresult = dependency1.subsubdirfileResult; diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts index 3c72ec27b..2aaa0dfd6 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -1,4 +1,5 @@ /** @noSelfInFile */ export declare function otherFileFromDependency1(): string; export declare function callUtil(): string; -export declare function otherFileUtil(): string; \ No newline at end of file +export declare function otherFileUtil(): string; +export const subsubdirfileResult: string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua index a4f17376c..8068497d1 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -2,6 +2,7 @@ local otherfile = require("otherfile") local util = require("util") local subdirfile = require("subdir.subdirfile") local othersubdirfile = require("subdir.othersubdirfile") +local subsubdirfile = require("subdir.subsubdir.subsubdirfile") return { otherFileFromDependency1 = otherfile.someFunc, @@ -10,5 +11,6 @@ return { end, otherFileUtil = otherfile.callUtil, subdirfileResult = subdirfile.subdirfileResult, - othersubdirfileResult = othersubdirfile.othersubdirfileResult + othersubdirfileResult = othersubdirfile.othersubdirfileResult, + subsubdirfileResult = subsubdirfile.subsubresult } \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua new file mode 100644 index 000000000..581c8f858 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua @@ -0,0 +1,3 @@ +return { + subsubresult = "result from subsub dir" +} \ No newline at end of file diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index ddc678f34..b8179363a 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -109,6 +109,29 @@ test("cyclic imports", () => { .expectToEqual(new util.ExecutionError("stack overflow")); }); +test("does not evaluate files multiple times", () => { + util.testBundle` + import "./countingfile"; + import "./otherfile"; + + export const count = _count; + ` + .addExtraFile( + "otherfile.ts", + ` + import "./countingfile"; + ` + ) + .addExtraFile( + "countingfile.ts", + ` + declare var _count: number | undefined; + _count = (_count ?? 0) + 1; + ` + ) + .expectToEqual({ count: 1 }); +}); + test("no entry point", () => { util.testBundle`` .setOptions({ luaBundleEntry: undefined }) From d47019903976015d8d61fe62758fdeff89826cac Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 21:54:18 +0200 Subject: [PATCH 89/91] Check baseUrl when resolving imported files (#1067) --- src/transpilation/resolve.ts | 2 +- test/transpile/module-resolution.spec.ts | 40 ++++++++++++++++++++++++ test/util.ts | 8 ++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index da74621aa..9829aa06d 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -167,7 +167,7 @@ function resolveDependency( } // Check if file is a file in the project - const resolvedPath = path.join(fileDirectory, dependency); + const resolvedPath = path.join(options.baseUrl ?? fileDirectory, dependency); const possibleProjectFiles = [ resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 528b1f25d..01386a146 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -350,3 +350,43 @@ test("module resolution should not rewrite @NoResolution requires in library mod expect(transpiledFiles).toHaveLength(1); expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); }); + +test("module resolution uses baseURL to resolve imported files", () => { + util.testModule` + import { foo } from "dep1"; + import { bar } from "dep2"; + import { baz } from "luadep"; + + export const fooResult = foo(); + export const barResult = bar(); + ` + .addExtraFile( + "myproject/mydeps/dep1.ts", + ` + export function foo() { return "foo"; } + ` + ) + .addExtraFile( + "myproject/mydeps/dep2.ts", + ` + export function bar() { return "bar"; } + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.d.ts", + ` + export function baz(): string; + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.lua", + ` + return { baz = function() return "baz" end } + ` + ) + .setOptions({ baseUrl: "./myproject/mydeps" }) + .expectToEqual({ + fooResult: "foo", + barResult: "bar", + }); +}); diff --git a/test/util.ts b/test/util.ts index b493f43e0..b7f285777 100644 --- a/test/util.ts +++ b/test/util.ts @@ -178,8 +178,14 @@ export abstract class TestBuilder { @memoize public getProgram(): ts.Program { this.hasProgram = true; + + // Exclude lua files from TS program, but keep them in extraFiles so module resolution can find them + const nonLuaExtraFiles = Object.fromEntries( + Object.entries(this.extraFiles).filter(([fileName]) => !fileName.endsWith(".lua")) + ); + return tstl.createVirtualProgram( - { ...this.extraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, + { ...nonLuaExtraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, this.options ); } From 4910922a89bc7036abbe5e01fe63ea0c2e000d7a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 22:03:08 +0200 Subject: [PATCH 90/91] Module resolution should ignore functions that look like requires but are not (#1066) * Module resolution should ignore functions that look like requires but are not * fix prettier * Escape special characters in require regex --- src/transpilation/resolve.ts | 13 +++++++-- test/transpile/module-resolution.spec.ts | 35 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 9829aa06d..bc5d098c4 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -274,11 +274,11 @@ function isBuildModeLibrary(program: ts.Program) { function findRequiredPaths(code: string): string[] { // Find all require("") paths in a lua code string const paths: string[] = []; - const pattern = /require\("(.+)"\)/g; + 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[1]); + paths.push(match[2]); } return paths; @@ -286,7 +286,14 @@ function findRequiredPaths(code: string): string[] { function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); - file.code = file.code.replace(`require("${originalRequire}")`, `require("${requirePath}")`); + + // Escape special characters to prevent the regex from breaking... + const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); + + file.code = file.code.replace( + new RegExp(`(^|\\s|;|=)require\\("${escapedRequire}"\\)`), + `$1require("${requirePath}")` + ); } function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 01386a146..f23f77988 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -329,6 +329,7 @@ test("module resolution should not try to resolve @noResolution annotation", () .expectToHaveNoDiagnostics(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 test("module resolution should not rewrite @NoResolution requires in library mode", () => { const { transpiledFiles } = util.testModule` import * as json from "json"; @@ -351,6 +352,40 @@ test("module resolution should not rewrite @NoResolution requires in library mod expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 +test("module resolution should not try to resolve resolve-like functions", () => { + util.testModule` + function custom_require(this: void, value: string) { + return value; + } + + namespace ns { + export function require(this: void, value: string) { + return value; + } + } + + class MyClass { + require(value: string) { + return value; + } + } + const inst = new MyClass(); + + export const result = [ + custom_require("value 1"), + ns.require("value 2"), + inst.require("value 3") + ]; + + ` + .expectToHaveNoDiagnostics() + .expectToEqual({ + result: ["value 1", "value 2", "value 3"], + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 test("module resolution uses baseURL to resolve imported files", () => { util.testModule` import { foo } from "dep1"; From d39de69570c949d5eebcbd2f1ef6715542c5308b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 5 Aug 2021 22:14:57 +0200 Subject: [PATCH 91/91] 0.41.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3aa24f585..d7055278b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index fc55ec87a..fa3fc0575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "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/",