From 228dad802c15aace99149afe1dc9103e76d3712e Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 10:33:47 -0400 Subject: [PATCH 01/15] Install new deps --- package-lock.json | 1833 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 24 +- 2 files changed, 1845 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11167c5d2d..0ad50604e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,11 +67,15 @@ "bootstrap": "^4.6.1", "empty-module": "0.0.2", "eslint": "^8.10.0", + "eslint-config-prettier": "^8.8.0", "eslint-plugin-cypress": "^2.12.1", + "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.29.2", "fancy-log": "^1.3.3", "gulp": "^4.0.2", "plugin-error": "^1.0.1", + "prettier": "^2.8.7", + "prettier-eslint-cli": "^7.1.0", "sass": "^1.51.0", "sinon": "^1.17.6", "source-map-support": "^0.5.19", @@ -2482,6 +2486,50 @@ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, + "node_modules/@messageformat/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.1.0.tgz", + "integrity": "sha512-UxAnjecnRG4u2iaggwIyylYPHmk5BTErJcKmWyAKTXqYgSW1bFLp4D7fIzuh6bk17Qfcmf3qtufdrstCB23nBA==", + "dev": true, + "dependencies": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.0.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "node_modules/@messageformat/date-skeleton": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.0.1.tgz", + "integrity": "sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==", + "dev": true + }, + "node_modules/@messageformat/number-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.1.0.tgz", + "integrity": "sha512-F0Io+GOSvFFxvp9Ze3L5kAoZ2NnOAT0Mr/jpGNd3fqo8A0t4NxNIAcCdggtl2B/gN2ErkIKSBVPrF7xcW1IGvA==", + "dev": true + }, + "node_modules/@messageformat/parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz", + "integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==", + "dev": true, + "dependencies": { + "moo": "^0.5.1" + } + }, + "node_modules/@messageformat/runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", + "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "dev": true, + "dependencies": { + "make-plural": "^7.0.0" + } + }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -2971,6 +3019,32 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@prettier/eslint": { + "name": "prettier-eslint", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-15.0.1.tgz", + "integrity": "sha512-mGOWVHixSvpZWARqSDXbdtTL54mMBxc5oQYQ6RAqy8jecuNJBgN3t9E5a81G66F8x8fsKNiR1HWaBV66MJDOpg==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.4.2", + "@types/prettier": "^2.6.0", + "@typescript-eslint/parser": "^5.10.0", + "common-tags": "^1.4.0", + "dlv": "^1.1.0", + "eslint": "^8.7.0", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.0", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^2.5.1", + "pretty-format": "^23.0.1", + "require-relative": "^0.8.7", + "typescript": "^4.5.4", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@restart/context": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", @@ -3108,6 +3182,22 @@ "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.2.tgz", "integrity": "sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==" }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -3152,6 +3242,12 @@ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -3250,6 +3346,152 @@ "@types/node": "*" } }, + "node_modules/@typescript-eslint/parser": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", + "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -3840,6 +4082,15 @@ "node": ">=0.10.0" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -3879,6 +4130,15 @@ "get-intrinsic": "^1.1.3" } }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -5051,6 +5311,12 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, + "node_modules/boolify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", + "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", + "dev": true + }, "node_modules/bootstrap": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", @@ -5392,6 +5658,60 @@ "node": ">=0.10.0" } }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001477", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001477.tgz", @@ -5910,7 +6230,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "optional": true, + "devOptional": true, "engines": { "node": ">=4.0.0" } @@ -6988,6 +7308,33 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -7615,6 +7962,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-plugin-cypress": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.13.2.tgz", @@ -7627,6 +7986,27 @@ "eslint": ">= 3.2.1" } }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react": { "version": "7.32.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", @@ -8301,6 +8681,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -8865,6 +9251,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -9143,6 +9541,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/glogg": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", @@ -12270,6 +12697,12 @@ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.2.0.tgz", "integrity": "sha512-jdDTz4ZD5diub+/8u8mNbcLy90DiKt9DygicrhKZOliTMSAZttTl5l94TxsvBaNN5ou9JF6c1GupWgBhFpj00A==" }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -12450,6 +12883,84 @@ "node": ">=8" } }, + "node_modules/loglevel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-colored-level-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", + "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "loglevel": "^1.4.1" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/lolex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", @@ -12520,6 +13031,12 @@ "node": ">=0.10.0" } }, + "node_modules/make-plural": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.2.0.tgz", + "integrity": "sha512-WkdI+iaWaBCFM2wUXwos8Z7spg5Dt64Xe/VI6NpRaly21cDtD76N6S97K//UtzV0dHOiXX+E90TnszdXHG0aMg==", + "dev": true + }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -12528,6 +13045,18 @@ "node": ">=0.10.0" } }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -12922,6 +13451,12 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true + }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -14238,6 +14773,381 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-eslint-cli": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-7.1.0.tgz", + "integrity": "sha512-kMMvV7Mt6VqdJSb25aCkOA7HTIxy5mii2tzBb1vCSmzlIECOzTP2wRPIeAtBky6WdpfN0n1Zxa4E37Atp1IksA==", + "dev": true, + "dependencies": { + "@messageformat/core": "^3.0.1", + "@prettier/eslint": "npm:prettier-eslint@^15.0.1", + "arrify": "^2.0.1", + "boolify": "^1.0.1", + "camelcase-keys": "^7.0.2", + "chalk": "^4.1.2", + "common-tags": "^1.8.2", + "core-js": "^3.24.1", + "eslint": "^8.21.0", + "find-up": "^5.0.0", + "get-stdin": "^8.0.0", + "glob": "^7.2.3", + "ignore": "^5.2.0", + "indent-string": "^4.0.0", + "lodash.memoize": "^4.1.2", + "loglevel-colored-level-prefix": "^1.0.0", + "rxjs": "^7.5.6", + "yargs": "^13.1.1" + }, + "bin": { + "prettier-eslint": "dist/index.js" + }, + "engines": { + "node": ">=12.22" + }, + "peerDependencies": { + "prettier-eslint": "*" + }, + "peerDependenciesMeta": { + "prettier-eslint": { + "optional": true + } + } + }, + "node_modules/prettier-eslint-cli/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prettier-eslint-cli/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/prettier-eslint-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/prettier-eslint-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/prettier-eslint-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/core-js": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.0.tgz", + "integrity": "sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/prettier-eslint-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/prettier-eslint-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-eslint-cli/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-eslint-cli/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettier-eslint-cli/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-eslint-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/rxjs": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/prettier-eslint-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier-eslint-cli/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-eslint-cli/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-eslint-cli/node_modules/wrap-ansi/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/prettier-eslint-cli/node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/prettier-eslint-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/prettier-eslint-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/prettier-eslint-cli/node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -14250,6 +15160,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -15255,6 +16184,12 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, + "node_modules/require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", + "dev": true + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -15491,6 +16426,12 @@ } ] }, + "node_modules/safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "dev": true + }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -17315,6 +18256,21 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, "node_modules/tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -17405,6 +18361,19 @@ "dup": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/ua-parser-js": { "version": "0.7.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", @@ -17924,6 +18893,88 @@ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" }, + "node_modules/vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-eslint-parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -20621,6 +21672,50 @@ } } }, + "@messageformat/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.1.0.tgz", + "integrity": "sha512-UxAnjecnRG4u2iaggwIyylYPHmk5BTErJcKmWyAKTXqYgSW1bFLp4D7fIzuh6bk17Qfcmf3qtufdrstCB23nBA==", + "dev": true, + "requires": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.0.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "@messageformat/date-skeleton": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.0.1.tgz", + "integrity": "sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==", + "dev": true + }, + "@messageformat/number-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.1.0.tgz", + "integrity": "sha512-F0Io+GOSvFFxvp9Ze3L5kAoZ2NnOAT0Mr/jpGNd3fqo8A0t4NxNIAcCdggtl2B/gN2ErkIKSBVPrF7xcW1IGvA==", + "dev": true + }, + "@messageformat/parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz", + "integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==", + "dev": true, + "requires": { + "moo": "^0.5.1" + } + }, + "@messageformat/runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", + "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "dev": true, + "requires": { + "make-plural": "^7.0.0" + } + }, "@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -21077,6 +22172,28 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==" }, + "@prettier/eslint": { + "version": "npm:prettier-eslint@15.0.1", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-15.0.1.tgz", + "integrity": "sha512-mGOWVHixSvpZWARqSDXbdtTL54mMBxc5oQYQ6RAqy8jecuNJBgN3t9E5a81G66F8x8fsKNiR1HWaBV66MJDOpg==", + "dev": true, + "requires": { + "@types/eslint": "^8.4.2", + "@types/prettier": "^2.6.0", + "@typescript-eslint/parser": "^5.10.0", + "common-tags": "^1.4.0", + "dlv": "^1.1.0", + "eslint": "^8.7.0", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.0", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^2.5.1", + "pretty-format": "^23.0.1", + "require-relative": "^0.8.7", + "typescript": "^4.5.4", + "vue-eslint-parser": "^8.0.1" + } + }, "@restart/context": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", @@ -21179,6 +22296,22 @@ "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.2.tgz", "integrity": "sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==" }, + "@types/eslint": { + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -21223,6 +22356,12 @@ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -21325,6 +22464,93 @@ "@types/node": "*" } }, + "@typescript-eslint/parser": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", + "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" + } + }, + "@typescript-eslint/types": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.58.0", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -21802,6 +23028,12 @@ } } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -21832,6 +23064,12 @@ "get-intrinsic": "^1.1.3" } }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -22823,6 +24061,12 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, + "boolify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", + "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", + "dev": true + }, "bootstrap": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", @@ -23097,6 +24341,38 @@ "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", "dev": true }, + "camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "requires": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, "caniuse-lite": { "version": "1.0.30001477", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001477.tgz", @@ -23500,7 +24776,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "optional": true + "devOptional": true }, "commondir": { "version": "1.0.1", @@ -24421,6 +25697,29 @@ } } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -25034,6 +26333,13 @@ } } }, + "eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "dev": true, + "requires": {} + }, "eslint-plugin-cypress": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.13.2.tgz", @@ -25043,6 +26349,15 @@ "globals": "^11.12.0" } }, + "eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "eslint-plugin-react": { "version": "7.32.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", @@ -25466,6 +26781,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -25921,6 +27242,12 @@ "has-symbols": "^1.0.3" } }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -26139,6 +27466,28 @@ "define-properties": "^1.1.3" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "glogg": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", @@ -28614,6 +29963,12 @@ "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.2.0.tgz", "integrity": "sha512-jdDTz4ZD5diub+/8u8mNbcLy90DiKt9DygicrhKZOliTMSAZttTl5l94TxsvBaNN5ou9JF6c1GupWgBhFpj00A==" }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -28747,6 +30102,64 @@ } } }, + "loglevel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", + "dev": true + }, + "loglevel-colored-level-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", + "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "loglevel": "^1.4.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, "lolex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", @@ -28804,11 +30217,23 @@ "kind-of": "^6.0.2" } }, + "make-plural": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.2.0.tgz", + "integrity": "sha512-WkdI+iaWaBCFM2wUXwos8Z7spg5Dt64Xe/VI6NpRaly21cDtD76N6S97K//UtzV0dHOiXX+E90TnszdXHG0aMg==", + "dev": true + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -29131,6 +30556,12 @@ "minimist": "^1.2.6" } }, + "moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -30150,12 +31581,326 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==" }, + "prettier-eslint-cli": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-7.1.0.tgz", + "integrity": "sha512-kMMvV7Mt6VqdJSb25aCkOA7HTIxy5mii2tzBb1vCSmzlIECOzTP2wRPIeAtBky6WdpfN0n1Zxa4E37Atp1IksA==", + "dev": true, + "requires": { + "@messageformat/core": "^3.0.1", + "@prettier/eslint": "npm:prettier-eslint@^15.0.1", + "arrify": "^2.0.1", + "boolify": "^1.0.1", + "camelcase-keys": "^7.0.2", + "chalk": "^4.1.2", + "common-tags": "^1.8.2", + "core-js": "^3.24.1", + "eslint": "^8.21.0", + "find-up": "^5.0.0", + "get-stdin": "^8.0.0", + "glob": "^7.2.3", + "ignore": "^5.2.0", + "indent-string": "^4.0.0", + "lodash.memoize": "^4.1.2", + "loglevel-colored-level-prefix": "^1.0.0", + "rxjs": "^7.5.6", + "yargs": "^13.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "core-js": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.0.tgz", + "integrity": "sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "rxjs": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "dev": true + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "optional": true }, + "pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + } + } + }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -30965,6 +32710,12 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -31138,6 +32889,12 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "dev": true + }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -32580,6 +34337,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -32655,6 +34421,12 @@ "dup": "^1.0.0" } }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, "ua-parser-js": { "version": "0.7.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", @@ -33068,6 +34840,63 @@ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" }, + "vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "dependencies": { + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/package.json b/package.json index 5722e2bb02..f19b6c96d7 100644 --- a/package.json +++ b/package.json @@ -33,11 +33,15 @@ "bootstrap": "^4.6.1", "empty-module": "0.0.2", "eslint": "^8.10.0", + "eslint-config-prettier": "^8.8.0", "eslint-plugin-cypress": "^2.12.1", + "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.29.2", "fancy-log": "^1.3.3", "gulp": "^4.0.2", "plugin-error": "^1.0.1", + "prettier": "^2.8.7", + "prettier-eslint-cli": "^7.1.0", "sass": "^1.51.0", "sinon": "^1.17.6", "source-map-support": "^0.5.19", @@ -49,9 +53,9 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^5.15.4", - "@hms-dbmi-bgm/react-workflow-viz": "0.1.5", "@gmod/tabix": "^1.5.3", "@gmod/vcf": "^5.0.6", + "@hms-dbmi-bgm/react-workflow-viz": "0.1.5", "@hms-dbmi-bgm/shared-portal-components": "git+https://github.com/4dn-dcic/shared-portal-components#0.1.63", "auth0-lock": "^11.33.0", "d3": "^5.16.0", @@ -61,18 +65,18 @@ "form-serialize": "^0.7.2", "generic-filehandle": "^3.0.0", "higlass": "1.12.2", - "higlass-register": "^0.3.0", - "higlass-sequence": "0.4.2", - "higlass-transcripts": "0.3.8", - "higlass-text": "0.1.6", - "higlass-orthologs": "0.2.4", + "higlass-bigwig-datafetcher": "0.1.2", "higlass-clinvar": "0.2.5", - "higlass-pileup": "1.4.1", - "higlass-gnomad": "0.2.2-beta.1", - "higlass-general-vcf": "0.1.2-beta.1", "higlass-cohort": "0.3.3", - "higlass-bigwig-datafetcher": "0.1.2", + "higlass-general-vcf": "0.1.2-beta.1", + "higlass-gnomad": "0.2.2-beta.1", + "higlass-orthologs": "0.2.4", + "higlass-pileup": "1.4.1", + "higlass-register": "^0.3.0", + "higlass-sequence": "0.4.2", "higlass-sv": "1.0.4-beta.0", + "higlass-text": "0.1.6", + "higlass-transcripts": "0.3.8", "markdown-to-jsx": "^6.11.4", "memoize-one": "^5.1.1", "pagedjs": "^0.2.0", From 423595cd092af50fcd166874a4d01b42a54d2874 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 10:34:02 -0400 Subject: [PATCH 02/15] Add basic config --- .eslintrc.json | 19 ++++++++++++++----- .prettierrc.json | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 .prettierrc.json diff --git a/.eslintrc.json b/.eslintrc.json index d63be0fe1c..d1bdbcec2b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,6 +25,7 @@ "prefer-const" : "error", "prefer-destructuring" : "warn", "prefer-spread" : "error", + "prettier/prettier": "error", "react/button-has-type" : "error", "react/destructuring-assignment" : ["warn", "always"], "react/display-name" : 0, @@ -57,19 +58,22 @@ "parser" : "@babel/eslint-parser", "extends": [ "eslint:recommended", - "plugin:react/recommended" + "plugin:react/recommended", + "prettier" ], "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true, - "classes" : true + "classes" : true, + "modules": true } }, "plugins": [ "react", - "cypress" + "cypress", + "prettier" ], "overrides": [ { @@ -80,5 +84,10 @@ "react/react-in-jsx-scope" : 0 } } - ] -} + ], + "settings": { + "react": { + "version": "detect" + } + } +} \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..655dacf460 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "trailingComma": "es5", + "semi": false, + "singleQuote": true +} \ No newline at end of file From e9782702d04f448769bfa8d161d89bc01626eaf2 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 10:34:11 -0400 Subject: [PATCH 03/15] Ignore some stuff --- .prettierignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..85a10be4d0 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +# Ignore deps & build files +/node_modules/ +/src/encoded/static/build/ \ No newline at end of file From dc57c04fd102176adf6951fd0a0aec7a6c5ad853 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 13:49:44 -0400 Subject: [PATCH 04/15] Fix eslint rules + adjust prettier rules config --- .eslintrc.json | 27 +++++++++------------------ .prettierrc.json | 10 +++++++--- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d1bdbcec2b..98254f0e40 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,42 +1,34 @@ { - "rules": { + "rules": { "array-callback-return" : "error", - "arrow-body-style" : ["error", "as-needed", { "requireReturnForObjectLiteral": true }], - "arrow-parens" : ["error", "always"], - "generator-star-spacing" : "error", - "indent": [2, 4, {"SwitchCase": 1}], - "getter-return" :"error", - "jsx-quotes" : ["error", "prefer-double"], - "linebreak-style": [2, "unix"], "new-cap" : "error", "no-await-in-loop": "error", "no-console": 0, "no-empty": 0, "no-global-assign" : "error", "no-invalid-this" : "error", - "no-tabs" : "error", - "no-trailing-spaces" : "error", "no-undef": 0, "no-unused-vars": ["warn", { "args" : "none" }], "no-useless-concat": "error", "no-useless-constructor": "error", - "no-whitespace-before-property" : "error", - "object-curly-spacing" : ["error", "always"], "prefer-const" : "error", "prefer-destructuring" : "warn", "prefer-spread" : "error", - "prettier/prettier": "error", + "prettier/prettier": + ["error", { + "endOfLine": "lf", + "tabs": true, + "tabWidth": 4, + "singleQuote": true, + "jsxSingleQuote": false + }], "react/button-has-type" : "error", "react/destructuring-assignment" : ["warn", "always"], "react/display-name" : 0, - "react/jsx-closing-tag-location" : "error", - "react/jsx-indent" : "error", - "react/jsx-indent-props" : "error", "react/jsx-key" : "error", "react/jsx-no-duplicate-props" : "error", "react/jsx-no-bind" : ["warn", { "ignoreDOMComponents" : true }], "react/jsx-pascal-case" : ["error", { "allowAllCaps" : true }], - "react/jsx-props-no-multi-spaces" : "error", "react/no-access-state-in-setstate" : "error", "react/no-direct-mutation-state" : "error", "react/no-children-prop" : 1, @@ -46,7 +38,6 @@ "react/no-this-in-sfc" : "error", "react/no-typos": "error", "react/prop-types": [1, { "skipUndeclared" : true }], - "semi": ["error", "always"], "valid-typeof" : ["error", { "requireStringLiterals": true }] }, "env": { diff --git a/.prettierrc.json b/.prettierrc.json index 655dacf460..e417c028c6 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,5 +1,9 @@ { - "trailingComma": "es5", - "semi": false, - "singleQuote": true + "bracketSameLine": true, + "endOfLine": "lf", + "singleQuote": true, + "jsxSingleQuote": false, + "tabs": true, + "tabWidth": 4, + "trailingComma": "es5" } \ No newline at end of file From 8a16dba7bc0923972d395f827d30c9c17bbe34ce Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 13:49:58 -0400 Subject: [PATCH 05/15] Ignore a few jsx files that aren't formatting well --- .prettierignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 85a10be4d0..f5689ff61f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,9 @@ # Ignore deps & build files /node_modules/ -/src/encoded/static/build/ \ No newline at end of file +/src/encoded/static/build/ + +# Ignore jsx static sections (overzealous about adding unnecessary semicolons) +/docs/public/help/ + +# Also ignore that help doc for embedded search tables +/src/encoded/static/data/embedded-search-table-demo.jsx \ No newline at end of file From 9897f770ac664cccd208399ce2f80d44c15b172f Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 13:50:51 -0400 Subject: [PATCH 06/15] Add a npm script to format all js/jsx w/prettier --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f19b6c96d7..2c28e9edef 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "cypress:open": "node_modules/.bin/cypress open --project './deploy/post_deploy_testing' --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret", "cypress:open-local": "node_modules/.bin/cypress open --project './deploy/post_deploy_testing' --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret --config baseUrl=http://localhost:8000", "cypress:test": "node_modules/.bin/cypress run --project './deploy/post_deploy_testing' --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret --config videoRecording=false", - "cypress:test-recorded": "node_modules/.bin/cypress run --project './deploy/post_deploy_testing' --record --key $CYPRESS_KEY --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret" + "cypress:test-recorded": "node_modules/.bin/cypress run --project './deploy/post_deploy_testing' --record --key $CYPRESS_KEY --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret", + "format": "prettier-eslint --write \"{,!(node_modules)/**/}*.{js,jsx}\"" }, "author": "", "license": "MIT", From acf45df2911756570779c379d29a0a5c307571e5 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 13:51:28 -0400 Subject: [PATCH 07/15] Add a script to lint JS & JSX files w/eslint alone --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 2c28e9edef..226f52da4a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "cypress:open-local": "node_modules/.bin/cypress open --project './deploy/post_deploy_testing' --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret --config baseUrl=http://localhost:8000", "cypress:test": "node_modules/.bin/cypress run --project './deploy/post_deploy_testing' --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret --config videoRecording=false", "cypress:test-recorded": "node_modules/.bin/cypress run --project './deploy/post_deploy_testing' --record --key $CYPRESS_KEY --env Auth0Client=$Auth0Client,Auth0Secret=$Auth0Secret", - "format": "prettier-eslint --write \"{,!(node_modules)/**/}*.{js,jsx}\"" + "format": "prettier-eslint --write \"{,!(node_modules)/**/}*.{js,jsx}\"", + "lint": "eslint src --ext '.js,.jsx'", + "lint:fix": "npm run lint -- --fix" }, "author": "", "license": "MIT", From 825b87284c8031f9148e96376bb46d4dee96d0b5 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:16:07 -0400 Subject: [PATCH 08/15] Remove prettier options from .eslintrc --- .eslintrc.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 98254f0e40..67529e84ba 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,14 +14,9 @@ "prefer-const" : "error", "prefer-destructuring" : "warn", "prefer-spread" : "error", - "prettier/prettier": - ["error", { - "endOfLine": "lf", - "tabs": true, - "tabWidth": 4, - "singleQuote": true, - "jsxSingleQuote": false - }], + "prettier/prettier": "error", + // Do not add rules options for config here; it will interfere with editor extensions + // See: https://github.com/prettier/eslint-plugin-prettier#options "react/button-has-type" : "error", "react/destructuring-assignment" : ["warn", "always"], "react/display-name" : 0, From 2d102992666ba9ef93e5f4911fdef461a567c2e1 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:16:33 -0400 Subject: [PATCH 09/15] Typo --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 67529e84ba..2863d25806 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,7 +15,7 @@ "prefer-destructuring" : "warn", "prefer-spread" : "error", "prettier/prettier": "error", - // Do not add rules options for config here; it will interfere with editor extensions + // Do not add rules options for prettier config here; it will interfere with editor extensions // See: https://github.com/prettier/eslint-plugin-prettier#options "react/button-has-type" : "error", "react/destructuring-assignment" : ["warn", "always"], From a7d62686418d7ab5cb9a482d81b5ac8c808a6609 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:20:37 -0400 Subject: [PATCH 10/15] Prune from overrides --- .eslintrc.json | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2863d25806..c5e30fd0a3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -62,14 +62,17 @@ "prettier" ], "overrides": [ - { - "files" : ["./src/encoded/static/data/*.jsx"], - "rules" : { - "react/jsx-no-undef" : 0, - "semi" : 0, - "react/react-in-jsx-scope" : 0 - } - } + // Removed these in v1 prettier update due to incompatibility; + // instead not auto-formatting static sections. Keeping for reference, in case + // parsing these files becomes necessary/more options available in future. + // { + // "files" : ["./src/encoded/static/data/*.jsx"], + // "rules" : { + // "react/jsx-no-undef" : 0, + // "semi" : 0, + // "react/react-in-jsx-scope" : 0 + // } + // } ], "settings": { "react": { From a537882c73c54dc54887d6ccf927767dc04c80ab Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:34:02 -0400 Subject: [PATCH 11/15] Annnd actually revert changes to overrides --- .eslintrc.json | 21 ++++++++++----------- .prettierignore | 5 +---- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index c5e30fd0a3..3376d364b5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -62,17 +62,16 @@ "prettier" ], "overrides": [ - // Removed these in v1 prettier update due to incompatibility; - // instead not auto-formatting static sections. Keeping for reference, in case - // parsing these files becomes necessary/more options available in future. - // { - // "files" : ["./src/encoded/static/data/*.jsx"], - // "rules" : { - // "react/jsx-no-undef" : 0, - // "semi" : 0, - // "react/react-in-jsx-scope" : 0 - // } - // } + // Prettier isn't great at formatting these files, so we're skipping + // them there; doing this here to prevent annoying squigglies + { + "files" : ["./src/encoded/static/data/*.jsx"], + "rules" : { + "react/jsx-no-undef" : 0, + "semi" : 0, + "react/react-in-jsx-scope" : 0 + } + } ], "settings": { "react": { diff --git a/.prettierignore b/.prettierignore index f5689ff61f..f7b84d058a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,7 +3,4 @@ /src/encoded/static/build/ # Ignore jsx static sections (overzealous about adding unnecessary semicolons) -/docs/public/help/ - -# Also ignore that help doc for embedded search tables -/src/encoded/static/data/embedded-search-table-demo.jsx \ No newline at end of file +/docs/public/help/ \ No newline at end of file From a358933c189db0a4812fc0d4e211a0bb49313bf5 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:35:17 -0400 Subject: [PATCH 12/15] Compromise --- .prettierignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index f7b84d058a..f5689ff61f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,7 @@ /src/encoded/static/build/ # Ignore jsx static sections (overzealous about adding unnecessary semicolons) -/docs/public/help/ \ No newline at end of file +/docs/public/help/ + +# Also ignore that help doc for embedded search tables +/src/encoded/static/data/embedded-search-table-demo.jsx \ No newline at end of file From 86602829fcfadd1485f3657bf5e6011346279733 Mon Sep 17 00:00:00 2001 From: Bianca Morris Date: Tue, 11 Apr 2023 14:36:13 -0400 Subject: [PATCH 13/15] Run bulk format w/Prettier --- babel.config.js | 21 +- deploy/post_deploy_testing/cypress.config.js | 26 +- .../cypress/e2e/00_homepage.cy.js | 16 +- .../cypress/e2e/01b_static_content.cy.js | 336 ++- .../cypress/e2e/02_users_permissions.cy.js | 245 +- .../cypress/e2e/04a_search_views_local.cy.js | 55 +- .../cypress/e2e/04b_search_views.cy.js | 32 +- .../cypress/e2e/05a_case_view_basic.cy.js | 147 +- .../cypress/e2e/05b_case_view_fsui.cy.js | 161 +- .../cypress/plugins/index.js | 6 +- .../cypress/support/commands.js | 399 +-- .../cypress/support/e2e.js | 4 +- .../cypress/support/index.js | 3 +- gulpfile.js | 240 +- src/encoded/static/browser.js | 54 +- src/encoded/static/components/Footer.js | 16 +- .../static/components/PageTitleSection.js | 388 ++- src/encoded/static/components/app.js | 1438 ++++++---- .../browse/AboveTableControlsBaseCGAP.js | 18 +- .../components/browse/CaseDetailPane.js | 1201 ++++++--- .../static/components/browse/SearchBar.js | 169 +- .../static/components/browse/SearchView.js | 181 +- .../components/browse/columnExtensionMap.js | 869 +++--- .../browse/variantSampleColumnExtensionMap.js | 943 ++++--- .../components/forms/CGAPSubmissionView.js | 17 +- .../components/forms/ExcelSubmissionView.js | 1186 ++++++--- .../static/components/forms/IconCheckbox.js | 35 +- .../components/forms/UserRegistrationForm.js | 579 ++-- .../components/forms/attachment-input.js | 98 +- src/encoded/static/components/globals.js | 42 +- src/encoded/static/components/index.js | 114 +- .../CaseReviewTab/CaseReviewController.js | 369 ++- .../CaseReviewTab/ReportGenerationView.js | 677 +++-- .../CaseReviewTab/SaveFindingsButton.js | 118 +- .../CaseView/CaseReviewTab/index.js | 703 +++-- .../item-pages/CaseView/CaseStats.js | 218 +- .../item-pages/CaseView/CaseSummaryTable.js | 746 +++--- ...aseViewEmbeddedVariantSampleSearchTable.js | 565 ++-- .../CaseView/CurrentFamilyController.js | 171 +- .../item-pages/CaseView/FilteringTab.js | 578 ++-- .../AddToVariantSampleListButton.js | 292 +- .../ExportSearchSpreadsheetButton.js | 99 +- .../FilteringTableFilterSetUI/FieldBlocks.js | 288 +- .../FilteringTableFilterSetUI/FilterBlock.js | 310 ++- .../FilterSetController.js | 556 ++-- .../PresetFilterSetSelectionUI.js | 786 ++++-- .../SaveFilterSetButton.js | 331 ++- .../SaveFilterSetPresetButton.js | 466 ++-- .../FilteringTableFilterSetUI/index.js | 784 ++++-- .../item-pages/CaseView/InterpretationTab.js | 406 ++- .../item-pages/CaseView/PedigreeTabView.js | 384 ++- .../CaseView/TechnicalReviewColumn.js | 1614 ++++++++---- .../CaseView/VariantSampleListController.js | 342 +-- .../CaseView/VariantSampleSelection.js | 2342 +++++++++++------ .../item-pages/CaseView/family-parsing.js | 178 +- .../components/item-pages/CaseView/index.js | 1427 ++++++---- .../variant-sample-selection-panels.js | 962 ++++--- .../components/item-pages/DefaultItemView.js | 553 ++-- .../components/item-pages/DocumentView.js | 42 +- .../components/item-pages/FallbackView.js | 4 +- .../item-pages/FileProcessedView.js | 68 +- .../components/item-pages/HealthView.js | 773 ++++-- .../components/item-pages/IndividualView.js | 53 +- .../item-pages/MetaWorkflowRunView.js | 519 ++-- .../item-pages/ReportView/PrintPreviewPane.js | 137 +- .../ReportView/ReportPrintPreviewPane.js | 423 ++- .../ReportView/ReportPrintPreviewTab.js | 64 +- .../components/item-pages/ReportView/index.js | 31 +- .../ReportView/project-settings-draft.js | 240 +- .../components/item-pages/SampleView.js | 64 +- .../components/item-pages/SchemaView.js | 64 +- .../item-pages/StaticSectionView.js | 42 +- .../StructuralVariantSampleOverview.js | 421 ++- .../StructuralVariantSampleView/SvBrowser.js | 463 ++-- .../SvBrowserHiglass.js | 58 +- .../SvBrowserTabBody.js | 15 +- .../SvDetailPanes.js | 268 +- .../SvGeneTabBody.js | 299 ++- .../SvSampleTabBody.js | 334 ++- .../SvVariantTabBody.js | 122 +- .../StructuralVariantSampleView/index.js | 160 +- .../static/components/item-pages/UserView.js | 777 +++--- .../AnnotationBrowserTabBody.js | 75 +- .../VariantSampleView/AnnotationSections.js | 1203 +++++---- .../BamFileBrowserTabBody.js | 68 +- .../VariantSampleView/GeneTabBody.js | 80 +- .../InterpretationSpaceController.js | 1556 ++++++++--- .../VariantSampleView/SampleTabBody.js | 470 ++-- .../VariantSampleInfoHeader.js | 297 ++- .../VariantSampleOverview.js | 748 ++++-- .../VariantSampleView/VariantTabBody.js | 669 +++-- .../item-pages/VariantSampleView/index.js | 150 +- .../item-pages/components/AutoGrowTextArea.js | 118 +- .../item-pages/components/BadgesTabView.js | 594 +++-- .../CohortStatisticalAnalysisTable.js | 896 ++++--- .../CollapsibleItemViewButtonToolbar.js | 87 +- .../components/EmbeddedItemSearchTable.js | 186 +- .../item-pages/components/FeedbackButton.js | 35 +- .../components/FullHeightCalculator.js | 34 +- .../HiGlass/EmbeddedCohortBrowser.js | 1112 ++++---- .../components/HiGlass/GeneSearchBox.js | 380 +-- .../HiGlass/HiGlassAjaxLoadContainer.js | 471 ++-- .../HiGlass/HiGlassPlainContainer.js | 354 ++- .../components/HiGlass/HiglassTabView.js | 41 +- .../HiGlass/higlass-dependencies.js | 2 +- .../item-pages/components/HiGlass/index.js | 5 +- .../components/ItemFileAttachment.js | 146 +- .../components/OverviewHeadingContainer.js | 159 +- .../PedigreeDetailPane/ClinicianNotes.js | 115 +- .../PedigreeDetailPane/DiseasesLegend.js | 32 +- .../components/PedigreeDetailPane/Files.js | 142 +- .../PedigreeDetailPane/IndividualBody.js | 219 +- .../components/PedigreeDetailPane/index.js | 95 +- .../components/PedigreeTabViewBody.js | 255 +- .../item-pages/components/QuickPopover.js | 58 +- .../item-pages/components/TabView.js | 396 +-- .../item-pages/components/Workflow/Legend.js | 74 +- .../ProvenanceGraphOptionsStateController.js | 108 +- .../ProvenanceGraphStepsFetchingController.js | 142 +- .../Workflow/ProvenanceGraphTabView.js | 162 +- .../components/Workflow/WorkflowDetailPane.js | 93 +- .../Workflow/WorkflowGraphSectionControls.js | 145 +- .../Workflow/WorkflowNodeElement.js | 489 ++-- .../components/child-window-controls.js | 66 +- .../components/pedigree-viz-loader.js | 16 +- .../components/utils/chrom-utils.js | 296 +-- ...cohort-statistical-analysis-table-utils.js | 102 +- .../components/navigation/NavigationBar.js | 75 +- .../navigation/components/AccountNav.js | 175 +- .../BigDropdown/BigDropdownContainer.js | 93 +- .../BigDropdown/BigDropdownGroupController.js | 108 +- .../BigDropdownIntroductionWrapper.js | 30 +- .../BigDropdown/BigDropdownNavItem.js | 138 +- .../BigDropdown/BigDropdownPageLoader.js | 66 +- .../BigDropdown/BigDropdownPageTreeMenu.js | 201 +- .../components/BigDropdown/index.js | 5 +- .../navigation/components/CollapsedNav.js | 107 +- .../navigation/components/LoginNavItem.js | 83 +- .../navigation/components/TestWarning.js | 26 +- .../components/UserRegistrationModal.js | 97 +- .../components/static-pages/DirectoryPage.js | 134 +- .../components/static-pages/ErrorPage.js | 73 +- .../static-pages/HomePage/GuestHomeView.js | 111 +- .../static-pages/HomePage/UserDashboard.js | 368 ++- .../components/static-pages/HomePage/index.js | 39 +- .../components/static-pages/StaticPage.js | 116 +- .../components/BasicUserContentBody.js | 66 +- .../components/UserContentBodyList.js | 85 +- .../components/YoutubeVideoEmbed.js | 118 +- .../static-pages/components/index.js | 5 +- .../static-pages/placeholders/index.js | 72 +- .../components/util/PatchItemsProgress.js | 191 +- src/encoded/static/components/util/Schemas.js | 273 +- src/encoded/static/components/util/acmg.js | 421 ++- src/encoded/static/components/util/file.js | 9 +- src/encoded/static/components/util/hooks.js | 4 +- src/encoded/static/components/util/index.js | 3 +- src/encoded/static/components/util/layout.js | 27 +- .../static/components/util/navigate.js | 9 +- .../components/util/package-lock-loader.js | 13 +- src/encoded/static/components/util/seo.js | 290 +- .../static/components/util/typedefs.js | 19 - src/encoded/static/components/viz/CGAPLogo.js | 215 +- .../PedigreeViz/DefaultDetailPaneComponent.js | 139 +- .../components/viz/PedigreeViz/EdgesLayer.js | 89 +- .../viz/PedigreeViz/GraphTransformer.js | 91 +- .../PedigreeViz/IndividualNodeShapeLayer.js | 493 ++-- .../viz/PedigreeViz/IndividualsLayer.js | 252 +- .../PedigreeViz/RelationshipNodeShapeLayer.js | 117 +- .../viz/PedigreeViz/ScaleController.js | 268 +- .../viz/PedigreeViz/SelectedNodeController.js | 127 +- .../viz/PedigreeViz/data-utilities.js | 389 +-- .../viz/PedigreeViz/default-props.js | 181 +- .../components/viz/PedigreeViz/index.js | 610 +++-- .../PedigreeViz/layout-utilities-drawing.js | 916 ++++--- .../layout-utilities-ordering-deprecated.js | 399 +-- .../viz/PedigreeViz/layout-utilities.js | 1039 +++++--- .../components/viz/PedigreeViz/prop-types.js | 65 +- .../static/components/viz/SlideInPane.js | 50 +- src/encoded/static/libs/jsonScriptEscape.js | 6 +- src/encoded/static/libs/react-middleware.js | 47 +- src/encoded/static/server.js | 12 +- src/encoded/static/store.js | 31 +- webpack.config.js | 153 +- 184 files changed, 33722 insertions(+), 19303 deletions(-) diff --git a/babel.config.js b/babel.config.js index 9418e4ffb6..d9260b526d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,19 +1,18 @@ - -module.exports = function(api){ +module.exports = function (api) { api.cache(true); return { - "presets" : [ + presets: [ // We don't need to convert import/export statements. // @see https://stackoverflow.com/questions/63563485/how-can-i-preserve-dynamic-import-statements-with-babel-preset-env - [ "@babel/preset-env", { "modules": false } ], - "@babel/preset-react", + ['@babel/preset-env', { modules: false }], + '@babel/preset-react', ], - "plugins": [ - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-proposal-object-rest-spread", - "@babel/plugin-proposal-class-properties", - "babel-plugin-minify-dead-code-elimination" + plugins: [ + '@babel/plugin-syntax-dynamic-import', + '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-proposal-class-properties', + 'babel-plugin-minify-dead-code-elimination', ], - "comments": true + comments: true, }; }; diff --git a/deploy/post_deploy_testing/cypress.config.js b/deploy/post_deploy_testing/cypress.config.js index 9ccc9b0901..ca768881c7 100644 --- a/deploy/post_deploy_testing/cypress.config.js +++ b/deploy/post_deploy_testing/cypress.config.js @@ -1,17 +1,17 @@ -const { defineConfig } = require("cypress"); +const { defineConfig } = require('cypress'); module.exports = defineConfig({ - projectId: "9hf9k3", - defaultCommandTimeout : 60000, - pageLoadTimeout : 120000, - requestTimeout : 40000, - responseTimeout : 120000, - blockHosts: "www.google-analytics.com", + projectId: '9hf9k3', + defaultCommandTimeout: 60000, + pageLoadTimeout: 120000, + requestTimeout: 40000, + responseTimeout: 120000, + blockHosts: 'www.google-analytics.com', e2e: { - baseUrl: "https://cgap-mgb.hms.harvard.edu/", - specPattern: "./cypress/e2e/*.cy.js", - setupNodeEvents(on, config) { - // implement node event listeners here - } - } + baseUrl: 'https://cgap-mgb.hms.harvard.edu/', + specPattern: './cypress/e2e/*.cy.js', + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, }); diff --git a/deploy/post_deploy_testing/cypress/e2e/00_homepage.cy.js b/deploy/post_deploy_testing/cypress/e2e/00_homepage.cy.js index f7bd64bb71..9c558d2786 100644 --- a/deploy/post_deploy_testing/cypress/e2e/00_homepage.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/00_homepage.cy.js @@ -1,14 +1,14 @@ import { cypressVisitHeaders } from './../support'; describe('Home Page', function () { - it('Has correct title', function () { - - cy.visit('/', { headers: cypressVisitHeaders }).end() - .title().should('include', 'Computational Genome Analysis Platform').end() - .get('#top-nav .navbar-title').should('have.text', 'CGAP').end(); - + cy.visit('/', { headers: cypressVisitHeaders }) + .end() + .title() + .should('include', 'Computational Genome Analysis Platform') + .end() + .get('#top-nav .navbar-title') + .should('have.text', 'CGAP') + .end(); }); - }); - diff --git a/deploy/post_deploy_testing/cypress/e2e/01b_static_content.cy.js b/deploy/post_deploy_testing/cypress/e2e/01b_static_content.cy.js index 1a3ea66ff5..dd81e0736e 100644 --- a/deploy/post_deploy_testing/cypress/e2e/01b_static_content.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/01b_static_content.cy.js @@ -1,162 +1,236 @@ import { cypressVisitHeaders } from './../support'; - describe.skip('Static Page & Content Tests', function () { - - before(function(){ + before(function () { cy.visit('/', { headers: cypressVisitHeaders }); }); - - it('Click & visit each page from menu, ensure ToC exists somewhere, ensure ToC works.', function(){ - - cy.on('uncaught:exception', function(err, runnable){ - - expect(err.message).to.include("return response;"); + it('Click & visit each page from menu, ensure ToC exists somewhere, ensure ToC works.', function () { + cy.on('uncaught:exception', function (err, runnable) { + expect(err.message).to.include('return response;'); Cypress.log({ - 'name' : "Negligible JSON err.", - 'message' : "Hit error re: non-serializable function; fixed in subseq. deploys." + name: 'Negligible JSON err.', + message: + 'Hit error re: non-serializable function; fixed in subseq. deploys.', }); return false; }); // Wait until help menu has loaded via AJAX and has 'span' child w/ caret. - cy.get('#help-menu-item').should('have.descendants', 'span').click().wait(500).then(()=>{ - cy.get('div.big-dropdown-menu div.level-1-title-container a, div.big-dropdown-menu a.level-2-title').then((listItems)=>{ - console.log(listItems); - - expect(listItems).to.have.length.above(2); // At least 3 help pages in dropdown. - var allLinkElementIDs = Cypress._.map(listItems, function(liEl){ - return Cypress.$(liEl).attr('id'); - }); - - cy.get('#page-title-container span.title').should('have.text', '4D Nucleome Data Portal').then((title)=>{ - - let prevTitle = title.text(); - let count = 0; - let haveWeSeenPageWithTableOfContents = false; - - function doVisit(listItem){ - - function finish(titleText){ - count++; - Cypress.log({ - 'name' : "Help Page " + count + '/' + listItems.length, - 'message' : 'Visited page with title "' + titleText + '".' - }); - if (count < listItems.length){ - cy.get('#help-menu-item').click().wait(500).then(()=>{ - cy.get('div.big-dropdown-menu #' + allLinkElementIDs[count]).click().wait(300).then((nextListItem)=>{ - doVisit(nextListItem); - }); - }); - } + cy.get('#help-menu-item') + .should('have.descendants', 'span') + .click() + .wait(500) + .then(() => { + cy.get( + 'div.big-dropdown-menu div.level-1-title-container a, div.big-dropdown-menu a.level-2-title' + ).then((listItems) => { + console.log(listItems); + + expect(listItems).to.have.length.above(2); // At least 3 help pages in dropdown. + var allLinkElementIDs = Cypress._.map( + listItems, + function (liEl) { + return Cypress.$(liEl).attr('id'); } - - cy.wait(300).get('#page-title-container span.title').should('not.have.text', prevTitle).then((t)=>{ - var titleText = t.text(); - expect(titleText).to.have.length.above(0); - cy.title().should('equal', titleText + ' – 4DN Data Portal').end(); // Ensure ...TITLE... matches. - prevTitle = titleText; - - if (!haveWeSeenPageWithTableOfContents) { - cy.window().then((w)=>{ - if (w.document.querySelectorAll('div.table-of-contents li.table-content-entry a').length > 0){ - haveWeSeenPageWithTableOfContents = true; - const origScrollTop = w.scrollY; - cy.wrap(w).scrollTo('top').end().get('div.table-of-contents li.table-content-entry a').last().click({ force: true }).end().wait(1500).then(()=>{ - expect(w.scrollY).to.not.equal(origScrollTop); - finish(titleText); - }); - } else { - finish(titleText); + ); + + cy.get('#page-title-container span.title') + .should('have.text', '4D Nucleome Data Portal') + .then((title) => { + let prevTitle = title.text(); + let count = 0; + let haveWeSeenPageWithTableOfContents = false; + + function doVisit(listItem) { + function finish(titleText) { + count++; + Cypress.log({ + name: + 'Help Page ' + + count + + '/' + + listItems.length, + message: + 'Visited page with title "' + + titleText + + '".', + }); + if (count < listItems.length) { + cy.get('#help-menu-item') + .click() + .wait(500) + .then(() => { + cy.get( + 'div.big-dropdown-menu #' + + allLinkElementIDs[count] + ) + .click() + .wait(300) + .then((nextListItem) => { + doVisit(nextListItem); + }); + }); } - }); - - } else { - finish(titleText); + } + + cy.wait(300) + .get('#page-title-container span.title') + .should('not.have.text', prevTitle) + .then((t) => { + var titleText = t.text(); + expect(titleText).to.have.length.above( + 0 + ); + cy.title() + .should( + 'equal', + titleText + ' – 4DN Data Portal' + ) + .end(); // Ensure ...TITLE... matches. + prevTitle = titleText; + + if ( + !haveWeSeenPageWithTableOfContents + ) { + cy.window().then((w) => { + if ( + w.document.querySelectorAll( + 'div.table-of-contents li.table-content-entry a' + ).length > 0 + ) { + haveWeSeenPageWithTableOfContents = true; + const origScrollTop = + w.scrollY; + cy.wrap(w) + .scrollTo('top') + .end() + .get( + 'div.table-of-contents li.table-content-entry a' + ) + .last() + .click({ force: true }) + .end() + .wait(1500) + .then(() => { + expect( + w.scrollY + ).to.not.equal( + origScrollTop + ); + finish(titleText); + }); + } else { + finish(titleText); + } + }); + } else { + finish(titleText); + } + }); } - + listItems[0].click(); + doVisit(listItems[count]); }); - } - listItems[0].click(); - doVisit(listItems[count]); - }); }); - }); - }); + it('Every help page has links which return success status codes - SAMPLING', function () { + cy.get('#help-menu-item') + .click() + .then(() => { + // Get all links to _level 2_ static pages. Exclude directory pages for now. Do directory pages in later test. + cy.get('.big-dropdown-menu.is-open a.level-2-title').then( + (listItems) => { + console.log(listItems); + const listItemsTotalCount = listItems.length; + + expect(listItemsTotalCount).to.be.above(2); // At least 3 help pages in dropdown. + + // To avoid running on every single page x multiple network requests, lets create a random + // sampling of 5 list item indices to visit. + var itemIndicesToVisit = Cypress._.sampleSize( + Cypress._.range(listItemsTotalCount), + 5 + ); + + let prevTitle = null; + let count = 0; + + function doVisit() { + function finish(titleText) { + count++; + Cypress.log({ + name: + 'Help Page ' + + count + + '/5/' + + listItemsTotalCount, + message: + 'Visited page with title "' + + titleText + + '".', + }); - it('Every help page has links which return success status codes - SAMPLING', function(){ - - cy.get('#help-menu-item').click().then(()=>{ - - // Get all links to _level 2_ static pages. Exclude directory pages for now. Do directory pages in later test. - cy.get('.big-dropdown-menu.is-open a.level-2-title').then((listItems)=>{ - - console.log(listItems); - const listItemsTotalCount = listItems.length; - - expect(listItemsTotalCount).to.be.above(2); // At least 3 help pages in dropdown. - - // To avoid running on every single page x multiple network requests, lets create a random - // sampling of 5 list item indices to visit. - var itemIndicesToVisit = Cypress._.sampleSize(Cypress._.range(listItemsTotalCount), 5); - - let prevTitle = null; - let count = 0; - - function doVisit(){ - - function finish(titleText){ - count++; - Cypress.log({ - 'name' : "Help Page " + count + '/5/' + listItemsTotalCount, - 'message' : 'Visited page with title "' + titleText + '".' - }); - - if (itemIndicesToVisit.length > 0){ - var nextIndexToVisit = itemIndicesToVisit.shift(); - cy.get('#help-menu-item').click().wait(100).then(()=>{ - cy.get('.big-dropdown-menu.is-open a.level-2-title').eq(nextIndexToVisit).click().then(doVisit); - }); + if (itemIndicesToVisit.length > 0) { + var nextIndexToVisit = + itemIndicesToVisit.shift(); + cy.get('#help-menu-item') + .click() + .wait(100) + .then(() => { + cy.get( + '.big-dropdown-menu.is-open a.level-2-title' + ) + .eq(nextIndexToVisit) + .click() + .then(doVisit); + }); + } + } + cy.wait(100) + .get('#page-title-container span.title') + .should('not.have.text', prevTitle) + .then((t) => { + var titleText = t.text(); + expect(titleText).to.have.length.above(0); + prevTitle = titleText; + + cy.get( + '.help-entry.static-section-entry a:not([href^="#"]):not([href^="mailto:"]):not([href*=".gov"])' + ) + .each(($linkElem) => { + const linkHref = + $linkElem.attr('href'); + console.log($linkElem.attr('href')); + return cy.request({ + url: linkHref, + method: 'GET', + headers: { + 'Content-Type': + 'application/json; charset=UTF-8', + }, + followRedirect: true, + }); + }) + .then(() => { + finish(titleText); + }); + }); } - } - cy.wait(100).get('#page-title-container span.title').should('not.have.text', prevTitle).then((t)=>{ - var titleText = t.text(); - expect(titleText).to.have.length.above(0); - prevTitle = titleText; - - cy.get('.help-entry.static-section-entry a:not([href^="#"]):not([href^="mailto:"]):not([href*=".gov"])').each(($linkElem)=>{ - const linkHref = $linkElem.attr('href'); - console.log($linkElem.attr('href')); - return cy.request({ - 'url' : linkHref, - 'method' : 'GET', - 'headers' : { 'Content-Type' : "application/json; charset=UTF-8" }, - 'followRedirect' : true - }); - }).then(()=>{ - finish(titleText); - }); - - }); - } - - const firstItemIndexToVisit = itemIndicesToVisit.shift(); - listItems[firstItemIndexToVisit].click(); - doVisit(); + const firstItemIndexToVisit = + itemIndicesToVisit.shift(); + listItems[firstItemIndexToVisit].click(); + doVisit(); + } + ); }); - }); - }); // TODO: // test which visits directory page(s) maybe. - }); diff --git a/deploy/post_deploy_testing/cypress/e2e/02_users_permissions.cy.js b/deploy/post_deploy_testing/cypress/e2e/02_users_permissions.cy.js index eace4b6fa5..0309b7bb27 100644 --- a/deploy/post_deploy_testing/cypress/e2e/02_users_permissions.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/02_users_permissions.cy.js @@ -1,12 +1,8 @@ import { cypressVisitHeaders } from './../support'; - describe.skip('Impersonate user JWT, navigate to profile, edit last_name to & back.', function () { - - context('Frontend Test User Profile', function () { - - beforeEach(function(){ + beforeEach(function () { cy.visit('/', { headers: cypressVisitHeaders }); }); @@ -17,68 +13,191 @@ describe.skip('Impersonate user JWT, navigate to profile, edit last_name to & ba }); */ - it('Ensure logged in, visit profile page, add & remove access key', function(){ - - cy.login4DN({ 'email' : 'ud4dntest@gmail.com', 'useEnvToken' : false }).end() - .get('ul.navbar-acct li.user-account-item').should('have.class', 'is-logged-in').then((accountListItem)=>{ - expect(accountListItem.children('#user_account_nav_button').text()).to.contain('Frontend'); - }).end() - .get("#user_account_nav_button").click().end() - .get('ul.dropdown-menu[aria-labelledby="user_account_nav_button"]').contains('Profile').click().end() - .get('.page-container .user-title-row-container h1.user-title').should('contain', "Frontend").end() // Test only for first name as we're editing last name & it may change re: delayed indexing, etc. - .get('.page-container .access-keys-container h3').should('contain', "Access Keys").end() - .get('.page-container .access-keys-container #add-access-key').scrollToCenterElement().click({ force : true }).wait(100).end() - .get('.modal-body').should('contain', 'Access Key ID').should('contain', 'Secret Access Key').end() - .get('.modal-body div.row:first-of-type code').invoke('text').then(function(accessKeyID){ - return cy.get('.fade.in.modal').click().wait(500).end() - .get('.page-container .access-keys-container').should('contain', accessKeyID).end() - .get('.page-container .access-keys-container .access-keys-table tr:last-child .access-key-buttons .btn-danger').click({ force : true }).end() - .get('.page-container .access-keys-container').should('not.contain', accessKeyID); + it('Ensure logged in, visit profile page, add & remove access key', function () { + cy.login4DN({ email: 'ud4dntest@gmail.com', useEnvToken: false }) + .end() + .get('ul.navbar-acct li.user-account-item') + .should('have.class', 'is-logged-in') + .then((accountListItem) => { + expect( + accountListItem + .children('#user_account_nav_button') + .text() + ).to.contain('Frontend'); + }) + .end() + .get('#user_account_nav_button') + .click() + .end() + .get( + 'ul.dropdown-menu[aria-labelledby="user_account_nav_button"]' + ) + .contains('Profile') + .click() + .end() + .get('.page-container .user-title-row-container h1.user-title') + .should('contain', 'Frontend') + .end() // Test only for first name as we're editing last name & it may change re: delayed indexing, etc. + .get('.page-container .access-keys-container h3') + .should('contain', 'Access Keys') + .end() + .get('.page-container .access-keys-container #add-access-key') + .scrollToCenterElement() + .click({ force: true }) + .wait(100) + .end() + .get('.modal-body') + .should('contain', 'Access Key ID') + .should('contain', 'Secret Access Key') + .end() + .get('.modal-body div.row:first-of-type code') + .invoke('text') + .then(function (accessKeyID) { + return cy + .get('.fade.in.modal') + .click() + .wait(500) + .end() + .get('.page-container .access-keys-container') + .should('contain', accessKeyID) + .end() + .get( + '.page-container .access-keys-container .access-keys-table tr:last-child .access-key-buttons .btn-danger' + ) + .click({ force: true }) + .end() + .get('.page-container .access-keys-container') + .should('not.contain', accessKeyID); }); - }); - it('Ensure logged in, visit profile page, edit last name 2x.', function(){ - - cy.login4DN({ 'email' : 'ud4dntest@gmail.com', 'useEnvToken' : false }).end() - .get('ul.navbar-acct li.user-account-item').should('have.class', 'is-logged-in').then((accountListItem)=>{ - expect(accountListItem.children('#user_account_nav_button').text()).to.contain('Frontend'); - }).end() - .get("#user_account_nav_button").click().end() - .get('ul.dropdown-menu[aria-labelledby="user_account_nav_button"]').contains('Profile').click().end() - .get('.page-container .user-title-row-container h1.user-title').invoke('text').should('include', "Frontend").end() // Test only for first name as we're editing last name & it may change re: delayed indexing, etc. - .url().then(function(currUrl){ - return cy.visit(currUrl + '?datastore=database', { headers: cypressVisitHeaders }).end() // Edit last name ON DATASTORE=DATABASE TO PREVENT ERRORS DUE TO INDEXING NOT BEING CAUGHT UP FROM PRIOR TEST - .get('.page-container .user-title-row-container h1.user-title .last_name .value.saved a.edit-button').click().end() - .get('.page-container .user-title-row-container h1.user-title .last_name .value.editing input') - .scrollToCenterElement().clear({ force : true }).type('SuperTest', { force : true }).then(function(inputfield){ - return cy.wait(100).window().screenshot().end().get('.page-container .user-title-row-container h1.user-title .last_name .value.editing .save-button').click({ force : true }) - .should('have.length', 0).wait(100).end() - .get('.page-container .user-title-row-container h1.user-title .last_name .value.editing .loading-icon').should('have.length', 0).end() - .get('.page-container .user-title-row-container h1.user-title').should('have.text', "Frontend SuperTest").wait(500).end() - // After reloading on datastore=database, last name stays edited. Then change back. - .reload()//.visit(currUrl + '?datastore=database', { headers: cypressVisitHeaders }).end() - .get('.page-container .user-title-row-container h1.user-title').should('have.text', "Frontend SuperTest").end() - // Cleanup & test again - .get('.page-container .user-title-row-container h1.user-title .last_name .value.saved a.edit-button').click({ force : true }).end() - .get('.page-container .user-title-row-container h1.user-title .last_name .value.editing input').should('have.value', 'SuperTest') - .clear({ force : true }).type('Test', { force : true }).then(function(inputfield){ - return cy.wait(100) - .get('.page-container .user-title-row-container h1.user-title .last_name .value.editing .save-button').click({ force : true }) - .should('have.length', 0).wait(100).end() - .get('.page-container .user-title-row-container h1.user-title .last_name .value.editing .loading-icon').should('have.length', 0).end() - .get('.page-container .user-title-row-container h1.user-title').should('have.text', "Frontend Test").wait(500).end() - .reload() - .get('.page-container .user-title-row-container h1.user-title').should('have.text', "Frontend Test").end(); - }); - + it('Ensure logged in, visit profile page, edit last name 2x.', function () { + cy.login4DN({ email: 'ud4dntest@gmail.com', useEnvToken: false }) + .end() + .get('ul.navbar-acct li.user-account-item') + .should('have.class', 'is-logged-in') + .then((accountListItem) => { + expect( + accountListItem + .children('#user_account_nav_button') + .text() + ).to.contain('Frontend'); + }) + .end() + .get('#user_account_nav_button') + .click() + .end() + .get( + 'ul.dropdown-menu[aria-labelledby="user_account_nav_button"]' + ) + .contains('Profile') + .click() + .end() + .get('.page-container .user-title-row-container h1.user-title') + .invoke('text') + .should('include', 'Frontend') + .end() // Test only for first name as we're editing last name & it may change re: delayed indexing, etc. + .url() + .then(function (currUrl) { + return cy + .visit(currUrl + '?datastore=database', { + headers: cypressVisitHeaders, + }) + .end() // Edit last name ON DATASTORE=DATABASE TO PREVENT ERRORS DUE TO INDEXING NOT BEING CAUGHT UP FROM PRIOR TEST + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.saved a.edit-button' + ) + .click() + .end() + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing input' + ) + .scrollToCenterElement() + .clear({ force: true }) + .type('SuperTest', { force: true }) + .then(function (inputfield) { + return ( + cy + .wait(100) + .window() + .screenshot() + .end() + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing .save-button' + ) + .click({ force: true }) + .should('have.length', 0) + .wait(100) + .end() + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing .loading-icon' + ) + .should('have.length', 0) + .end() + .get( + '.page-container .user-title-row-container h1.user-title' + ) + .should('have.text', 'Frontend SuperTest') + .wait(500) + .end() + // After reloading on datastore=database, last name stays edited. Then change back. + .reload() //.visit(currUrl + '?datastore=database', { headers: cypressVisitHeaders }).end() + .get( + '.page-container .user-title-row-container h1.user-title' + ) + .should('have.text', 'Frontend SuperTest') + .end() + // Cleanup & test again + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.saved a.edit-button' + ) + .click({ force: true }) + .end() + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing input' + ) + .should('have.value', 'SuperTest') + .clear({ force: true }) + .type('Test', { force: true }) + .then(function (inputfield) { + return cy + .wait(100) + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing .save-button' + ) + .click({ force: true }) + .should('have.length', 0) + .wait(100) + .end() + .get( + '.page-container .user-title-row-container h1.user-title .last_name .value.editing .loading-icon' + ) + .should('have.length', 0) + .end() + .get( + '.page-container .user-title-row-container h1.user-title' + ) + .should( + 'have.text', + 'Frontend Test' + ) + .wait(500) + .end() + .reload() + .get( + '.page-container .user-title-row-container h1.user-title' + ) + .should( + 'have.text', + 'Frontend Test' + ) + .end(); + }) + ); }); - }).end().logout4DN(); - - + }) + .end() + .logout4DN(); }); - }); - - }); diff --git a/deploy/post_deploy_testing/cypress/e2e/04a_search_views_local.cy.js b/deploy/post_deploy_testing/cypress/e2e/04a_search_views_local.cy.js index 46cc89d979..bba68b25fa 100644 --- a/deploy/post_deploy_testing/cypress/e2e/04a_search_views_local.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/04a_search_views_local.cy.js @@ -1,49 +1,54 @@ import { cypressVisitHeaders } from './../support'; - describe('Deployment/CI Search View Tests', function () { - context('/search/?type=Item', function () { - - before(function(){ - cy.visit("/", { headers: cypressVisitHeaders }).loginCGAP().end(); + before(function () { + cy.visit('/', { headers: cypressVisitHeaders }).loginCGAP().end(); }); - beforeEach(function(){ + beforeEach(function () { // See https://docs.cypress.io/api/cypress-api/cookies#Preserve-Once Cypress.Cookies.preserveOnce('jwtToken', 'searchSessionID'); }); it('Has at least 5 results for /search/?type=Item', function () { - cy.visit("/search/", { headers: cypressVisitHeaders }).end() - .location('search').should('include', 'type=Item').end() - .get('.search-results-container .search-result-row').then(($searchResultElems)=>{ + cy.visit('/search/', { headers: cypressVisitHeaders }) + .end() + .location('search') + .should('include', 'type=Item') + .end() + .get('.search-results-container .search-result-row') + .then(($searchResultElems) => { expect($searchResultElems.length).to.be.greaterThan(5); - }).end() - .searchPageTotalResultCount().should('be.greaterThan', 5); + }) + .end() + .searchPageTotalResultCount() + .should('be.greaterThan', 5); }); - }); - context('/search/?type=Page', function(){ - - beforeEach(function(){ + context('/search/?type=Page', function () { + beforeEach(function () { // Ensure we preserve search session cookie for proper ordering. Cypress.Cookies.preserveOnce('jwtToken', 'searchSessionID'); }); - it('Should redirect to /search/?type=Page correctly', function(){ - cy.visit('/pages', { headers: cypressVisitHeaders }).end() // We should get redirected to ?type=Page - .location('search').should('include', 'type=Page').end() - .location('pathname').should('include', '/search/'); + it('Should redirect to /search/?type=Page correctly', function () { + cy.visit('/pages', { headers: cypressVisitHeaders }) + .end() // We should get redirected to ?type=Page + .location('search') + .should('include', 'type=Page') + .end() + .location('pathname') + .should('include', '/search/'); }); - it('Should have at least 2 results.', function(){ - cy.get('.search-results-container .search-result-row').then(($searchResultElems)=>{ - expect($searchResultElems.length).to.be.greaterThan(2); - }); + it('Should have at least 2 results.', function () { + cy.get('.search-results-container .search-result-row').then( + ($searchResultElems) => { + expect($searchResultElems.length).to.be.greaterThan(2); + } + ); }); - }); - }); diff --git a/deploy/post_deploy_testing/cypress/e2e/04b_search_views.cy.js b/deploy/post_deploy_testing/cypress/e2e/04b_search_views.cy.js index 461fe882cc..ae636fbdc3 100644 --- a/deploy/post_deploy_testing/cypress/e2e/04b_search_views.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/04b_search_views.cy.js @@ -1,35 +1,35 @@ import { cypressVisitHeaders } from './../support'; - describe('Post-Deployment Search View Tests', function () { - context('/search/?type=Item', function () { - - before(function(){ + before(function () { cy.visit('/search/', { headers: cypressVisitHeaders }); }); - beforeEach(function(){ + beforeEach(function () { // Ensure we preserve search session cookie for proper ordering. - Cypress.Cookies.preserveOnce("searchSessionID"); + Cypress.Cookies.preserveOnce('searchSessionID'); }); it('Load as you scroll works for ?type=Item', function () { - cy.location('search').should('include', 'type=Item'); - cy.searchPageTotalResultCount().then((totalCountExpected)=>{ - const intervalCount = Math.min(10, parseInt(totalCountExpected / 15)); - - for (let interval = 0; interval < intervalCount; interval++){ - cy.scrollToBottom().then(()=>{ - cy.get('.search-results-container .search-result-row[data-row-number="' + (15 * (interval + 1)) + '"]').should('have.length', 1); + cy.searchPageTotalResultCount().then((totalCountExpected) => { + const intervalCount = Math.min( + 10, + parseInt(totalCountExpected / 15) + ); + + for (let interval = 0; interval < intervalCount; interval++) { + cy.scrollToBottom().then(() => { + cy.get( + '.search-results-container .search-result-row[data-row-number="' + + 15 * (interval + 1) + + '"]' + ).should('have.length', 1); }); } }); - }); - }); - }); diff --git a/deploy/post_deploy_testing/cypress/e2e/05a_case_view_basic.cy.js b/deploy/post_deploy_testing/cypress/e2e/05a_case_view_basic.cy.js index 5f6f40ceb1..914aec6da1 100644 --- a/deploy/post_deploy_testing/cypress/e2e/05a_case_view_basic.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/05a_case_view_basic.cy.js @@ -1,13 +1,11 @@ import { cypressVisitHeaders } from './../support'; - describe('Case View - Initial', function () { - - before(function(){ - cy.visit("/", { headers: cypressVisitHeaders }).loginCGAP().end(); + before(function () { + cy.visit('/', { headers: cypressVisitHeaders }).loginCGAP().end(); }); - beforeEach(function(){ + beforeEach(function () { // See https://docs.cypress.io/api/cypress-api/cookies#Preserve-Once Cypress.Cookies.preserveOnce('jwtToken', 'searchSessionID'); }); @@ -17,86 +15,121 @@ describe('Case View - Initial', function () { * @todo - Once big enough, split up into multiple files (keeping a common naming, like 05b, 05c, or similar) to parallelize. */ - it('CGAP Core project "GAPCAJQ1L99X" exists; search result clickable', function(){ + it('CGAP Core project "GAPCAJQ1L99X" exists; search result clickable', function () { cy.visit( - "/search/?proband_case=true&project.display_title=CGAP+Core&type=Case&accession=GAPCAJQ1L99X", + '/search/?proband_case=true&project.display_title=CGAP+Core&type=Case&accession=GAPCAJQ1L99X', { headers: cypressVisitHeaders } ) - .get(".search-result-row").should('have.length.greaterThan', 0) - .first().within(function($rowElem){ - return cy.get(".search-result-column-block[data-field=\"display_title\"] .adv-block-link").should('be.visible').click({ - // Using force: true here since sometimes Cypress scrolls a bit too much while getting this element and then thinks its hidden - force: true - }); + .get('.search-result-row') + .should('have.length.greaterThan', 0) + .first() + .within(function ($rowElem) { + return cy + .get( + '.search-result-column-block[data-field="display_title"] .adv-block-link' + ) + .should('be.visible') + .click({ + // Using force: true here since sometimes Cypress scrolls a bit too much while getting this element and then thinks its hidden + force: true, + }); }); }); - context("Top area", function(){ - - it("Has panels for patient info and family info with phenotypic features", function(){ - cy.get(".col-stats #case-stats > div:first-child .card-header").contains("Patient Info").end() - .get(".col-stats #case-stats > div:first-child .card-footer > div a.badge").should('have.length', 1) - .get(".col-stats #case-stats > div:last-child .card-header").contains("Family Info").end() - .get(".col-stats #case-stats > div:last-child .card-footer > div a.badge").should('have.length', 4); + context('Top area', function () { + it('Has panels for patient info and family info with phenotypic features', function () { + cy.get('.col-stats #case-stats > div:first-child .card-header') + .contains('Patient Info') + .end() + .get( + '.col-stats #case-stats > div:first-child .card-footer > div a.badge' + ) + .should('have.length', 1) + .get('.col-stats #case-stats > div:last-child .card-header') + .contains('Family Info') + .end() + .get( + '.col-stats #case-stats > div:last-child .card-footer > div a.badge' + ) + .should('have.length', 4); }); - it("Has pedigree with some nodes present", function(){ - cy.get(".pedigree-vis-heading button.view-pedigree-btn").should("have.text", "View").end() - .get("svg.pedigree-viz-shapes-layer.shapes-layer g.individuals-bg-shape-layer > g").should('have.length', 13); + it('Has pedigree with some nodes present', function () { + cy.get('.pedigree-vis-heading button.view-pedigree-btn') + .should('have.text', 'View') + .end() + .get( + 'svg.pedigree-viz-shapes-layer.shapes-layer g.individuals-bg-shape-layer > g' + ) + .should('have.length', 13); }); - }); - - context("Tabs area", function(){ - - it("Have 5 tabs, with first being active by default", function(){ - cy.get(".tab-router .dot-tab-nav-list .arrow-tab").should("have.length", 5) + context('Tabs area', function () { + it('Have 5 tabs, with first being active by default', function () { + cy.get('.tab-router .dot-tab-nav-list .arrow-tab') + .should('have.length', 5) .eq(0) - .should("have.text", "Accessioning") - .should("have.class", "active").end() + .should('have.text', 'Accessioning') + .should('have.class', 'active') + .end() // `id="case-info.accessioning"`; NOT class="accessioning" - .get("#case-info\\.accessioning > h1").contains("Accessioning Report and History"); + .get('#case-info\\.accessioning > h1') + .contains('Accessioning Report and History'); }); - it("Click 2nd tab, see QC metrics", function(){ - cy.get(".tab-router .dot-tab-nav-list .arrow-tab") + it('Click 2nd tab, see QC metrics', function () { + cy.get('.tab-router .dot-tab-nav-list .arrow-tab') .eq(1) - .should("have.text", "Bioinformatics") + .should('have.text', 'Bioinformatics') .click() - .should("have.class", "active").end() - .get("#case-info\\.bioinformatics > h1").contains("Bioinformatics Analysis").end() - .get("#case-info\\.bioinformatics .tab-inner-container.card:first-of-type .card-body .qc-summary") - .should("have.length", 12) - .eq(0).should("have.text", "Total Number of Reads:466,477,333") - .get("#case-info\\.bioinformatics .tab-inner-container.card:first-of-type .card-body .qc-summary") - .eq(1).should("have.text", "Coverage:47.2X"); + .should('have.class', 'active') + .end() + .get('#case-info\\.bioinformatics > h1') + .contains('Bioinformatics Analysis') + .end() + .get( + '#case-info\\.bioinformatics .tab-inner-container.card:first-of-type .card-body .qc-summary' + ) + .should('have.length', 12) + .eq(0) + .should('have.text', 'Total Number of Reads:466,477,333') + .get( + '#case-info\\.bioinformatics .tab-inner-container.card:first-of-type .card-body .qc-summary' + ) + .eq(1) + .should('have.text', 'Coverage:47.2X'); }); - it("Click 3rd tab, see FSUI & Filtering Table", function(){ + it('Click 3rd tab, see FSUI & Filtering Table', function () { /** Todo - more in-depth testing, maybe in sep file. */ - cy.get(".tab-router .dot-tab-nav-list .arrow-tab") + cy.get('.tab-router .dot-tab-nav-list .arrow-tab') .eq(2) - .should("have.text", "Filtering") + .should('have.text', 'Filtering') .click() - .should("have.class", "active").end() - .get("#case-info\\.filtering h1").contains("Variant Filtering and Technical Review").end() - .get("#case-info\\.filtering .above-variantsample-table-ui .blocks-container .filterset-block").should("have.length.greaterThan", 0); + .should('have.class', 'active') + .end() + .get('#case-info\\.filtering h1') + .contains('Variant Filtering and Technical Review') + .end() + .get( + '#case-info\\.filtering .above-variantsample-table-ui .blocks-container .filterset-block' + ) + .should('have.length.greaterThan', 0); }); - it("Wait for VSL to load, click 4th tab, see >0 VariantSampleList Item contents", function(){ + it('Wait for VSL to load, click 4th tab, see >0 VariantSampleList Item contents', function () { /** Todo - more in-depth testing, maybe in sep file. */ - cy.get(".tab-router .dot-tab-nav-list .arrow-tab") + cy.get('.tab-router .dot-tab-nav-list .arrow-tab') .eq(3) - .should("have.text", "Interpretation") + .should('have.text', 'Interpretation') // Wait to become not disabled first (-- VSL item is loading --) - .should("not.have.class", "disabled") + .should('not.have.class', 'disabled') .click() - .should("have.class", "active").end() - .get("#case-info\\.interpretation div.card").should("have.length.greaterThan", 0); + .should('have.class', 'active') + .end() + .get('#case-info\\.interpretation div.card') + .should('have.length.greaterThan', 0); }); - }); - }); - diff --git a/deploy/post_deploy_testing/cypress/e2e/05b_case_view_fsui.cy.js b/deploy/post_deploy_testing/cypress/e2e/05b_case_view_fsui.cy.js index a99278098f..969edbeacc 100644 --- a/deploy/post_deploy_testing/cypress/e2e/05b_case_view_fsui.cy.js +++ b/deploy/post_deploy_testing/cypress/e2e/05b_case_view_fsui.cy.js @@ -1,113 +1,156 @@ import { cypressVisitHeaders } from './../support'; - -function onSupersededAjaxRequestHandler(err, runnable){ +function onSupersededAjaxRequestHandler(err, runnable) { // When we click on things like "Add New Filter Block", // we might cancel previous search requests, which may // emit error like "Did not get back a search response, request was potentially aborted." - if (err.message.includes('Did not get back a search response, request was potentially aborted.')) { + if ( + err.message.includes( + 'Did not get back a search response, request was potentially aborted.' + ) + ) { Cypress.log({ - "name": "Information about request", - "displayName": "INFO", - "message": "An app AJAX request was aborted or superseded" + name: 'Information about request', + displayName: 'INFO', + message: 'An app AJAX request was aborted or superseded', }); return false; } // Don't do anything == fail the test } - describe('Case View - FSUI', function () { - - before(function(){ - cy.visit("/", { headers: cypressVisitHeaders }) - .loginCGAP() - .end(); + before(function () { + cy.visit('/', { headers: cypressVisitHeaders }).loginCGAP().end(); }); - beforeEach(function(){ + beforeEach(function () { // See https://docs.cypress.io/api/cypress-api/cookies#Preserve-Once Cypress.Cookies.preserveOnce('jwtToken', 'searchSessionID'); }); let countFBInitial = null; - it("We should be on right tab upon page initialization/login", function(){ - cy.visit("/cases/GAPCAJQ1L99X/#case-info.filtering", { headers: cypressVisitHeaders }) - .get(".tab-router .dot-tab-nav-list .arrow-tab") + it('We should be on right tab upon page initialization/login', function () { + cy.visit('/cases/GAPCAJQ1L99X/#case-info.filtering', { + headers: cypressVisitHeaders, + }) + .get('.tab-router .dot-tab-nav-list .arrow-tab') .eq(2) - .should("have.class", "active") - .should("have.text", "Filtering").end() - .get("#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header h4").should("not.have.text", "Loading Filter Set").end() - .get("#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .blocks-container .filterset-block").should("have.length.greaterThan", 0).then(function($fsBlocks){ + .should('have.class', 'active') + .should('have.text', 'Filtering') + .end() + .get( + '#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header h4' + ) + .should('not.have.text', 'Loading Filter Set') + .end() + .get( + '#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .blocks-container .filterset-block' + ) + .should('have.length.greaterThan', 0) + .then(function ($fsBlocks) { countFBInitial = $fsBlocks.length; Cypress.log({ - "name": "Get count of initial filter blocks", - "displayName": "# blocks", - "message": countFBInitial + name: 'Get count of initial filter blocks', + displayName: '# blocks', + message: countFBInitial, }); }); }); - - it("Save buttons disabled initially", function(){ - cy.get("div#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header div.pl-16 button:first-child").should(function($btn){ - expect($btn.children("span")).to.have.text('Save Case FilterSet'); - expect($btn).to.have.attr('disabled'); - }).end() - .get("div#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header div.pl-16 button:last-child").should(function($btn){ + it('Save buttons disabled initially', function () { + cy.get( + 'div#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header div.pl-16 button:first-child' + ) + .should(function ($btn) { + expect($btn.children('span')).to.have.text( + 'Save Case FilterSet' + ); + expect($btn).to.have.attr('disabled'); + }) + .end() + .get( + 'div#case-info\\.filtering #snv-filtering .above-variantsample-table-ui .filter-set-ui-header div.pl-16 button:last-child' + ) + .should(function ($btn) { expect($btn).to.have.text('Create Preset'); expect($btn).to.have.attr('disabled'); }); }); - it("Add Filter Block button creates new empty block", function(){ - + it('Add Filter Block button creates new empty block', function () { // New FB block created+selected may cancel an existing search request for previous filterset block selection - cy.once('uncaught:exception', onSupersededAjaxRequestHandler).end() - .get("#case-info\\.filtering #snv-filtering").within(function(){ - cy.get(".above-variantsample-table-ui div[aria-label=\"Creation Controls\"] button:first-child") - .should("have.text", "Add Filter Block").click().end() - .get(".above-variantsample-table-ui .filterset-blocks-container") - .should("have.attr", "data-all-selected", "false").end() - .get(".above-variantsample-table-ui .filterset-blocks-container .blocks-container .filterset-block").should("have.length", countFBInitial + 1) + cy.once('uncaught:exception', onSupersededAjaxRequestHandler) + .end() + .get('#case-info\\.filtering #snv-filtering') + .within(function () { + cy.get( + '.above-variantsample-table-ui div[aria-label="Creation Controls"] button:first-child' + ) + .should('have.text', 'Add Filter Block') + .click() + .end() + .get( + '.above-variantsample-table-ui .filterset-blocks-container' + ) + .should('have.attr', 'data-all-selected', 'false') + .end() + .get( + '.above-variantsample-table-ui .filterset-blocks-container .blocks-container .filterset-block' + ) + .should('have.length', countFBInitial + 1) .eq(-1) - .should("have.class", "selected").within(function($fb){ + .should('have.class', 'selected') + .within(function ($fb) { // Wait until is finished loading (else next test may fail) - return cy.get("i.icon").should("have.class", "icon-times-circle"); + return cy + .get('i.icon') + .should('have.class', 'icon-times-circle'); }) - .contains("No Filters Selected").end(); + .contains('No Filters Selected') + .end(); }); }); - it("Selecting term from FacetList adds to the new filter block", function(){ - - cy.once('uncaught:exception', onSupersededAjaxRequestHandler).end() - .get("#case-info\\.filtering #snv-filtering").within(function(){ + it('Selecting term from FacetList adds to the new filter block', function () { + cy.once('uncaught:exception', onSupersededAjaxRequestHandler) + .end() + .get('#case-info\\.filtering #snv-filtering') + .within(function () { // Open "Genotype" grouping facet -- allow this to fail as `Proband Genotype` might be ungrouped //.get(".facets-column > .facets-container > .facets-body div.facet[data-group=\"Genotype\"] .facet-title") // Open "Proband Genotype" field facet - cy.get(".facets-column > .facets-container > .facets-body div.facet[data-field=\"associated_genotype_labels.proband_genotype_label\"] .facet-title") + cy.get( + '.facets-column > .facets-container > .facets-body div.facet[data-field="associated_genotype_labels.proband_genotype_label"] .facet-title' + ) .click() - .get(".facets-column > .facets-container > .facets-body div.facet[data-field=\"associated_genotype_labels.proband_genotype_label\"] .facet-list-element[data-key=\"Heterozygous\"]") - .should("not.have.class", "selected") + .get( + '.facets-column > .facets-container > .facets-body div.facet[data-field="associated_genotype_labels.proband_genotype_label"] .facet-list-element[data-key="Heterozygous"]' + ) + .should('not.have.class', 'selected') .click() // Get it again, else might be referring to non-existing/unmounted elem as term changes locations. - .get(".facets-column > .facets-container > .facets-body div.facet[data-field=\"associated_genotype_labels.proband_genotype_label\"] .facet-list-element[data-key=\"Heterozygous\"]") - .should("have.class", "selected").end() - .get(".filterset-blocks-container .blocks-container .filterset-block:last-child .field-block").should("have.length", 1) - .within(function($fb){ - cy.get(".field-name").should("have.text", "Proband Genotype").end() - .get(".value-blocks .value-block") - .should("have.text", "Heterozygous"); + .get( + '.facets-column > .facets-container > .facets-body div.facet[data-field="associated_genotype_labels.proband_genotype_label"] .facet-list-element[data-key="Heterozygous"]' + ) + .should('have.class', 'selected') + .end() + .get( + '.filterset-blocks-container .blocks-container .filterset-block:last-child .field-block' + ) + .should('have.length', 1) + .within(function ($fb) { + cy.get('.field-name') + .should('have.text', 'Proband Genotype') + .end() + .get('.value-blocks .value-block') + .should('have.text', 'Heterozygous'); }); }); - }); // TODO: Test RangeFacets // TODO: Test Presets (after UX feedback) - - }); diff --git a/deploy/post_deploy_testing/cypress/plugins/index.js b/deploy/post_deploy_testing/cypress/plugins/index.js index fd170fba69..0e35b18c5a 100644 --- a/deploy/post_deploy_testing/cypress/plugins/index.js +++ b/deploy/post_deploy_testing/cypress/plugins/index.js @@ -12,6 +12,6 @@ // the project's config changing) module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +}; diff --git a/deploy/post_deploy_testing/cypress/support/commands.js b/deploy/post_deploy_testing/cypress/support/commands.js index c726a59487..2f780f01ed 100644 --- a/deploy/post_deploy_testing/cypress/support/commands.js +++ b/deploy/post_deploy_testing/cypress/support/commands.js @@ -28,219 +28,280 @@ import _ from 'underscore'; var jwt = require('jsonwebtoken'); import { Buffer } from 'buffer'; - /** Expected to throw error of some sort if not on search page, or no results. */ -Cypress.Commands.add('searchPageTotalResultCount', function(options){ - return cy.get('div.above-results-table-row #results-count') - .invoke('text').then(function(resultText){ +Cypress.Commands.add('searchPageTotalResultCount', function (options) { + return cy + .get('div.above-results-table-row #results-count') + .invoke('text') + .then(function (resultText) { return parseInt(resultText); }); }); - - -Cypress.Commands.add('scrollToBottom', function(options){ - return cy.get('body').then(($body)=>{ +Cypress.Commands.add('scrollToBottom', function (options) { + return cy.get('body').then(($body) => { cy.scrollTo(0, $body[0].scrollHeight); }); }); - -Cypress.Commands.add('scrollToCenterElement', { prevSubject : true }, (subject, options) => { - expect(subject.length).to.equal(1); - const subjectElem = subject[0]; - var bounds = subjectElem.getBoundingClientRect(); - return cy.window().then((w)=>{ - w.scrollBy(0, (bounds.top - (w.innerHeight / 2))); - return cy.wrap(subjectElem); - }); -}); - - +Cypress.Commands.add( + 'scrollToCenterElement', + { prevSubject: true }, + (subject, options) => { + expect(subject.length).to.equal(1); + const subjectElem = subject[0]; + var bounds = subjectElem.getBoundingClientRect(); + return cy.window().then((w) => { + w.scrollBy(0, bounds.top - w.innerHeight / 2); + return cy.wrap(subjectElem); + }); + } +); /** * This emulates login.js. Perhaps we should adjust login.js somewhat to match this better re: navigate.then(...) . */ -Cypress.Commands.add('loginCGAP', function(options = { 'useEnvToken': false, 'email': null }){ - - function performLogin(token){ - return cy.window().then((w)=>{ - cy.request({ - 'url' : '/login', - 'method' : 'POST', - 'body' : JSON.stringify({ 'id_token' : token }), - 'headers' : { - 'Authorization': 'Bearer ' + token, - 'Accept': "application/json", - 'Content-Type': "application/json; charset=UTF-8" - }, - 'followRedirect' : true - }).then(function(resp){ - if (resp.status && resp.status === 200) { +Cypress.Commands.add( + 'loginCGAP', + function (options = { useEnvToken: false, email: null }) { + function performLogin(token) { + return cy + .window() + .then((w) => { cy.request({ - 'url': '/session-properties', - 'method': 'GET', - 'headers' : { - 'Accept': "application/json", - 'Content-Type': "application/json; charset=UTF-8" - } - }).then(function (userInfoResponse) { - w.fourfront.JWT.saveUserInfoLocalStorage(userInfoResponse.body); - // Triggers app.state.session change (req'd to update UI) - w.fourfront.app.updateAppSessionState(); - // Refresh curr page/context - w.fourfront.navigate('', { 'inPlace' : true }); - }).end(); - } - }).end(); - }).end(); - } - - let jwt_token = null; - - if (options.useEnvToken) { - jwt_token = Cypress.env('JWT_TOKEN'); - console.log('ENV TOKEN', jwt_token); - if (typeof jwt_token === 'string' && jwt_token) { - console.log('Logging in with token'); - return performLogin(jwt_token); + url: '/login', + method: 'POST', + body: JSON.stringify({ id_token: token }), + headers: { + Authorization: 'Bearer ' + token, + Accept: 'application/json', + 'Content-Type': 'application/json; charset=UTF-8', + }, + followRedirect: true, + }) + .then(function (resp) { + if (resp.status && resp.status === 200) { + cy.request({ + url: '/session-properties', + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': + 'application/json; charset=UTF-8', + }, + }) + .then(function (userInfoResponse) { + w.fourfront.JWT.saveUserInfoLocalStorage( + userInfoResponse.body + ); + // Triggers app.state.session change (req'd to update UI) + w.fourfront.app.updateAppSessionState(); + // Refresh curr page/context + w.fourfront.navigate('', { + inPlace: true, + }); + }) + .end(); + } + }) + .end(); + }) + .end(); } - } - - // If no token, we try to generate/impersonate one ourselves - const email = options.email || options.user || "cypress-test-user@cgap.hms.harvard.edu"; - const auth0client = Cypress.env('Auth0Client'); - const auth0secret = Cypress.env('Auth0Secret'); + let jwt_token = null; - if (!auth0client || !auth0secret) throw new Error('Cannot test login if no Auth0Client & Auth0Secret in ENV vars.'); - - Cypress.log({ - 'name' : "Login CGAP", - 'message' : 'Attempting to impersonate-login for ' + email, - 'consoleProps' : ()=>{ - return { auth0client, auth0secret, email }; + if (options.useEnvToken) { + jwt_token = Cypress.env('JWT_TOKEN'); + console.log('ENV TOKEN', jwt_token); + if (typeof jwt_token === 'string' && jwt_token) { + console.log('Logging in with token'); + return performLogin(jwt_token); + } } - }); - // Generate JWT - const jwtPayload = { - 'email': email, - 'email_verified': true, - 'aud': auth0client, - "iss": "https://hms-dbmi.auth0.com/" - }; - - jwt_token = jwt.sign(jwtPayload, Buffer.from(auth0secret, 'utf-8')); - expect(jwt_token).to.have.length.greaterThan(0); - Cypress.log({ - 'name' : "Login 4DN", - 'message' : 'Generated own JWT with length ' + jwt_token.length, - }); - return performLogin(jwt_token); - -}); + // If no token, we try to generate/impersonate one ourselves + + const email = + options.email || + options.user || + 'cypress-test-user@cgap.hms.harvard.edu'; + const auth0client = Cypress.env('Auth0Client'); + const auth0secret = Cypress.env('Auth0Secret'); + + if (!auth0client || !auth0secret) + throw new Error( + 'Cannot test login if no Auth0Client & Auth0Secret in ENV vars.' + ); + + Cypress.log({ + name: 'Login CGAP', + message: 'Attempting to impersonate-login for ' + email, + consoleProps: () => { + return { auth0client, auth0secret, email }; + }, + }); -Cypress.Commands.add('logoutCGAP', function(options = { 'useEnvToken' : true }){ - cy.get("#user_account_nav_button").click().wait(100).end() - .get('#logoutbtn').click().end().get('#user_account_nav_button').should('contain', 'Log In').wait(300).end() - .get('#slow-load-container').should('not.have.class', 'visible').end(); + // Generate JWT + const jwtPayload = { + email: email, + email_verified: true, + aud: auth0client, + iss: 'https://hms-dbmi.auth0.com/', + }; + + jwt_token = jwt.sign(jwtPayload, Buffer.from(auth0secret, 'utf-8')); + expect(jwt_token).to.have.length.greaterThan(0); + Cypress.log({ + name: 'Login 4DN', + message: 'Generated own JWT with length ' + jwt_token.length, + }); + return performLogin(jwt_token); + } +); + +Cypress.Commands.add('logoutCGAP', function (options = { useEnvToken: true }) { + cy.get('#user_account_nav_button') + .click() + .wait(100) + .end() + .get('#logoutbtn') + .click() + .end() + .get('#user_account_nav_button') + .should('contain', 'Log In') + .wait(300) + .end() + .get('#slow-load-container') + .should('not.have.class', 'visible') + .end(); }); - - - /** Session Caching */ -var localStorageCache = { 'user_info' : null }; -var cookieCache = { 'jwtToken' : null, 'searchSessionID' : null }; +var localStorageCache = { user_info: null }; +var cookieCache = { jwtToken: null, searchSessionID: null }; - -Cypress.Commands.add('saveBrowserSession', function(options = {}){ - _.forEach(_.keys(localStorageCache), function(storageKey){ - localStorageCache[storageKey] = localStorage.getItem(storageKey) || null; +Cypress.Commands.add('saveBrowserSession', function (options = {}) { + _.forEach(_.keys(localStorageCache), function (storageKey) { + localStorageCache[storageKey] = + localStorage.getItem(storageKey) || null; }); - _.forEach(_.keys(cookieCache), function(cookieKey){ + _.forEach(_.keys(cookieCache), function (cookieKey) { cookieCache[cookieKey] = cy.getCookie(cookieKey) || null; }); }); -Cypress.Commands.add('loadBrowserSession', function(options = {}){ - _.forEach(_.keys(localStorageCache), function(storageKey){ - if (typeof localStorageCache[storageKey] === 'string'){ +Cypress.Commands.add('loadBrowserSession', function (options = {}) { + _.forEach(_.keys(localStorageCache), function (storageKey) { + if (typeof localStorageCache[storageKey] === 'string') { localStorage.setItem(storageKey, localStorageCache[storageKey]); } }); - _.forEach(_.keys(cookieCache), function(cookieKey){ - if (typeof cookieCache[cookieKey] === 'string'){ + _.forEach(_.keys(cookieCache), function (cookieKey) { + if (typeof cookieCache[cookieKey] === 'string') { cy.setCookie(cookieKey, cookieCache[cookieKey]); } }); }); -Cypress.Commands.add('clearBrowserSession', function(options = {}){ - _.forEach(_.keys(localStorageCache), function(storageKey){ +Cypress.Commands.add('clearBrowserSession', function (options = {}) { + _.forEach(_.keys(localStorageCache), function (storageKey) { localStorageCache[storageKey] = null; }); - _.forEach(_.keys(cookieCache), function(cookieKey){ + _.forEach(_.keys(cookieCache), function (cookieKey) { cookieCache[cookieKey] = null; }); cy.loadBrowserSession(); }); - /* Hovering */ -Cypress.Commands.add('hoverIn', { prevSubject : true }, function(subject, options){ - - expect(subject.length).to.equal(1); - - var subjElem = subject[0]; - - var bounds = subjElem.getBoundingClientRect(); - var cursorPos = { 'clientX' : bounds.left + (bounds.width / 2), 'clientY' : bounds.top + (bounds.height / 2) }; - var commonEventVals = _.extend({ bubbles : true, cancelable : true }, cursorPos); - - subjElem.dispatchEvent(new MouseEvent('mouseenter', commonEventVals ) ); - subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventVals ) ); - subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventVals ) ); - - return subject; -}); - -Cypress.Commands.add('hoverOut', { prevSubject : true }, function(subject, options){ - - expect(subject.length).to.equal(1); - - var subjElem = subject[0]; - - var bounds = subjElem.getBoundingClientRect(); - var cursorPos = { 'clientX' : Math.max(bounds.left - (bounds.width / 2), 0), 'clientY' : Math.max(bounds.top - (bounds.height / 2), 0) }; - var commonEventValsIn = _.extend({ 'bubbles' : true, 'cancelable' : true, }, cursorPos); - - subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mouseleave', _.extend({ 'relatedTarget' : subjElem }, commonEventValsIn, { 'clientX' : bounds.left - 5, 'clientY' : bounds.top - 5 }) ) ); - - return subject; -}); - -Cypress.Commands.add('clickEvent', { prevSubject : true }, function(subject, options){ - - expect(subject.length).to.equal(1); - - var subjElem = subject[0]; - - var bounds = subjElem.getBoundingClientRect(); - var cursorPos = { 'clientX' : bounds.left + (bounds.width / 2), 'clientY' : bounds.top + (bounds.height / 2) }; - var commonEventValsIn = _.extend({ 'bubbles' : true, 'cancelable' : true, }, cursorPos); - - subjElem.dispatchEvent(new MouseEvent('mouseenter', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mousedown', commonEventValsIn ) ); - subjElem.dispatchEvent(new MouseEvent('mouseup', commonEventValsIn ) ); - //subjElem.dispatchEvent(new MouseEvent('mouseleave', _.extend({ 'relatedTarget' : subjElem }, commonEventValsIn, { 'clientX' : bounds.left - 5, 'clientY' : bounds.top - 5 }) ) ); - - return subject; -}); +Cypress.Commands.add( + 'hoverIn', + { prevSubject: true }, + function (subject, options) { + expect(subject.length).to.equal(1); + + var subjElem = subject[0]; + + var bounds = subjElem.getBoundingClientRect(); + var cursorPos = { + clientX: bounds.left + bounds.width / 2, + clientY: bounds.top + bounds.height / 2, + }; + var commonEventVals = _.extend( + { bubbles: true, cancelable: true }, + cursorPos + ); + + subjElem.dispatchEvent(new MouseEvent('mouseenter', commonEventVals)); + subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventVals)); + subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventVals)); + + return subject; + } +); + +Cypress.Commands.add( + 'hoverOut', + { prevSubject: true }, + function (subject, options) { + expect(subject.length).to.equal(1); + + var subjElem = subject[0]; + + var bounds = subjElem.getBoundingClientRect(); + var cursorPos = { + clientX: Math.max(bounds.left - bounds.width / 2, 0), + clientY: Math.max(bounds.top - bounds.height / 2, 0), + }; + var commonEventValsIn = _.extend( + { bubbles: true, cancelable: true }, + cursorPos + ); + + subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventValsIn)); + subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventValsIn)); + subjElem.dispatchEvent( + new MouseEvent( + 'mouseleave', + _.extend({ relatedTarget: subjElem }, commonEventValsIn, { + clientX: bounds.left - 5, + clientY: bounds.top - 5, + }) + ) + ); + + return subject; + } +); + +Cypress.Commands.add( + 'clickEvent', + { prevSubject: true }, + function (subject, options) { + expect(subject.length).to.equal(1); + + var subjElem = subject[0]; + + var bounds = subjElem.getBoundingClientRect(); + var cursorPos = { + clientX: bounds.left + bounds.width / 2, + clientY: bounds.top + bounds.height / 2, + }; + var commonEventValsIn = _.extend( + { bubbles: true, cancelable: true }, + cursorPos + ); + + subjElem.dispatchEvent(new MouseEvent('mouseenter', commonEventValsIn)); + subjElem.dispatchEvent(new MouseEvent('mousemove', commonEventValsIn)); + subjElem.dispatchEvent(new MouseEvent('mouseover', commonEventValsIn)); + subjElem.dispatchEvent(new MouseEvent('mousedown', commonEventValsIn)); + subjElem.dispatchEvent(new MouseEvent('mouseup', commonEventValsIn)); + //subjElem.dispatchEvent(new MouseEvent('mouseleave', _.extend({ 'relatedTarget' : subjElem }, commonEventValsIn, { 'clientX' : bounds.left - 5, 'clientY' : bounds.top - 5 }) ) ); + + return subject; + } +); diff --git a/deploy/post_deploy_testing/cypress/support/e2e.js b/deploy/post_deploy_testing/cypress/support/e2e.js index 0e7290a13d..5df9c0186c 100644 --- a/deploy/post_deploy_testing/cypress/support/e2e.js +++ b/deploy/post_deploy_testing/cypress/support/e2e.js @@ -14,7 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import './commands'; // Alternatively you can use CommonJS syntax: -// require('./commands') \ No newline at end of file +// require('./commands') diff --git a/deploy/post_deploy_testing/cypress/support/index.js b/deploy/post_deploy_testing/cypress/support/index.js index ec98931579..afa6f4c9d1 100644 --- a/deploy/post_deploy_testing/cypress/support/index.js +++ b/deploy/post_deploy_testing/cypress/support/index.js @@ -21,12 +21,11 @@ import './commands'; // Alternatively you can use CommonJS syntax: // require('./commands') - /* ---- */ export const cypressVisitHeaders = { // This matches the Accept header that Chrome sends up. // By default, Cypress sends up "text/html, */*" which gets incorrectly negotiated to "*/*" --> "application/json" as seems // that request.accept.acceptable_offers() doesn't select most narrow content-type when multiple supplied unless proper 'q' values are included as well. - "Accept" : "text/html, application/xhtml+xml, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8, application/signed-exchange;v=b3;q=0.9" + Accept: 'text/html, application/xhtml+xml, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8, application/signed-exchange;v=b3;q=0.9', }; diff --git a/gulpfile.js b/gulpfile.js index 39bcbea135..a171f1d2b3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,28 +7,28 @@ const webpack = require('webpack'); const sass = require('sass'); const fs = require('fs'); - -function setProduction(done){ +function setProduction(done) { process.env.NODE_ENV = 'production'; done(); } -function setQuick(done){ +function setQuick(done) { process.env.NODE_ENV = 'quick'; done(); } -function setDevelopment(done){ +function setDevelopment(done) { process.env.NODE_ENV = 'development'; done(); } -function cleanBuildDirectory(done){ - const buildDir = "./src/encoded/static/build/"; +function cleanBuildDirectory(done) { + const buildDir = './src/encoded/static/build/'; const pathsToDelete = []; - fs.readdir(buildDir, function(err, files){ - files.forEach(function(fileName){ - if (fileName === ".gitignore") { // Skip + fs.readdir(buildDir, function (err, files) { + files.forEach(function (fileName) { + if (fileName === '.gitignore') { + // Skip return; } const filePath = path.resolve(buildDir, fileName); @@ -43,11 +43,13 @@ function cleanBuildDirectory(done){ } var countDeleted = 0; - pathsToDelete.forEach(function(filePath){ - fs.unlink(filePath, function(err){ + pathsToDelete.forEach(function (filePath) { + fs.unlink(filePath, function (err) { countDeleted++; if (countDeleted === filesToDeleteLen) { - console.log("Cleaned " + countDeleted + " files from " + buildDir); + console.log( + 'Cleaned ' + countDeleted + ' files from ' + buildDir + ); done(); } }); @@ -59,29 +61,37 @@ function webpackOnBuild(done) { const start = Date.now(); return function (err, stats) { if (err) { - throw new PluginError("webpack", err); + throw new PluginError('webpack', err); } - log("[webpack]", stats.toString({ - colors: true - })); + log( + '[webpack]', + stats.toString({ + colors: true, + }) + ); const end = Date.now(); - log("Build Completed, running for " + ((end - start)/1000)) + 's'; - if (done) { done(err); } + log('Build Completed, running for ' + (end - start) / 1000) + 's'; + if (done) { + done(err); + } }; } -function doWebpack(cb){ +function doWebpack(cb) { const webpackConfig = require('./webpack.config.js'); webpack(webpackConfig).run(webpackOnBuild(cb)); } -function watch(done){ +function watch(done) { const webpackConfig = require('./webpack.config.js'); webpack(webpackConfig).watch(300, webpackOnBuild()); } -function getLinkedSharedComponentsPath(){ - let sharedComponentPath = path.resolve(__dirname, 'node_modules/@hms-dbmi-bgm/shared-portal-components'); +function getLinkedSharedComponentsPath() { + let sharedComponentPath = path.resolve( + __dirname, + 'node_modules/@hms-dbmi-bgm/shared-portal-components' + ); const origPath = sharedComponentPath; // Follow any symlinks to get to real path. @@ -90,17 +100,23 @@ function getLinkedSharedComponentsPath(){ const isLinked = origPath !== sharedComponentPath; console.log( - "`@hms-dbmi-bgm/shared-portal-components` directory is", - isLinked ? "sym-linked to `" + sharedComponentPath + "`." : "NOT sym-linked." + '`@hms-dbmi-bgm/shared-portal-components` directory is', + isLinked + ? 'sym-linked to `' + sharedComponentPath + '`.' + : 'NOT sym-linked.' ); - return { isLinked, sharedComponentPath: isLinked ? sharedComponentPath : null }; + return { + isLinked, + sharedComponentPath: isLinked ? sharedComponentPath : null, + }; } -function buildSharedPortalComponents(done){ +function buildSharedPortalComponents(done) { const { isLinked, sharedComponentPath } = getLinkedSharedComponentsPath(); - if (!isLinked){ // Exit + if (!isLinked) { + // Exit done(); return; } @@ -110,30 +126,32 @@ function buildSharedPortalComponents(done){ path.join(sharedComponentPath, 'node_modules/.bin/babel'), [ path.join(sharedComponentPath, 'src'), - "--out-dir", + '--out-dir', path.join(sharedComponentPath, 'es'), - "--env-name", - "esm" + '--env-name', + 'esm', ], - { stdio: "inherit" } + { stdio: 'inherit' } ); - subP.on("error", (err)=>{ + subP.on('error', (err) => { console.log(`buildSharedPortalComponents errored - ${err}`); return; }); - subP.on("close", (code)=>{ - console.log(`buildSharedPortalComponents process exited with code ${code}`); + subP.on('close', (code) => { + console.log( + `buildSharedPortalComponents process exited with code ${code}` + ); done(); }); - } -function watchSharedPortalComponents(done){ +function watchSharedPortalComponents(done) { const { isLinked, sharedComponentPath } = getLinkedSharedComponentsPath(); - if (!isLinked){ // Exit + if (!isLinked) { + // Exit done(); return; } @@ -143,89 +161,117 @@ function watchSharedPortalComponents(done){ path.join(sharedComponentPath, 'node_modules/.bin/babel'), [ path.join(sharedComponentPath, 'src'), - "--out-dir", + '--out-dir', path.join(sharedComponentPath, 'es'), - "--env-name", - "esm", - "--watch" + '--env-name', + 'esm', + '--watch', ], - { stdio: "inherit" } + { stdio: 'inherit' } ); - subP.on("error", (err)=>{ + subP.on('error', (err) => { console.log(`watchSharedPortalComponents errored - ${err}`); return; }); - subP.on("close", (code)=>{ - console.log(`watchSharedPortalComponents process exited with code ${code}`); + subP.on('close', (code) => { + console.log( + `watchSharedPortalComponents process exited with code ${code}` + ); done(); }); - } - // TODO: Just use command-line `node-sass` ? -const cssOutputLocation = "./src/encoded/static/css/style.css"; -const sourceMapLocation = "./src/encoded/static/css/style.css.map"; +const cssOutputLocation = './src/encoded/static/css/style.css'; +const sourceMapLocation = './src/encoded/static/css/style.css.map'; // TODO: Consider renaming to print-preview and having separate print stylesheet (for any page) -const printCssOutputLocation = "./src/encoded/static/css/print.css"; -const printSourceMapLocation = "./src/encoded/static/css/print.css.map"; +const printCssOutputLocation = './src/encoded/static/css/print.css'; +const printSourceMapLocation = './src/encoded/static/css/print.css.map'; function doSassBuild(done, options = {}) { - let finishedCount = 4; // 2 x (regular + print) = 4 - function onFinishCount(addCt = 1){ + function onFinishCount(addCt = 1) { finishedCount -= addCt; if (finishedCount === 0) { done(); } } - function commonRenderProcess(fromFile, toFile, sourceMapLocation){ - sass.render({ - file: fromFile, - outFile: toFile, // sourceMap location - outputStyle: options.outputStyle || 'compressed', - sourceMap: true - }, function(error, result) { // node-style callback from v3.0.0 onwards - if (error) { - console.error("Error", error.status, error.file, error.line + ':' + error.column); - console.log(error.message); - onFinishCount(2); - } else { - //console.log(result.css.toString()); - - console.log("Finished compiling SCSS in", result.stats.duration, "ms"); - console.log("Writing to", toFile); - - fs.writeFile(toFile, result.css.toString(), null, function(err){ - if (err){ - return console.error(err); - } - console.log("Wrote " + toFile); - onFinishCount(); - }); - - fs.writeFile(sourceMapLocation, result.map.toString(), null, function(err){ - if (err){ - return console.error(err); - } - console.log("Wrote " + sourceMapLocation); - onFinishCount(); - }); - + function commonRenderProcess(fromFile, toFile, sourceMapLocation) { + sass.render( + { + file: fromFile, + outFile: toFile, // sourceMap location + outputStyle: options.outputStyle || 'compressed', + sourceMap: true, + }, + function (error, result) { + // node-style callback from v3.0.0 onwards + if (error) { + console.error( + 'Error', + error.status, + error.file, + error.line + ':' + error.column + ); + console.log(error.message); + onFinishCount(2); + } else { + //console.log(result.css.toString()); + + console.log( + 'Finished compiling SCSS in', + result.stats.duration, + 'ms' + ); + console.log('Writing to', toFile); + + fs.writeFile( + toFile, + result.css.toString(), + null, + function (err) { + if (err) { + return console.error(err); + } + console.log('Wrote ' + toFile); + onFinishCount(); + } + ); + + fs.writeFile( + sourceMapLocation, + result.map.toString(), + null, + function (err) { + if (err) { + return console.error(err); + } + console.log('Wrote ' + sourceMapLocation); + onFinishCount(); + } + ); + } } - }); + ); } - commonRenderProcess('./src/encoded/static/scss/style.scss', cssOutputLocation, sourceMapLocation); - commonRenderProcess('./src/encoded/static/scss/print.scss', printCssOutputLocation, printSourceMapLocation); + commonRenderProcess( + './src/encoded/static/scss/style.scss', + cssOutputLocation, + sourceMapLocation + ); + commonRenderProcess( + './src/encoded/static/scss/print.scss', + printCssOutputLocation, + printSourceMapLocation + ); } - const devQuick = gulp.series( cleanBuildDirectory, setQuick, @@ -240,12 +286,7 @@ const devAnalyzed = gulp.series( doWebpack ); -const build = gulp.series( - cleanBuildDirectory, - setProduction, - doWebpack -); - +const build = gulp.series(cleanBuildDirectory, setProduction, doWebpack); //gulp.task('dev', devSlow); //gulp.task('build-quick', buildQuick); @@ -258,10 +299,11 @@ gulp.task('build-scss', (done) => doSassBuild(done, {})); gulp.task('build-scss-dev', (done) => { doSassBuild( () => { - console.log('Watching for changes (if ran via `npm run watch-scss`)'); + console.log( + 'Watching for changes (if ran via `npm run watch-scss`)' + ); done(); }, - { outputStyle : 'expanded' } + { outputStyle: 'expanded' } ); }); - diff --git a/src/encoded/static/browser.js b/src/encoded/static/browser.js index bedd0b1dd9..8dcef5140f 100644 --- a/src/encoded/static/browser.js +++ b/src/encoded/static/browser.js @@ -18,8 +18,7 @@ import { BrowserFeat } from '@hms-dbmi-bgm/shared-portal-components/es/component * If no user_details provided, assume not logged in and unset JWT, then continue. * User info would have been obtained on login & contains user_actions (only obtained through /login). */ -function updateSessionInfo(){ - +function updateSessionInfo() { let props; // Try-block just in case, @@ -27,7 +26,7 @@ function updateSessionInfo(){ // so is available before this JS (via bundle.js) try { props = getRenderedPropValues(document, 'user_info'); - } catch(e) { + } catch (e) { console.error(e); return false; } @@ -35,7 +34,7 @@ function updateSessionInfo(){ const { user_info } = props; const { details: { email } = {} } = user_info || {}; - if (email && typeof email === 'string'){ + if (email && typeof email === 'string') { // We have user_info from server-side; keep client-side in sync (in case updated via/by back-end / dif client at some point) JWT.saveUserInfoLocalStorage(user_info); } else { @@ -48,41 +47,46 @@ function updateSessionInfo(){ // Inside this function, kick-off all initialization, everything up to this // point should be definitions. if (typeof window !== 'undefined' && window.document && !window.TEST_RUNNER) { - - window.onload = function(){ - console.log("Window Loaded"); + window.onload = function () { + console.log('Window Loaded'); window._onload_event_fired = true; }; updateSessionInfo(); - domready(function(){ + domready(function () { console.log('Browser: ready'); // Update Redux store from Redux store props that've been rendered server-side // into */} - */} -