From 05dd13aa74365ac2dacf6030f5a58fd3de919bbc Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Mon, 13 Dec 2021 17:54:11 +0100 Subject: [PATCH] chore(release): 1.48.0 (#3254) See [CHANGELOG](https://github.com/aws/jsii/blob/bump/1.48.0/CHANGELOG.md) --- .github/workflows/main.yml | 1 - .mergify/config.yml | 10 +- CHANGELOG.md | 26 + .../lib-author/quick-start/write-code.md | 2 +- lerna.json | 2 +- package.json | 16 +- packages/@jsii/check-node/package.json | 2 +- packages/@jsii/go-runtime/package.json | 4 +- packages/@jsii/integ-test/package.json | 6 +- packages/@jsii/kernel/package.json | 8 +- packages/@jsii/runtime/package.json | 10 +- packages/@jsii/spec/lib/configuration.ts | 31 +- packages/@jsii/spec/package.json | 6 +- .../jsii-calc-base-of-base/package.json | 2 +- .../jsii-calc-base-of-base/test/assembly.jsii | 5 +- packages/@scope/jsii-calc-base/package.json | 2 +- packages/@scope/jsii-calc-lib/package.json | 2 +- .../@scope/jsii-calc-lib/test/assembly.jsii | 5 +- packages/codemaker/package.json | 6 +- packages/jsii-calc/package.json | 4 +- packages/jsii-calc/test/assembly.jsii | 10 +- packages/jsii-config/package.json | 6 +- packages/jsii-diff/package.json | 6 +- packages/jsii-pacmak/lib/dependency-graph.ts | 27 +- packages/jsii-pacmak/lib/npm-modules.ts | 25 +- .../lib/targets/python/requirements-dev.txt | 2 +- packages/jsii-pacmak/lib/util.ts | 94 +- packages/jsii-pacmak/package.json | 10 +- .../jsii-pacmak/test/dependency-graph.test.ts | 15 +- .../prerelease-identifiers.test.ts | 2 + packages/jsii-reflect/lib/type-system.ts | 59 +- packages/jsii-reflect/lib/util.ts | 93 ++ packages/jsii-reflect/package.json | 6 +- .../jsii-reflect/test/independent.test.ts | 6 +- packages/jsii-rosetta/bin/jsii-rosetta.ts | 2 +- packages/jsii-rosetta/lib/jsii/jsii-utils.ts | 66 +- .../lib/languages/record-references.ts | 2 +- packages/jsii-rosetta/lib/util.ts | 6 +- packages/jsii-rosetta/package.json | 6 +- .../test/commands/extract.test.ts | 72 ++ packages/jsii-rosetta/test/testutil.ts | 45 +- packages/jsii/lib/assembler.ts | 190 ++- packages/jsii/lib/compiler.ts | 82 +- packages/jsii/lib/helpers.ts | 205 +++- packages/jsii/lib/jsii-diagnostic.ts | 12 +- packages/jsii/lib/project-info.ts | 27 +- packages/jsii/lib/symbol-id.ts | 182 ++- .../lib/transforms/deprecation-warnings.ts | 31 +- packages/jsii/lib/utils.ts | 96 ++ packages/jsii/package.json | 8 +- packages/jsii/test/compiler.test.ts | 49 +- packages/jsii/test/project-info.test.ts | 20 +- packages/jsii/test/submodules.test.ts | 60 +- packages/jsii/test/symbol-identifiers.test.ts | 101 +- packages/oo-ascii-tree/package.json | 6 +- tools/jsii-compliance/package.json | 4 +- yarn.lock | 1085 +++++++++-------- 57 files changed, 1917 insertions(+), 951 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2eea33c9f1..5e2a263a9f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -241,7 +241,6 @@ jobs: python: '3.6' - java: '8' dotnet: '6.0.x' - dotnet-prerelease: true go: '1.16' node: '12' os: ubuntu-latest diff --git a/.mergify/config.yml b/.mergify/config.yml index 25c38d619a..0dba861be7 100644 --- a/.mergify/config.yml +++ b/.mergify/config.yml @@ -82,7 +82,10 @@ pull_request_rules: queue: name: default method: squash - commit_message: title+body + commit_message_template: |- + {{ title }} (#{{ number }}) + + {{ body }} comment: message: Merging (with squash)... conditions: @@ -130,7 +133,10 @@ pull_request_rules: queue: name: default method: merge - commit_message: title+body + commit_message_template: |- + {{ title }} (#{{ number }}) + + {{ body }} comment: message: Merging (no-squash)... conditions: diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9e0cd1cb..2c1888ed25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.48.0](https://github.com/aws/jsii/compare/v1.45.0...v1.48.0) (2021-12-13) + + +### Features + +* **reflect:** add `allTypes` accessor ([#3194](https://github.com/aws/jsii/issues/3194)) ([41f301a](https://github.com/aws/jsii/commit/41f301a8304bd1ed6ed7ec4e31bd23ffd1a2ed8b)) +* **rosetta:** metadata tag for fixtures in docs ([#3200](https://github.com/aws/jsii/issues/3200)) ([8cefa8b](https://github.com/aws/jsii/commit/8cefa8bc8c9554913960b48226531aff874ee247)) +* **rosetta:** generate rosetta tablets next to each assembly ([#3223](https://github.com/aws/jsii/issues/3223)) ([1e7b604](https://github.com/aws/jsii/commit/1e7b604c15a0083f27ceafd8ca32ff9b6cf61759)) +* **rosetta:** reuse output file as additional cache and introduce `--infuse` option for `extract` ([#3210](https://github.com/aws/jsii/issues/3210)) ([ccb3c57](https://github.com/aws/jsii/commit/ccb3c57b834225f16ec619f55a7976e59b7a53c3)) + + +### Bug Fixes + +* improve compatibility with restricted-export modules ([#3205](https://github.com/aws/jsii/issues/3205)) ([31a7172](https://github.com/aws/jsii/commit/31a71721bfaff28876ce0554230e63803591e112)) +* **jsii:** constants can't mix letters and digits ([#3209](https://github.com/aws/jsii/issues/3209)) ([a444e29](https://github.com/aws/jsii/commit/a444e2993b73dc002586e2c4a3446121c279eb65)), closes [#3208](https://github.com/aws/jsii/issues/3208) +* **jsii:** correctly identify types regardless of import method ([#3233](https://github.com/aws/jsii/issues/3233)) ([aa37d62](https://github.com/aws/jsii/commit/aa37d623f866d2b2a3802a90578e8e85227b37b1)), closes [aws/aws-cdk#17860](https://github.com/aws/aws-cdk/issues/17860) +* **jsii:** deprecation message is not displayed for deprecated classes ([#3206](https://github.com/aws/jsii/issues/3206)) ([3841538](https://github.com/aws/jsii/commit/3841538179226b67c756ca8689ac1a3de4bec521)) +* **jsii:** handle imports from libraries compiled with old jsii ([#3245](https://github.com/aws/jsii/issues/3245)) ([133d1cf](https://github.com/aws/jsii/commit/133d1cf371367b1516b175aa9ed904eb701fac0f)), closes [#3233](https://github.com/aws/jsii/issues/3233) [#3233](https://github.com/aws/jsii/issues/3233) +* **jsii:** symbolid for single-valued enums is incorrect ([#3234](https://github.com/aws/jsii/issues/3234)) ([83d3fc8](https://github.com/aws/jsii/commit/83d3fc805874a72b7a76d08f62e8b10121b4777b)) +* **pacmak:** don't automatically translate examples without asking ([#3219](https://github.com/aws/jsii/issues/3219)) ([937f8c3](https://github.com/aws/jsii/commit/937f8c3753bec27269ce9213a6bc55fea79647b0)) +* **rosetta:** `extract` ignores `--compile` option ([#3193](https://github.com/aws/jsii/issues/3193)) ([639c510](https://github.com/aws/jsii/commit/639c510ba6d07b26bf35d0c8d3c9cdcced6d916a)) +* **rosetta:** classes are not correctly identified if package uses an outDir ([#3225](https://github.com/aws/jsii/issues/3225)) ([05631a7](https://github.com/aws/jsii/commit/05631a723b8c08d8d82e9ec50c6adaee1e2d693e)) +* **rosetta:** enum resolution breaks for properties ([#3190](https://github.com/aws/jsii/issues/3190)) ([3b49066](https://github.com/aws/jsii/commit/3b49066e4dd960385709dbdce1d9c1fbfb2f20cf)) +* **rosetta:** infuse drops first assembly ([#3243](https://github.com/aws/jsii/issues/3243)) ([29a6a84](https://github.com/aws/jsii/commit/29a6a848e2cada2a695d0d1a852c6c53c24d35ac)) +* **rosetta:** use `--compile` flag by default ([#3218](https://github.com/aws/jsii/issues/3218)) ([9df7950](https://github.com/aws/jsii/commit/9df7950f263aae045877accb45007e0f9a5b03bd)) + ## [1.47.0](https://github.com/aws/jsii/compare/v1.45.0...v1.47.0) (2021-12-06) diff --git a/gh-pages/content/user-guides/lib-author/quick-start/write-code.md b/gh-pages/content/user-guides/lib-author/quick-start/write-code.md index df4cad3be5..dcf5b79796 100644 --- a/gh-pages/content/user-guides/lib-author/quick-start/write-code.md +++ b/gh-pages/content/user-guides/lib-author/quick-start/write-code.md @@ -29,7 +29,7 @@ necessary `tsconfig.json` is automatically created so the **TypeScript** compile ## Generate Targets -Once you are satisfied with the library, bindings in all supproted languages can be generated by running `jsii-pacmak`, +Once you are satisfied with the library, bindings in all supported languages can be generated by running `jsii-pacmak`, typically by using the `package` script from the [Set Up](set-up.md) step. Publishable artifacts will be generated and placed in per-language sub-directories of the `dist` folder: diff --git a/lerna.json b/lerna.json index 4b6def9308..60e312aa8b 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "rejectCycles": true } }, - "version": "1.47.0" + "version": "1.48.0" } diff --git a/package.json b/package.json index dde647af0e..1034e0e10f 100644 --- a/package.json +++ b/package.json @@ -15,22 +15,22 @@ "compliance": "(cd tools/jsii-compliance && yarn report)" }, "devDependencies": { - "@jest/types": "^27.2.5", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", + "@jest/types": "^27.4.2", + "@typescript-eslint/eslint-plugin": "^5.6.0", + "@typescript-eslint/parser": "^5.6.0", "all-contributors-cli": "^6.20.0", - "eslint": "^8.3.0", + "eslint": "^8.4.1", "eslint-config-prettier": "^8.3.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^2.5.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", - "jest-circus": "^27.3.1", - "jest-config": "^27.3.1", + "jest-circus": "^27.4.4", + "jest-config": "^27.4.4", "lerna": "^4.0.0", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "standard-version": "^9.3.2", - "ts-jest": "^27.0.7", + "ts-jest": "^27.1.1", "ts-node": "^10.4.0", "typescript": "~3.9.10" }, diff --git a/packages/@jsii/check-node/package.json b/packages/@jsii/check-node/package.json index e553956449..dfe42f1f80 100644 --- a/packages/@jsii/check-node/package.json +++ b/packages/@jsii/check-node/package.json @@ -43,6 +43,6 @@ "@types/chalk": "^2.2.0", "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "jest": "^27.3.1" + "jest": "^27.4.4" } } diff --git a/packages/@jsii/go-runtime/package.json b/packages/@jsii/go-runtime/package.json index 92c125dfd0..023cd8c66c 100644 --- a/packages/@jsii/go-runtime/package.json +++ b/packages/@jsii/go-runtime/package.json @@ -26,11 +26,11 @@ "@types/fs-extra": "^9.0.13", "@types/node": "^12.20.37", "codemaker": "^0.0.0", - "eslint": "^8.3.0", + "eslint": "^8.4.1", "fs-extra": "^9.1.0", "jsii-build-tools": "^0.0.0", "jsii-calc": "^3.20.120", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "ts-node": "^10.4.0", "typescript": "~3.9.10" } diff --git a/packages/@jsii/integ-test/package.json b/packages/@jsii/integ-test/package.json index 55e57cf026..2af63f492e 100644 --- a/packages/@jsii/integ-test/package.json +++ b/packages/@jsii/integ-test/package.json @@ -20,7 +20,7 @@ "@octokit/rest": "^18.12.0", "dotenv": "^8.6.0", "fs-extra": "^9.1.0", - "jest": "^27.3.1", + "jest": "^27.4.4", "jsii": "^0.0.0", "jsii-pacmak": "^0.0.0", "jsii-rosetta": "^0.0.0", @@ -32,8 +32,8 @@ "@types/jest": "^27.0.3", "@types/node": "^12.20.37", "@types/tar": "^6.1.1", - "eslint": "^8.3.0", - "prettier": "^2.4.1", + "eslint": "^8.4.1", + "prettier": "^2.5.1", "typescript": "~3.9.10" } } diff --git a/packages/@jsii/kernel/package.json b/packages/@jsii/kernel/package.json index eecf968f32..6299d3de7c 100644 --- a/packages/@jsii/kernel/package.json +++ b/packages/@jsii/kernel/package.json @@ -42,13 +42,13 @@ "@types/jest": "^27.0.3", "@types/node": "^12.20.37", "@types/tar": "^6.1.1", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jest-expect-message": "^1.0.2", "jsii-build-tools": "^0.0.0", "jsii-calc": "^3.20.120", - "prettier": "^2.4.1", - "ts-jest": "^27.0.7", + "prettier": "^2.5.1", + "ts-jest": "^27.1.1", "typescript": "~3.9.10" } } diff --git a/packages/@jsii/runtime/package.json b/packages/@jsii/runtime/package.json index 8d337546d7..0900b30f70 100644 --- a/packages/@jsii/runtime/package.json +++ b/packages/@jsii/runtime/package.json @@ -43,15 +43,15 @@ "@scope/jsii-calc-lib": "^0.0.0", "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii-build-tools": "^0.0.0", "jsii-calc": "^3.20.120", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "source-map-loader": "^3.0.0", - "ts-jest": "^27.0.7", + "ts-jest": "^27.1.1", "typescript": "~3.9.10", - "webpack": "^5.64.3", + "webpack": "^5.65.0", "webpack-cli": "^4.9.1" } } diff --git a/packages/@jsii/spec/lib/configuration.ts b/packages/@jsii/spec/lib/configuration.ts index fdb0f23b52..ca5e9fffec 100644 --- a/packages/@jsii/spec/lib/configuration.ts +++ b/packages/@jsii/spec/lib/configuration.ts @@ -7,7 +7,7 @@ export interface Config { /** * Output directory of typescript compiler */ - outdir: string; + outdir?: string; /** * Determines the format of the jsii toolchain version string that will be @@ -19,12 +19,12 @@ export interface Config { * short - only the version number of jsii will be used * example: 0.14.3 */ - versionFormat: 'full' | 'short'; + versionFormat?: 'full' | 'short'; /** * Defines which target languages the module supports. */ - targets: { + targets?: { java?: { /* * generated maven package name @@ -87,6 +87,16 @@ export interface Config { metadata?: { [key: string]: any; }; + + /** + * TypeScript compiler options + */ + tsc?: { + outDir?: string; + rootDir?: string; + + [key: string]: any; + }; } /** @@ -146,5 +156,20 @@ export interface PackageJson { */ stability?: Stability; + /** + * Run-time dependencies that are private to this assembly + */ + dependencies?: Record; + + /** + * Run-time dependencies that will be shared with other assemblies + */ + peerDependencies?: Record; + + /** + * Build-time dependencies + */ + devDependencies?: Record; + [key: string]: unknown; } diff --git a/packages/@jsii/spec/package.json b/packages/@jsii/spec/package.json index 3e7a5ef946..24d999323d 100644 --- a/packages/@jsii/spec/package.json +++ b/packages/@jsii/spec/package.json @@ -36,10 +36,10 @@ "devDependencies": { "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii-build-tools": "^0.0.0", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "typescript": "~3.9.10", "typescript-json-schema": "^0.52.0" } diff --git a/packages/@scope/jsii-calc-base-of-base/package.json b/packages/@scope/jsii-calc-base-of-base/package.json index b4ed0b7c0d..169e3ad14e 100644 --- a/packages/@scope/jsii-calc-base-of-base/package.json +++ b/packages/@scope/jsii-calc-base-of-base/package.json @@ -34,7 +34,7 @@ "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-rosetta": "^0.0.0", - "prettier": "^2.4.1" + "prettier": "^2.5.1" }, "jsii": { "outdir": "dist", diff --git a/packages/@scope/jsii-calc-base-of-base/test/assembly.jsii b/packages/@scope/jsii-calc-base-of-base/test/assembly.jsii index 5549a32ecf..fe77b83324 100644 --- a/packages/@scope/jsii-calc-base-of-base/test/assembly.jsii +++ b/packages/@scope/jsii-calc-base-of-base/test/assembly.jsii @@ -19,7 +19,8 @@ "rosetta": { "strict": true } - } + }, + "tscRootDir": "." }, "name": "@scope/jsii-calc-base-of-base", "repository": { @@ -165,5 +166,5 @@ } }, "version": "2.1.1", - "fingerprint": "6Qes5fbC/YvlKQaK6Oqw0RGgsr/feI/vaRWDYXJJaU8=" + "fingerprint": "BYVFW3VSnno85aN3BfEZ3Px9cEKhgfteosHUXjQW0rw=" } diff --git a/packages/@scope/jsii-calc-base/package.json b/packages/@scope/jsii-calc-base/package.json index 0398e3d2c0..f54d629988 100644 --- a/packages/@scope/jsii-calc-base/package.json +++ b/packages/@scope/jsii-calc-base/package.json @@ -39,7 +39,7 @@ "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-rosetta": "^0.0.0", - "prettier": "^2.4.1" + "prettier": "^2.5.1" }, "jsii": { "metadata": { diff --git a/packages/@scope/jsii-calc-lib/package.json b/packages/@scope/jsii-calc-lib/package.json index e068cebef4..f1437c4c79 100644 --- a/packages/@scope/jsii-calc-lib/package.json +++ b/packages/@scope/jsii-calc-lib/package.json @@ -43,7 +43,7 @@ "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-rosetta": "^0.0.0", - "prettier": "^2.4.1" + "prettier": "^2.5.1" }, "jsii": { "outdir": "dist", diff --git a/packages/@scope/jsii-calc-lib/test/assembly.jsii b/packages/@scope/jsii-calc-lib/test/assembly.jsii index b932b84ed4..6ee1fc1ebd 100644 --- a/packages/@scope/jsii-calc-lib/test/assembly.jsii +++ b/packages/@scope/jsii-calc-lib/test/assembly.jsii @@ -80,7 +80,8 @@ "rosetta": { "strict": true } - } + }, + "tscRootDir": "lib" }, "name": "@scope/jsii-calc-lib", "repository": { @@ -952,5 +953,5 @@ } }, "version": "0.0.0", - "fingerprint": "BJ528BPiptJdqvxyoh4Ax2l2Knaz2KcuNYBYhVpyTw8=" + "fingerprint": "wtswDMhtuMcC4+ami5KddQIznqdpVjt8qc7Ba2QnnHk=" } diff --git a/packages/codemaker/package.json b/packages/codemaker/package.json index 960ad07123..4ec77d1b86 100644 --- a/packages/codemaker/package.json +++ b/packages/codemaker/package.json @@ -39,9 +39,9 @@ "@types/fs-extra": "^9.0.13", "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "jest": "^27.3.1", - "prettier": "^2.4.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", + "prettier": "^2.5.1", "typescript": "~3.9.10" } } diff --git a/packages/jsii-calc/package.json b/packages/jsii-calc/package.json index 16fea36110..dc3489e567 100644 --- a/packages/jsii-calc/package.json +++ b/packages/jsii-calc/package.json @@ -52,11 +52,11 @@ }, "devDependencies": { "@types/node": "^12.20.37", - "eslint": "^8.3.0", + "eslint": "^8.4.1", "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-rosetta": "^0.0.0", - "prettier": "^2.4.1" + "prettier": "^2.5.1" }, "jsii": { "outdir": "dist", diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 5d53eb9849..213c90a2fd 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -11760,7 +11760,7 @@ } ], "name": "SingletonIntEnum", - "symbolId": "lib/compliance:SingletonIntEnum.SINGLETON_INT" + "symbolId": "lib/compliance:SingletonIntEnum" }, "jsii-calc.SingletonString": { "assembly": "jsii-calc", @@ -11825,7 +11825,7 @@ } ], "name": "SingletonStringEnum", - "symbolId": "lib/compliance:SingletonStringEnum.SINGLETON_STRING" + "symbolId": "lib/compliance:SingletonStringEnum" }, "jsii-calc.SmellyStruct": { "assembly": "jsii-calc", @@ -16363,7 +16363,7 @@ ], "name": "Awesomeness", "namespace": "submodule.child", - "symbolId": "lib/submodule/child/index:Awesomeness.AWESOME" + "symbolId": "lib/submodule/child/index:Awesomeness" }, "jsii-calc.submodule.child.Goodness": { "assembly": "jsii-calc", @@ -16541,7 +16541,7 @@ ], "name": "SomeEnum", "namespace": "submodule.child", - "symbolId": "lib/submodule/child/index:SomeEnum.SOME" + "symbolId": "lib/submodule/child/index:SomeEnum" }, "jsii-calc.submodule.child.SomeStruct": { "assembly": "jsii-calc", @@ -16807,5 +16807,5 @@ } }, "version": "3.20.120", - "fingerprint": "wBGhJE4ZhvVb8R2qk5FWg49mt+ZKqW60TjlMMtT1Klo=" + "fingerprint": "w6AJ35Nh9lBusQyMGP28WJp5MNbg527uO9TsHaP+DiE=" } diff --git a/packages/jsii-config/package.json b/packages/jsii-config/package.json index c3ca077367..c1ec0acbb4 100644 --- a/packages/jsii-config/package.json +++ b/packages/jsii-config/package.json @@ -23,10 +23,10 @@ "@types/jest": "^27.0.3", "@types/node": "^12.20.37", "@types/yargs": "^17.0.7", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jest-expect-message": "^1.0.2", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "typescript": "~3.9.10" }, "dependencies": { diff --git a/packages/jsii-diff/package.json b/packages/jsii-diff/package.json index d28555edd9..53fdf318d7 100644 --- a/packages/jsii-diff/package.json +++ b/packages/jsii-diff/package.json @@ -46,11 +46,11 @@ "@types/jest": "^27.0.3", "@types/node": "^12.20.37", "@types/tar-fs": "^2.0.1", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jest-expect-message": "^1.0.2", "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", - "prettier": "^2.4.1" + "prettier": "^2.5.1" } } diff --git a/packages/jsii-pacmak/lib/dependency-graph.ts b/packages/jsii-pacmak/lib/dependency-graph.ts index b4f80e6f18..d00bdae639 100644 --- a/packages/jsii-pacmak/lib/dependency-graph.ts +++ b/packages/jsii-pacmak/lib/dependency-graph.ts @@ -21,7 +21,7 @@ export async function traverseDependencyGraph( callback: Callback, host: TraverseDependencyGraphHost = { readJson: fs.readJson, - resolveDependencyDirectory: util.resolveDependencyDirectory, + findDependencyDirectory: util.findDependencyDirectory, }, ): Promise { return real$traverseDependencyGraph(packageDir, callback, host, new Set()); @@ -49,7 +49,7 @@ export type Callback = ( */ export interface TraverseDependencyGraphHost { readonly readJson: typeof fs.readJson; - readonly resolveDependencyDirectory: typeof util.resolveDependencyDirectory; + readonly findDependencyDirectory: typeof util.findDependencyDirectory; } /** @@ -87,15 +87,20 @@ async function real$traverseDependencyGraph( ...Object.keys(meta.peerDependencies ?? {}), ]); return Promise.all( - Array.from(deps).map((dep) => { - const dependencyDir = host.resolveDependencyDirectory(packageDir, dep); - return real$traverseDependencyGraph( - dependencyDir, - callback, - host, - visited, - ); - }), + Array.from(deps) + .filter((m) => !util.isBuiltinModule(m)) + .map(async (dep) => { + const dependencyDir = await host.findDependencyDirectory( + dep, + packageDir, + ); + return real$traverseDependencyGraph( + dependencyDir, + callback, + host, + visited, + ); + }), // The following ".then" literally just turns a `Promise` into a `Promise`. Convenient! ).then(); } diff --git a/packages/jsii-pacmak/lib/npm-modules.ts b/packages/jsii-pacmak/lib/npm-modules.ts index 664b9fb58e..f0f5ba1d4d 100644 --- a/packages/jsii-pacmak/lib/npm-modules.ts +++ b/packages/jsii-pacmak/lib/npm-modules.ts @@ -5,7 +5,7 @@ import * as path from 'path'; import * as logging from '../lib/logging'; import { JsiiModule } from './packaging'; import { topologicalSort, Toposorted } from './toposort'; -import { resolveDependencyDirectory } from './util'; +import { findDependencyDirectory, isBuiltinModule } from './util'; /** * Find all modules that need to be packagerd @@ -67,9 +67,26 @@ export async function findJsiiModules( // if --recurse is set, find dependency dirs and build them. if (recurse) { await Promise.all( - dependencyNames - .map((dep) => resolveDependencyDirectory(realPath, dep)) - .map((depDir) => visitPackage(depDir, false)), + dependencyNames.flatMap(async (dep) => { + if (isBuiltinModule(dep)) { + return []; + } + + try { + const depDir = await findDependencyDirectory(dep, realPath); + return [await visitPackage(depDir, false)]; + } catch (e) { + // Some modules like `@types/node` cannot be require()d, but we also don't need them. + if ( + !['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'].includes( + e.code, + ) + ) { + throw e; + } + return []; + } + }), ); } diff --git a/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt b/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt index b2dc5a9e05..43f5f355a6 100644 --- a/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt +++ b/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt @@ -6,4 +6,4 @@ setuptools~=59.1.1 # build-system wheel~=0.37.0 # build-system -twine~=3.6.0 +twine~=3.7.0 diff --git a/packages/jsii-pacmak/lib/util.ts b/packages/jsii-pacmak/lib/util.ts index 98ee8f24b0..c37d276baf 100644 --- a/packages/jsii-pacmak/lib/util.ts +++ b/packages/jsii-pacmak/lib/util.ts @@ -6,19 +6,93 @@ import * as path from 'path'; import * as logging from './logging'; /** - * Given an npm package directory and a dependency name, returns the package directory of the dep. - * @param packageDir the root of the package declaring the dependency. - * @param dependencyName the name of the dependency to be resolved. - * @return the resolved directory path. + * Find the directory that contains a given dependency, identified by its 'package.json', from a starting search directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) */ -export function resolveDependencyDirectory( - packageDir: string, +export async function findDependencyDirectory( dependencyName: string, -): string { - const lookupPaths = [path.join(packageDir, 'node_modules')]; - return path.dirname( - require.resolve(`${dependencyName}/package.json`, { paths: lookupPaths }), + searchStart: string, +) { + // Explicitly do not use 'require("dep/package.json")' because that will fail if the + // package does not export that particular file. + const entryPoint = require.resolve(dependencyName, { + paths: [searchStart], + }); + + // Search up from the given directory, looking for a package.json that matches + // the dependency name (so we don't accidentally find stray 'package.jsons'). + const depPkgJsonPath = await findPackageJsonUp( + dependencyName, + path.dirname(entryPoint), ); + + if (!depPkgJsonPath) { + throw new Error( + `Could not find dependency '${dependencyName}' from '${searchStart}'`, + ); + } + + return depPkgJsonPath; +} + +/** + * Whether the given dependency is a built-in + * + * Some dependencies that occur in `package.json` are also built-ins in modern Node + * versions (most egregious example: 'punycode'). Detect those and filter them out. + */ +export function isBuiltinModule(depName: string) { + // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires + const { builtinModules } = require('module'); + return (builtinModules ?? []).includes(depName); +} + +/** + * Find the package.json for a given package upwards from the given directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findPackageJsonUp( + packageName: string, + directory: string, +) { + return findUp(directory, async (dir) => { + const pjFile = path.join(dir, 'package.json'); + return ( + (await fs.pathExists(pjFile)) && + (await fs.readJson(pjFile)).name === packageName + ); + }); +} + +/** + * Find a directory up the tree from a starting directory matching a condition + * + * Will return `undefined` if no directory matches + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findUp( + directory: string, + pred: (dir: string) => Promise, +): Promise { + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + if (await pred(directory)) { + return directory; + } + + const parent = path.dirname(directory); + if (parent === directory) { + return undefined; + } + directory = parent; + } } export interface RetryOptions { diff --git a/packages/jsii-pacmak/package.json b/packages/jsii-pacmak/package.json index 493492d406..80e6ca8d58 100644 --- a/packages/jsii-pacmak/package.json +++ b/packages/jsii-pacmak/package.json @@ -33,7 +33,7 @@ "test": "npm run test:unit && npm run test:build", "test:unit": "jest", "test:build": "bash test/build-test.sh", - "test:update": "jest -u && npm run test:build", + "test:update": "true", "package": "package-js" }, "dependencies": { @@ -62,13 +62,13 @@ "@types/jest": "^27.0.3", "@types/node": "^12.20.37", "@types/semver": "^7.3.9", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-calc": "^3.20.120", - "prettier": "^2.4.1", - "ts-jest": "^27.0.7", + "prettier": "^2.5.1", + "ts-jest": "^27.1.1", "typescript": "~3.9.10" }, "keywords": [ diff --git a/packages/jsii-pacmak/test/dependency-graph.test.ts b/packages/jsii-pacmak/test/dependency-graph.test.ts index dfbe0c56c0..e46446c167 100644 --- a/packages/jsii-pacmak/test/dependency-graph.test.ts +++ b/packages/jsii-pacmak/test/dependency-graph.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/require-await */ import { tmpdir } from 'os'; import { join } from 'path'; @@ -5,9 +6,9 @@ import { Callback, traverseDependencyGraph } from '../lib/dependency-graph'; const mockHost = { readJson: jest.fn, [string]>().mockName('fs.readJson'), - resolveDependencyDirectory: jest - .fn() - .mockName('resolveDependencyDirectory'), + findDependencyDirectory: jest + .fn, [string, string]>() + .mockName('findDependencyDirectory'), }; afterEach((done) => { @@ -42,7 +43,7 @@ test('de-duplicates package root directories', async () => { : Promise.reject(new Error(`Unexpected file access: ${file}`)); }); - mockHost.resolveDependencyDirectory.mockImplementation((_dir, dep) => { + mockHost.findDependencyDirectory.mockImplementation(async (dep, _dir) => { const result = packages[dep]?.root; if (result == null) { throw new Error(`Unknown dependency: ${dep}`); @@ -63,7 +64,7 @@ test('de-duplicates package root directories', async () => { } expect(mockHost.readJson).toHaveBeenCalledTimes(3); - expect(mockHost.resolveDependencyDirectory).toHaveBeenCalledTimes(3); + expect(mockHost.findDependencyDirectory).toHaveBeenCalledTimes(3); }); test('stops traversing when callback returns false', async () => { @@ -90,7 +91,7 @@ test('stops traversing when callback returns false', async () => { : Promise.reject(new Error(`Unexpected file access: ${file}`)); }); - mockHost.resolveDependencyDirectory.mockImplementation((_dir, dep) => { + mockHost.findDependencyDirectory.mockImplementation(async (dep, _dir) => { const result = packages[dep]?.root; if (result == null) { throw new Error(`Unknown dependency: ${dep}`); @@ -110,5 +111,5 @@ test('stops traversing when callback returns false', async () => { expect(cb).toHaveBeenCalledWith(packages.B.root, packages.B.meta, false); expect(mockHost.readJson).toHaveBeenCalledTimes(2); - expect(mockHost.resolveDependencyDirectory).toHaveBeenCalledTimes(1); + expect(mockHost.findDependencyDirectory).toHaveBeenCalledTimes(1); }); diff --git a/packages/jsii-pacmak/test/generated-code/prerelease-identifiers.test.ts b/packages/jsii-pacmak/test/generated-code/prerelease-identifiers.test.ts index a65ae3d7eb..4005cf5c0a 100644 --- a/packages/jsii-pacmak/test/generated-code/prerelease-identifiers.test.ts +++ b/packages/jsii-pacmak/test/generated-code/prerelease-identifiers.test.ts @@ -100,6 +100,8 @@ async function mockSourceDirectory( }, { spaces: 2 }, ); + // Necessary otherwise 'require.resolve()' will fail + await fs.writeFile(join(pkgDir, 'index.js'), 'module.exports = {};'); } /* eslint-enable no-await-in-loop */ diff --git a/packages/jsii-reflect/lib/type-system.ts b/packages/jsii-reflect/lib/type-system.ts index 302f600282..0b696ebe0d 100644 --- a/packages/jsii-reflect/lib/type-system.ts +++ b/packages/jsii-reflect/lib/type-system.ts @@ -1,6 +1,6 @@ import * as jsii from '@jsii/spec'; +import * as fs from 'fs-extra'; import * as path from 'path'; -import { promisify } from 'util'; import { Assembly } from './assembly'; import { ClassType } from './class'; @@ -10,6 +10,7 @@ import { Method } from './method'; import { ModuleLike } from './module-like'; import { Property } from './property'; import { Type } from './type'; +import { findDependencyDirectory, isBuiltinModule } from './util'; export class TypeSystem { /** @@ -34,30 +35,36 @@ export class TypeSystem { packageRoot: string, options: { validate?: boolean } = {}, ): Promise { - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports - const pkg = require(path.resolve(packageRoot, 'package.json')); + const pkg = await fs.readJson(path.resolve(packageRoot, 'package.json')); for (const dep of dependenciesOf(pkg)) { - // Filter jsii dependencies - const depPkgJsonPath = require.resolve(`${dep}/package.json`, { - paths: [packageRoot], - }); - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports - const depPkgJson = require(depPkgJsonPath); + if (isBuiltinModule(dep)) { + continue; + } + + // eslint-disable-next-line no-await-in-loop + const depDir = await findDependencyDirectory(dep, packageRoot); + + // eslint-disable-next-line no-await-in-loop + const depPkgJson = await fs.readJson(path.join(depDir, 'package.json')); if (!depPkgJson.jsii) { continue; } // eslint-disable-next-line no-await-in-loop - await this.loadModule(path.dirname(depPkgJsonPath), options); + await this.loadModule(depDir, options); } } /** * Loads a jsii module or a single .jsii file into the type system. * + * If `fileOrDirectory` is a directory, it will be treated as a jsii npm module, + * and its dependencies (as determined by its 'package.json' file) will be loaded + * as well. + * * If `fileOrDirectory` is a file, it will be treated as a single .jsii file. - * If `fileOrDirectory` is a directory, it will be treated as a jsii npm module. + * No dependencies will be loaded. You almost never want this. * * Not validating makes the difference between loading assemblies with lots * of dependencies (such as app-delivery) in 90ms vs 3500ms. @@ -69,7 +76,7 @@ export class TypeSystem { fileOrDirectory: string, options: { validate?: boolean } = {}, ) { - if ((await stat(fileOrDirectory)).isDirectory()) { + if ((await fs.stat(fileOrDirectory)).isDirectory()) { return this.loadModule(fileOrDirectory, options); } return this.loadFile(fileOrDirectory, { ...options, isRoot: true }); @@ -92,7 +99,9 @@ export class TypeSystem { isRoot = false, ) { const filePath = path.join(moduleDirectory, 'package.json'); - const pkg = JSON.parse((await readFile(filePath)).toString()); + const pkg = JSON.parse( + await fs.readFile(filePath, { encoding: 'utf-8' }), + ); if (!pkg.jsii) { throw new Error(`No "jsii" section in ${filePath}`); } @@ -134,11 +143,11 @@ export class TypeSystem { continue; } - const depDir = require.resolve(`${name}/package.json`, { - paths: [moduleDirectory], - }); // eslint-disable-next-line no-await-in-loop - await _loadModule.call(this, path.dirname(depDir)); + const depDir = await findDependencyDirectory(name, moduleDirectory); + + // eslint-disable-next-line no-await-in-loop + await _loadModule.call(this, depDir); } return root; @@ -300,7 +309,7 @@ export class TypeSystem { * @param validate Whether to validate the assembly or just assume it matches the schema */ private async loadAssembly(file: string, validate = true) { - const spec = JSON.parse((await readFile(file)).toString()); + const spec = JSON.parse(await fs.readFile(file, { encoding: 'utf-8' })); const ass = validate ? jsii.validateAssembly(spec) : (spec as jsii.Assembly); @@ -341,17 +350,3 @@ function flatMap( .map(mapper) .reduce((acc, elt) => acc.concat(elt), new Array()); } - -function stat(p: string) { - // just-in-time require so that this file can be loaded in browsers as well. - // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires - const fs = require('fs'); - return promisify(fs.stat)(p); -} - -function readFile(p: string) { - // just-in-time require so that this file can be loaded in browsers as well. - // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires - const fs = require('fs'); - return promisify(fs.readFile)(p); -} diff --git a/packages/jsii-reflect/lib/util.ts b/packages/jsii-reflect/lib/util.ts index fc0cd60196..285f08c1c5 100644 --- a/packages/jsii-reflect/lib/util.ts +++ b/packages/jsii-reflect/lib/util.ts @@ -1,3 +1,6 @@ +import * as fs from 'fs-extra'; +import * as path from 'path'; + export function indexBy(xs: T[], f: (x: T) => string): { [key: string]: T } { const ret: { [key: string]: T } = {}; for (const x of xs) { @@ -5,3 +8,93 @@ export function indexBy(xs: T[], f: (x: T) => string): { [key: string]: T } { } return ret; } + +/** + * Find the directory that contains a given dependency, identified by its 'package.json', from a starting search directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findDependencyDirectory( + dependencyName: string, + searchStart: string, +) { + // Explicitly do not use 'require("dep/package.json")' because that will fail if the + // package does not export that particular file. + const entryPoint = require.resolve(dependencyName, { + paths: [searchStart], + }); + + // Search up from the given directory, looking for a package.json that matches + // the dependency name (so we don't accidentally find stray 'package.jsons'). + const depPkgJsonPath = await findPackageJsonUp( + dependencyName, + path.dirname(entryPoint), + ); + + if (!depPkgJsonPath) { + throw new Error( + `Could not find dependency '${dependencyName}' from '${searchStart}'`, + ); + } + + return depPkgJsonPath; +} + +/** + * Whether the given dependency is a built-in + * + * Some dependencies that occur in `package.json` are also built-ins in modern Node + * versions (most egregious example: 'punycode'). Detect those and filter them out. + */ +export function isBuiltinModule(depName: string) { + // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires + const { builtinModules } = require('module'); + return (builtinModules ?? []).includes(depName); +} + +/** + * Find the package.json for a given package upwards from the given directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findPackageJsonUp( + packageName: string, + directory: string, +) { + return findUp(directory, async (dir) => { + const pjFile = path.join(dir, 'package.json'); + return ( + (await fs.pathExists(pjFile)) && + (await fs.readJson(pjFile)).name === packageName + ); + }); +} + +/** + * Find a directory up the tree from a starting directory matching a condition + * + * Will return `undefined` if no directory matches + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findUp( + directory: string, + pred: (dir: string) => Promise, +): Promise { + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + if (await pred(directory)) { + return directory; + } + + const parent = path.dirname(directory); + if (parent === directory) { + return undefined; + } + directory = parent; + } +} diff --git a/packages/jsii-reflect/package.json b/packages/jsii-reflect/package.json index 577c9f8d51..e155ebebd5 100644 --- a/packages/jsii-reflect/package.json +++ b/packages/jsii-reflect/package.json @@ -46,12 +46,12 @@ "@types/fs-extra": "^9.0.13", "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii": "^0.0.0", "jsii-build-tools": "^0.0.0", "jsii-calc": "^3.20.120", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "typescript": "~3.9.10" } } diff --git a/packages/jsii-reflect/test/independent.test.ts b/packages/jsii-reflect/test/independent.test.ts index dd0f9d546e..b059ba88b5 100644 --- a/packages/jsii-reflect/test/independent.test.ts +++ b/packages/jsii-reflect/test/independent.test.ts @@ -11,7 +11,11 @@ test('get full github source location for a class or method', async () => { } } `.trim(), - (obj) => (obj.repository.directory = 'some/sub/dir'), + (obj) => { + if (typeof obj.repository === 'object') { + obj.repository.directory = 'some/sub/dir'; + } + }, ); // THEN diff --git a/packages/jsii-rosetta/bin/jsii-rosetta.ts b/packages/jsii-rosetta/bin/jsii-rosetta.ts index 8fbae7a2a2..a3e059f18b 100644 --- a/packages/jsii-rosetta/bin/jsii-rosetta.ts +++ b/packages/jsii-rosetta/bin/jsii-rosetta.ts @@ -66,7 +66,7 @@ function main() { }), ) .command( - 'infuse [ASSEMBLY..]', + 'infuse [ASSEMBLY..]', '(EXPERIMENTAL) mutates one or more assemblies by adding documentation examples to top-level types', (command) => command diff --git a/packages/jsii-rosetta/lib/jsii/jsii-utils.ts b/packages/jsii-rosetta/lib/jsii/jsii-utils.ts index 4bd417273e..ec5e845093 100644 --- a/packages/jsii-rosetta/lib/jsii/jsii-utils.ts +++ b/packages/jsii-rosetta/lib/jsii/jsii-utils.ts @@ -127,15 +127,20 @@ export function lookupJsiiSymbol(typeChecker: ts.TypeChecker, sym: ts.Symbol): J if (ts.isSourceFile(decl)) { // This is a module. - // FIXME: for now assume this is the assembly root. Handle the case where it isn't later. const sourceAssembly = findTypeLookupAssembly(decl.fileName); return fmap( sourceAssembly, (asm) => ({ fqn: - fmap(symbolIdentifier(typeChecker, sym), (symbolId) => sourceAssembly?.symbolIdMap[symbolId]) ?? - sourceAssembly?.assembly.name, + fmap( + symbolIdentifier( + typeChecker, + sym, + fmap(sourceAssembly, (sa) => ({ assembly: sa.assembly })), + ), + (symbolId) => sourceAssembly?.symbolIdMap[symbolId], + ) ?? sourceAssembly?.assembly.name, sourceAssembly: asm, symbolType: 'module', } as JsiiSymbol), @@ -157,10 +162,23 @@ export function lookupJsiiSymbol(typeChecker: ts.TypeChecker, sym: ts.Symbol): J } const fileName = decl.getSourceFile().fileName; - if (hasAnyFlag(declSym.flags, ts.SymbolFlags.Method | ts.SymbolFlags.Property | ts.SymbolFlags.EnumMember)) { - return lookupMemberSymbol(typeChecker, sym, fileName); + const sourceAssembly = findTypeLookupAssembly(fileName); + const symbolId = symbolIdentifier(typeChecker, declSym, { assembly: sourceAssembly?.assembly }); + if (!symbolId) { + return undefined; } - return lookupTypeSymbol(typeChecker, sym, fileName); + + return fmap(/([^#]*)(#.*)?/.exec(symbolId), ([, typeSymbolId, memberFragment]) => { + if (memberFragment) { + return fmap(sourceAssembly?.symbolIdMap[typeSymbolId], (fqn) => ({ + fqn: `${fqn}${memberFragment}`, + sourceAssembly, + symbolType: 'member', + })); + } + + return fmap(sourceAssembly?.symbolIdMap[typeSymbolId], (fqn) => ({ fqn, sourceAssembly, symbolType: 'type' })); + }); } function isDeclaration(x: ts.Node): x is ts.Declaration { @@ -179,42 +197,6 @@ function isDeclaration(x: ts.Node): x is ts.Declaration { ); } -/** - * Look up the jsii fqn for a given type symbol - */ -function lookupTypeSymbol( - typeChecker: ts.TypeChecker, - typeSymbol: ts.Symbol, - fileName: string, -): JsiiSymbol | undefined { - const symbolId = symbolIdentifier(typeChecker, typeSymbol); - if (!symbolId) { - return undefined; - } - - const sourceAssembly = findTypeLookupAssembly(fileName); - return fmap(sourceAssembly?.symbolIdMap[symbolId], (fqn) => ({ fqn, sourceAssembly, symbolType: 'type' })); -} - -function lookupMemberSymbol( - typeChecker: ts.TypeChecker, - memberSymbol: ts.Symbol, - fileName: string, -): JsiiSymbol | undefined { - const declParent = memberSymbol.declarations?.[0]?.parent; - if (!declParent || !isDeclaration(declParent)) { - return undefined; - } - - const declParentSym = getSymbolFromDeclaration(declParent, typeChecker); - if (!declParentSym) { - return undefined; - } - - const result = lookupTypeSymbol(typeChecker, declParentSym, fileName); - return fmap(result, (result) => ({ ...result, fqn: `${result.fqn}#${memberSymbol.name}`, symbolType: 'member' })); -} - /** * If the given type is an enum literal, resolve to the enum type */ diff --git a/packages/jsii-rosetta/lib/languages/record-references.ts b/packages/jsii-rosetta/lib/languages/record-references.ts index 3b4b049a10..d53750845c 100644 --- a/packages/jsii-rosetta/lib/languages/record-references.ts +++ b/packages/jsii-rosetta/lib/languages/record-references.ts @@ -45,7 +45,7 @@ export class RecordReferencesVisitor extends DefaultVisitor(xs: Array): Record< * only for the `Maybe` Functor). */ export function fmap(value: NonNullable, fn: (x: NonNullable) => B): B; -export function fmap(value: undefined, fn: (x: NonNullable) => B): undefined; -export function fmap(value: A | undefined, fn: (x: A) => B): B | undefined; +export function fmap(value: undefined | null, fn: (x: NonNullable) => B): undefined; +export function fmap(value: A | undefined | null, fn: (x: A) => B): B | undefined; export function fmap(value: A, fn: (x: A) => B): B | undefined { - if (value === undefined) { + if (value == null) { return undefined; } return fn(value); diff --git a/packages/jsii-rosetta/package.json b/packages/jsii-rosetta/package.json index 85bdc5862f..0749a0a0ed 100644 --- a/packages/jsii-rosetta/package.json +++ b/packages/jsii-rosetta/package.json @@ -22,12 +22,12 @@ "@types/mock-fs": "^4.13.1", "@types/node": "^12.20.37", "@types/workerpool": "^6.1.0", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii-build-tools": "0.0.0", "memory-streams": "^0.1.3", "mock-fs": "^5.1.2", - "prettier": "^2.4.1" + "prettier": "^2.5.1" }, "dependencies": { "@jsii/check-node": "0.0.0", diff --git a/packages/jsii-rosetta/test/commands/extract.test.ts b/packages/jsii-rosetta/test/commands/extract.test.ts index 6735ef1c8f..7eb0f2aebf 100644 --- a/packages/jsii-rosetta/test/commands/extract.test.ts +++ b/packages/jsii-rosetta/test/commands/extract.test.ts @@ -294,6 +294,45 @@ test('do not ignore example strings', async () => { } }); +describe('can find fqns via symbolId when ', () => { + test('there is an outDir', async () => { + const outDir = 'jsii-outDir'; + const otherAssembly = await createAssemblyWithDirectories(undefined, outDir); + try { + const outputFile = path.join(otherAssembly.moduleDirectory, 'test.tabl.json'); + await extract.extractSnippets([otherAssembly.moduleDirectory], { + cacheToFile: outputFile, + ...defaultExtractOptions, + }); + + const tablet = await LanguageTablet.fromFile(outputFile); + const tr = tablet.tryGetSnippet(tablet.snippetKeys[0]); + expect(tr?.fqnsReferenced()).toEqual(['my_assembly.ClassA']); + } finally { + await otherAssembly.cleanup(); + } + }); + + test('there is an outDir and rootDir', async () => { + const outDir = 'jsii-outDir'; + const rootDir = '.'; + const otherAssembly = await createAssemblyWithDirectories(rootDir, outDir); + try { + const outputFile = path.join(otherAssembly.moduleDirectory, 'test.tabl.json'); + await extract.extractSnippets([otherAssembly.moduleDirectory], { + cacheToFile: outputFile, + ...defaultExtractOptions, + }); + + const tablet = await LanguageTablet.fromFile(outputFile); + const tr = tablet.tryGetSnippet(tablet.snippetKeys[0]); + expect(tr?.fqnsReferenced()).toEqual(['my_assembly.ClassA']); + } finally { + await otherAssembly.cleanup(); + } + }); +}); + test('extract and infuse in one command', async () => { const cacheToFile = path.join(assembly.moduleDirectory, 'test.tabl.json'); await extract.extractAndInfuse([assembly.moduleDirectory], { @@ -331,6 +370,39 @@ class MockTranslator extends RosettaTranslator { } } +async function createAssemblyWithDirectories(rootDir?: string, outDir?: string) { + return TestJsiiModule.fromSource( + { + 'index.ts': ` + export class ClassA { + /** + * Some method + * + * @example + * import * as ass from 'my_assembly'; + * new ass.ClassA.someMethod(); + */ + public someMethod() { + } + } + `, + 'README.md': '', + }, + { + name: 'my_assembly', + main: `${outDir}/index.js`, + types: `${outDir}/index.d.ts`, + jsii: { + ...DUMMY_JSII_CONFIG, + tsc: { + outDir, + rootDir, + }, + }, + }, + ); +} + function bogusTranslatedSnippet() { return TranslatedSnippet.fromTypeScript( typeScriptSnippetFromVisibleSource('console.log("hello");', testSnippetLocation('x.ts'), true), diff --git a/packages/jsii-rosetta/test/testutil.ts b/packages/jsii-rosetta/test/testutil.ts index 73ecf6795c..953ae3c5fa 100644 --- a/packages/jsii-rosetta/test/testutil.ts +++ b/packages/jsii-rosetta/test/testutil.ts @@ -1,6 +1,6 @@ import * as spec from '@jsii/spec'; import * as fs from 'fs-extra'; -import { PackageInfo, compileJsiiForTest } from 'jsii'; +import { PackageInfo, compileJsiiForTest, TestWorkspace } from 'jsii'; import * as os from 'os'; import * as path from 'path'; @@ -21,44 +21,25 @@ export type MultipleSources = { [key: string]: string; 'index.ts': string }; export class TestJsiiModule { public static async fromSource( source: string | MultipleSources, - packageInfo: Partial & { name: string }, + packageInfo: Partial & { name: string; main?: string; types?: string }, ) { - const { assembly, files } = await compileJsiiForTest(source, (pi) => { + const asm = await compileJsiiForTest(source, (pi) => { Object.assign(pi, packageInfo); }); - // The following is silly, however: the helper has compiled the given source to - // an assembly, and output files, and then removed their traces from disk. - // But for the purposes of Rosetta, we need those files back on disk. So write - // them back out again >_< - // - // In fact we will drop them in 'node_modules/' so they can be imported - // as if they were installed. - const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'jsii-rosetta')); - const modDir = path.join(tmpDir, 'node_modules', packageInfo.name); - await fs.ensureDir(modDir); + const ws = await TestWorkspace.create(); + await ws.addDependency(asm); + return new TestJsiiModule(asm.assembly, ws); + } - await fs.writeJSON(path.join(modDir, '.jsii'), assembly); - await fs.writeJSON(path.join(modDir, 'package.json'), { - name: packageInfo.name, - jsii: packageInfo.jsii, - }); - for (const [fileName, fileContents] of Object.entries(files)) { - // eslint-disable-next-line no-await-in-loop - await fs.ensureDir(path.dirname(path.join(modDir, fileName))); - // eslint-disable-next-line no-await-in-loop - await fs.writeFile(path.join(modDir, fileName), fileContents); - } + public readonly moduleDirectory: string; + public readonly workspaceDirectory: string; - return new TestJsiiModule(assembly, modDir, tmpDir); + private constructor(public readonly assembly: spec.Assembly, private readonly workspace: TestWorkspace) { + this.moduleDirectory = workspace.dependencyDir(assembly.name); + this.workspaceDirectory = workspace.rootDirectory; } - private constructor( - public readonly assembly: spec.Assembly, - public readonly moduleDirectory: string, - public readonly workspaceDirectory: string, - ) {} - /** * Make a snippet translator for the given source w.r.t this compiled assembly */ @@ -104,7 +85,7 @@ export class TestJsiiModule { } public async cleanup() { - await fs.remove(this.moduleDirectory); + await this.workspace.cleanup(); } } diff --git a/packages/jsii/lib/assembler.ts b/packages/jsii/lib/assembler.ts index ad69225cbc..6d4a94c88c 100644 --- a/packages/jsii/lib/assembler.ts +++ b/packages/jsii/lib/assembler.ts @@ -1,4 +1,5 @@ import * as spec from '@jsii/spec'; +import { PackageJson } from '@jsii/spec'; import * as Case from 'case'; import * as colors from 'colors/safe'; import * as crypto from 'crypto'; @@ -46,6 +47,7 @@ export class Assembler implements Emitter { private readonly warningsInjector?: DeprecationWarningsInjector; private readonly mainFile: string; + private readonly tscRootDir?: string; private _diagnostics = new Array(); private _deferred = new Array(); @@ -113,10 +115,10 @@ export class Assembler implements Emitter { // rootDir may be set explicitly or not. If not, inferRootDir replicates // tsc's behavior of using the longest prefix of all built source files. - const tscRootDir = + this.tscRootDir = program.getCompilerOptions().rootDir ?? inferRootDir(program); - if (tscRootDir != null) { - mainFile = path.join(tscRootDir, mainFile); + if (this.tscRootDir != null) { + mainFile = path.join(this.tscRootDir, mainFile); } } @@ -253,7 +255,13 @@ export class Assembler implements Emitter { types: this._types, submodules: noEmptyDict(toSubmoduleDeclarations(this.mySubmodules())), targets: this.projectInfo.targets, - metadata: this.projectInfo.metadata, + metadata: { + ...this.projectInfo.metadata, + + // Downstream consumers need this to map a symbolId in the outDir to a + // symbolId in the rootDir. + tscRootDir: this.tscRootDir, + }, docs, readme, jsiiVersion, @@ -456,31 +464,19 @@ export class Assembler implements Emitter { typeUse: TypeUseKind, isThisType: boolean, ): Promise { - const singleValuedEnum = isSingleValuedEnum(type, this._typeChecker); + const sym = symbolFromType(type, this._typeChecker); - const tsFullName = this._typeChecker.getFullyQualifiedName(type.symbol); - const tsName = singleValuedEnum - ? // If it's a single-valued enum, we need to remove the last qualifier to get back to the enum. - tsFullName.replace(/\.[^.]+$/, '') - : tsFullName; - - let typeDeclaration = singleValuedEnum - ? // If it's a single-valued enum, we need to move to the parent to have the enum declaration - type.symbol.valueDeclaration.parent - : type.symbol.valueDeclaration; - if (!typeDeclaration && type.symbol.declarations.length > 0) { - typeDeclaration = type.symbol.declarations[0]; - } + const typeDeclaration = sym.valueDeclaration ?? sym.declarations?.[0]; // Set to true to prevent further adding of Error diagnostics for known-bad reference let hasError = false; - if (this._isPrivateOrInternal(type.symbol)) { + if (this._isPrivateOrInternal(sym)) { // Check if this type is "this" (explicit or inferred method return type). this._diagnostics.push( JsiiDiagnostic.JSII_3001_EXPOSED_INTERNAL_TYPE.create( typeAnnotationNode, - type.symbol, + sym, isThisType, typeUse, ).addRelatedInformation( @@ -492,13 +488,14 @@ export class Assembler implements Emitter { hasError = true; } + const tsName = this._typeChecker.getFullyQualifiedName(sym); const groups = /^"([^"]+)"\.(.*)$/.exec(tsName); if (!groups) { if (!hasError) { this._diagnostics.push( JsiiDiagnostic.JSII_3001_EXPOSED_INTERNAL_TYPE.create( typeAnnotationNode, - type.symbol, + sym, isThisType, typeUse, ).addRelatedInformation( @@ -528,22 +525,48 @@ export class Assembler implements Emitter { return `unknown.${typeName}`; } - const submodule = this._submoduleMap.get(type.symbol); - if (submodule != null) { - const submoduleNs = this._submodules.get(submodule)!.fqnResolutionPrefix; - return `${submoduleNs}.${typeName}`; + // If the symbol comes from the current assembly or an assembly whose + // submodules we've already spidered, look up in the tables we are currently building + if (pkg.name === this.projectInfo.name) { + const submodule = this._submoduleMap.get(sym); + if (submodule != null) { + const submoduleNs = + this._submodules.get(submodule)!.fqnResolutionPrefix; + return `${submoduleNs}.${typeName}`; + } + + return `${this.projectInfo.name}.${typeName}`; } - const fqn = `${pkg.name}.${typeName}`; - if ( - pkg.name !== this.projectInfo.name && - !this._dereference({ fqn }, type.symbol.valueDeclaration) - ) { + // This is the fallback: in case we can't find a symbolId for the given + // type, we're return this value. This is for backwards compatibility with + // modules that haven't been compiled to have symbolId support. Those also + // most likely won't be using submodules so this legacy guess will be correct. + const fallbackFqn = `${pkg.name}.${typeName}`; + + // Otherwise look up the symbol identifier in the dependency assemblies + const dep = this.projectInfo.dependencyClosure.find( + (d) => d.name === pkg.name, + ); + if (!dep) { + this._diagnostics.push( + JsiiDiagnostic.JSII_9000_UNKNOWN_MODULE.createDetached(pkg.name), + ); + return fallbackFqn; + } + const symbolId = symbolIdentifier(this._typeChecker, sym, { + assembly: dep, + }); + const fqn = + (dep && symbolId ? symbolIdIndex(dep)[symbolId] : undefined) ?? + fallbackFqn; + + if (!fqn || !this._dereference({ fqn }, sym.valueDeclaration)) { if (!hasError) { this._diagnostics.push( JsiiDiagnostic.JSII_3002_USE_OF_UNEXPORTED_FOREIGN_TYPE.create( typeAnnotationNode, - fqn, + fqn ?? tsName, typeUse, pkg, ).addRelatedInformation( @@ -554,6 +577,7 @@ export class Assembler implements Emitter { hasError = true; } } + return fqn; } @@ -732,7 +756,9 @@ export class Assembler implements Emitter { const symbolLocation = sym .getDeclarations()?.[0] ?.getSourceFile()?.fileName; - const pkgInfo = symbolLocation && (await findPackageInfo(symbolLocation)); + const pkgInfo = symbolLocation + ? await findPackageInfo(symbolLocation) + : undefined; const assemblyName: string = pkgInfo?.name ?? this.projectInfo.name; const fqn = `${assemblyName}.${sym.name}`; return { @@ -1002,7 +1028,10 @@ export class Assembler implements Emitter { return []; } - jsiiType.symbolId = this.getSymbolId(node); + // If symbolId hasn't been set yet, set it here + if (!jsiiType.symbolId) { + jsiiType.symbolId = this.getSymbolId(node); + } // Let's quickly verify the declaration does not collide with a submodule. Submodules get case-adjusted for each // target language separately, so names cannot collide with case-variations. @@ -1703,10 +1732,15 @@ export class Assembler implements Emitter { } // Forcefully resolving to the EnumDeclaration symbol for single-valued enums - const symbol: ts.Symbol = type.isLiteral() - ? (type.symbol as any).parent - : type.symbol; - if (!symbol) { + let decl: ts.Node | undefined = type.symbol.declarations[0]; + let symbol: ts.Symbol | undefined; + if (ts.isEnumMember(decl)) { + decl = decl?.parent; + } + if (ts.isEnumDeclaration(decl)) { + symbol = getSymbolFromDeclaration(decl, this._typeChecker); + } + if (!decl || !symbol || !ts.isEnumDeclaration(decl)) { throw new Error( `Unable to resolve enum declaration for ${type.symbol.name}!`, ); @@ -1716,14 +1750,13 @@ export class Assembler implements Emitter { return Promise.resolve(undefined); } - this._warnAboutReservedWords(type.symbol); + this._warnAboutReservedWords(symbol); - const decl = symbol.valueDeclaration; const flags = ts.getCombinedModifierFlags(decl); if (flags & ts.ModifierFlags.Const) { this._diagnostics.push( JsiiDiagnostic.JSII_1000_NO_CONST_ENUM.create( - (decl as ts.EnumDeclaration).modifiers?.find( + decl.modifiers?.find( (mod) => mod.kind === ts.SyntaxKind.ConstKeyword, ) ?? decl, ), @@ -1751,8 +1784,12 @@ export class Assembler implements Emitter { namespace: ctx.namespace.length > 0 ? ctx.namespace.join('.') : undefined, docs, + + // Set SymbolId here instead of later, as by default TS will pick single-enum members + // as the target symbol if possible. + symbolId: symbolIdentifier(this._typeChecker, symbol), }, - decl as ts.EnumDeclaration, + decl, ); this.overrideDocComment(type.getSymbol(), jsiiType?.docs); @@ -3300,7 +3337,9 @@ function isSingleValuedEnum( return false; } -async function findPackageInfo(fromDir: string): Promise { +async function findPackageInfo( + fromDir: string, +): Promise { const filePath = path.join(fromDir, 'package.json'); if (await fs.pathExists(filePath)) { return fs.readJson(filePath); @@ -3371,3 +3410,70 @@ type TypeUseKind = | 'parameter type' | 'property type' | 'return type'; + +/** + * Resolve a Type to Symbol, taking into account single-valued enums which have a bug + * + * Bug reference: https://github.com/microsoft/TypeScript/issues/46755 + */ +function symbolFromType(type: ts.Type, typeChecker: ts.TypeChecker): ts.Symbol { + if ((type.flags & ts.TypeFlags.EnumLiteral) === 0) { + return type.symbol; + } + + const decl = type.symbol.declarations?.[0]; + if (!decl) { + return type.symbol; + } + + if (!ts.isEnumMember(decl)) { + return type.symbol; + } + + const parentDecl = decl.parent; + if (!parentDecl || !ts.isEnumDeclaration(parentDecl)) { + return type.symbol; + } + + const name = ts.getNameOfDeclaration(parentDecl); + if (!name) { + return type.symbol; + } + return typeChecker.getSymbolAtLocation(name) ?? type.symbol; +} + +const SYMBOLID_CACHE = new WeakMap>(); + +/** + * Build and return an index of { symbolId -> fqn } + * + * Uses a cache for performance reasons. + */ +function symbolIdIndex(asm: spec.Assembly): Record { + const existing = SYMBOLID_CACHE.get(asm); + if (existing) { + return existing; + } + + const ret = buildIndex(); + SYMBOLID_CACHE.set(asm, ret); + return ret; + + function buildIndex() { + const ret: Record = {}; + for (const [fqn, type] of Object.entries(asm.types ?? {})) { + if (type.symbolId) { + ret[type.symbolId] = fqn; + } + } + return ret; + } +} + +function getSymbolFromDeclaration( + decl: ts.Declaration, + typeChecker: ts.TypeChecker, +): ts.Symbol | undefined { + const name = ts.getNameOfDeclaration(decl); + return name ? typeChecker.getSymbolAtLocation(name) : undefined; +} diff --git a/packages/jsii/lib/compiler.ts b/packages/jsii/lib/compiler.ts index aaae7f1799..55829de2e2 100644 --- a/packages/jsii/lib/compiler.ts +++ b/packages/jsii/lib/compiler.ts @@ -9,6 +9,7 @@ import { Assembler } from './assembler'; import { Emitter } from './emitter'; import { JsiiDiagnostic } from './jsii-diagnostic'; import { ProjectInfo } from './project-info'; +import { WARNINGSCODE_FILE_NAME } from './transforms/deprecation-warnings'; import * as utils from './utils'; const BASE_COMPILER_OPTIONS: ts.CompilerOptions = { @@ -292,6 +293,26 @@ export class Compiler implements Emitter { ); } + // Some extra validation on the config. + // Make sure that { "./.warnings.jsii.js": "./.warnings.jsii.js" } is in the set of + // exports, if they are specified. + if ( + this.options.addDeprecationWarnings && + this.options.projectInfo.exports !== undefined + ) { + const expected = `./${WARNINGSCODE_FILE_NAME}`; + const warningsExport = Object.entries( + this.options.projectInfo.exports, + ).filter(([k, v]) => k === expected && v === expected); + + if (warningsExport.length === 0) { + hasErrors = true; + diagnostics.push( + JsiiDiagnostic.JSII_0007_MISSING_WARNINGS_EXPORT.createDetached(), + ); + } + } + return { emitSkipped: hasErrors, diagnostics: ts.sortAndDeduplicateDiagnostics(diagnostics), @@ -530,25 +551,40 @@ export class Compiler implements Emitter { private async findMonorepoPeerTsconfig( depName: string, ): Promise { - const paths = nodeJsCompatibleSearchPaths( - this.options.projectInfo.projectRoot, - ); - - let dep; - try { - dep = require.resolve(`${depName}/tsconfig.json`, { paths }); - } catch { - // Package does not have a tsconfig.json + // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires + const { builtinModules } = require('module'); + if ((builtinModules ?? []).includes(depName)) { + // Can happen for modules like 'punycode' which are declared as dependency for polyfill purposes return undefined; } - // Resolve symlinks, to check if this is a monorepo peer - const dependencyRealPath = await fs.realpath(dep); - if (dependencyRealPath.split(path.sep).includes('node_modules')) { - return undefined; - } + try { + const depDir = await utils.findDependencyDirectory( + depName, + this.options.projectInfo.projectRoot, + ); + + const dep = path.join(depDir, 'tsconfig.json'); + if (!(await fs.pathExists(dep))) { + return undefined; + } + + // Resolve symlinks, to check if this is a monorepo peer + const dependencyRealPath = await fs.realpath(dep); + if (dependencyRealPath.split(path.sep).includes('node_modules')) { + return undefined; + } - return dependencyRealPath; + return dependencyRealPath; + } catch (e) { + // @types modules cannot be required, for example + if ( + ['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'].includes(e.code) + ) { + return undefined; + } + throw e; + } } private diagsHaveAbortableErrors(diags: readonly ts.Diagnostic[]) { @@ -607,22 +643,6 @@ function _pathOfLibraries( return BASE_COMPILER_OPTIONS.lib.map((name) => path.join(lib, name)); } -/** - * Return all possible 'node_modules' directories from a given starting directory. - */ -function nodeJsCompatibleSearchPaths(dir: string): string[] { - const ret = new Array(); - - let lastDir; - do { - ret.push(path.join(dir, 'node_modules')); - lastDir = dir; - dir = path.dirname(dir); - } while (dir !== lastDir); // path.dirname('/') === '/', also works on Windows - - return ret; -} - function parseConfigHostFromCompilerHost( host: ts.CompilerHost, ): ts.ParseConfigHost { diff --git a/packages/jsii/lib/helpers.ts b/packages/jsii/lib/helpers.ts index 03c19ae0ff..37e09040b4 100644 --- a/packages/jsii/lib/helpers.ts +++ b/packages/jsii/lib/helpers.ts @@ -7,6 +7,7 @@ */ import * as spec from '@jsii/spec'; +import { PackageJson } from '@jsii/spec'; import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; @@ -31,12 +32,14 @@ export type MultipleSourceFiles = { * * @param source can either be a single `string` (the content of `index.ts`), or * a map of fileName to content, which *must* include `index.ts`. + * @param options accepts a callback for historical reasons but really expects to + * take an options object. */ export async function sourceToAssemblyHelper( source: string | MultipleSourceFiles, - cb?: (obj: PackageInfo) => void, + options?: TestCompilationOptions | ((obj: PackageJson) => void), ): Promise { - return (await compileJsiiForTest(source, cb)).assembly; + return (await compileJsiiForTest(source, options)).assembly; } export interface HelperCompilationResult { @@ -48,6 +51,11 @@ export interface HelperCompilationResult { * Generated .js/.d.ts file(s) */ readonly files: Record; + + /** + * The packageInfo used + */ + readonly packageJson: PackageJson; } /** @@ -57,26 +65,43 @@ export interface HelperCompilationResult { * * @param source can either be a single `string` (the content of `index.ts`), or * a map of fileName to content, which *must* include `index.ts`. + * @param options accepts a callback for historical reasons but really expects to + * take an options object. */ export async function compileJsiiForTest( source: string | { 'index.ts': string; [name: string]: string }, - cb?: (obj: PackageInfo) => void, + options?: TestCompilationOptions | ((obj: PackageJson) => void), compilerOptions?: Omit, ): Promise { if (typeof source === 'string') { source = { 'index.ts': source }; } + const inSomeLocation = + isOptionsObject(options) && options.compilationDirectory + ? inOtherDir(options.compilationDirectory) + : inTempDir; + // Easiest way to get the source into the compiler is to write it to disk somewhere. // I guess we could make an in-memory compiler host but that seems like work... - return inTempDir(async () => { + return inSomeLocation(async () => { await Promise.all( Object.entries(source).map(async ([fileName, content]) => { await fs.mkdirp(path.dirname(fileName)); return fs.writeFile(fileName, content, { encoding: 'utf-8' }); }), ); - const projectInfo = await makeProjectInfo('index.ts', cb); + const { projectInfo, packageJson } = await makeProjectInfo( + 'index.ts', + typeof options === 'function' + ? options + : (pi) => { + Object.assign( + pi, + options?.packageJson ?? options?.projectInfo ?? {}, + ); + }, + ); const compiler = new Compiler({ projectInfo, ...compilerOptions, @@ -97,8 +122,12 @@ export async function compileJsiiForTest( const files: Record = {}; for (const filename of Object.keys(source)) { - const jsFile = filename.replace(/\.ts$/, '.js'); - const dtsFile = filename.replace(/\.ts$/, '.d.ts'); + let jsFile = filename.replace(/\.ts$/, '.js'); + let dtsFile = filename.replace(/\.ts$/, '.d.ts'); + if (projectInfo.tsc?.outDir && filename !== 'README.md') { + jsFile = path.join(projectInfo.tsc.outDir, jsFile); + dtsFile = path.join(projectInfo.tsc.outDir, dtsFile); + } // eslint-disable-next-line no-await-in-loop files[jsFile] = await fs.readFile(jsFile, { encoding: 'utf-8' }); @@ -114,7 +143,7 @@ export async function compileJsiiForTest( } } - return { assembly, files }; + return { assembly, files, packageJson } as HelperCompilationResult; }); } @@ -128,6 +157,19 @@ async function inTempDir(block: () => Promise): Promise { return ret; } +function inOtherDir(dir: string) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint + return async (block: () => Promise): Promise => { + const origDir = process.cwd(); + process.chdir(dir); + try { + return await block(); + } finally { + process.chdir(origDir); + } + }; +} + /** * Obtain project info so we can call the compiler * @@ -139,23 +181,24 @@ async function inTempDir(block: () => Promise): Promise { */ async function makeProjectInfo( types: string, - cb?: (obj: PackageInfo) => Promise | void, -): Promise { - const packageInfo: PackageInfo = { + cb?: (obj: PackageJson) => Promise | void, +): Promise<{ projectInfo: ProjectInfo; packageJson: PackageJson }> { + const packageJson: PackageJson = { types, main: types.replace(/(?:\.d)?\.ts(x?)/, '.js$1'), name: 'testpkg', // That's what package.json would tell if we look up... version: '0.0.1', license: 'Apache-2.0', - author: { name: 'John Doe', roles: ['author'] }, + author: { name: 'John Doe' }, repository: { type: 'git', url: 'https://github.com/aws/jsii.git' }, jsii: {}, }; + if (cb) { - await cb(packageInfo); + await cb(packageJson); } - await fs.writeJson('package.json', packageInfo, { + await fs.writeJson('package.json', packageJson, { encoding: 'utf-8', replacer: (_: string, v: any) => v, spaces: 2, @@ -164,27 +207,117 @@ async function makeProjectInfo( const { projectInfo } = await loadProjectInfo( path.resolve(process.cwd(), '.'), ); - return projectInfo; + return { projectInfo, packageJson }; } +export interface TestCompilationOptions { + /** + * The directory in which we write and compile the files + */ + readonly compilationDirectory?: string; -export type PackageInfo = { - name: string; - version: string; - license: string; - types: string; - author: { - name: string; - roles: string[]; - [key: string]: any; - }; - repository: { - type?: string; - url: string; - directory?: string; - [key: string]: any; - }; - jsii: { - [key: string]: any; - }; - [key: string]: any; -}; + /** + * Parts of projectInfo to override (package name etc) + */ + readonly projectInfo?: Partial; + + /** + * Parts of projectInfo to override (package name etc) + */ + readonly packageJson?: Partial; +} + +function isOptionsObject( + x: TestCompilationOptions | ((obj: PackageJson) => void) | undefined, +): x is TestCompilationOptions { + return x ? typeof x === 'object' : false; +} + +/** + * An NPM-ready workspace where we can install test-compile dependencies and compile new assemblies + */ +export class TestWorkspace { + /** + * Create a new workspace. + * + * Creates a temporary directory, don't forget to call cleanUp + */ + public static async create(): Promise { + const tmpDir = await fs.mkdtemp( + path.join(os.tmpdir(), 'jsii-testworkspace'), + ); + await fs.ensureDir(tmpDir); + return new TestWorkspace(tmpDir); + } + + /** + * Execute a block with a temporary workspace + */ + public static async withWorkspace( + block: (ws: TestWorkspace) => A | Promise, + ): Promise { + const ws = await TestWorkspace.create(); + try { + return await block(ws); + } finally { + await ws.cleanup(); + } + } + + private readonly installed = new Set(); + + private constructor(public readonly rootDirectory: string) {} + + /** + * Add a test-compiled jsii assembly as a dependency + */ + public async addDependency(dependencyAssembly: HelperCompilationResult) { + if (this.installed.has(dependencyAssembly.assembly.name)) { + throw new Error( + `A dependency with name '${dependencyAssembly.assembly.name}' was already installed. Give one a different name.`, + ); + } + this.installed.add(dependencyAssembly.assembly.name); + + // The following is silly, however: the helper has compiled the given source to + // an assembly, and output files, and then removed their traces from disk. + // We need those files back on disk, so write them back out again. + // + // We will drop them in 'node_modules/' so they can be imported + // as if they were installed. + const modDir = path.join( + this.rootDirectory, + 'node_modules', + dependencyAssembly.assembly.name, + ); + await fs.ensureDir(modDir); + + await fs.writeJSON(path.join(modDir, '.jsii'), dependencyAssembly.assembly); + await fs.writeJSON( + path.join(modDir, 'package.json'), + dependencyAssembly.packageJson, + ); + + for (const [fileName, fileContents] of Object.entries( + dependencyAssembly.files, + )) { + // eslint-disable-next-line no-await-in-loop + await fs.ensureDir(path.dirname(path.join(modDir, fileName))); + // eslint-disable-next-line no-await-in-loop + await fs.writeFile(path.join(modDir, fileName), fileContents); + } + } + + public dependencyDir(name: string) { + if (!this.installed.has(name)) { + throw new Error(`No dependency with name '${name}' has been installed`); + } + return path.join(this.rootDirectory, 'node_modules', name); + } + + public async cleanup() { + await fs.remove(this.rootDirectory); + } +} + +// Alias for backwards compatibility +export type PackageInfo = PackageJson; diff --git a/packages/jsii/lib/jsii-diagnostic.ts b/packages/jsii/lib/jsii-diagnostic.ts index 4e04d9f5ee..5207ec30c5 100644 --- a/packages/jsii/lib/jsii-diagnostic.ts +++ b/packages/jsii/lib/jsii-diagnostic.ts @@ -3,6 +3,7 @@ import { camel, constant as allCaps, pascal } from 'case'; import * as ts from 'typescript'; import { TypeSystemHints } from './docs'; +import { WARNINGSCODE_FILE_NAME } from './transforms/deprecation-warnings'; import { JSII_DIAGNOSTICS_CODE, _formatDiagnostic } from './utils'; /** @@ -254,6 +255,15 @@ export class JsiiDiagnostic implements ts.Diagnostic { name: 'metadata/missing-dev-dependency', }); + public static readonly JSII_0007_MISSING_WARNINGS_EXPORT = Code.error({ + code: 7, + formatter: () => + 'If you are compiling with --add-deprecation-warnings and your package.json ' + + `declares subpath exports, you must include { "./${WARNINGSCODE_FILE_NAME}": "./${WARNINGSCODE_FILE_NAME}" } ` + + 'in the set of exports.', + name: 'metadata/missing-warnings-export', + }); + ////////////////////////////////////////////////////////////////////////////// // 1000 => 1999 -- TYPESCRIPT LANGUAGE RESTRICTIONS @@ -306,7 +316,7 @@ export class JsiiDiagnostic implements ts.Diagnostic { public static readonly JSII_3002_USE_OF_UNEXPORTED_FOREIGN_TYPE = Code.error({ code: 3002, - formatter: (fqn: string, typeUse: string, pkg: spec.Assembly) => + formatter: (fqn: string, typeUse: string, pkg: { readonly name: string }) => `Type "${fqn}" cannot be used as a ${typeUse} because it is not exported from ${pkg.name}`, name: 'type-model/unexported-foreign-type', }); diff --git a/packages/jsii/lib/project-info.ts b/packages/jsii/lib/project-info.ts index 9a3af0d61a..01f4f67858 100644 --- a/packages/jsii/lib/project-info.ts +++ b/packages/jsii/lib/project-info.ts @@ -7,7 +7,7 @@ import { intersect } from 'semver-intersect'; import * as ts from 'typescript'; import { JsiiDiagnostic } from './jsii-diagnostic'; -import { parsePerson, parseRepository } from './utils'; +import { parsePerson, parseRepository, findDependencyDirectory } from './utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports const spdx: Set = require('spdx-license-list/simple'); @@ -55,6 +55,9 @@ export interface ProjectInfo { readonly projectReferences?: boolean; readonly tsc?: TSCompilerOptions; readonly bin?: { readonly [name: string]: string }; + readonly exports?: { + readonly [name: string]: string | { readonly [name: string]: string }; + }; } export interface ProjectInfoResult { @@ -67,7 +70,7 @@ export async function loadProjectInfo( ): Promise { const packageJsonPath = path.join(projectRoot, 'package.json'); // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-require-imports - const pkg = require(packageJsonPath); + const pkg = await fs.readJson(packageJsonPath); const diagnostics: ts.Diagnostic[] = []; @@ -213,6 +216,7 @@ export async function loadProjectInfo( rootDir: pkg.jsii?.tsc?.rootDir, }, bin: pkg.bin, + exports: pkg.exports, diagnostics: _loadDiagnostics(pkg.jsii?.diagnostics), }; return { projectInfo, diagnostics }; @@ -256,7 +260,8 @@ async function _loadDependencies( `Invalid semver expression for ${name}: ${versionString}`, ); } - const pkg = _tryResolveAssembly(name, localPackage, searchPath); + // eslint-disable-next-line no-await-in-loop + const pkg = await _tryResolveAssembly(name, localPackage, searchPath); LOG.debug(`Resolved dependency ${name} to ${pkg}`); // eslint-disable-next-line no-await-in-loop const assm = await loadAndValidateAssembly(pkg, assemblyCache); @@ -346,11 +351,11 @@ function _toRepository(value: any): { }; } -function _tryResolveAssembly( +async function _tryResolveAssembly( mod: string, localPackage: string | undefined, searchPath: string, -): string { +): Promise { if (localPackage) { const result = path.join(localPackage, '.jsii'); if (!fs.existsSync(result)) { @@ -359,11 +364,11 @@ function _tryResolveAssembly( return result; } try { - const paths = [searchPath, path.join(searchPath, 'node_modules')]; - return require.resolve(path.join(mod, '.jsii'), { paths }); - } catch { + const dependencyDir = await findDependencyDirectory(mod, searchPath); + return path.join(dependencyDir, '.jsii'); + } catch (e) { throw new Error( - `Unable to locate jsii assembly for "${mod}". If this module is not jsii-enabled, it must also be declared under bundledDependencies.`, + `Unable to locate jsii assembly for "${mod}". If this module is not jsii-enabled, it must also be declared under bundledDependencies: ${e}`, ); } } @@ -432,7 +437,9 @@ function _resolveVersion( return { // Rendering as a caret version to maintain uniformity against the "standard". // eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires - version: `^${require(path.join(localPackage, 'package.json')).version}`, + version: `^${ + fs.readJsonSync(path.join(localPackage, 'package.json')).version + }`, localPackage, }; } diff --git a/packages/jsii/lib/symbol-id.ts b/packages/jsii/lib/symbol-id.ts index 2c6b189e49..1d49efe95a 100644 --- a/packages/jsii/lib/symbol-id.ts +++ b/packages/jsii/lib/symbol-id.ts @@ -1,84 +1,120 @@ -import * as fs from 'fs'; +import { Assembly } from '@jsii/spec'; +import * as fs from 'fs-extra'; import * as path from 'path'; import * as ts from 'typescript'; +import { findUp } from './utils'; + +/** + * Additional options that may be provided to the symbolIdentifier. + */ +interface SymbolIdOptions { + /** + * The assembly that the symbol is found in. + * This is used to provide the correct root directory + * as specified in the assembly metadata. In turn, + * the root directory is used to ensure that the + * symbolId comes from source code and not compiled code. + */ + readonly assembly?: Assembly; +} + +/** + * Return a symbol identifier for the given symbol + * + * The symbol identifier identifies a TypeScript symbol in a source file inside + * a package. We can use this to map between jsii entries in the manifest, and + * entities in the TypeScript source code. + * + * Going via symbol id is the only way to identify symbols in submodules. Otherwise, + * all the TypeScript compiler sees is: + * + * ``` + * /my/package/lib/source/directory/dist.js MyClass + * ``` + * + * And there's no way to figure out what submodule name + * `lib/source/directory/dist` is exported as. + * + * The format of a symbol id is: + * + * ``` + * relative/source/file:Name.space.Class[#member] + * ``` + * + * We used to build this identifier ourselves. Turns out there was a built-in + * way to get pretty much the same, by calling `typeChecker.getFullyQualifiedName()`. + * Whoops ^_^ (this historical accident is why the format is similar to but + * different from what the TS checker returns). + */ export function symbolIdentifier( typeChecker: ts.TypeChecker, sym: ts.Symbol, + options: SymbolIdOptions = {}, ): string | undefined { // If this symbol happens to be an alias, resolve it first while ((sym.flags & ts.SymbolFlags.Alias) !== 0) { sym = typeChecker.getAliasedSymbol(sym); } - const inFileNameParts: string[] = []; - - let decl: ts.Node | undefined = sym.declarations?.[0]; - while (decl && !ts.isSourceFile(decl)) { - if ( - ts.isClassDeclaration(decl) || - ts.isNamespaceExportDeclaration(decl) || - ts.isNamespaceExport(decl) || - ts.isModuleDeclaration(decl) || - ts.isEnumDeclaration(decl) || - ts.isEnumMember(decl) || - ts.isInterfaceDeclaration(decl) || - ts.isMethodDeclaration(decl) || - ts.isMethodSignature(decl) || - ts.isPropertyDeclaration(decl) || - ts.isPropertySignature(decl) - ) { - const name = ts.getNameOfDeclaration(decl); - const declSym = name ? typeChecker.getSymbolAtLocation(name) : undefined; - if (declSym) { - inFileNameParts.unshift(declSym.name); - } - } - decl = decl.parent; - } - if (!decl) { + const isMember = + (sym.flags & + (ts.SymbolFlags.Method | + ts.SymbolFlags.Property | + ts.SymbolFlags.EnumMember)) !== + 0; + + const tsName = typeChecker.getFullyQualifiedName(sym); + + // TypeScript fqn looks like "/path/to/file"[.name.in.file] + const groups = /^"([^"]+)"(?:\.(.*))?$/.exec(tsName); + if (!groups) { return undefined; } - const namespace = assemblyRelativeSourceFile(decl.getSourceFile().fileName); - if (!namespace) { + const [, fileName, inFileName] = groups; // inFileName may be absent + + const relFile = assemblyRelativeSourceFile(fileName, options?.assembly); + if (!relFile) { return undefined; } - return `${namespace}:${inFileNameParts.join('.')}`; + // If this is a member symbol, replace the final '.' with a '#' + const typeSymbol = isMember + ? (inFileName ?? '').replace(/\.([^.]+)$/, '#$1') + : inFileName ?? ''; + + return `${relFile}:${typeSymbol}`; } -function assemblyRelativeSourceFile(sourceFileName: string) { - const packageJsonLocation = findPackageJsonLocation( - path.dirname(sourceFileName), +function assemblyRelativeSourceFile(sourceFileName: string, asm?: Assembly) { + const packageJsonDir = findUp(path.dirname(sourceFileName), (dir) => + fs.pathExistsSync(path.join(dir, 'package.json')), ); - if (!packageJsonLocation) { + if (!packageJsonDir) { return undefined; } - const packageJson = JSON.parse( - fs.readFileSync(packageJsonLocation).toString(), + const packageJson = fs.readJsonSync( + path.join(packageJsonDir, 'package.json'), ); - const sourcePath = removePrefix( + let sourcePath = removePrefix( packageJson.jsii?.outdir ?? '', - path.relative(path.dirname(packageJsonLocation), sourceFileName), + path.relative(packageJsonDir, sourceFileName), ); - return sourcePath.replace(/(\.d)?\.ts$/, ''); - - function findPackageJsonLocation(currentPath: string): string | undefined { - const candidate = path.join(currentPath, 'package.json'); - if (fs.existsSync(candidate)) { - return candidate; - } - const parentPath = path.resolve(currentPath, '..'); - return parentPath !== currentPath - ? findPackageJsonLocation(parentPath) - : undefined; + // Modify the namespace if we send in the assembly. + if (asm) { + const tscRootDir = + packageJson.jsii?.tsc?.rootDir ?? asm.metadata?.tscRootDir; + const tscOutDir = packageJson.jsii?.tsc?.outDir; + sourcePath = normalizePath(sourcePath, tscRootDir, tscOutDir); } + return sourcePath.replace(/(\.d)?\.ts$/, ''); + function removePrefix(prefix: string, filePath: string) { const prefixParts = prefix.split(/[/\\]/g); const pathParts = filePath.split(/[/\\]/g); @@ -89,3 +125,51 @@ function assemblyRelativeSourceFile(sourceFileName: string) { return pathParts.slice(i).join('/'); } } + +/** + * Ensures that the sourcePath is pointing to the source code + * and not compiled code. This can happen if the root directory + * and/or out directory is set for the project. We check to see + * if the out directory is present in the sourcePath, and if so, + * we replace it with the root directory. + */ +export function normalizePath( + sourcePath: string, + rootDir?: string, + outDir?: string, +): string { + if (rootDir === undefined || outDir === undefined) { + return sourcePath; + } + + outDir = removeEndSlash(path.normalize(outDir)); + const outDirLength = outDir.split(path.sep).length; + rootDir = removeEndSlash(path.normalize(rootDir)); + + let paths = path.normalize(sourcePath).split(path.sep); + const pathDir = paths.slice(0, outDirLength).join(path.sep); + + if (outDir === pathDir || outDir === '.') { + // outDir === '.' is a special case where we do not want + // to remove any paths from the list. + if (outDir !== '.') { + paths = paths.slice(outDirLength); + } + sourcePath = + rootDir === '.' ? paths.join('/') : `${rootDir}/${paths.join('/')}`; + } + return unixize(sourcePath); + + function removeEndSlash(filePath: string) { + return filePath.endsWith(path.sep) + ? filePath.slice(0, filePath.length - 1) + : filePath; + } +} + +/** + * Turn backslashes in a path into forward slashes + */ +function unixize(p: string) { + return p.replace(/\\/g, '/'); +} diff --git a/packages/jsii/lib/transforms/deprecation-warnings.ts b/packages/jsii/lib/transforms/deprecation-warnings.ts index a2e56bd15b..6b19e65391 100644 --- a/packages/jsii/lib/transforms/deprecation-warnings.ts +++ b/packages/jsii/lib/transforms/deprecation-warnings.ts @@ -2,13 +2,12 @@ import * as spec from '@jsii/spec'; import { Assembly } from '@jsii/spec'; import * as fs from 'fs'; import * as path from 'path'; -import { EmitHint, Statement } from 'typescript'; -import * as ts from 'typescript/lib/tsserverlibrary'; +import * as ts from 'typescript'; import { ProjectInfo } from '../project-info'; import { symbolIdentifier } from '../symbol-id'; -const FILE_NAME = '.warnings.jsii.js'; +export const WARNINGSCODE_FILE_NAME = '.warnings.jsii.js'; const WARNING_FUNCTION_NAME = 'print'; const PARAMETER_NAME = 'p'; const NAMESPACE = 'jsiiDeprecationWarnings'; @@ -28,7 +27,7 @@ export class DeprecationWarningsInjector { const types = assembly.types ?? {}; for (const type of Object.values(types)) { - const statements: Statement[] = []; + const statements: ts.Statement[] = []; let isEmpty = true; // This will add the parameter to the set of visited objects, to prevent infinite recursion @@ -157,7 +156,7 @@ function processInterfaceType( types: { [p: string]: spec.Type }, assembly: Assembly, projectInfo: ProjectInfo, - statementsByProp: Map = new Map(), + statementsByProp: Map = new Map(), excludedProps: Set = new Set(), ) { for (const prop of Object.values(type.properties ?? {})) { @@ -252,7 +251,7 @@ function fnName(fqn: string): string { return fqn.replace(/[^\w\d]/g, '_'); } -function createFunctionBlock(statements: Statement[]): ts.Block { +function createFunctionBlock(statements: ts.Statement[]): ts.Block { if (statements.length > 0) { const validation = ts.createIf( ts.createIdentifier(`${PARAMETER_NAME} == null`), @@ -268,7 +267,7 @@ function createWarningFunctionCall( message = '', condition?: ts.Identifier, includeNamespace = false, -): Statement { +): ts.Statement { const functionName = includeNamespace ? `${NAMESPACE}.${WARNING_FUNCTION_NAME}` : WARNING_FUNCTION_NAME; @@ -291,7 +290,7 @@ function generateWarningsFile( const names = [...functionDeclarations] .map((d) => d.name?.text) .filter(Boolean); - const exports = [WARNING_FUNCTION_NAME, ...names].join(','); + const exportedSymbols = [WARNING_FUNCTION_NAME, ...names].join(','); const functionText = `function ${WARNING_FUNCTION_NAME}(name, deprecationMessage) { const deprecated = process.env.JSII_DEPRECATED; @@ -310,13 +309,13 @@ const ${VISITED_OBJECTS_SET_NAME} = new Set(); class DeprecationError extends Error {} -module.exports = {${exports}} +module.exports = {${exportedSymbols}} module.exports.DeprecationError = DeprecationError; `; const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const resultFile = ts.createSourceFile( - path.join(projectRoot, FILE_NAME), + path.join(projectRoot, WARNINGSCODE_FILE_NAME), functionText, ts.ScriptTarget.Latest, false, @@ -324,12 +323,12 @@ module.exports.DeprecationError = DeprecationError; ); const declarations = functionDeclarations.map((declaration) => - printer.printNode(EmitHint.Unspecified, declaration, resultFile), + printer.printNode(ts.EmitHint.Unspecified, declaration, resultFile), ); const content = declarations.concat(printer.printFile(resultFile)).join('\n'); - fs.writeFileSync(path.join(projectRoot, FILE_NAME), content); + fs.writeFileSync(path.join(projectRoot, WARNINGSCODE_FILE_NAME), content); } class Transformer { @@ -354,8 +353,8 @@ class Transformer { this.projectRoot, ); const importPath = importDir.startsWith('..') - ? unixPath(path.join(importDir, FILE_NAME)) - : `./${FILE_NAME}`; + ? unixPath(path.join(importDir, WARNINGSCODE_FILE_NAME)) + : `./${WARNINGSCODE_FILE_NAME}`; return ts.updateSourceFileNode(result, [ createRequireStatement(NAMESPACE, importPath), @@ -587,7 +586,7 @@ function importedFunctionName( const { type, moduleName } = findType(typeName, assemblies); if (type) { return moduleName !== assembly.name - ? `require("${moduleName}/${FILE_NAME}").${fnName(type.fqn)}` + ? `require("${moduleName}/${WARNINGSCODE_FILE_NAME}").${fnName(type.fqn)}` : fnName(type.fqn); } return undefined; @@ -614,7 +613,7 @@ function findType(typeName: string, assemblies: Assembly[]) { function createTypeHandlerCall( functionName: string, parameter: string, -): Statement { +): ts.Statement { return ts.createIf( ts.createIdentifier(`!${VISITED_OBJECTS_SET_NAME}.has(${parameter})`), ts.createExpressionStatement( diff --git a/packages/jsii/lib/utils.ts b/packages/jsii/lib/utils.ts index f413bdbf27..947ec86237 100644 --- a/packages/jsii/lib/utils.ts +++ b/packages/jsii/lib/utils.ts @@ -1,4 +1,6 @@ +import * as fs from 'fs-extra'; import * as log4js from 'log4js'; +import * as path from 'path'; import * as ts from 'typescript'; import { JsiiDiagnostic } from './jsii-diagnostic'; @@ -163,3 +165,97 @@ export function parseRepository(value: string): { url: string } { throw new Error(`Unknown host service: ${host}`); } } + +/** + * Find the directory that contains a given dependency, identified by its 'package.json', from a starting search directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findDependencyDirectory( + dependencyName: string, + searchStart: string, +) { + // Explicitly do not use 'require("dep/package.json")' because that will fail if the + // package does not export that particular file. + const entryPoint = require.resolve(dependencyName, { + paths: [searchStart], + }); + + // Search up from the given directory, looking for a package.json that matches + // the dependency name (so we don't accidentally find stray 'package.jsons'). + const depPkgJsonPath = await findPackageJsonUp( + dependencyName, + path.dirname(entryPoint), + ); + + if (!depPkgJsonPath) { + throw new Error( + `Could not find dependency '${dependencyName}' from '${searchStart}'`, + ); + } + + return depPkgJsonPath; +} + +/** + * Find the package.json for a given package upwards from the given directory + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export async function findPackageJsonUp( + packageName: string, + directory: string, +) { + return findUp(directory, async (dir) => { + const pjFile = path.join(dir, 'package.json'); + return ( + (await fs.pathExists(pjFile)) && + (await fs.readJson(pjFile)).name === packageName + ); + }); +} + +/** + * Find a directory up the tree from a starting directory matching a condition + * + * Will return `undefined` if no directory matches + * + * (This code is duplicated among jsii/jsii-pacmak/jsii-reflect. Changes should be done in all + * 3 locations, and we should unify these at some point: https://github.com/aws/jsii/issues/3236) + */ +export function findUp( + directory: string, + pred: (dir: string) => Promise, +): Promise; +export function findUp( + directory: string, + pred: (dir: string) => boolean, +): string | undefined; +// eslint-disable-next-line @typescript-eslint/promise-function-async +export function findUp( + directory: string, + pred: ((dir: string) => boolean) | ((dir: string) => Promise), +): Promise | string | undefined { + const result = pred(directory); + if (isPromise(result)) { + return result.then((thisDirectory) => + thisDirectory ? directory : recurse(), + ); + } + + return result ? directory : recurse(); + + function recurse() { + const parent = path.dirname(directory); + if (parent === directory) { + return undefined; + } + return findUp(parent, pred as any); + } +} + +function isPromise(x: A | Promise): x is Promise { + return typeof x === 'object' && (x as any).then; +} diff --git a/packages/jsii/package.json b/packages/jsii/package.json index 65b15433ce..4ee56f67dd 100644 --- a/packages/jsii/package.json +++ b/packages/jsii/package.json @@ -57,11 +57,11 @@ "@types/node": "^12.20.37", "@types/semver": "^7.3.9", "clone": "^2.1.2", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jest-expect-message": "^1.0.2", "jsii-build-tools": "^0.0.0", - "prettier": "^2.4.1", - "ts-jest": "^27.0.7" + "prettier": "^2.5.1", + "ts-jest": "^27.1.1" } } diff --git a/packages/jsii/test/compiler.test.ts b/packages/jsii/test/compiler.test.ts index ae82311d9c..6e56673839 100644 --- a/packages/jsii/test/compiler.test.ts +++ b/packages/jsii/test/compiler.test.ts @@ -1,4 +1,11 @@ -import { mkdtemp, remove, writeFile, readFile, readJson } from 'fs-extra'; +import { + ensureDir, + mkdtemp, + remove, + writeFile, + readFile, + readJson, +} from 'fs-extra'; import { tmpdir } from 'os'; import { join } from 'path'; @@ -40,6 +47,7 @@ describe(Compiler, () => { ).toEqual(expectedTypeScriptConfig()); }); }); + test('"watch" mode', async () => { // This can be a little slow, allowing 15 seconds maximum here (default is 5 seconds) jest.setTimeout(15_000); @@ -103,6 +111,45 @@ describe(Compiler, () => { await remove(sourceDir); } }); + + test('rootDir is added to assembly', async () => { + const outDir = 'jsii-outdir'; + const rootDir = 'jsii-rootdir'; + const sourceDir = await mkdtemp(join(tmpdir(), 'jsii-tmpdir')); + await ensureDir(join(sourceDir, rootDir)); + + try { + await writeFile( + join(sourceDir, rootDir, 'index.ts'), + 'export class MarkerA {}', + ); + // Intentionally using lower case name - it should be case-insensitive + await writeFile(join(sourceDir, rootDir, 'readme.md'), '# Test Package'); + + const compiler = new Compiler({ + projectInfo: { + ..._makeProjectInfo(sourceDir, join(outDir, 'index.d.ts')), + tsc: { + outDir, + rootDir, + }, + }, + failOnWarnings: true, + projectReferences: false, + }); + + await compiler.emit(); + + const assembly = await readJson(join(sourceDir, '.jsii'), 'utf-8'); + expect(assembly.metadata).toEqual( + expect.objectContaining({ + tscRootDir: rootDir, + }), + ); + } finally { + await remove(sourceDir); + } + }); }); function _makeProjectInfo(sourceDir: string, types: string): ProjectInfo { diff --git a/packages/jsii/test/project-info.test.ts b/packages/jsii/test/project-info.test.ts index 6f754f24e3..bf106243f1 100644 --- a/packages/jsii/test/project-info.test.ts +++ b/packages/jsii/test/project-info.test.ts @@ -320,14 +320,16 @@ async function _withTestProject( ); const jsiiTestDep = path.join(tmpdir, 'node_modules', 'jsii-test-dep'); - await fs.mkdirs(jsiiTestDep); + await writeNpmPackageSkeleton(jsiiTestDep); + await fs.writeJson(path.join(jsiiTestDep, '.jsii'), TEST_DEP_ASSEMBLY); const jsiiTestDepDep = path.join( jsiiTestDep, 'node_modules', 'jsii-test-dep-dep', ); - await fs.mkdirs(jsiiTestDepDep); + + await writeNpmPackageSkeleton(jsiiTestDepDep); await fs.writeJson( path.join(jsiiTestDepDep, '.jsii'), TEST_DEP_DEP_ASSEMBLY, @@ -339,6 +341,20 @@ async function _withTestProject( } } +/** + * Write a package.json and an index.js so the package is mostly well-formed + */ +async function writeNpmPackageSkeleton(directory: string) { + await fs.mkdirs(directory); + await fs.writeJson(path.join(directory, 'package.json'), { + name: path.basename(directory), + }); + await fs.writeFile( + path.join(directory, 'index.js'), + '// There should be some JS', + ); +} + /** * Removes keys from an object if the associated value is ``undefined``. * diff --git a/packages/jsii/test/submodules.test.ts b/packages/jsii/test/submodules.test.ts index 0b159faafb..7d117358d4 100644 --- a/packages/jsii/test/submodules.test.ts +++ b/packages/jsii/test/submodules.test.ts @@ -1,4 +1,10 @@ -import { sourceToAssemblyHelper } from '../lib'; +import * as spec from '@jsii/spec'; + +import { + sourceToAssemblyHelper, + TestWorkspace, + compileJsiiForTest, +} from '../lib'; test('submodules loaded from directories can have a README', async () => { const assembly = await sourceToAssemblyHelper({ @@ -51,3 +57,55 @@ test('submodules loaded from directories can have targets', async () => { }), ); }); + +test('can reference classes in submodules via direct import', () => + TestWorkspace.withWorkspace(async (ws) => { + // There are 2 import styles: + // + // import { submodule } from 'lib'; + // import * as submodule from 'lib/submodule'; + // + // We need to support both import styles. + + // Dependency that exports a submodule + await ws.addDependency( + await compileJsiiForTest({ + 'index.ts': 'export * as submodule from "./subdir"', + 'subdir/index.ts': 'export class Foo { }', + 'subdir/README.md': 'This is the README', + }), + ); + + // Main library that imports the submodule class directly + const result = await compileJsiiForTest( + { + 'index.ts': ` + import { Foo } from 'testpkg/subdir'; + + export class Bar { + constructor(public readonly foo: Foo) { } + } + `, + }, + { + packageJson: { + // Must be a different name from the dependency + name: 'consumerpkg', + peerDependencies: { testpkg: '*' }, + }, + compilationDirectory: ws.rootDirectory, + }, + ); + + expect( + (result.assembly.types?.['consumerpkg.Bar'] as spec.ClassType) + ?.initializer?.parameters, + ).toEqual([ + { + name: 'foo', + type: { + fqn: 'testpkg.submodule.Foo', + }, + }, + ]); + })); diff --git a/packages/jsii/test/symbol-identifiers.test.ts b/packages/jsii/test/symbol-identifiers.test.ts index 995b467305..04a6a83c80 100644 --- a/packages/jsii/test/symbol-identifiers.test.ts +++ b/packages/jsii/test/symbol-identifiers.test.ts @@ -1,4 +1,4 @@ -import { compileJsiiForTest } from '../lib'; +import { compileJsiiForTest, normalizePath } from '../lib'; test('Symbol map is generated', async () => { const result = await compileJsiiForTest( @@ -29,6 +29,23 @@ test('Symbol map is generated', async () => { expect(types['testpkg.Baz'].symbolId).toEqual('some/nested/file:Baz'); }); +test('Symbol id for single-value enum correctly identifies enum', async () => { + const result = await compileJsiiForTest( + { + 'index.ts': ` + export enum SomeEnum { + SINGLETON_VALUE = 'value', + } + `, + }, + undefined /* callback */, + { stripDeprecated: true }, + ); + + const types = result.assembly.types ?? {}; + expect(types['testpkg.SomeEnum'].symbolId).toEqual('index:SomeEnum'); +}); + test('Module declarations are included in symbolId', async () => { const result = await compileJsiiForTest( { @@ -92,3 +109,85 @@ test('Submodules also have symbol identifiers', async () => { 'index:cookie', ); }); + +describe(normalizePath, () => { + test('basic rootDir and outDir', () => { + expect(normalizePath('out/filename.ts', 'root', 'out')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/filename.ts', undefined, 'out')).toEqual( + 'out/filename.ts', + ); + expect(normalizePath('out/filename.ts', 'root', undefined)).toEqual( + 'out/filename.ts', + ); + expect(normalizePath('out/filename.ts', undefined, undefined)).toEqual( + 'out/filename.ts', + ); + }); + + test('extra slashes in directories', () => { + expect(normalizePath('out/filename.ts', 'root/', 'out/')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/filename.ts', 'root////', 'out////')).toEqual( + 'root/filename.ts', + ); + // eslint-disable-next-line prettier/prettier + expect(normalizePath('out/lib/filename.ts', 'root///', 'out//lib//')).toEqual( + 'root/filename.ts', + ); + }); + + test('additional paths in directories', () => { + expect(normalizePath('out/filename.ts', './root', 'out')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/filename.ts', 'root', './out')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/filename.ts', 'root', './here/../out')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/filename.ts', 'root/../root/..', '.')).toEqual( + 'out/filename.ts', + ); + }); + + test('empty paths', () => { + expect(normalizePath('out/lib/filename.ts', '', 'out')).toEqual( + 'lib/filename.ts', + ); + expect(normalizePath('out/lib/filename.ts', '.', 'out')).toEqual( + 'lib/filename.ts', + ); + expect(normalizePath('lib/filename.ts', 'root', '')).toEqual( + 'root/lib/filename.ts', + ); + expect(normalizePath('lib/filename.ts', 'root', '.')).toEqual( + 'root/lib/filename.ts', + ); + // eslint-disable-next-line prettier/prettier + expect(normalizePath('lib/filename.ts', '', '')).toEqual( + 'lib/filename.ts', + ); + expect(normalizePath('lib/filename.ts', '.', '.')).toEqual( + 'lib/filename.ts', + ); + }); + + test('specify multiple directories', () => { + expect(normalizePath('out/lib/filename.ts', 'root', 'out/lib')).toEqual( + 'root/filename.ts', + ); + expect(normalizePath('out/lib/filename.ts', 'root/extra', 'out')).toEqual( + 'root/extra/lib/filename.ts', + ); + expect(normalizePath('out/lib/filename.ts', '.', 'out/lib')).toEqual( + 'filename.ts', + ); + expect(normalizePath('lib/filename.ts', 'root/extra', '.')).toEqual( + 'root/extra/lib/filename.ts', + ); + }); +}); diff --git a/packages/oo-ascii-tree/package.json b/packages/oo-ascii-tree/package.json index d715821ae8..d83af25dbe 100644 --- a/packages/oo-ascii-tree/package.json +++ b/packages/oo-ascii-tree/package.json @@ -33,10 +33,10 @@ "devDependencies": { "@types/jest": "^27.0.3", "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "jest": "^27.3.1", + "eslint": "^8.4.1", + "jest": "^27.4.4", "jsii-build-tools": "^0.0.0", - "prettier": "^2.4.1", + "prettier": "^2.5.1", "typescript": "~3.9.10" } } diff --git a/tools/jsii-compliance/package.json b/tools/jsii-compliance/package.json index 527ea50ef1..330f39132b 100644 --- a/tools/jsii-compliance/package.json +++ b/tools/jsii-compliance/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@types/node": "^12.20.37", - "eslint": "^8.3.0", - "prettier": "^2.4.1", + "eslint": "^8.4.1", + "prettier": "^2.5.1", "ts-node": "^10.4.0", "typescript": "~3.9.10" } diff --git a/yarn.lock b/yarn.lock index fc0473f6d9..6fd133b9e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -322,18 +322,18 @@ "@cspotcode/source-map-consumer" "0.8.0" "@discoveryjs/json-ext@^0.5.0": - version "0.5.5" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" - integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== -"@eslint/eslintrc@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31" - integrity sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q== +"@eslint/eslintrc@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318" + integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.0.0" + espree "^9.2.0" globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" @@ -349,16 +349,16 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== -"@humanwhocodes/config-array@^0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" - integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== +"@humanwhocodes/config-array@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" + integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/object-schema@^1.2.0": +"@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== @@ -384,93 +384,93 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.3.1.tgz#e8ea3a475d3f8162f23d69efbfaa9cbe486bee93" - integrity sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw== +"@jest/console@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.4.2.tgz#7a95612d38c007ddb528ee446fe5e5e785e685ce" + integrity sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.3.1" - jest-util "^27.3.1" + jest-message-util "^27.4.2" + jest-util "^27.4.2" slash "^3.0.0" -"@jest/core@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.3.1.tgz#04992ef1b58b17c459afb87ab56d81e63d386925" - integrity sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg== +"@jest/core@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.4.4.tgz#f2ba293235ca23fb48b4b923ccfe67c17e791a92" + integrity sha512-xBNPVqYAdAiAMXnb4ugx9Cdmr0S52lBsLbQMR/sGBRO0810VSPKiuSDtuup6qdkK1e9vxbv3KK3IAP1QFAp8mw== dependencies: - "@jest/console" "^27.3.1" - "@jest/reporters" "^27.3.1" - "@jest/test-result" "^27.3.1" - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/console" "^27.4.2" + "@jest/reporters" "^27.4.4" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^27.3.0" - jest-config "^27.3.1" - jest-haste-map "^27.3.1" - jest-message-util "^27.3.1" - jest-regex-util "^27.0.6" - jest-resolve "^27.3.1" - jest-resolve-dependencies "^27.3.1" - jest-runner "^27.3.1" - jest-runtime "^27.3.1" - jest-snapshot "^27.3.1" - jest-util "^27.3.1" - jest-validate "^27.3.1" - jest-watcher "^27.3.1" + jest-changed-files "^27.4.2" + jest-config "^27.4.4" + jest-haste-map "^27.4.4" + jest-message-util "^27.4.2" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.4" + jest-resolve-dependencies "^27.4.4" + jest-runner "^27.4.4" + jest-runtime "^27.4.4" + jest-snapshot "^27.4.4" + jest-util "^27.4.2" + jest-validate "^27.4.2" + jest-watcher "^27.4.2" micromatch "^4.0.4" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.3.1.tgz#2182defbce8d385fd51c5e7c7050f510bd4c86b1" - integrity sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw== +"@jest/environment@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.4.tgz#66ebebc79673d84aad29d2bb70a8c51e6c29bb4d" + integrity sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ== dependencies: - "@jest/fake-timers" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.3.0" + jest-mock "^27.4.2" -"@jest/fake-timers@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.3.1.tgz#1fad860ee9b13034762cdb94266e95609dfce641" - integrity sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA== +"@jest/fake-timers@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.4.2.tgz#d217f86c3ba2027bf29e0b731fd0cb761a72d093" + integrity sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - jest-message-util "^27.3.1" - jest-mock "^27.3.0" - jest-util "^27.3.1" + jest-message-util "^27.4.2" + jest-mock "^27.4.2" + jest-util "^27.4.2" -"@jest/globals@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.3.1.tgz#ce1dfb03d379237a9da6c1b99ecfaca1922a5f9e" - integrity sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg== +"@jest/globals@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.4.tgz#fe501a80c23ea2dab585c42be2a519bb5e38530d" + integrity sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ== dependencies: - "@jest/environment" "^27.3.1" - "@jest/types" "^27.2.5" - expect "^27.3.1" + "@jest/environment" "^27.4.4" + "@jest/types" "^27.4.2" + expect "^27.4.2" -"@jest/reporters@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.3.1.tgz#28b5c1f5789481e23788048fa822ed15486430b9" - integrity sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w== +"@jest/reporters@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.4.4.tgz#9e809829f602cd6e68bd058d1ea528f4b7482365" + integrity sha512-ssyJSw9B9Awb1QaxDhIPSs4de1b7SE2kv7tqFehQL13xpn5HUkMYZK/ufTOXiCAnXFOZS+XDl1GaQ/LmJAzI1A== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.3.1" - "@jest/test-result" "^27.3.1" - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/console" "^27.4.2" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -482,70 +482,70 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^27.3.1" - jest-resolve "^27.3.1" - jest-util "^27.3.1" - jest-worker "^27.3.1" + jest-haste-map "^27.4.4" + jest-resolve "^27.4.4" + jest-util "^27.4.2" + jest-worker "^27.4.4" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" -"@jest/source-map@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" - integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== +"@jest/source-map@^27.4.0": + version "27.4.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" + integrity sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.3.1.tgz#89adee8b771877c69b3b8d59f52f29dccc300194" - integrity sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg== +"@jest/test-result@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.4.2.tgz#05fd4a5466ec502f3eae0b39dff2b93ea4d5d9ec" + integrity sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA== dependencies: - "@jest/console" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/console" "^27.4.2" + "@jest/types" "^27.4.2" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz#4b3bde2dbb05ee74afdae608cf0768e3354683b1" - integrity sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA== +"@jest/test-sequencer@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.4.tgz#60be14369b2702e42d6042e71b8ab3fc69f5ce68" + integrity sha512-mCh+d4JTGTtX7vr13d7q2GHJy33nAobEwtEJ8X3u7R8+0ImVO2eAsQzsLfX8lyvdYHBxYABhqbYuaUNo42/pQw== dependencies: - "@jest/test-result" "^27.3.1" + "@jest/test-result" "^27.4.2" graceful-fs "^4.2.4" - jest-haste-map "^27.3.1" - jest-runtime "^27.3.1" + jest-haste-map "^27.4.4" + jest-runtime "^27.4.4" -"@jest/transform@^27.3.1": - version "27.3.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.3.1.tgz#ff80eafbeabe811e9025e4b6f452126718455220" - integrity sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ== +"@jest/transform@^27.4.4": + version "27.4.4" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.4.tgz#347e39402730879ba88c6ea6982db0d88640aa78" + integrity sha512-7U/nDSrGsGzL7+X8ScNFV71w8u8knJQWSa9C2xsrrKLMOgb+rWuCG4VAyWke/53BU96GnT+Ka81xCAHA5gk6zA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^27.3.1" - jest-regex-util "^27.0.6" - jest-util "^27.3.1" + jest-haste-map "^27.4.4" + jest-regex-util "^27.4.0" + jest-util "^27.4.2" micromatch "^4.0.4" pirates "^4.0.1" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^27.2.5": - version "27.2.5" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.2.5.tgz#420765c052605e75686982d24b061b4cbba22132" - integrity sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ== +"@jest/types@^27.4.2": + version "27.4.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" + integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -1251,9 +1251,9 @@ integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== "@npmcli/fs@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.0.0.tgz#589612cfad3a6ea0feafcb901d29c63fd52db09f" - integrity sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.0.tgz#bec1d1b89c170d40e1b73ad6c943b0b75e7d2951" + integrity sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA== dependencies: "@gar/promisify" "^1.0.1" semver "^7.3.5" @@ -1456,9 +1456,9 @@ integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" - integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== + version "7.1.17" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64" + integrity sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1526,9 +1526,9 @@ "@types/estree" "*" "@types/eslint@*": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.0.tgz#afd0519223c29c347087542cbaee2fedc0873b16" - integrity sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ== + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" + integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1622,9 +1622,9 @@ "@types/node" "*" "@types/node@*", "@types/node@^16.9.2": - version "16.11.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.10.tgz#2e3ad0a680d96367103d3e670d41c2fed3da61ae" - integrity sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA== + version "16.11.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10" + integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw== "@types/node@^12.20.37": version "12.20.37" @@ -1712,13 +1712,13 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz#05e711a2e7b68342661fde61bccbd1531c19521a" - integrity sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg== +"@typescript-eslint/eslint-plugin@^5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz#efd8668b3d6627c46ce722c2afe813928fe120a0" + integrity sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA== dependencies: - "@typescript-eslint/experimental-utils" "5.4.0" - "@typescript-eslint/scope-manager" "5.4.0" + "@typescript-eslint/experimental-utils" "5.6.0" + "@typescript-eslint/scope-manager" "5.6.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -1726,60 +1726,60 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz#238a7418d2da3b24874ba35385eb21cc61d2a65e" - integrity sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg== +"@typescript-eslint/experimental-utils@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz#f3a5960f2004abdcac7bb81412bafc1560841c23" + integrity sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.4.0" - "@typescript-eslint/types" "5.4.0" - "@typescript-eslint/typescript-estree" "5.4.0" + "@typescript-eslint/scope-manager" "5.6.0" + "@typescript-eslint/types" "5.6.0" + "@typescript-eslint/typescript-estree" "5.6.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.4.0.tgz#3aa83ce349d66e39b84151f6d5464928044ca9e3" - integrity sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw== +"@typescript-eslint/parser@^5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.6.0.tgz#11677324659641400d653253c03dcfbed468d199" + integrity sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ== dependencies: - "@typescript-eslint/scope-manager" "5.4.0" - "@typescript-eslint/types" "5.4.0" - "@typescript-eslint/typescript-estree" "5.4.0" + "@typescript-eslint/scope-manager" "5.6.0" + "@typescript-eslint/types" "5.6.0" + "@typescript-eslint/typescript-estree" "5.6.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz#aaab08415f4a9cf32b870c7750ae8ba4607126a1" - integrity sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA== +"@typescript-eslint/scope-manager@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz#9dd7f007dc8f3a34cdff6f79f5eaab27ae05157e" + integrity sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A== dependencies: - "@typescript-eslint/types" "5.4.0" - "@typescript-eslint/visitor-keys" "5.4.0" + "@typescript-eslint/types" "5.6.0" + "@typescript-eslint/visitor-keys" "5.6.0" -"@typescript-eslint/types@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.4.0.tgz#b1c130f4b381b77bec19696c6e3366f9781ce8f2" - integrity sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA== +"@typescript-eslint/types@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.6.0.tgz#745cb1b59daadcc1f32f7be95f0f68accf38afdd" + integrity sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA== -"@typescript-eslint/typescript-estree@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz#fe524fb308973c68ebeb7428f3b64499a6ba5fc0" - integrity sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA== +"@typescript-eslint/typescript-estree@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz#dfbb19c9307fdd81bd9c650c67e8397821d7faf0" + integrity sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA== dependencies: - "@typescript-eslint/types" "5.4.0" - "@typescript-eslint/visitor-keys" "5.4.0" + "@typescript-eslint/types" "5.6.0" + "@typescript-eslint/visitor-keys" "5.6.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz#09bc28efd3621f292fe88c86eef3bf4893364c8c" - integrity sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg== +"@typescript-eslint/visitor-keys@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz#3e36509e103fe9713d8f035ac977235fd63cb6e6" + integrity sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng== dependencies: - "@typescript-eslint/types" "5.4.0" + "@typescript-eslint/types" "5.6.0" eslint-visitor-keys "^3.0.0" "@webassemblyjs/ast@1.11.1": @@ -2227,16 +2227,16 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -babel-jest@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.3.1.tgz#0636a3404c68e07001e434ac4956d82da8a80022" - integrity sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ== +babel-jest@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.4.tgz#a012441f8a155df909839543a09510ab3477aa11" + integrity sha512-+6RVutZxOQgJkt4svgTHPFtOQlVe9dUg3wrimIAM38pY6hL/nsL8glfFSUjD9jNVjaVjzkCzj6loFFecrjr9Qw== dependencies: - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.2.0" + babel-preset-jest "^27.4.0" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -2252,10 +2252,10 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^27.2.0: - version "27.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz#79f37d43f7e5c4fdc4b2ca3e10cc6cf545626277" - integrity sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw== +babel-plugin-jest-hoist@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" + integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -2280,12 +2280,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^27.2.0: - version "27.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz#556bbbf340608fed5670ab0ea0c8ef2449fba885" - integrity sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg== +babel-preset-jest@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" + integrity sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg== dependencies: - babel-plugin-jest-hoist "^27.2.0" + babel-plugin-jest-hoist "^27.4.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -2427,9 +2427,9 @@ camelcase@^6.2.0, camelcase@^6.2.1: integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== caniuse-lite@^1.0.30001280: - version "1.0.30001282" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz#38c781ee0a90ccfe1fe7fefd00e43f5ffdcb96fd" - integrity sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg== + version "1.0.30001286" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001286.tgz#3e9debad420419618cfdf52dc9b6572b28a8fff6" + integrity sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ== case@^1.6.3: version "1.6.3" @@ -2441,13 +2441,10 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@*, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" +chalk@*: + version "5.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.0.tgz#bd96c6bb8e02b96e08c0c3ee2a9d90e050c7b832" + integrity sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ== chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" @@ -2458,6 +2455,14 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -2938,9 +2943,9 @@ dateformat@^3.0.0: integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -3094,10 +3099,10 @@ didyoumean@^1.2.1: resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== -diff-sequences@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" - integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== +diff-sequences@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" + integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== diff@^4.0.1: version "4.0.2" @@ -3183,9 +3188,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.3.896: - version "1.4.0" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.0.tgz#7456192519838f881e35e4038bf4ad2c36353e63" - integrity sha512-+oXCt6SaIu8EmFTPx8wNGSB0tHQ5biDscnlf6Uxuz17e9CjzMRtGk9B8705aMPnj0iWr3iC74WuIkngCsLElmA== + version "1.4.16" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.16.tgz#38ddecc616385e6f101359d1b978c802664157d2" + integrity sha512-BQb7FgYwnu6haWLU63/CdVW+9xhmHls3RCQUFiV4lvw3wimEHTVcUk2hkuZo76QhR8nnDdfZE7evJIZqijwPdA== emittery@^0.8.1: version "0.8.1" @@ -3424,13 +3429,13 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== -eslint@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.3.0.tgz#a3c2409507403c1c7f6c42926111d6cbefbc3e85" - integrity sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww== +eslint@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.4.1.tgz#d6531bbf3e598dffd7c0c7d35ec52a0b30fdfa2d" + integrity sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg== dependencies: - "@eslint/eslintrc" "^1.0.4" - "@humanwhocodes/config-array" "^0.6.0" + "@eslint/eslintrc" "^1.0.5" + "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -3441,7 +3446,7 @@ eslint@^8.3.0: eslint-scope "^7.1.0" eslint-utils "^3.0.0" eslint-visitor-keys "^3.1.0" - espree "^9.1.0" + espree "^9.2.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -3468,10 +3473,10 @@ eslint@^8.3.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^9.0.0, espree@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.1.0.tgz#ba9d3c9b34eeae205724124e31de4543d59fbf74" - integrity sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ== +espree@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.2.0.tgz#c50814e01611c2d0f8bd4daa83c369eabba80dbc" + integrity sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg== dependencies: acorn "^8.6.0" acorn-jsx "^5.3.1" @@ -3541,17 +3546,17 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expect@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.3.1.tgz#d0f170b1f5c8a2009bab0beffd4bb94f043e38e7" - integrity sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg== +expect@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.2.tgz#4429b0f7e307771d176de9bdf23229b101db6ef6" + integrity sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" ansi-styles "^5.0.0" - jest-get-type "^27.3.1" - jest-matcher-utils "^27.3.1" - jest-message-util "^27.3.1" - jest-regex-util "^27.0.6" + jest-get-type "^27.4.0" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-regex-util "^27.4.0" extend@~3.0.2: version "3.0.2" @@ -4337,9 +4342,9 @@ is-map@^2.0.1, is-map@^2.0.2: integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.6" @@ -4458,16 +4463,19 @@ is-weakmap@^2.0.1: integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" is-weakset@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" - integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" isarray@0.0.1: version "0.0.1" @@ -4544,238 +4552,239 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384" - integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ== + version "3.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.1.tgz#7085857f17d2441053c6ce5c3b8fdf6882289397" + integrity sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^27.3.0: - version "27.3.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.3.0.tgz#22a02cc2b34583fc66e443171dc271c0529d263c" - integrity sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg== +jest-changed-files@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" + integrity sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.3.1.tgz#1679e74387cbbf0c6a8b42de963250a6469e0797" - integrity sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw== +jest-circus@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.4.tgz#8bf89aa604b914ecc10e3d895aae283b529f965d" + integrity sha512-4DWhvQerDq5X4GaqhEUoZiBhuNdKDGr0geW0iJwarbDljAmGaGOErKQG+z2PBr0vgN05z7tsGSY51mdWr8E4xg== dependencies: - "@jest/environment" "^27.3.1" - "@jest/test-result" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/environment" "^27.4.4" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.3.1" + expect "^27.4.2" is-generator-fn "^2.0.0" - jest-each "^27.3.1" - jest-matcher-utils "^27.3.1" - jest-message-util "^27.3.1" - jest-runtime "^27.3.1" - jest-snapshot "^27.3.1" - jest-util "^27.3.1" - pretty-format "^27.3.1" + jest-each "^27.4.2" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-runtime "^27.4.4" + jest-snapshot "^27.4.4" + jest-util "^27.4.2" + pretty-format "^27.4.2" slash "^3.0.0" stack-utils "^2.0.3" throat "^6.0.1" -jest-cli@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.3.1.tgz#b576f9d146ba6643ce0a162d782b40152b6b1d16" - integrity sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q== +jest-cli@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.4.4.tgz#7115ff01f605c2c848314141b1ac144099ddeed5" + integrity sha512-+MfsHnZPUOBigCBURuQFRpgYoPCgmIFkICkqt4SrramZCUp/UAuWcst4pMZb84O3VU8JyKJmnpGG4qH8ClQloA== dependencies: - "@jest/core" "^27.3.1" - "@jest/test-result" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/core" "^27.4.4" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" - jest-config "^27.3.1" - jest-util "^27.3.1" - jest-validate "^27.3.1" + jest-config "^27.4.4" + jest-util "^27.4.2" + jest-validate "^27.4.2" prompts "^2.0.1" yargs "^16.2.0" -jest-config@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.3.1.tgz#cb3b7f6aaa8c0a7daad4f2b9573899ca7e09bbad" - integrity sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg== +jest-config@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.4.4.tgz#0e3615392361baae0e29dbf64c296d5563d7e28b" + integrity sha512-6lxg0ugO6KS2zKEbpdDwBzu1IT0Xg4/VhxXMuBu+z/5FvBjLCEMTaWQm3bCaGCZUR9j9FK4DzUIxyhIgn6kVEg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.3.1" - "@jest/types" "^27.2.5" - babel-jest "^27.3.1" + "@jest/test-sequencer" "^27.4.4" + "@jest/types" "^27.4.2" + babel-jest "^27.4.4" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-circus "^27.3.1" - jest-environment-jsdom "^27.3.1" - jest-environment-node "^27.3.1" - jest-get-type "^27.3.1" - jest-jasmine2 "^27.3.1" - jest-regex-util "^27.0.6" - jest-resolve "^27.3.1" - jest-runner "^27.3.1" - jest-util "^27.3.1" - jest-validate "^27.3.1" + jest-circus "^27.4.4" + jest-environment-jsdom "^27.4.4" + jest-environment-node "^27.4.4" + jest-get-type "^27.4.0" + jest-jasmine2 "^27.4.4" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.4" + jest-runner "^27.4.4" + jest-util "^27.4.2" + jest-validate "^27.4.2" micromatch "^4.0.4" - pretty-format "^27.3.1" + pretty-format "^27.4.2" + slash "^3.0.0" -jest-diff@^27.0.0, jest-diff@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.3.1.tgz#d2775fea15411f5f5aeda2a5e02c2f36440f6d55" - integrity sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ== +jest-diff@^27.0.0, jest-diff@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" + integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.6" - jest-get-type "^27.3.1" - pretty-format "^27.3.1" + diff-sequences "^27.4.0" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-docblock@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" - integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== +jest-docblock@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" + integrity sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg== dependencies: detect-newline "^3.0.0" -jest-each@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.3.1.tgz#14c56bb4f18dd18dc6bdd853919b5f16a17761ff" - integrity sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ== +jest-each@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.4.2.tgz#19364c82a692d0d26557642098d1f4619c9ee7d3" + integrity sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" chalk "^4.0.0" - jest-get-type "^27.3.1" - jest-util "^27.3.1" - pretty-format "^27.3.1" - -jest-environment-jsdom@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz#63ac36d68f7a9303494df783494856222b57f73e" - integrity sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg== - dependencies: - "@jest/environment" "^27.3.1" - "@jest/fake-timers" "^27.3.1" - "@jest/types" "^27.2.5" + jest-get-type "^27.4.0" + jest-util "^27.4.2" + pretty-format "^27.4.2" + +jest-environment-jsdom@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz#94f738e99514d7a880e8ed8e03e3a321d43b49db" + integrity sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA== + dependencies: + "@jest/environment" "^27.4.4" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.3.0" - jest-util "^27.3.1" + jest-mock "^27.4.2" + jest-util "^27.4.2" jsdom "^16.6.0" -jest-environment-node@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.3.1.tgz#af7d0eed04edafb740311b303f3fe7c8c27014bb" - integrity sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw== +jest-environment-node@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.4.tgz#42fe5e3b224cb69b99811ebf6f5eaa5a59618514" + integrity sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA== dependencies: - "@jest/environment" "^27.3.1" - "@jest/fake-timers" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/environment" "^27.4.4" + "@jest/fake-timers" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.3.0" - jest-util "^27.3.1" + jest-mock "^27.4.2" + jest-util "^27.4.2" jest-expect-message@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/jest-expect-message/-/jest-expect-message-1.0.2.tgz#6d67cdf093457a607d231038a3b84aa3a076bcba" integrity sha512-WFiXMgwS2lOqQZt1iJMI/hOXpUm32X+ApsuzYcQpW5m16Pv6/Gd9kgC+Q+Q1YVNU04kYcAOv9NXMnjg6kKUy6Q== -jest-get-type@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.3.1.tgz#a8a2b0a12b50169773099eee60a0e6dd11423eff" - integrity sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg== +jest-get-type@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" + integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== -jest-haste-map@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.3.1.tgz#7656fbd64bf48bda904e759fc9d93e2c807353ee" - integrity sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg== +jest-haste-map@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.4.tgz#ec6013845368a155372e25e42e2b77e6ecc5019f" + integrity sha512-kvspmHmgPIZoDaqUsvsJFTaspuxhATvdO6wsFNGNSi8kfdiOCEEvECNbht8xG+eE5Ol88JyJmp2D7RF4dYo85Q== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.4" - jest-regex-util "^27.0.6" - jest-serializer "^27.0.6" - jest-util "^27.3.1" - jest-worker "^27.3.1" + jest-regex-util "^27.4.0" + jest-serializer "^27.4.0" + jest-util "^27.4.2" + jest-worker "^27.4.4" micromatch "^4.0.4" walker "^1.0.7" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz#df6d3d07c7dafc344feb43a0072a6f09458d32b0" - integrity sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg== +jest-jasmine2@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.4.tgz#1fcdc64de932913366e7d5f2960c375e1145176e" + integrity sha512-ygk2tUgtLeN3ouj4KEYw9p81GLI1EKrnvourPULN5gdgB482PH5op9gqaRG0IenbJhBbbRwiSvh5NoBoQZSqdA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.3.1" - "@jest/source-map" "^27.0.6" - "@jest/test-result" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/environment" "^27.4.4" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^27.3.1" + expect "^27.4.2" is-generator-fn "^2.0.0" - jest-each "^27.3.1" - jest-matcher-utils "^27.3.1" - jest-message-util "^27.3.1" - jest-runtime "^27.3.1" - jest-snapshot "^27.3.1" - jest-util "^27.3.1" - pretty-format "^27.3.1" + jest-each "^27.4.2" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-runtime "^27.4.4" + jest-snapshot "^27.4.4" + jest-util "^27.4.2" + pretty-format "^27.4.2" throat "^6.0.1" -jest-leak-detector@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz#7fb632c2992ef707a1e73286e1e704f9cc1772b2" - integrity sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg== +jest-leak-detector@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz#7fc3120893a7a911c553f3f2bdff9faa4454abbb" + integrity sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw== dependencies: - jest-get-type "^27.3.1" - pretty-format "^27.3.1" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-matcher-utils@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz#257ad61e54a6d4044e080d85dbdc4a08811e9c1c" - integrity sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w== +jest-matcher-utils@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" + integrity sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ== dependencies: chalk "^4.0.0" - jest-diff "^27.3.1" - jest-get-type "^27.3.1" - pretty-format "^27.3.1" + jest-diff "^27.4.2" + jest-get-type "^27.4.0" + pretty-format "^27.4.2" -jest-message-util@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.3.1.tgz#f7c25688ad3410ab10bcb862bcfe3152345c6436" - integrity sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg== +jest-message-util@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.2.tgz#07f3f1bf207d69cf798ce830cc57f1a849f99388" + integrity sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.4" - pretty-format "^27.3.1" + pretty-format "^27.4.2" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.3.0: - version "27.3.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.3.0.tgz#ddf0ec3cc3e68c8ccd489bef4d1f525571a1b867" - integrity sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw== +jest-mock@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.4.2.tgz#184ff197a25491bfe4570c286daa5d62eb760b88" + integrity sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -4783,76 +4792,76 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" - integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== +jest-regex-util@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" + integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== -jest-resolve-dependencies@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz#85b99bdbdfa46e2c81c6228fc4c91076f624f6e2" - integrity sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A== +jest-resolve-dependencies@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.4.tgz#dae11e067a6d6a9553f1386a0ea1efe5be0e2332" + integrity sha512-iAnpCXh81sd9nbyqySvm5/aV9X6JZKE0dQyFXTC8tptXcdrgS0vjPFy+mEgzPHxXw+tq4TQupuTa0n8OXwRIxw== dependencies: - "@jest/types" "^27.2.5" - jest-regex-util "^27.0.6" - jest-snapshot "^27.3.1" + "@jest/types" "^27.4.2" + jest-regex-util "^27.4.0" + jest-snapshot "^27.4.4" -jest-resolve@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.3.1.tgz#0e5542172a1aa0270be6f66a65888647bdd74a3e" - integrity sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw== +jest-resolve@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.4.tgz#5b690662f54f38f7cfaffc0adcdb341ff7724408" + integrity sha512-Yh5jK3PBmDbm01Rc8pT0XqpBlTPEGwWp7cN61ijJuwony/tR2Taof3TLy6yfNiuRS8ucUOPO7NBYm3ei38kkcg== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" chalk "^4.0.0" graceful-fs "^4.2.4" - jest-haste-map "^27.3.1" + jest-haste-map "^27.4.4" jest-pnp-resolver "^1.2.2" - jest-util "^27.3.1" - jest-validate "^27.3.1" + jest-util "^27.4.2" + jest-validate "^27.4.2" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.3.1.tgz#1d594dcbf3bd8600a7e839e790384559eaf96e3e" - integrity sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww== +jest-runner@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.4.tgz#0b40cdcbac293ebc4c19c2d7805d17ab1072f1fd" + integrity sha512-AXv/8Q0Xf1puWnDf52m7oLrK7sXcv6re0V/kItwTSVHJbX7Oebm07oGFQqGmq0R0mhO1zpmB3OpqRuaCN2elPA== dependencies: - "@jest/console" "^27.3.1" - "@jest/environment" "^27.3.1" - "@jest/test-result" "^27.3.1" - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/console" "^27.4.2" + "@jest/environment" "^27.4.4" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-docblock "^27.0.6" - jest-environment-jsdom "^27.3.1" - jest-environment-node "^27.3.1" - jest-haste-map "^27.3.1" - jest-leak-detector "^27.3.1" - jest-message-util "^27.3.1" - jest-resolve "^27.3.1" - jest-runtime "^27.3.1" - jest-util "^27.3.1" - jest-worker "^27.3.1" + jest-docblock "^27.4.0" + jest-environment-jsdom "^27.4.4" + jest-environment-node "^27.4.4" + jest-haste-map "^27.4.4" + jest-leak-detector "^27.4.2" + jest-message-util "^27.4.2" + jest-resolve "^27.4.4" + jest-runtime "^27.4.4" + jest-util "^27.4.2" + jest-worker "^27.4.4" source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.3.1.tgz#80fa32eb85fe5af575865ddf379874777ee993d7" - integrity sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg== - dependencies: - "@jest/console" "^27.3.1" - "@jest/environment" "^27.3.1" - "@jest/globals" "^27.3.1" - "@jest/source-map" "^27.0.6" - "@jest/test-result" "^27.3.1" - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" +jest-runtime@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.4.tgz#0d486735e8a1c8bbcdbb9285b3155ed94c5e3670" + integrity sha512-tZGay6P6vXJq8t4jVFAUzYHx+lzIHXjz+rj1XBk6mAR1Lwtf5kz0Uun7qNuU+oqpZu4+hhuxpUfXb6j30bEPqA== + dependencies: + "@jest/console" "^27.4.2" + "@jest/environment" "^27.4.4" + "@jest/globals" "^27.4.4" + "@jest/source-map" "^27.4.0" + "@jest/test-result" "^27.4.2" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/yargs" "^16.0.0" chalk "^4.0.0" cjs-module-lexer "^1.0.0" @@ -4861,30 +4870,30 @@ jest-runtime@^27.3.1: exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-haste-map "^27.3.1" - jest-message-util "^27.3.1" - jest-mock "^27.3.0" - jest-regex-util "^27.0.6" - jest-resolve "^27.3.1" - jest-snapshot "^27.3.1" - jest-util "^27.3.1" - jest-validate "^27.3.1" + jest-haste-map "^27.4.4" + jest-message-util "^27.4.2" + jest-mock "^27.4.2" + jest-regex-util "^27.4.0" + jest-resolve "^27.4.4" + jest-snapshot "^27.4.4" + jest-util "^27.4.2" + jest-validate "^27.4.2" slash "^3.0.0" strip-bom "^4.0.0" yargs "^16.2.0" -jest-serializer@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" - integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== +jest-serializer@^27.4.0: + version "27.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" + integrity sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ== dependencies: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.3.1.tgz#1da5c0712a252d70917d46c037054f5918c49ee4" - integrity sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg== +jest-snapshot@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.4.tgz#fc0a2cd22f742fe66621c5359c9cd64f88260c6b" + integrity sha512-yy+rpCvYMOjTl7IMuaMI9OP9WT229zi8BhdNHm6e6mttAOIzvIiCxFoZ6yRxaV3HDPPgMryi+ReX2b8+IQJdPA== dependencies: "@babel/core" "^7.7.2" "@babel/generator" "^7.7.2" @@ -4892,79 +4901,79 @@ jest-snapshot@^27.3.1: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/transform" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/transform" "^27.4.4" + "@jest/types" "^27.4.2" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.3.1" + expect "^27.4.2" graceful-fs "^4.2.4" - jest-diff "^27.3.1" - jest-get-type "^27.3.1" - jest-haste-map "^27.3.1" - jest-matcher-utils "^27.3.1" - jest-message-util "^27.3.1" - jest-resolve "^27.3.1" - jest-util "^27.3.1" + jest-diff "^27.4.2" + jest-get-type "^27.4.0" + jest-haste-map "^27.4.4" + jest-matcher-utils "^27.4.2" + jest-message-util "^27.4.2" + jest-resolve "^27.4.4" + jest-util "^27.4.2" natural-compare "^1.4.0" - pretty-format "^27.3.1" + pretty-format "^27.4.2" semver "^7.3.2" -jest-util@^27.0.0, jest-util@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.3.1.tgz#a58cdc7b6c8a560caac9ed6bdfc4e4ff23f80429" - integrity sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw== +jest-util@^27.0.0, jest-util@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" + integrity sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.4" picomatch "^2.2.3" -jest-validate@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.3.1.tgz#3a395d61a19cd13ae9054af8cdaf299116ef8a24" - integrity sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q== +jest-validate@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.4.2.tgz#eecfcc1b1c9429aa007da08a2bae4e32a81bbbc3" + integrity sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^27.3.1" + jest-get-type "^27.4.0" leven "^3.1.0" - pretty-format "^27.3.1" + pretty-format "^27.4.2" -jest-watcher@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.3.1.tgz#ba5e0bc6aa843612b54ddb7f009d1cbff7e05f3e" - integrity sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA== +jest-watcher@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.4.2.tgz#c9037edfd80354c9fe90de4b6f8b6e2b8e736744" + integrity sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg== dependencies: - "@jest/test-result" "^27.3.1" - "@jest/types" "^27.2.5" + "@jest/test-result" "^27.4.2" + "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^27.3.1" + jest-util "^27.4.2" string-length "^4.0.1" -jest-worker@^27.0.6, jest-worker@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.3.1.tgz#0def7feae5b8042be38479799aeb7b5facac24b2" - integrity sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g== +jest-worker@^27.0.6, jest-worker@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.4.tgz#9390a97c013a54d07f5c2ad2b5f6109f30c4966d" + integrity sha512-jfwxYJvfua1b1XkyuyPh01ATmgg4e5fPM/muLmhy9Qc6dmiwacQB0MLHaU6IjEsv/+nAixHGxTn8WllA27Pn0w== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.3.1.tgz#b5bab64e8f56b6f7e275ba1836898b0d9f1e5c8a" - integrity sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng== +jest@^27.4.4: + version "27.4.4" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.4.tgz#9b1aa1db25d0b13477a49d18e22ba7cdff97105b" + integrity sha512-AXwEIFa58Uf1Jno3/KSo5HZZ0/2Xwqvfrz0/3bmTwImkFlbOvz5vARAW9nTrxRLkojjkitaZ1KNKAtw3JRFAaA== dependencies: - "@jest/core" "^27.3.1" + "@jest/core" "^27.4.4" import-local "^3.0.2" - jest-cli "^27.3.1" + jest-cli "^27.4.4" js-tokens@^4.0.0: version "4.0.0" @@ -5030,12 +5039,12 @@ jsesc@^2.5.1: integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== json-fixer@^1.5.1: - version "1.6.12" - resolved "https://registry.yarnpkg.com/json-fixer/-/json-fixer-1.6.12.tgz#352026c905c6366e214c9f10f77d6d7f93c48322" - integrity sha512-BGO9HExf0ZUVYvuWsps71Re513Ss0il1Wp7wYWkir2NthzincvNJEUu82KagEfAkGdjOMsypj3t2JB7drBKWnA== + version "1.6.13" + resolved "https://registry.yarnpkg.com/json-fixer/-/json-fixer-1.6.13.tgz#27d2f0e837aec54afbc9ec1cd8c1dd965bf534c9" + integrity sha512-DKQ71M+0uwAG3QsUkeVgh6XREw/OkpnTfHfM+sdmxRjHvYZ8PlcMVF4ibsHQ1ckR63NROs68qUr1I0u6yPVePQ== dependencies: "@babel/runtime" "^7.14.6" - chalk "^4.1.1" + chalk "^4.1.2" pegjs "^0.10.0" json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: @@ -5053,10 +5062,10 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -5109,13 +5118,13 @@ jsonschema@^1.4.0: integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" extsprintf "1.3.0" - json-schema "0.2.3" + json-schema "0.4.0" verror "1.10.0" kind-of@^6.0.2, kind-of@^6.0.3: @@ -5543,9 +5552,9 @@ minipass@^2.6.0, minipass@^2.9.0: yallist "^3.0.0" minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.5.tgz#71f6251b0a33a49c01b3cf97ff77eda030dff732" - integrity sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw== + version "3.1.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" + integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== dependencies: yallist "^4.0.0" @@ -5693,11 +5702,6 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" @@ -5879,9 +5883,9 @@ object-assign@^4.1.0: integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + version "1.11.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" + integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== object-is@^1.1.4: version "1.1.5" @@ -6241,11 +6245,9 @@ pify@^5.0.0: integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" + version "4.0.4" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" + integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== pkg-dir@^2.0.0: version "2.0.0" @@ -6278,17 +6280,17 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== -pretty-format@^27.0.0, pretty-format@^27.3.1: - version "27.3.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.3.1.tgz#7e9486365ccdd4a502061fa761d3ab9ca1b78df5" - integrity sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA== +pretty-format@^27.0.0, pretty-format@^27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" + integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== dependencies: - "@jest/types" "^27.2.5" + "@jest/types" "^27.4.2" ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -6357,9 +6359,9 @@ q@^1.5.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qs@^6.9.4: - version "6.10.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" - integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + version "6.10.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.2.tgz#c1431bea37fc5b24c5bdbafa20f16bdf2a4b9ffe" + integrity sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw== dependencies: side-channel "^1.0.4" @@ -6710,9 +6712,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-stable-stringify@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.2.0.tgz#26a52f13a6988de16a0d88e20248f38e8a7d840c" - integrity sha512-C6AuMdYPuPV/P1leplHNu0lgc2LAElq/g3TdoksDCIVtBhr78o/CH03bt/9SKqugFbKU9CUjsNlCu0fjtQzQUw== + version "2.3.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" + integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" @@ -7062,7 +7064,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7384,10 +7386,10 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -ts-jest@^27.0.7: - version "27.0.7" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.0.7.tgz#fb7c8c8cb5526ab371bc1b23d06e745652cca2d0" - integrity sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q== +ts-jest@^27.1.1: + version "27.1.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.1.tgz#5a54aca96db1dac37c681f3029dd10f3a8c36192" + integrity sha512-Ds0VkB+cB+8g2JUmP/GKWndeZcCKrbe6jzolGrVWdqVUFByY/2KDHqxJ7yBSon7hDB1TA4PXxjfZ+JjzJisvgA== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" @@ -7540,9 +7542,9 @@ typescript@~4.4.4: integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== uglify-js@^3.1.4: - version "3.14.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" - integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g== + version "3.14.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859" + integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ== uid-number@0.0.6: version "0.0.6" @@ -7693,10 +7695,10 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -watchpack@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" - integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== +watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -7754,10 +7756,10 @@ webpack-sources@^3.2.2: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== -webpack@^5.64.3: - version "5.64.3" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.3.tgz#f4792cc3f8528db2c18375fa2cd269f69e0bf69f" - integrity sha512-XF6/IL9Bw2PPQioiR1UYA8Bs4tX3QXJtSelezKECdLFeSFzWoe44zqTzPW5N+xI3fACaRl2/G3sNA4WYHD7Iww== +webpack@^5.65.0: + version "5.65.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be" + integrity sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.50" @@ -7781,7 +7783,7 @@ webpack@^5.64.3: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" + watchpack "^2.3.1" webpack-sources "^3.2.2" whatwg-encoding@^1.0.5: @@ -8035,6 +8037,11 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^21.0.0: + version "21.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" + integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== + yargs@^15.0.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -8066,17 +8073,17 @@ yargs@^16.0.0, yargs@^16.2.0: yargs-parser "^20.2.2" yargs@^17.1.1: - version "17.2.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea" - integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q== + version "17.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.0.tgz#295c4ffd0eef148ef3e48f7a2e0f58d0e4f26b1c" + integrity sha512-GQl1pWyDoGptFPJx9b9L6kmR33TGusZvXIZUT+BOz9f7X2L94oeAskFYLEg/FkhV06zZPBYLvLZRWeYId29lew== dependencies: cliui "^7.0.2" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" - string-width "^4.2.0" + string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^20.2.2" + yargs-parser "^21.0.0" yn@3.1.1: version "3.1.1"