From f809c7fa9efef1cd01110c59fae0912ef9616ec3 Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 1 Dec 2023 18:00:39 -0500 Subject: [PATCH 1/8] feat(chrome-extension): Extend WebSSO in Chrome Extension [SDK-836] --- .changeset/shiny-glasses-switch.md | 57 + package-lock.json | 1175 ++++++----------- package.json | 4 + packages/chrome-extension/README.md | 38 +- packages/chrome-extension/jest.config.js | 4 +- packages/chrome-extension/jest.setup.ts | 5 + packages/chrome-extension/package.json | 4 +- .../chrome-extension/src/ClerkProvider.tsx | 29 +- packages/chrome-extension/src/cache.ts | 31 - packages/chrome-extension/src/constants.ts | 2 + packages/chrome-extension/src/index.ts | 4 +- packages/chrome-extension/src/singleton.ts | 90 +- packages/chrome-extension/src/utils.test.ts | 67 - packages/chrome-extension/src/utils.ts | 17 - .../src/utils/cookies.test.ts | 37 + .../chrome-extension/src/utils/cookies.ts | 5 + packages/chrome-extension/src/utils/errors.ts | 12 + .../src/utils/storage.test.ts | 104 ++ .../chrome-extension/src/utils/storage.ts | 47 + .../src/utils/validation.test.ts | 62 + .../chrome-extension/src/utils/validation.ts | 23 + packages/chrome-extension/tsconfig.lint.json | 5 + 22 files changed, 832 insertions(+), 990 deletions(-) create mode 100644 .changeset/shiny-glasses-switch.md create mode 100644 packages/chrome-extension/jest.setup.ts delete mode 100644 packages/chrome-extension/src/cache.ts create mode 100644 packages/chrome-extension/src/constants.ts delete mode 100644 packages/chrome-extension/src/utils.test.ts delete mode 100644 packages/chrome-extension/src/utils.ts create mode 100644 packages/chrome-extension/src/utils/cookies.test.ts create mode 100644 packages/chrome-extension/src/utils/cookies.ts create mode 100644 packages/chrome-extension/src/utils/errors.ts create mode 100644 packages/chrome-extension/src/utils/storage.test.ts create mode 100644 packages/chrome-extension/src/utils/storage.ts create mode 100644 packages/chrome-extension/src/utils/validation.test.ts create mode 100644 packages/chrome-extension/src/utils/validation.ts create mode 100644 packages/chrome-extension/tsconfig.lint.json diff --git a/.changeset/shiny-glasses-switch.md b/.changeset/shiny-glasses-switch.md new file mode 100644 index 00000000000..898468d104d --- /dev/null +++ b/.changeset/shiny-glasses-switch.md @@ -0,0 +1,57 @@ +--- +'@clerk/chrome-extension': major +--- + +Expand the ability for `@clerk/chrome-extension` WebSSO to sync with host applications which use URL-based session syncing. + +### How to Update + +**WebSSO Local Development Host Permissions:** + +Add `*://localhost:*/*` to the `host_permissions` array in your `manifest.json` file: +```json +{ + "host_permissions": ["*://localhost:*/*"] +} +``` + +If you're using a local domain other than `localhost`, you'll want replace that entry with your domain: `*:///*` + +```json +{ + "host_permissions": ["*:///*"] +} +``` + +**WebSSO Provider settings:** + +```tsx + navigate(to)} + routerReplace={to => navigate(to, { replace: true })} + syncSessionWithTab + + // tokenCache is now storageCache (See below) + storageCache={/* ... */} + + // [Development Only]: If the host application isn't on + // `http://localhost`, you can provide it here: + syncSessionHost="http://" +> +``` + +**WebSSO Storage Cache Interface:** + +With the prop change from `tokenCache` to `storageCache`, the interface has been expanded to allow for more flexibility. + +The new interface is as follows: + +```ts +type StorageCache = { + createKey: (...keys: string[]) => string; + get: (key: string) => Promise; + remove: (key: string) => Promise; + set: (key: string, value: string) => Promise; +}; +``` diff --git a/package-lock.json b/package-lock.json index 09b65790a84..19431ba3dac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ "http-server": "^14.1.1", "husky": "^8.0.3", "jest": "^29.7.0", + "jest-chrome": "^0.8.0", "jest-environment-jsdom": "^29.3.1", "lint-staged": "^14.0.1", "npm-cli-adduser": "^1.1.4", @@ -80,9 +81,8 @@ }, "node_modules/@actions/core": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", - "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", "dev": true, + "license": "MIT", "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" @@ -90,9 +90,8 @@ }, "node_modules/@actions/http-client": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", - "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==", "dev": true, + "license": "MIT", "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" @@ -100,9 +99,8 @@ }, "node_modules/@actions/http-client/node_modules/undici": { "version": "5.27.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", - "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", "dev": true, + "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -1013,9 +1011,8 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -2342,9 +2339,8 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@builder.io/partytown": { "version": "0.7.6", @@ -3856,9 +3852,8 @@ }, "node_modules/@fastify/busboy": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" } @@ -4587,9 +4582,8 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "devOptional": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -4603,18 +4597,16 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "devOptional": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -4625,9 +4617,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "devOptional": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4637,9 +4628,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "devOptional": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -4649,18 +4639,16 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -4675,9 +4663,8 @@ }, "node_modules/@jest/console/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4690,9 +4677,8 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4706,9 +4692,8 @@ }, "node_modules/@jest/console/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4718,24 +4703,21 @@ }, "node_modules/@jest/console/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/console/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4745,9 +4727,8 @@ }, "node_modules/@jest/core": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", @@ -4792,9 +4773,8 @@ }, "node_modules/@jest/core/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4807,9 +4787,8 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4823,9 +4802,8 @@ }, "node_modules/@jest/core/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4835,24 +4813,21 @@ }, "node_modules/@jest/core/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/core/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/core/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -4864,9 +4839,8 @@ }, "node_modules/@jest/core/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4876,15 +4850,13 @@ }, "node_modules/@jest/core/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/core/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4894,9 +4866,8 @@ }, "node_modules/@jest/environment": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", @@ -4909,9 +4880,8 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "devOptional": true, + "license": "MIT", "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" @@ -4922,9 +4892,8 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "devOptional": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -4934,9 +4903,8 @@ }, "node_modules/@jest/fake-timers": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", @@ -4951,9 +4919,8 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -4966,9 +4933,8 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "devOptional": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", @@ -5009,9 +4975,8 @@ }, "node_modules/@jest/reporters/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5024,9 +4989,8 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5040,9 +5004,8 @@ }, "node_modules/@jest/reporters/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5052,15 +5015,13 @@ }, "node_modules/@jest/reporters/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/reporters/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5078,18 +5039,16 @@ }, "node_modules/@jest/reporters/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/reporters/node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "devOptional": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -5102,9 +5061,8 @@ }, "node_modules/@jest/reporters/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5117,9 +5075,8 @@ }, "node_modules/@jest/reporters/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5140,9 +5097,8 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -5154,9 +5110,8 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", @@ -5169,9 +5124,8 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", @@ -5184,9 +5138,8 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", @@ -5210,9 +5163,8 @@ }, "node_modules/@jest/transform/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5225,9 +5177,8 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5241,9 +5192,8 @@ }, "node_modules/@jest/transform/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5253,36 +5203,31 @@ }, "node_modules/@jest/transform/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/transform/node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@jest/transform/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/transform/node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/@jest/transform/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5292,9 +5237,8 @@ }, "node_modules/@jest/transform/node_modules/write-file-atomic": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "devOptional": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -5305,9 +5249,8 @@ }, "node_modules/@jest/types": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -5919,134 +5862,6 @@ "node": ">= 10" } }, - "node_modules/@next/swc-darwin-x64": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.6.tgz", - "integrity": "sha512-6cgBfxg98oOCSr4BckWjLLgiVwlL3vlLj8hXg2b+nDgm4bC/qVXXLfpLB9FHdoDu4057hzywbxKvmYGmi7yUzA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.6.tgz", - "integrity": "sha512-txagBbj1e1w47YQjcKgSU4rRVQ7uF29YpnlHV5xuVUsgCUf2FmyfJ3CPjZUvpIeXCJAoMCFAoGnbtX86BK7+sg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.6.tgz", - "integrity": "sha512-cGd+H8amifT86ZldVJtAKDxUqeFyLWW+v2NlBULnLAdWsiuuN8TuhVBt8ZNpCqcAuoruoSWynvMWixTFcroq+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.6.tgz", - "integrity": "sha512-Mc2b4xiIWKXIhBy2NBTwOxGD3nHLmq4keFk+d4/WL5fMsB8XdJRdtUlL87SqVCTSaf1BRuQQf1HvXZcy+rq3Nw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.6.tgz", - "integrity": "sha512-CFHvP9Qz98NruJiUnCe61O6GveKKHpJLloXbDSWRhqhkJdZD2zU5hG+gtVJR//tyW897izuHpM6Gtf6+sNgJPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.6.tgz", - "integrity": "sha512-aFv1ejfkbS7PUa1qVPwzDHjQWQtknzAZWGTKYIAaS4NMtBlk3VyA6AYn593pqNanlicewqyl2jUhQAaFV/qXsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.6.tgz", - "integrity": "sha512-XqqpHgEIlBHvzwG8sp/JXMFkLAfGLqkbVsyN+/Ih1mR8INb6YCc2x/Mbwi6hsAgUnqQztz8cvEbHJUbSl7RHDg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.6.tgz", - "integrity": "sha512-Cqfe1YmOS7k+5mGu92nl5ULkzpKuxJrP3+4AEuPmrpFZ3BHxTY3TnHmU1On3bFmFFs6FbTcdF58CCUProGpIGQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "license": "MIT", @@ -8100,9 +7915,8 @@ }, "node_modules/@types/babel__core": { "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz", - "integrity": "sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -8113,18 +7927,16 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.6", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.6.tgz", - "integrity": "sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.3.tgz", - "integrity": "sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -8132,18 +7944,16 @@ }, "node_modules/@types/babel__traverse": { "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.3.tgz", - "integrity": "sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/base-64": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/base-64/-/base-64-1.0.2.tgz", - "integrity": "sha512-uPgKMmM9fmn7I+Zi6YBqctOye4SlJsHKcisjHIMWpb2YKZRc36GpKyNuQ03JcT+oNXg1m7Uv4wU94EVltn8/cw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/better-sqlite3": { "version": "7.6.4", @@ -8336,9 +8146,8 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz", - "integrity": "sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==", "devOptional": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -8497,9 +8306,8 @@ }, "node_modules/@types/node": { "version": "18.18.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", - "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", "devOptional": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -8678,6 +8486,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/webextension-polyfill": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@types/webextension-polyfill/-/webextension-polyfill-0.10.7.tgz", + "integrity": "sha512-10ql7A0qzBmFB+F+qAke/nP1PIonS0TXZAOMVOxEUsm+lGSW6uwVcISFNa0I4Oyj0884TZVWGGMIWeXOVSNFHw==", + "dev": true + }, "node_modules/@types/webpack-dev-server": { "version": "4.7.2", "dev": true, @@ -9581,19 +9395,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/@zxcvbn-ts/core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", - "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", - "dependencies": { - "fastest-levenshtein": "1.0.16" - } - }, - "node_modules/@zxcvbn-ts/language-common": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", - "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==" - }, "node_modules/abab": { "version": "2.0.6", "dev": true, @@ -9704,9 +9505,8 @@ }, "node_modules/aggregate-error": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^4.0.0", "indent-string": "^5.0.0" @@ -9720,9 +9520,8 @@ }, "node_modules/aggregate-error/node_modules/indent-string": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -10279,9 +10078,8 @@ }, "node_modules/babel-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -10300,9 +10098,8 @@ }, "node_modules/babel-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -10315,9 +10112,8 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10331,9 +10127,8 @@ }, "node_modules/babel-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -10343,24 +10138,21 @@ }, "node_modules/babel-jest/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/babel-jest/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/babel-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -10423,9 +10215,8 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -10439,9 +10230,8 @@ }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -10455,18 +10245,16 @@ }, "node_modules/babel-plugin-istanbul/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "devOptional": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -10621,9 +10409,8 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -10710,9 +10497,8 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "devOptional": true, + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" @@ -10730,8 +10516,7 @@ }, "node_modules/base-64": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" + "license": "MIT" }, "node_modules/base-x": { "version": "3.0.9", @@ -11591,9 +11376,8 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -11689,9 +11473,8 @@ }, "node_modules/cjs-module-lexer": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/clean-regexp": { "version": "1.0.0", @@ -11712,9 +11495,8 @@ }, "node_modules/clean-stack": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "5.0.0" }, @@ -11727,9 +11509,8 @@ }, "node_modules/clean-stack/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -12029,9 +11810,8 @@ }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "devOptional": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -12048,9 +11828,8 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/color": { "version": "4.2.3", @@ -12612,9 +12391,8 @@ }, "node_modules/cp-file": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", - "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.10", "nested-error-stacks": "^2.1.1", @@ -12629,9 +12407,8 @@ }, "node_modules/cpy": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", - "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", "dev": true, + "license": "MIT", "dependencies": { "arrify": "^3.0.0", "cp-file": "^10.0.0", @@ -12651,9 +12428,8 @@ }, "node_modules/cpy-cli": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", - "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", "dev": true, + "license": "MIT", "dependencies": { "cpy": "^10.1.0", "meow": "^12.0.1" @@ -12670,9 +12446,8 @@ }, "node_modules/cpy-cli/node_modules/meow": { "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, + "license": "MIT", "engines": { "node": ">=16.10" }, @@ -12682,9 +12457,8 @@ }, "node_modules/cpy/node_modules/arrify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -12694,9 +12468,8 @@ }, "node_modules/cpy/node_modules/p-filter": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", - "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", "dev": true, + "license": "MIT", "dependencies": { "p-map": "^5.1.0" }, @@ -12709,9 +12482,8 @@ }, "node_modules/cpy/node_modules/p-filter/node_modules/p-map": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^4.0.0" }, @@ -12724,9 +12496,8 @@ }, "node_modules/cpy/node_modules/p-map": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", - "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -12747,9 +12518,8 @@ }, "node_modules/create-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -12768,9 +12538,8 @@ }, "node_modules/create-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -12783,9 +12552,8 @@ }, "node_modules/create-jest/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12799,9 +12567,8 @@ }, "node_modules/create-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -12811,24 +12578,21 @@ }, "node_modules/create-jest/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/create-jest/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/create-jest/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -13325,9 +13089,8 @@ }, "node_modules/dedent": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", "devOptional": true, + "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -13633,9 +13396,8 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13783,9 +13545,8 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "devOptional": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -14028,9 +13789,8 @@ }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -15211,8 +14971,7 @@ }, "node_modules/eslint-plugin-unused-imports": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz", - "integrity": "sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==", + "license": "MIT", "dependencies": { "eslint-rule-composer": "^0.3.0" }, @@ -15231,8 +14990,7 @@ }, "node_modules/eslint-rule-composer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -15598,8 +15356,6 @@ }, "node_modules/exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "devOptional": true, "engines": { "node": ">= 0.8.0" @@ -15615,9 +15371,8 @@ }, "node_modules/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -18160,9 +17915,8 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -18911,9 +18665,8 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/html-rewriter-wasm": { "version": "0.4.1", @@ -19741,9 +19494,8 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -20175,18 +19927,16 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.1.tgz", - "integrity": "sha512-opCrKqbthmq3SKZ10mFMQG9dk3fTa3quaOLD35kJa5ejwZHd9xAr+kLuziiZz2cG32s4lMZxNdmdcEQnTDP4+g==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -20200,9 +19950,8 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -20214,18 +19963,16 @@ }, "node_modules/istanbul-lib-report/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "devOptional": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -20238,9 +19985,8 @@ }, "node_modules/istanbul-lib-report/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -20250,9 +19996,8 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -20264,18 +20009,16 @@ }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -20319,9 +20062,8 @@ }, "node_modules/jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -20345,9 +20087,8 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "devOptional": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", @@ -20359,9 +20100,8 @@ }, "node_modules/jest-changed-files/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "devOptional": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -20372,11 +20112,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jest-chrome": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/jest-chrome/-/jest-chrome-0.8.0.tgz", + "integrity": "sha512-39RR1GT9nI4e4jsuH1vIf4l5ApxxkcstjGJr+GsOURL8f4Db0UlbRnsZaM+ZRniaGtokqklUH5VFKGZZ6YztUg==", + "dev": true, + "dependencies": { + "@types/chrome": "^0.0.114" + }, + "peerDependencies": { + "jest": "^26.0.1 || ^27.0.0" + } + }, + "node_modules/jest-chrome/node_modules/@types/chrome": { + "version": "0.0.114", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.114.tgz", + "integrity": "sha512-i7qRr74IrxHtbnrZSKUuP5Uvd5EOKwlwJq/yp7+yTPihOXnPhNQO4Z5bqb1XTnrjdbUKEJicaVVbhcgtRijmLA==", + "dev": true, + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, "node_modules/jest-circus": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -20405,9 +20166,8 @@ }, "node_modules/jest-circus/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -20420,9 +20180,8 @@ }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20436,9 +20195,8 @@ }, "node_modules/jest-circus/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -20448,24 +20206,21 @@ }, "node_modules/jest-circus/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-circus/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-circus/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "devOptional": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -20478,9 +20233,8 @@ }, "node_modules/jest-circus/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -20492,9 +20246,8 @@ }, "node_modules/jest-circus/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -20504,15 +20257,13 @@ }, "node_modules/jest-circus/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-circus/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -20522,9 +20273,8 @@ }, "node_modules/jest-cli": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", @@ -20555,9 +20305,8 @@ }, "node_modules/jest-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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -20570,9 +20319,8 @@ }, "node_modules/jest-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==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20586,9 +20334,8 @@ }, "node_modules/jest-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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -20598,24 +20345,21 @@ }, "node_modules/jest-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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -20625,9 +20369,8 @@ }, "node_modules/jest-config": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", @@ -20670,9 +20413,8 @@ }, "node_modules/jest-config/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -20685,9 +20427,8 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20701,9 +20442,8 @@ }, "node_modules/jest-config/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -20713,15 +20453,13 @@ }, "node_modules/jest-config/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-config/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -20739,18 +20477,16 @@ }, "node_modules/jest-config/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-config/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -20762,9 +20498,8 @@ }, "node_modules/jest-config/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -20774,15 +20509,13 @@ }, "node_modules/jest-config/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-config/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -20792,9 +20525,8 @@ }, "node_modules/jest-diff": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "devOptional": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -20807,9 +20539,8 @@ }, "node_modules/jest-diff/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -20822,9 +20553,8 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20838,9 +20568,8 @@ }, "node_modules/jest-diff/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -20850,24 +20579,21 @@ }, "node_modules/jest-diff/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-diff/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-diff/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -20879,9 +20605,8 @@ }, "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -20891,15 +20616,13 @@ }, "node_modules/jest-diff/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-diff/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -20909,9 +20632,8 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "devOptional": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -20921,9 +20643,8 @@ }, "node_modules/jest-each": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -20937,9 +20658,8 @@ }, "node_modules/jest-each/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -20952,9 +20672,8 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20968,9 +20687,8 @@ }, "node_modules/jest-each/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -20980,24 +20698,21 @@ }, "node_modules/jest-each/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-each/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-each/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -21009,9 +20724,8 @@ }, "node_modules/jest-each/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -21021,15 +20735,13 @@ }, "node_modules/jest-each/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-each/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21065,9 +20777,8 @@ }, "node_modules/jest-environment-node": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -21082,18 +20793,16 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "devOptional": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", @@ -21116,18 +20825,16 @@ }, "node_modules/jest-haste-map/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-haste-map/node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "devOptional": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -21140,9 +20847,8 @@ }, "node_modules/jest-haste-map/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21155,9 +20861,8 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "devOptional": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" @@ -21168,9 +20873,8 @@ }, "node_modules/jest-leak-detector/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -21180,9 +20884,8 @@ }, "node_modules/jest-leak-detector/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -21194,15 +20897,13 @@ }, "node_modules/jest-leak-detector/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-matcher-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "devOptional": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -21215,9 +20916,8 @@ }, "node_modules/jest-matcher-utils/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21230,9 +20930,8 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21246,9 +20945,8 @@ }, "node_modules/jest-matcher-utils/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21258,24 +20956,21 @@ }, "node_modules/jest-matcher-utils/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-matcher-utils/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -21287,9 +20982,8 @@ }, "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -21299,15 +20993,13 @@ }, "node_modules/jest-matcher-utils/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-matcher-utils/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21317,9 +21009,8 @@ }, "node_modules/jest-message-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -21390,9 +21081,8 @@ }, "node_modules/jest-message-util/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -21404,9 +21094,8 @@ }, "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -21416,9 +21105,8 @@ }, "node_modules/jest-message-util/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", @@ -21433,9 +21121,8 @@ }, "node_modules/jest-mock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -21447,9 +21134,8 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -21464,18 +21150,16 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "devOptional": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "devOptional": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -21493,9 +21177,8 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "devOptional": true, + "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" @@ -21506,9 +21189,8 @@ }, "node_modules/jest-resolve/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21521,9 +21203,8 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21537,9 +21218,8 @@ }, "node_modules/jest-resolve/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21549,24 +21229,21 @@ }, "node_modules/jest-resolve/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-resolve/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-resolve/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21576,9 +21253,8 @@ }, "node_modules/jest-runner": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", @@ -21608,9 +21284,8 @@ }, "node_modules/jest-runner/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21623,9 +21298,8 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21639,9 +21313,8 @@ }, "node_modules/jest-runner/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21651,24 +21324,21 @@ }, "node_modules/jest-runner/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-runner/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-runner/node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "devOptional": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -21681,9 +21351,8 @@ }, "node_modules/jest-runner/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21696,9 +21365,8 @@ }, "node_modules/jest-runner/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "devOptional": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -21711,9 +21379,8 @@ }, "node_modules/jest-runner/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21723,9 +21390,8 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -21756,9 +21422,8 @@ }, "node_modules/jest-runtime/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21771,9 +21436,8 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21787,9 +21451,8 @@ }, "node_modules/jest-runtime/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21799,15 +21462,13 @@ }, "node_modules/jest-runtime/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-runtime/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -21825,18 +21486,16 @@ }, "node_modules/jest-runtime/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-runtime/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21846,9 +21505,8 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "devOptional": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -21877,9 +21535,8 @@ }, "node_modules/jest-snapshot/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -21892,9 +21549,8 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -21908,9 +21564,8 @@ }, "node_modules/jest-snapshot/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -21920,24 +21575,21 @@ }, "node_modules/jest-snapshot/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-snapshot/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-snapshot/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -21949,9 +21601,8 @@ }, "node_modules/jest-snapshot/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -21961,15 +21612,13 @@ }, "node_modules/jest-snapshot/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-snapshot/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -21979,9 +21628,8 @@ }, "node_modules/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -22060,9 +21708,8 @@ }, "node_modules/jest-validate": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", @@ -22077,9 +21724,8 @@ }, "node_modules/jest-validate/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -22092,9 +21738,8 @@ }, "node_modules/jest-validate/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -22108,9 +21753,8 @@ }, "node_modules/jest-validate/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -22120,24 +21764,21 @@ }, "node_modules/jest-validate/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-validate/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-validate/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -22149,9 +21790,8 @@ }, "node_modules/jest-validate/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -22161,15 +21801,13 @@ }, "node_modules/jest-validate/node_modules/react-is": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-validate/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -22179,9 +21817,8 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "devOptional": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", @@ -22198,9 +21835,8 @@ }, "node_modules/jest-watcher/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -22213,9 +21849,8 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -22229,9 +21864,8 @@ }, "node_modules/jest-watcher/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==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -22241,24 +21875,21 @@ }, "node_modules/jest-watcher/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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jest-watcher/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==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-watcher/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==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -22547,9 +22178,8 @@ }, "node_modules/junk": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", - "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -22668,9 +22298,8 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -23488,9 +23117,8 @@ }, "node_modules/makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -24194,9 +23822,8 @@ }, "node_modules/nested-error-stacks": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", - "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/next": { "version": "13.4.19", @@ -25201,9 +24828,8 @@ }, "node_modules/p-event": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", - "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", "dev": true, + "license": "MIT", "dependencies": { "p-timeout": "^5.0.2" }, @@ -25302,9 +24928,8 @@ }, "node_modules/p-timeout": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -26953,8 +26578,6 @@ }, "node_modules/pure-rand": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", "devOptional": true, "funding": [ { @@ -26965,7 +26588,8 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/q": { "version": "1.5.1", @@ -28009,9 +27633,8 @@ }, "node_modules/resolve.exports": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -28153,7 +27776,7 @@ "license": "BSD-3-Clause" }, "node_modules/rollup": { - "version": "3.23.1", + "version": "3.29.4", "dev": true, "license": "MIT", "bin": { @@ -29219,9 +28842,8 @@ }, "node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "devOptional": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -29229,9 +28851,8 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -29590,9 +29211,8 @@ }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "devOptional": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -29767,9 +29387,8 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -30318,9 +29937,8 @@ }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "devOptional": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -30332,9 +29950,8 @@ }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -30489,9 +30106,8 @@ }, "node_modules/tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "devOptional": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -31108,9 +30724,8 @@ }, "node_modules/tunnel": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } @@ -31128,9 +30743,8 @@ }, "node_modules/turbo": { "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo/-/turbo-1.10.16.tgz", - "integrity": "sha512-2CEaK4FIuSZiP83iFa9GqMTQhroW2QryckVqUydmg4tx78baftTOS0O+oDAhvo9r9Nit4xUEtC1RAHoqs6ZEtg==", "dev": true, + "license": "MPL-2.0", "bin": { "turbo": "bin/turbo" }, @@ -31143,84 +30757,18 @@ "turbo-windows-arm64": "1.10.16" } }, - "node_modules/turbo-darwin-64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.10.16.tgz", - "integrity": "sha512-+Jk91FNcp9e9NCLYlvDDlp2HwEDp14F9N42IoW3dmHI5ZkGSXzalbhVcrx3DOox3QfiNUHxzWg4d7CnVNCuuMg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, "node_modules/turbo-darwin-arm64": { "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.10.16.tgz", - "integrity": "sha512-jqGpFZipIivkRp/i+jnL8npX0VssE6IAVNKtu573LXtssZdV/S+fRGYA16tI46xJGxSAivrZ/IcgZrV6Jk80bw==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "darwin" ] }, - "node_modules/turbo-linux-64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.10.16.tgz", - "integrity": "sha512-PpqEZHwLoizQ6sTUvmImcRmACyRk9EWLXGlqceogPZsJ1jTRK3sfcF9fC2W56zkSIzuLEP07k5kl+ZxJd8JMcg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-linux-arm64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.10.16.tgz", - "integrity": "sha512-TMjFYz8to1QE0fKVXCIvG/4giyfnmqcQIwjdNfJvKjBxn22PpbjeuFuQ5kNXshUTRaTJihFbuuCcb5OYFNx4uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-windows-64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.10.16.tgz", - "integrity": "sha512-+jsf68krs0N66FfC4/zZvioUap/Tq3sPFumnMV+EBo8jFdqs4yehd6+MxIwYTjSQLIcpH8KoNMB0gQYhJRLZzw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/turbo-windows-arm64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.10.16.tgz", - "integrity": "sha512-sKm3hcMM1bl0B3PLG4ifidicOGfoJmOEacM5JtgBkYM48ncMHjkHfFY7HrJHZHUnXM4l05RQTpLFoOl/uIo2HQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/tweetnacl": { "version": "0.14.5", "dev": true, @@ -31429,9 +30977,8 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -31708,9 +31255,8 @@ }, "node_modules/v8-to-istanbul": { "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", "devOptional": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -31722,9 +31268,8 @@ }, "node_modules/v8-to-istanbul/node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -32001,9 +31546,8 @@ }, "node_modules/walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -32049,6 +31593,11 @@ "node": ">= 8" } }, + "node_modules/webextension-polyfill": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz", + "integrity": "sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==" + }, "node_modules/webidl-conversions": { "version": "7.0.0", "dev": true, @@ -33353,13 +32902,15 @@ "license": "MIT", "dependencies": { "@clerk/clerk-js": "5.0.0-alpha-v5.9", - "@clerk/clerk-react": "5.0.0-alpha-v5.9" + "@clerk/clerk-react": "5.0.0-alpha-v5.9", + "webextension-polyfill": "^0.10.0" }, "devDependencies": { "@types/chrome": "*", "@types/node": "^18.17.0", "@types/react": "*", "@types/react-dom": "*", + "@types/webextension-polyfill": "^0.10.7", "eslint-config-custom": "*", "tsup": "*", "typescript": "*" @@ -33430,6 +32981,19 @@ "react-dom": ">=18" } }, + "packages/clerk-js/node_modules/@zxcvbn-ts/core": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", + "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", + "dependencies": { + "fastest-levenshtein": "1.0.16" + } + }, + "packages/clerk-js/node_modules/@zxcvbn-ts/language-common": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", + "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==" + }, "packages/clerk-js/node_modules/ajv": { "version": "8.12.0", "dev": true, @@ -34000,9 +33564,8 @@ }, "packages/shared/node_modules/cross-fetch": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } diff --git a/package.json b/package.json index bfbfb338c6c..358fe856159 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "http-server": "^14.1.1", "husky": "^8.0.3", "jest": "^29.7.0", + "jest-chrome": "^0.8.0", "jest-environment-jsdom": "^29.3.1", "lint-staged": "^14.0.1", "npm-cli-adduser": "^1.1.4", @@ -101,5 +102,8 @@ "engines": { "node": ">=18.17.0", "npm": ">=8.5.0" + }, + "overrides": { + "jest": "$jest" } } diff --git a/packages/chrome-extension/README.md b/packages/chrome-extension/README.md index 41d46cf6802..83725dc178e 100644 --- a/packages/chrome-extension/README.md +++ b/packages/chrome-extension/README.md @@ -117,12 +117,13 @@ WebSSO usage snippet: // ... navigate(to)} + routerPush={to => navigate(to)} + routerReplace={to => navigate(to, { replace: true })} syncSessionWithTab > {/* ... */} -//... +// ... ``` Examples of a chrome extension using the `@clerk/chrome-extension` package for authentication @@ -134,19 +135,34 @@ The 2 supported cases (links to different branches of the same repository): ## WebSSO required settings -### Permissions (in manifest.json) - -- "cookies" for more info see (here)[https://developer.chrome.com/docs/extensions/reference/cookies/] -- "storage" for more info see (here)[https://developer.chrome.com/docs/extensions/reference/storage/] +### Extension Manifest (`manifest.json`) -### Host permissions (in manifest.json) +#### Permissions -You will need your Frontend API URL, which can be found in your `Dashboard > API Keys > Advanced > Clerk API URLs`. +You must enable the following permissions in your `manifest.json` file: ``` -"host_permissions": ["*://YOUR_CLERK_FRONTEND_API_GOES_HERE/"], +"permissions": ["cookies", "storage"] ``` +- For more info on the "cookies" permission: (Google Developer Cookies Reference)[https://developer.chrome.com/docs/extensions/reference/cookies/] +- For more info on the "storage" permission: (Google Developer Storage Reference)[https://developer.chrome.com/docs/extensions/reference/storage/] + +#### Host Permissions + +You must enable the following host permissions in your `manifest.json` file: + +- **Development:** `"host_permissions": ["*://localhost:*/*"]` + - If you're using a domain other than `localhost`, you'll want replace that entry with your domain: `*:///*` +- **Production:** `"host_permissions": ["*:///"]` + - Your Frontend API URL can be found in `Clerk Dashboard > API Keys > Advanced > Clerk API URLs`. + +For more info on host permissions: (Google Developer `host_permissions` Reference)[https://developer.chrome.com/docs/extensions/mv3/declare_permissions/#host-permissions] + +#### ClerkProvider + +If your plan to sync sessions with a host application not on `localhost`, you'll need to use the `syncSessionHost` prop on `ClerkProvider` to specify the domain you're using, inclusive of the protocol. (eg: `https://`) + ### Clerk settings @@ -160,10 +176,6 @@ curl -X PATCH https://api.clerk.com/v1/instance \ -d '{"allowed_origins": ["chrome-extension://extension_id_goes_here"]}' ``` -## Development - -The `Enable URL-based session syncing` should be `DISABLED` from the `Clerk Dashboard > Setting` for a development instance to support @clerk/chrome-extension functionality. - ## Deploy to Production Setting the `allowed_origins` (check [Clerk Settings](#clerk-settings)) is **REQUIRED** for both **Development** and **Production** instances when using the WebSSO use case. diff --git a/packages/chrome-extension/jest.config.js b/packages/chrome-extension/jest.config.js index 82554df0854..3bc23afa620 100644 --- a/packages/chrome-extension/jest.config.js +++ b/packages/chrome-extension/jest.config.js @@ -6,13 +6,13 @@ module.exports = { roots: ['/src'], testEnvironment: 'jsdom', - setupFilesAfterEnv: ['../../jest.setup-after-env.ts'], + setupFilesAfterEnv: ['../../jest.setup-after-env.ts', '/jest.setup.ts'], moduleDirectories: ['node_modules', '/src'], transform: { '^.+\\.m?tsx?$': ['ts-jest', { diagnostics: false }], }, - + clearMocks: true, testRegex: ['/src/.*.test.[jt]sx?$'], testPathIgnorePatterns: ['/node_modules/'], diff --git a/packages/chrome-extension/jest.setup.ts b/packages/chrome-extension/jest.setup.ts new file mode 100644 index 00000000000..b5df3d97614 --- /dev/null +++ b/packages/chrome-extension/jest.setup.ts @@ -0,0 +1,5 @@ +import { chrome } from 'jest-chrome'; + +// @ts-expect-error - required for the browser polyfill +chrome.runtime.id = 'chrome-extension-test'; +Object.assign(global, { chrome, browser: chrome }); diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index 80281de7b25..db5f4342007 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -46,13 +46,15 @@ }, "dependencies": { "@clerk/clerk-js": "5.0.0-alpha-v5.9", - "@clerk/clerk-react": "5.0.0-alpha-v5.9" + "@clerk/clerk-react": "5.0.0-alpha-v5.9", + "webextension-polyfill": "^0.10.0" }, "devDependencies": { "@types/chrome": "*", "@types/node": "^18.17.0", "@types/react": "*", "@types/react-dom": "*", + "@types/webextension-polyfill": "^0.10.7", "eslint-config-custom": "*", "tsup": "*", "typescript": "*" diff --git a/packages/chrome-extension/src/ClerkProvider.tsx b/packages/chrome-extension/src/ClerkProvider.tsx index 52f613f003b..bcde13c3604 100644 --- a/packages/chrome-extension/src/ClerkProvider.tsx +++ b/packages/chrome-extension/src/ClerkProvider.tsx @@ -3,9 +3,8 @@ import type { ClerkProp, ClerkProviderProps as ClerkReactProviderProps } from '@ import { __internal__setErrorThrowerOptions, ClerkProvider as ClerkReactProvider } from '@clerk/clerk-react'; import React from 'react'; -import type { TokenCache } from './cache'; -import { ChromeStorageCache } from './cache'; import { buildClerk } from './singleton'; +import type { StorageCache } from './utils/storage'; Clerk.sdkMetadata = { name: PACKAGE_NAME, @@ -18,30 +17,29 @@ __internal__setErrorThrowerOptions({ type WebSSOClerkProviderCustomProps = | { + syncSessionHost?: never; syncSessionWithTab?: false; - tokenCache?: never; + storageCache?: never; } | { + syncSessionHost?: string; syncSessionWithTab: true; - tokenCache?: TokenCache; + storageCache?: StorageCache; }; type WebSSOClerkProviderProps = ClerkReactProviderProps & WebSSOClerkProviderCustomProps; const WebSSOClerkProvider = (props: WebSSOClerkProviderProps): JSX.Element | null => { - const { children, tokenCache: runtimeTokenCache, ...rest } = props; + const { children, storageCache: runtimeStorageCache, syncSessionWithTab, ...rest } = props; const { publishableKey = '' } = props; const [clerkInstance, setClerkInstance] = React.useState(null); - // When syncSessionWithTab is set tokenCache is an optional parameter that defaults to ChromeStorageCache - const tokenCache = runtimeTokenCache || ChromeStorageCache; - React.useEffect(() => { void (async () => { - setClerkInstance(await buildClerk({ publishableKey, tokenCache })); + setClerkInstance(await buildClerk({ publishableKey, storageCache: runtimeStorageCache })); })(); - }, []); + }, []); // eslint-disable-line react-hooks/exhaustive-deps if (!clerkInstance) { return null; @@ -74,13 +72,6 @@ const StandaloneClerkProvider = (props: ClerkReactProviderProps): JSX.Element => type ChromeExtensionClerkProviderProps = WebSSOClerkProviderProps; export function ClerkProvider(props: ChromeExtensionClerkProviderProps): JSX.Element | null { - const { tokenCache, syncSessionWithTab, ...rest } = props; - return syncSessionWithTab ? ( - - ) : ( - - ); + const { syncSessionHost, storageCache, syncSessionWithTab, ...rest } = props; + return syncSessionWithTab ? : ; } diff --git a/packages/chrome-extension/src/cache.ts b/packages/chrome-extension/src/cache.ts deleted file mode 100644 index 597368ffa26..00000000000 --- a/packages/chrome-extension/src/cache.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { getFromStorage, setInStorage } from './utils'; - -export interface TokenCache { - getToken: (key: string) => Promise; - saveToken: (key: string, token: string) => Promise; -} - -const createMemoryTokenCache = (): TokenCache => { - const cache: Record = {}; - return { - saveToken: (key, token) => { - cache[key] = token; - return Promise.resolve(); - }, - getToken: key => { - return Promise.resolve(cache[key]); - }, - }; -}; - -// Use chrome.storage (local or sync) to persist Clerk client JWT. -// More information athttps://developer.chrome.com/docs/extensions/reference/storage -const createChromeStorageCache = (): TokenCache => { - return { - saveToken: setInStorage, - getToken: getFromStorage, - }; -}; - -export const ChromeStorageCache = createChromeStorageCache(); -export const MemoryTokenCache = createMemoryTokenCache(); diff --git a/packages/chrome-extension/src/constants.ts b/packages/chrome-extension/src/constants.ts new file mode 100644 index 00000000000..74c98ab9610 --- /dev/null +++ b/packages/chrome-extension/src/constants.ts @@ -0,0 +1,2 @@ +export const CLIENT_JWT_KEY = '__client'; +export const STORAGE_KEY_CLIENT_JWT = '__clerk_client_jwt'; diff --git a/packages/chrome-extension/src/index.ts b/packages/chrome-extension/src/index.ts index 58facee8907..da7fbe97acb 100644 --- a/packages/chrome-extension/src/index.ts +++ b/packages/chrome-extension/src/index.ts @@ -1,5 +1,5 @@ export * from '@clerk/clerk-react'; +export type { StorageCache } from './utils/storage'; -// order matters since we want override @clerk/clerk-react ClerkProvider - +// The order matters since we want override @clerk/clerk-react ClerkProvider export { ClerkProvider } from './ClerkProvider'; diff --git a/packages/chrome-extension/src/singleton.ts b/packages/chrome-extension/src/singleton.ts index 21caa55bd05..c3449541c55 100644 --- a/packages/chrome-extension/src/singleton.ts +++ b/packages/chrome-extension/src/singleton.ts @@ -1,53 +1,79 @@ import { Clerk } from '@clerk/clerk-js'; import type { ClerkProp } from '@clerk/clerk-react'; +import { DEV_BROWSER_JWT_MARKER } from '@clerk/shared'; +import { parsePublishableKey } from '@clerk/shared/keys'; +import browser from 'webextension-polyfill'; -import type { TokenCache } from './cache'; -import { convertPublishableKeyToFrontendAPIOrigin, getClientCookie } from './utils'; - -const KEY = '__clerk_client_jwt'; +import { CLIENT_JWT_KEY, STORAGE_KEY_CLIENT_JWT } from './constants'; +import { getClientCookie } from './utils/cookies'; +import { assertPublishableKey, errorLogger } from './utils/errors'; +import { BrowserStorageCache, type StorageCache } from './utils/storage'; +import { validateManifest } from './utils/validation'; export let clerk: ClerkProp; type BuildClerkOptions = { publishableKey: string; - tokenCache: TokenCache; + storageCache?: StorageCache; + syncSessionHost?: string; }; -// error handler that logs the error (used in cookie retrieval and token saving) -const logErrorHandler = (err: Error) => console.error(err); +export async function buildClerk({ + publishableKey, + storageCache = BrowserStorageCache, + syncSessionHost = 'http://localhost', +}: BuildClerkOptions): Promise { + if (clerk) { + return clerk; + } -export async function buildClerk({ publishableKey, tokenCache }: BuildClerkOptions): Promise { - if (!clerk) { - const clerkFrontendAPIOrigin = convertPublishableKeyToFrontendAPIOrigin(publishableKey); + // Will throw if manifest is invalid + validateManifest(browser.runtime.getManifest()); - const clientCookie = await getClientCookie(clerkFrontendAPIOrigin).catch(logErrorHandler); + // Parse publishableKey and assert it's present/valid + const key = parsePublishableKey(publishableKey); + assertPublishableKey(key); - // TODO: Listen to client cookie changes and sync updates - // https://developer.chrome.com/docs/extensions/reference/cookies/#event-onChanged + // Will throw if publishableKey is invalid + const isProd = key.instanceType === 'production'; - if (clientCookie) { - await tokenCache.saveToken(KEY, clientCookie.value).catch(logErrorHandler); - } + // Get client cookie from browser + const clientCookie = await (isProd + ? getClientCookie(key.frontendApi, CLIENT_JWT_KEY) + : getClientCookie(syncSessionHost, DEV_BROWSER_JWT_MARKER) + ).catch(errorLogger); - clerk = new Clerk(publishableKey); + // Create StorageCache key + const CACHE_KEY = storageCache.createKey(isProd ? key.frontendApi : syncSessionHost, STORAGE_KEY_CLIENT_JWT); - // @ts-expect-error - clerk.__unstable__onBeforeRequest(async requestInit => { - requestInit.credentials = 'omit'; - requestInit.url?.searchParams.append('_is_native', '1'); + // Set client cookie in StorageCache + if (clientCookie) { + await storageCache.set(CACHE_KEY, clientCookie.value).catch(errorLogger); + } - const jwt = await tokenCache.getToken(KEY); - (requestInit.headers as Headers).set('authorization', jwt || ''); - }); + // Create Clerk instance + clerk = new Clerk(publishableKey); - // @ts-expect-error - clerk.__unstable__onAfterResponse(async (_, response) => { - const authHeader = response.headers.get('authorization'); - if (authHeader) { - await tokenCache.saveToken(KEY, authHeader); - } - }); - } + // Append appropriate query params to all Clerk requests + // @ts-expect-error - Clerk doesn't expose this unstable method publicly + clerk.__unstable__onBeforeRequest(async requestInit => { + requestInit.credentials = 'omit'; + requestInit.url?.searchParams.append('_is_native', '1'); + + const jwt = await storageCache.get(CACHE_KEY); + + (requestInit.headers as Headers).set('authorization', jwt || ''); + }); + + // Store updated JWT in StorageCache on Clerk responses + // @ts-expect-error - Clerk doesn't expose this unstable method publicly + clerk.__unstable__onAfterResponse(async (_, response) => { + const authHeader = response.headers.get('authorization'); + + if (authHeader) { + await storageCache.set(CACHE_KEY, authHeader); + } + }); return clerk; } diff --git a/packages/chrome-extension/src/utils.test.ts b/packages/chrome-extension/src/utils.test.ts deleted file mode 100644 index d0c1ff69e1a..00000000000 --- a/packages/chrome-extension/src/utils.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { convertPublishableKeyToFrontendAPIOrigin, getClientCookie, getFromStorage, setInStorage } from './utils'; - -describe('utils', () => { - const _chrome = globalThis.chrome; - - beforeAll(() => { - globalThis.chrome = { - storage: { - // @ts-ignore - local: { set: jest.fn(), get: jest.fn(k => Promise.resolve({ [k]: `storage.get:${k}` })) }, - }, - // @ts-ignore - cookies: { get: jest.fn(({ url, name }) => `cookies.get:${url}:${name}`) }, - }; - }); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - afterAll(() => { - globalThis.chrome = _chrome; - }); - - describe('convertPublishableKeyToFrontendAPIOrigin(key)', () => { - test('returns FAPI domain for production', () => { - const livePk = 'pk_live_ZXhhbXBsZS5jbGVyay5hY2NvdW50cy5kZXYk'; - - expect(convertPublishableKeyToFrontendAPIOrigin(livePk)).toEqual('https://example.clerk.accounts.dev'); - }); - - test('returns FAPI domain for development', () => { - const devPk = 'pk_test_ZXhhbXBsZS5jbGVyay5hY2NvdW50cy5kZXYk'; - - expect(convertPublishableKeyToFrontendAPIOrigin(devPk)).toEqual('https://example.clerk.accounts.dev'); - }); - - test('returns FAPI domain for invalid key', () => { - const invalidPk = 'pk_ZXhhbXBsZS5jbGVyay5hY2NvdW50cy5kZXYk'; - - const errMsg = 'The string to be decoded contains invalid characters.'; - expect(() => convertPublishableKeyToFrontendAPIOrigin(invalidPk)).toThrowError(errMsg); - }); - }); - - describe('getClientCookie(url)', () => { - test('returns cookie value from chrome.cookies if is set for url', async () => { - const url = 'http://localhost:3000'; - await expect(getClientCookie(url)).resolves.toEqual(`cookies.get:${url}:__client`); - }); - }); - - describe('setInStorage(key, value)', () => { - test('sets value in chrome.storage', async () => { - await setInStorage('key', 'value'); - - expect(globalThis.chrome.storage.local.set).toBeCalledTimes(1); - expect(globalThis.chrome.storage.local.set).toBeCalledWith({ key: 'value' }); - }); - }); - - describe('getFromStorage(key)', () => { - test('gets value from chrome.storage', async () => { - await expect(getFromStorage('key')).resolves.toEqual(`storage.get:key`); - }); - }); -}); diff --git a/packages/chrome-extension/src/utils.ts b/packages/chrome-extension/src/utils.ts deleted file mode 100644 index c627450b5c7..00000000000 --- a/packages/chrome-extension/src/utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -export function convertPublishableKeyToFrontendAPIOrigin(key = '') { - return `https://${atob(key.replace(/pk_(test|live)_/, '')).slice(0, -1)}`; -} - -export async function getClientCookie(url: string) { - return chrome.cookies.get({ url, name: '__client' }); -} - -export function setInStorage(key: string, value: string) { - return chrome.storage.local.set({ [key]: value }); -} - -export function getFromStorage(key: string) { - return chrome.storage.local.get(key).then(result => { - return result[key]; - }); -} diff --git a/packages/chrome-extension/src/utils/cookies.test.ts b/packages/chrome-extension/src/utils/cookies.test.ts new file mode 100644 index 00000000000..78e66bbe082 --- /dev/null +++ b/packages/chrome-extension/src/utils/cookies.test.ts @@ -0,0 +1,37 @@ +import browser from 'webextension-polyfill'; + +import { getClientCookie } from './cookies'; + +type RequiredCookieOpts = 'domain' | 'name' | 'value'; +type CreateCookieOpts = Pick & + Partial>; + +const createCookie = (opts: CreateCookieOpts): browser.Cookies.Cookie => ({ + firstPartyDomain: opts.domain, + hostOnly: false, + httpOnly: true, + path: '/', + sameSite: 'lax', + secure: true, + session: false, + storeId: '0', + ...opts, +}); + +describe('Cookies', () => { + describe('getClientCookie', () => { + const domain = 'clerk.domain.com'; + const url = `https://${domain}`; + const name = '__client'; + const cookie = createCookie({ name, value: 'foo', domain }); + + test('returns cookie value from browser.cookies if is set for url', async () => { + const getMock = jest.mocked(browser.cookies.get).mockResolvedValue(cookie); + + expect(await getClientCookie(url, name)).toBe(cookie); + + expect(getMock).toHaveBeenCalledTimes(1); + expect(getMock).toHaveBeenCalledWith({ url, name }); + }); + }); +}); diff --git a/packages/chrome-extension/src/utils/cookies.ts b/packages/chrome-extension/src/utils/cookies.ts new file mode 100644 index 00000000000..880b7035efb --- /dev/null +++ b/packages/chrome-extension/src/utils/cookies.ts @@ -0,0 +1,5 @@ +import browser from 'webextension-polyfill'; + +export async function getClientCookie(url: string, name: string) { + return await browser.cookies.get({ url, name }); +} diff --git a/packages/chrome-extension/src/utils/errors.ts b/packages/chrome-extension/src/utils/errors.ts new file mode 100644 index 00000000000..dd28e3e2411 --- /dev/null +++ b/packages/chrome-extension/src/utils/errors.ts @@ -0,0 +1,12 @@ +import { buildErrorThrower } from '@clerk/shared/error'; + +export const errorLogger = (err: Error) => console.error(err, err.stack); +export const errorThrower = buildErrorThrower({ packageName: '@clerk/chrome-extension' }); + +export const missingManifestKeyError = (key: string) => `Missing \`${key}\` entry in manifest.json`; + +export function assertPublishableKey(publishableKey: unknown): asserts publishableKey { + if (!publishableKey) { + errorThrower.throwMissingPublishableKeyError(); + } +} diff --git a/packages/chrome-extension/src/utils/storage.test.ts b/packages/chrome-extension/src/utils/storage.test.ts new file mode 100644 index 00000000000..c0575bf8cbe --- /dev/null +++ b/packages/chrome-extension/src/utils/storage.test.ts @@ -0,0 +1,104 @@ +import browser from 'webextension-polyfill'; + +import { BrowserStorageCache, MemoryStorageCache } from './storage'; + +describe('StorageCache', () => { + const KEY = 'foo'; + const VALUE = 'bar'; + + const _void = void 0; + + describe('createKey', () => { + test('returns a string key', () => { + expect(BrowserStorageCache.createKey('a', 'b', 'c')).toBe('a|b|c'); + }); + + test('omits falsy values', () => { + // @ts-expect-error - Testing; Intentionally passing undefined value + expect(BrowserStorageCache.createKey('a', undefined, false, null, 'c')).toBe('a|c'); + }); + }); + + describe('set', () => { + test('setting the storage cache', async () => { + const setMock = jest.mocked(browser.storage.local.set).mockResolvedValueOnce(_void); + + expect(await BrowserStorageCache.set(KEY, VALUE)).toBe(_void); + expect(setMock).toHaveBeenCalledTimes(1); + expect(setMock).toHaveBeenCalledWith({ [KEY]: VALUE }); + }); + }); + + describe('remove', () => { + test('removing from the storage cache', async () => { + const removeMock = jest.mocked(browser.storage.local.remove).mockResolvedValueOnce(_void); + + expect(await BrowserStorageCache.remove(KEY)).toBe(_void); + expect(removeMock).toHaveBeenCalledTimes(1); + expect(removeMock).toHaveBeenCalledWith(KEY); + }); + }); + + describe('get', () => { + test('value missing', async () => { + const getMock = jest.mocked(browser.storage.local.get).mockResolvedValue({}); + + expect(await BrowserStorageCache.get(KEY)).toBeUndefined(); + expect(getMock).toHaveBeenCalledTimes(1); + expect(getMock).toHaveBeenCalledWith(KEY); + }); + + test('value exists', async () => { + const getMock = jest.mocked(browser.storage.local.get).mockResolvedValue({ [KEY]: VALUE }); + + expect(await BrowserStorageCache.get(KEY)).toBe(VALUE); + expect(getMock).toHaveBeenCalledTimes(1); + expect(getMock).toHaveBeenCalledWith(KEY); + }); + }); +}); + +describe('MemoryStorageCache', () => { + const KEY = 'foo'; + const VALUE = 'bar'; + + const _void = void 0; + + describe('createKey', () => { + test('returns a string key', () => { + expect(MemoryStorageCache.createKey('a', 'b', 'c')).toBe('a|b|c'); + }); + + test('omits falsy values', () => { + // @ts-expect-error - Testing; Intentionally passing undefined value + expect(MemoryStorageCache.createKey('a', undefined, false, null, 'c')).toBe('a|c'); + }); + }); + + describe('set', () => { + test('setting the storage cache', async () => { + await MemoryStorageCache.set(KEY, VALUE); + expect(await MemoryStorageCache.get(KEY)).toBe(VALUE); + }); + }); + + describe('remove', () => { + test('removing from the storage cache', async () => { + expect(await MemoryStorageCache.set(KEY, VALUE)).toBe(_void); + expect(await MemoryStorageCache.get(KEY)).toBe(VALUE); + expect(await MemoryStorageCache.remove(KEY)).toBe(_void); + expect(await MemoryStorageCache.get(KEY)).toBeUndefined(); + }); + }); + + describe('get', () => { + test('value missing', async () => { + expect(await MemoryStorageCache.get(KEY)).toBeUndefined(); + }); + + test('value exists', async () => { + expect(await MemoryStorageCache.set(KEY, VALUE)).toBe(_void); + expect(await MemoryStorageCache.get(KEY)).toBe(VALUE); + }); + }); +}); diff --git a/packages/chrome-extension/src/utils/storage.ts b/packages/chrome-extension/src/utils/storage.ts new file mode 100644 index 00000000000..8dedf36bb09 --- /dev/null +++ b/packages/chrome-extension/src/utils/storage.ts @@ -0,0 +1,47 @@ +import browser from 'webextension-polyfill'; + +type StorageCacheOptions = { + storageArea?: 'local' | 'sync'; +}; + +export type StorageCache = { + createKey: (...keys: string[]) => string; + get: (key: string) => Promise; + remove: (key: string) => Promise; + set: (key: string, value: string) => Promise; +}; + +const createKey: StorageCache['createKey'] = (...keys: string[]) => keys.filter(Boolean).join('|'); + +// Use browser.storage (local or sync) to persist Clerk client JWT. +// More information at https://developer.chrome.com/docs/extensions/reference/storage +const createBrowserStorageCache = (opts: StorageCacheOptions = {}): StorageCache => { + const __storageArea = opts.storageArea || 'local'; + + return { + createKey, + get: (key: string) => browser.storage[__storageArea].get(key).then(result => result[key] || undefined), + remove: (key: string) => browser.storage[__storageArea].remove(key), + set: (key: string, value: string) => browser.storage[__storageArea].set({ [key]: value }), + }; +}; + +const createMemoryStorageCache = (): StorageCache => { + const cache: Map = new Map(); + + return { + createKey, + get: (key: string) => Promise.resolve(cache.get(key)), + remove: (key: string) => { + cache.delete(key); + return Promise.resolve(); + }, + set: (key: string, value: string) => { + cache.set(key, value); + return Promise.resolve(); + }, + }; +}; + +export const BrowserStorageCache = createBrowserStorageCache(); +export const MemoryStorageCache = createMemoryStorageCache(); diff --git a/packages/chrome-extension/src/utils/validation.test.ts b/packages/chrome-extension/src/utils/validation.test.ts new file mode 100644 index 00000000000..115465bfa6f --- /dev/null +++ b/packages/chrome-extension/src/utils/validation.test.ts @@ -0,0 +1,62 @@ +import browser, { type Manifest } from 'webextension-polyfill'; + +import { missingManifestKeyError } from './errors'; +import { validateManifest } from './validation'; + +const validClerkManifest = { + permissions: ['cookies', 'storage'], + host_permissions: ['https://*/*'], +} as Manifest.WebExtensionManifest; + +describe('Validation', () => { + describe('validateManifest(manifest)', () => { + test('valid configuration', async () => { + browser.runtime.getManifest = jest.fn().mockReturnValue({ + permissions: ['cookies', 'storage'], + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest); + + expect(() => validateManifest(validClerkManifest)).not.toThrowError(); + }); + + describe('invalid configuration', () => { + describe('permissions', () => { + test('missing root key', async () => { + const manifest = { + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions')); + }); + + test('missing cookies', async () => { + const manifest = { + permissions: ['storage'], + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.cookies')); + }); + + test('missing storage', async () => { + const manifest = { + permissions: ['cookies'], + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.storage')); + }); + }); + + describe('host_permissions', () => { + test('should work', async () => { + const manifest = { + permissions: ['cookies', 'storage'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('host_permissions')); + }); + }); + }); + }); +}); diff --git a/packages/chrome-extension/src/utils/validation.ts b/packages/chrome-extension/src/utils/validation.ts new file mode 100644 index 00000000000..fa1c3516034 --- /dev/null +++ b/packages/chrome-extension/src/utils/validation.ts @@ -0,0 +1,23 @@ +import type { Manifest } from 'webextension-polyfill'; + +import { errorThrower, missingManifestKeyError } from '../utils/errors'; + +export function validateManifest(manifest: Manifest.WebExtensionManifest): void { + if (!manifest.permissions) { + return errorThrower.throw(missingManifestKeyError('permissions')); + } + + if (!manifest.host_permissions) { + return errorThrower.throw(missingManifestKeyError('host_permissions')); + } + + if (!manifest.permissions.includes('cookies')) { + return errorThrower.throw(missingManifestKeyError('permissions.cookies')); + } + + if (!manifest.permissions.includes('storage')) { + return errorThrower.throw(missingManifestKeyError('permissions.storage')); + } + + // TODO: Validate hosts +} diff --git a/packages/chrome-extension/tsconfig.lint.json b/packages/chrome-extension/tsconfig.lint.json new file mode 100644 index 00000000000..40b167e1f0e --- /dev/null +++ b/packages/chrome-extension/tsconfig.lint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["src", "./*.ts"], + "exclude": ["node_modules"] +} From 47498d1e97ae4d4c728b6b25c8a6c65b33de5934 Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 8 Dec 2023 12:25:58 -0500 Subject: [PATCH 2/8] chore(chrome-extension): Full CI rebuild --- packages/chrome-extension/src/singleton.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/chrome-extension/src/singleton.ts b/packages/chrome-extension/src/singleton.ts index c3449541c55..6b975a5c6b9 100644 --- a/packages/chrome-extension/src/singleton.ts +++ b/packages/chrome-extension/src/singleton.ts @@ -46,8 +46,8 @@ export async function buildClerk({ // Create StorageCache key const CACHE_KEY = storageCache.createKey(isProd ? key.frontendApi : syncSessionHost, STORAGE_KEY_CLIENT_JWT); - // Set client cookie in StorageCache if (clientCookie) { + // Set client cookie in StorageCache await storageCache.set(CACHE_KEY, clientCookie.value).catch(errorLogger); } From eb64946663b0d2782374f9fb79759710d3a32c96 Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 8 Dec 2023 12:28:54 -0500 Subject: [PATCH 3/8] chore(chrome-extension): Add internal deps --- package-lock.json | 92 +++++++++++++++++++--- packages/chrome-extension/package.json | 5 +- packages/chrome-extension/src/singleton.ts | 2 +- 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19431ba3dac..b4a246856a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7996,15 +7996,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/chrome": { - "version": "0.0.237", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/filesystem": "*", - "@types/har-format": "*" - } - }, "node_modules/@types/common-tags": { "version": "1.8.2", "dev": true, @@ -32901,8 +32892,9 @@ "version": "1.0.0-alpha-v5.9", "license": "MIT", "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.9", - "@clerk/clerk-react": "5.0.0-alpha-v5.9", + "@clerk/clerk-js": "5.0.0-alpha-v5.8", + "@clerk/clerk-react": "5.0.0-alpha-v5.8", + "@clerk/shared": "2.0.0-alpha-v5.5", "webextension-polyfill": "^0.10.0" }, "devDependencies": { @@ -32923,6 +32915,84 @@ "react-dom": ">=18" } }, + "packages/chrome-extension/node_modules/@clerk/clerk-js": { + "version": "5.0.0-alpha-v5.8", + "resolved": "https://registry.npmjs.org/@clerk/clerk-js/-/clerk-js-5.0.0-alpha-v5.8.tgz", + "integrity": "sha512-SdlDxorZuFaK5umRGu+j1eos0DyvGc6yI0d8CASlgOrimtRfxx12QsiH+pe5DhYe4c3lGh8UWT5PaukitrrqPw==", + "dependencies": { + "@clerk/localizations": "2.0.0-alpha-v5.6", + "@clerk/shared": "2.0.0-alpha-v5.5", + "@clerk/types": "4.0.0-alpha-v5.8", + "@emotion/cache": "11.11.0", + "@emotion/react": "11.11.1", + "@floating-ui/react": "0.25.4", + "@zxcvbn-ts/core": "2.2.1", + "@zxcvbn-ts/language-common": "3.0.2", + "browser-tabs-lock": "1.2.15", + "copy-to-clipboard": "3.3.3", + "core-js": "3.26.1", + "dequal": "2.0.3", + "qrcode.react": "3.1.0", + "qs": "6.11.0", + "regenerator-runtime": "0.13.11" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "packages/chrome-extension/node_modules/@clerk/clerk-react": { + "version": "5.0.0-alpha-v5.8", + "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.0.0-alpha-v5.8.tgz", + "integrity": "sha512-w2rlEi/KnXRa8TuWCW0eHQFUlfGWwubfXBWxfiGp+aNy0748aF+M4aLyeIiC9jz7ihL8huVi/oD15uYyiJ/VBQ==", + "dependencies": { + "@clerk/shared": "2.0.0-alpha-v5.5", + "@clerk/types": "4.0.0-alpha-v5.8", + "eslint-config-custom": "*", + "semver": "^7.5.4", + "tslib": "2.4.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "packages/chrome-extension/node_modules/@clerk/types": { + "version": "4.0.0-alpha-v5.8", + "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.0.0-alpha-v5.8.tgz", + "integrity": "sha512-C7gFQgrf+5br0uC64b+e+Naa3afJ2JNTaXMLVu70IeqR2v7mGFnH01zJ8wqDr3LXBbRuBVqCaaHoPiXQ9yURqA==", + "dependencies": { + "csstype": "3.1.1" + }, + "engines": { + "node": ">=18.17.0" + } + }, + "packages/chrome-extension/node_modules/@types/chrome": { + "version": "0.0.114", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, + "packages/chrome-extension/node_modules/csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, + "packages/chrome-extension/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "packages/clerk-js": { "name": "@clerk/clerk-js", "version": "5.0.0-alpha-v5.9", diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index db5f4342007..ec9b0a0bae0 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -45,8 +45,9 @@ "test:coverage": "jest --collectCoverage && open coverage/lcov-report/index.html" }, "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.9", - "@clerk/clerk-react": "5.0.0-alpha-v5.9", + "@clerk/clerk-js": "5.0.0-alpha-v5.8", + "@clerk/clerk-react": "5.0.0-alpha-v5.8", + "@clerk/shared": "2.0.0-alpha-v5.5", "webextension-polyfill": "^0.10.0" }, "devDependencies": { diff --git a/packages/chrome-extension/src/singleton.ts b/packages/chrome-extension/src/singleton.ts index 6b975a5c6b9..c3449541c55 100644 --- a/packages/chrome-extension/src/singleton.ts +++ b/packages/chrome-extension/src/singleton.ts @@ -46,8 +46,8 @@ export async function buildClerk({ // Create StorageCache key const CACHE_KEY = storageCache.createKey(isProd ? key.frontendApi : syncSessionHost, STORAGE_KEY_CLIENT_JWT); + // Set client cookie in StorageCache if (clientCookie) { - // Set client cookie in StorageCache await storageCache.set(CACHE_KEY, clientCookie.value).catch(errorLogger); } From 381f8d57a88c7fe12e8f6af2b3fefcc8d52d79eb Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 8 Dec 2023 12:38:31 -0500 Subject: [PATCH 4/8] fix(chrome-extension): Remove prepublishOnly command --- packages/chrome-extension/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index ec9b0a0bae0..055baf75de1 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -37,7 +37,6 @@ "lint": "eslint src/", "lint:attw": "attw --pack .", "lint:publint": "publint", - "prepublishOnly": "npm run build", "publish:local": "npx yalc push --replace --sig", "test": "jest", "test:cache:clear": "jest --clearCache --useStderr", From f466a2f56d4550ed3e2d311a27fcf48b0eff777a Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Fri, 8 Dec 2023 12:49:12 -0500 Subject: [PATCH 5/8] fix(repo): Explicitly account for subpaths --- turbo.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/turbo.json b/turbo.json index ded85cd265a..569c2f62069 100644 --- a/turbo.json +++ b/turbo.json @@ -3,7 +3,14 @@ "remoteCache": { "signature": true }, - "globalDependencies": ["jest.*.ts", "package.json", "package-lock.json", "tsconfig.json", "tsconfig.*.json"], + "globalDependencies": [ + "jest.*.ts", + "package.json", + "package-lock.json", + "tsconfig.json", + "tsconfig.*.json", + "scripts/subpath-workaround.mjs" + ], "globalEnv": [ "CLERK_*", "GATSBY_CLERK_*", @@ -28,6 +35,7 @@ "tsconfig.build.json", "tsconfig.declarations.json", "tsup.config.ts", + "subpaths.mjs", "!**/**/*.test.*", "!**/test/**", "!**/tests/**", From 67265c48061d276d26f2f7f38f6f492fc0e233ea Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Sun, 10 Dec 2023 14:01:10 -0500 Subject: [PATCH 6/8] chore(chrome-extension): Update dependencies --- package-lock.json | 52 +------------------------- packages/chrome-extension/package.json | 4 +- 2 files changed, 4 insertions(+), 52 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4a246856a5..8a843dfa78f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32892,8 +32892,8 @@ "version": "1.0.0-alpha-v5.9", "license": "MIT", "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.8", - "@clerk/clerk-react": "5.0.0-alpha-v5.8", + "@clerk/clerk-js": "5.0.0-alpha-v5.9", + "@clerk/clerk-react": "5.0.0-alpha-v5.9", "@clerk/shared": "2.0.0-alpha-v5.5", "webextension-polyfill": "^0.10.0" }, @@ -32915,54 +32915,6 @@ "react-dom": ">=18" } }, - "packages/chrome-extension/node_modules/@clerk/clerk-js": { - "version": "5.0.0-alpha-v5.8", - "resolved": "https://registry.npmjs.org/@clerk/clerk-js/-/clerk-js-5.0.0-alpha-v5.8.tgz", - "integrity": "sha512-SdlDxorZuFaK5umRGu+j1eos0DyvGc6yI0d8CASlgOrimtRfxx12QsiH+pe5DhYe4c3lGh8UWT5PaukitrrqPw==", - "dependencies": { - "@clerk/localizations": "2.0.0-alpha-v5.6", - "@clerk/shared": "2.0.0-alpha-v5.5", - "@clerk/types": "4.0.0-alpha-v5.8", - "@emotion/cache": "11.11.0", - "@emotion/react": "11.11.1", - "@floating-ui/react": "0.25.4", - "@zxcvbn-ts/core": "2.2.1", - "@zxcvbn-ts/language-common": "3.0.2", - "browser-tabs-lock": "1.2.15", - "copy-to-clipboard": "3.3.3", - "core-js": "3.26.1", - "dequal": "2.0.3", - "qrcode.react": "3.1.0", - "qs": "6.11.0", - "regenerator-runtime": "0.13.11" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "packages/chrome-extension/node_modules/@clerk/clerk-react": { - "version": "5.0.0-alpha-v5.8", - "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.0.0-alpha-v5.8.tgz", - "integrity": "sha512-w2rlEi/KnXRa8TuWCW0eHQFUlfGWwubfXBWxfiGp+aNy0748aF+M4aLyeIiC9jz7ihL8huVi/oD15uYyiJ/VBQ==", - "dependencies": { - "@clerk/shared": "2.0.0-alpha-v5.5", - "@clerk/types": "4.0.0-alpha-v5.8", - "eslint-config-custom": "*", - "semver": "^7.5.4", - "tslib": "2.4.1" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, "packages/chrome-extension/node_modules/@clerk/types": { "version": "4.0.0-alpha-v5.8", "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.0.0-alpha-v5.8.tgz", diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index 055baf75de1..6fc4b6cc63d 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -44,8 +44,8 @@ "test:coverage": "jest --collectCoverage && open coverage/lcov-report/index.html" }, "dependencies": { - "@clerk/clerk-js": "5.0.0-alpha-v5.8", - "@clerk/clerk-react": "5.0.0-alpha-v5.8", + "@clerk/clerk-js": "5.0.0-alpha-v5.9", + "@clerk/clerk-react": "5.0.0-alpha-v5.9", "@clerk/shared": "2.0.0-alpha-v5.5", "webextension-polyfill": "^0.10.0" }, From cdaf16b9c18f02ad93b162897c0c98600f767b5b Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Tue, 12 Dec 2023 18:26:43 -0500 Subject: [PATCH 7/8] feat(chrome-extension): Remove requirement for `syncSessionHost` --- .changeset/shiny-glasses-switch.md | 26 ++-- package-lock.json | 32 ++--- packages/chrome-extension/README.md | 12 +- packages/chrome-extension/package.json | 1 + .../chrome-extension/src/ClerkProvider.tsx | 4 +- packages/chrome-extension/src/constants.ts | 2 + packages/chrome-extension/src/singleton.ts | 41 ++++-- .../src/utils/cookies.test.ts | 86 ++++++++++-- .../chrome-extension/src/utils/cookies.ts | 24 +++- packages/chrome-extension/src/utils/errors.ts | 6 + .../src/utils/manifest.test.ts | 125 ++++++++++++++++++ .../chrome-extension/src/utils/manifest.ts | 45 +++++++ .../src/utils/validation.test.ts | 62 --------- .../chrome-extension/src/utils/validation.ts | 23 ---- 14 files changed, 339 insertions(+), 150 deletions(-) create mode 100644 packages/chrome-extension/src/utils/manifest.test.ts create mode 100644 packages/chrome-extension/src/utils/manifest.ts delete mode 100644 packages/chrome-extension/src/utils/validation.test.ts delete mode 100644 packages/chrome-extension/src/utils/validation.ts diff --git a/.changeset/shiny-glasses-switch.md b/.changeset/shiny-glasses-switch.md index 898468d104d..9c96fef5797 100644 --- a/.changeset/shiny-glasses-switch.md +++ b/.changeset/shiny-glasses-switch.md @@ -6,20 +6,32 @@ Expand the ability for `@clerk/chrome-extension` WebSSO to sync with host applic ### How to Update -**WebSSO Local Development Host Permissions:** +**WebSSO Host Permissions:** + +_Local Development: You must have your explicit development domain added to your `manifest.json` file in order to use the WebSSO flow._ + +Example: -Add `*://localhost:*/*` to the `host_permissions` array in your `manifest.json` file: ```json { - "host_permissions": ["*://localhost:*/*"] + "host_permissions": [ + // ... + "http://localhost" + // ... + ] } ``` -If you're using a local domain other than `localhost`, you'll want replace that entry with your domain: `*:///*` +_Production: You must have your explicit Clerk Frontend API domain added to your `manifest.json` file in order to use the WebSSO flow._ +Example: ```json { - "host_permissions": ["*:///*"] + "host_permissions": [ + // ... + "https://clerk.example.com" + // ... + ] } ``` @@ -34,10 +46,6 @@ If you're using a local domain other than `localhost`, you'll want replace that // tokenCache is now storageCache (See below) storageCache={/* ... */} - - // [Development Only]: If the host application isn't on - // `http://localhost`, you can provide it here: - syncSessionHost="http://" > ``` diff --git a/package-lock.json b/package-lock.json index 8a843dfa78f..be38c20dcd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32905,6 +32905,7 @@ "@types/webextension-polyfill": "^0.10.7", "eslint-config-custom": "*", "tsup": "*", + "type-fest": "^4.8.3", "typescript": "*" }, "engines": { @@ -32915,17 +32916,6 @@ "react-dom": ">=18" } }, - "packages/chrome-extension/node_modules/@clerk/types": { - "version": "4.0.0-alpha-v5.8", - "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.0.0-alpha-v5.8.tgz", - "integrity": "sha512-C7gFQgrf+5br0uC64b+e+Naa3afJ2JNTaXMLVu70IeqR2v7mGFnH01zJ8wqDr3LXBbRuBVqCaaHoPiXQ9yURqA==", - "dependencies": { - "csstype": "3.1.1" - }, - "engines": { - "node": ">=18.17.0" - } - }, "packages/chrome-extension/node_modules/@types/chrome": { "version": "0.0.114", "dev": true, @@ -32935,15 +32925,17 @@ "@types/har-format": "*" } }, - "packages/chrome-extension/node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" - }, - "packages/chrome-extension/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + "packages/chrome-extension/node_modules/type-fest": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz", + "integrity": "sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "packages/clerk-js": { "name": "@clerk/clerk-js", diff --git a/packages/chrome-extension/README.md b/packages/chrome-extension/README.md index 83725dc178e..3745d198f2c 100644 --- a/packages/chrome-extension/README.md +++ b/packages/chrome-extension/README.md @@ -152,20 +152,16 @@ You must enable the following permissions in your `manifest.json` file: You must enable the following host permissions in your `manifest.json` file: -- **Development:** `"host_permissions": ["*://localhost:*/*"]` - - If you're using a domain other than `localhost`, you'll want replace that entry with your domain: `*:///*` -- **Production:** `"host_permissions": ["*:///"]` +- **Development:** `"host_permissions": ["http://localhost"]` + - If you're using a domain other than `localhost`, you'll want replace that entry with your domain: `http://` +- **Production:** `"host_permissions": ["https:///"]` - Your Frontend API URL can be found in `Clerk Dashboard > API Keys > Advanced > Clerk API URLs`. For more info on host permissions: (Google Developer `host_permissions` Reference)[https://developer.chrome.com/docs/extensions/mv3/declare_permissions/#host-permissions] -#### ClerkProvider - -If your plan to sync sessions with a host application not on `localhost`, you'll need to use the `syncSessionHost` prop on `ClerkProvider` to specify the domain you're using, inclusive of the protocol. (eg: `https://`) - -### Clerk settings +### Clerk Settings Add your Chrome extension origin to your instance allowed_origins using BAPI: diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index 6fc4b6cc63d..9317286f1e4 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -57,6 +57,7 @@ "@types/webextension-polyfill": "^0.10.7", "eslint-config-custom": "*", "tsup": "*", + "type-fest": "^4.8.3", "typescript": "*" }, "peerDependencies": { diff --git a/packages/chrome-extension/src/ClerkProvider.tsx b/packages/chrome-extension/src/ClerkProvider.tsx index bcde13c3604..a243a34b622 100644 --- a/packages/chrome-extension/src/ClerkProvider.tsx +++ b/packages/chrome-extension/src/ClerkProvider.tsx @@ -17,12 +17,10 @@ __internal__setErrorThrowerOptions({ type WebSSOClerkProviderCustomProps = | { - syncSessionHost?: never; syncSessionWithTab?: false; storageCache?: never; } | { - syncSessionHost?: string; syncSessionWithTab: true; storageCache?: StorageCache; }; @@ -72,6 +70,6 @@ const StandaloneClerkProvider = (props: ClerkReactProviderProps): JSX.Element => type ChromeExtensionClerkProviderProps = WebSSOClerkProviderProps; export function ClerkProvider(props: ChromeExtensionClerkProviderProps): JSX.Element | null { - const { syncSessionHost, storageCache, syncSessionWithTab, ...rest } = props; + const { storageCache, syncSessionWithTab, ...rest } = props; return syncSessionWithTab ? : ; } diff --git a/packages/chrome-extension/src/constants.ts b/packages/chrome-extension/src/constants.ts index 74c98ab9610..334a49c1950 100644 --- a/packages/chrome-extension/src/constants.ts +++ b/packages/chrome-extension/src/constants.ts @@ -1,2 +1,4 @@ export const CLIENT_JWT_KEY = '__client'; export const STORAGE_KEY_CLIENT_JWT = '__clerk_client_jwt'; +export const VALID_HOST_PERMISSION_REGEX = /(https?:\/\/[\w.-]+)/; +export const DEFAULT_LOCAL_HOST_PERMISSION = 'http://localhost'; diff --git a/packages/chrome-extension/src/singleton.ts b/packages/chrome-extension/src/singleton.ts index c3449541c55..e8a8b21d33c 100644 --- a/packages/chrome-extension/src/singleton.ts +++ b/packages/chrome-extension/src/singleton.ts @@ -4,47 +4,60 @@ import { DEV_BROWSER_JWT_MARKER } from '@clerk/shared'; import { parsePublishableKey } from '@clerk/shared/keys'; import browser from 'webextension-polyfill'; -import { CLIENT_JWT_KEY, STORAGE_KEY_CLIENT_JWT } from './constants'; +import { CLIENT_JWT_KEY, DEFAULT_LOCAL_HOST_PERMISSION, STORAGE_KEY_CLIENT_JWT } from './constants'; +import type { GetClientCookieParams } from './utils/cookies'; import { getClientCookie } from './utils/cookies'; import { assertPublishableKey, errorLogger } from './utils/errors'; +import { getValidPossibleManifestHosts, validateHostPermissionExistence, validateManifest } from './utils/manifest'; import { BrowserStorageCache, type StorageCache } from './utils/storage'; -import { validateManifest } from './utils/validation'; export let clerk: ClerkProp; type BuildClerkOptions = { publishableKey: string; storageCache?: StorageCache; - syncSessionHost?: string; }; export async function buildClerk({ publishableKey, storageCache = BrowserStorageCache, - syncSessionHost = 'http://localhost', }: BuildClerkOptions): Promise { if (clerk) { return clerk; } - // Will throw if manifest is invalid - validateManifest(browser.runtime.getManifest()); - - // Parse publishableKey and assert it's present/valid + // Parse publishableKey and assert it's present/valid, throw if not const key = parsePublishableKey(publishableKey); assertPublishableKey(key); - // Will throw if publishableKey is invalid const isProd = key.instanceType === 'production'; + const hostHint = isProd ? key.frontendApi : DEFAULT_LOCAL_HOST_PERMISSION; + const manifest = browser.runtime.getManifest(); + + // Will throw if manifest is invalid + validateManifest(manifest); + + const validHosts = getValidPossibleManifestHosts(manifest); + + // Will throw if manifest host_permissions doesn't contain a valid host + validateHostPermissionExistence(validHosts, hostHint); + + // Set up cookie params based on environment + const getClientCookieParams: GetClientCookieParams = isProd + ? { + urls: key.frontendApi, + name: CLIENT_JWT_KEY, + } + : { + urls: validHosts, + name: DEV_BROWSER_JWT_MARKER, + }; // Get client cookie from browser - const clientCookie = await (isProd - ? getClientCookie(key.frontendApi, CLIENT_JWT_KEY) - : getClientCookie(syncSessionHost, DEV_BROWSER_JWT_MARKER) - ).catch(errorLogger); + const clientCookie = await getClientCookie(getClientCookieParams).catch(errorLogger); // Create StorageCache key - const CACHE_KEY = storageCache.createKey(isProd ? key.frontendApi : syncSessionHost, STORAGE_KEY_CLIENT_JWT); + const CACHE_KEY = storageCache.createKey(key.frontendApi, STORAGE_KEY_CLIENT_JWT); // Set client cookie in StorageCache if (clientCookie) { diff --git a/packages/chrome-extension/src/utils/cookies.test.ts b/packages/chrome-extension/src/utils/cookies.test.ts index 78e66bbe082..e7d0fb779cd 100644 --- a/packages/chrome-extension/src/utils/cookies.test.ts +++ b/packages/chrome-extension/src/utils/cookies.test.ts @@ -19,19 +19,87 @@ const createCookie = (opts: CreateCookieOpts): browser.Cooki }); describe('Cookies', () => { + const domain = 'clerk.domain.com'; + const urls = [`https://${domain}`, 'https://foo.com']; + const name = '__client'; + const cookie = createCookie({ name, value: 'foo', domain }); + + const getMock = jest.mocked(browser.cookies.get); + + afterEach(() => getMock.mockReset()); + afterAll(() => getMock.mockRestore()); + + function expectMockCalls(mockedFn: typeof getMock, name: string, urls: string[]) { + expect(mockedFn).toHaveBeenCalledTimes(urls.length); + expect(mockedFn.mock.calls.flat()).toEqual(urls.map(url => ({ url, name }))); + } + describe('getClientCookie', () => { - const domain = 'clerk.domain.com'; - const url = `https://${domain}`; - const name = '__client'; - const cookie = createCookie({ name, value: 'foo', domain }); + describe('Single Host', () => { + test('returns cookie value from browser.cookies if is set for url', async () => { + const url = urls[0]; + + getMock.mockResolvedValue(cookie); + + expect(await getClientCookie({ urls: url, name })).toBe(cookie); + + expectMockCalls(getMock, name, [url]); + }); + }); + + describe('Multiple Hosts', () => { + test('with valid urls', async () => { + getMock.mockResolvedValueOnce(cookie).mockResolvedValueOnce(null).mockResolvedValueOnce(null); + + expect(await getClientCookie({ urls, name })).toBe(cookie); + + expectMockCalls(getMock, name, urls); + }); + + test('with invalid urls', async () => { + const urls = ['foo']; + + getMock.mockResolvedValue(null); + expect(await getClientCookie({ urls, name })).toBe(null); + + expectMockCalls(getMock, name, urls); + }); + + test('with single result', async () => { + getMock.mockResolvedValueOnce(cookie).mockResolvedValueOnce(null); + + expect(await getClientCookie({ urls, name })).toBe(cookie); + + expectMockCalls(getMock, name, urls); + }); + + test('with multiple results - should pick first result', async () => { + const cookie2 = createCookie({ name, value: 'result2', domain }); + + getMock.mockResolvedValueOnce(cookie).mockResolvedValueOnce(cookie2); + + expect(await getClientCookie({ urls, name })).toBe(cookie); + + expectMockCalls(getMock, name, urls); + }); + + test('with rejected result', async () => { + const urls = [`https://${domain}`, 'https://foo.com']; + + getMock.mockResolvedValueOnce(cookie).mockRejectedValueOnce(null); + + expect(await getClientCookie({ urls, name })).toBe(cookie); + + expectMockCalls(getMock, name, urls); + }); - test('returns cookie value from browser.cookies if is set for url', async () => { - const getMock = jest.mocked(browser.cookies.get).mockResolvedValue(cookie); + test('with empty result', async () => { + getMock.mockResolvedValueOnce(null).mockRejectedValueOnce(null); - expect(await getClientCookie(url, name)).toBe(cookie); + expect(await getClientCookie({ urls, name })).toBe(null); - expect(getMock).toHaveBeenCalledTimes(1); - expect(getMock).toHaveBeenCalledWith({ url, name }); + expectMockCalls(getMock, name, urls); + }); }); }); }); diff --git a/packages/chrome-extension/src/utils/cookies.ts b/packages/chrome-extension/src/utils/cookies.ts index 880b7035efb..258a1fff266 100644 --- a/packages/chrome-extension/src/utils/cookies.ts +++ b/packages/chrome-extension/src/utils/cookies.ts @@ -1,5 +1,25 @@ import browser from 'webextension-polyfill'; -export async function getClientCookie(url: string, name: string) { - return await browser.cookies.get({ url, name }); +export type GetClientCookieParams = { + urls: string | string[]; + name: string; +}; + +export async function getClientCookie({ urls, name }: GetClientCookieParams) { + // Handle single host request + if (typeof urls === 'string') { + return browser.cookies.get({ url: urls, name }); + } + + // Handle multi-host request + const cookiePromises = urls.map(url => browser.cookies.get({ url, name })); + const cookieResults = await Promise.allSettled(cookiePromises); + + for (const cookie of cookieResults) { + if (cookie.status === 'fulfilled') { + return cookie.value; + } + } + + return null; } diff --git a/packages/chrome-extension/src/utils/errors.ts b/packages/chrome-extension/src/utils/errors.ts index dd28e3e2411..7c758db578c 100644 --- a/packages/chrome-extension/src/utils/errors.ts +++ b/packages/chrome-extension/src/utils/errors.ts @@ -1,9 +1,15 @@ import { buildErrorThrower } from '@clerk/shared/error'; +export type HostPermissionHintOpts = { + hostHint: string; +}; + export const errorLogger = (err: Error) => console.error(err, err.stack); export const errorThrower = buildErrorThrower({ packageName: '@clerk/chrome-extension' }); export const missingManifestKeyError = (key: string) => `Missing \`${key}\` entry in manifest.json`; +export const missingValidManifestHostPermission = (hostHint: string) => + `You're missing a valid host permission. Please add ${hostHint} to \`host_permissions\` in manifest.json.`; export function assertPublishableKey(publishableKey: unknown): asserts publishableKey { if (!publishableKey) { diff --git a/packages/chrome-extension/src/utils/manifest.test.ts b/packages/chrome-extension/src/utils/manifest.test.ts new file mode 100644 index 00000000000..6d1d1802fc4 --- /dev/null +++ b/packages/chrome-extension/src/utils/manifest.test.ts @@ -0,0 +1,125 @@ +import browser, { type Manifest } from 'webextension-polyfill'; + +import { missingManifestKeyError, missingValidManifestHostPermission } from './errors'; +import type { ValidatedManifest } from './manifest'; +import { getValidPossibleManifestHosts, validateHostPermissionExistence, validateManifest } from './manifest'; + +const validClerkManifest = { + permissions: ['cookies', 'storage'], + host_permissions: ['http://localhost:3000'], +} as ValidatedManifest; + +describe('Manifest', () => { + describe('validateManifest(manifest)', () => { + test('valid configuration', async () => { + browser.runtime.getManifest = jest.fn().mockReturnValue(validClerkManifest); + + expect(() => validateManifest(validClerkManifest)).not.toThrowError(); + }); + + describe('invalid configuration', () => { + describe('permissions', () => { + test('missing root key', async () => { + const manifest = { + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions')); + }); + + test('missing cookies', async () => { + const manifest = { + permissions: ['storage'], + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.cookies')); + }); + + test('missing storage', async () => { + const manifest = { + permissions: ['cookies'], + host_permissions: ['https://*/*'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.storage')); + }); + }); + + describe('host_permissions', () => { + test('missing root key', async () => { + const manifest = { + permissions: ['cookies', 'storage'], + } as Manifest.WebExtensionManifest; + + expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('host_permissions')); + }); + }); + }); + }); + + describe('validateHostPermissionExistence(manifest.host_permissions[])', () => { + describe('valid configuration', () => { + const hostHint = 'https://clerk.clerk.com'; + + test('valid', () => { + expect(() => validateHostPermissionExistence(['http://localhost:3000'], hostHint)).not.toThrowError(); + }); + + test('invalid', () => { + expect(() => validateHostPermissionExistence([], hostHint)).toThrowError( + missingValidManifestHostPermission(hostHint), + ); + }); + }); + }); + + describe('getPossibleManifestHosts(manifest)', () => { + describe('valid configuration', () => { + test('should not throw error', async () => { + expect(() => getValidPossibleManifestHosts(validClerkManifest)).not.toThrowError(); + }); + + test('should return localhost', async () => { + expect(() => getValidPossibleManifestHosts(validClerkManifest)).not.toThrowError(); + }); + }); + + describe('configurations', () => { + it('should appropriately parse host_permissions', () => { + const host_permissions = [ + '', + 'http://localhost', + 'http://localhost/', + 'http://localhost/*', + 'http://localhost:80/*', + 'http://localhost:*/*', + 'https://*.com/*', + '*://developer.mozilla.org/*', + '*://developer.mozilla.org*', + '*://*.example.org/*', + 'https://developer.mozilla.org/*', + 'ftp://*.example.org/*', + 'https://example.org:80/', + 'https://example.org:*', + 'http://example.org:*', + 'https://example.org:*/*', + ]; + + const manifest = { + permissions: ['cookies', 'storage'], + host_permissions, + } as ValidatedManifest; + + const result = [ + 'http://localhost', + 'https://developer.mozilla.org', + 'https://example.org', + 'http://example.org', + ]; + + expect(getValidPossibleManifestHosts(manifest)).toStrictEqual(result); + }); + }); + }); +}); diff --git a/packages/chrome-extension/src/utils/manifest.ts b/packages/chrome-extension/src/utils/manifest.ts new file mode 100644 index 00000000000..80cdfebd527 --- /dev/null +++ b/packages/chrome-extension/src/utils/manifest.ts @@ -0,0 +1,45 @@ +import type { SetRequired } from 'type-fest'; +import type { Manifest } from 'webextension-polyfill'; + +import { VALID_HOST_PERMISSION_REGEX } from '../constants'; +import { errorThrower, missingManifestKeyError, missingValidManifestHostPermission } from '../utils/errors'; + +export type ValidatedManifest = SetRequired; + +export function validateManifest(manifest: Manifest.WebExtensionManifest): asserts manifest is ValidatedManifest { + if (!manifest.permissions) { + return errorThrower.throw(missingManifestKeyError('permissions')); + } + + if (!manifest.permissions.includes('cookies')) { + return errorThrower.throw(missingManifestKeyError('permissions.cookies')); + } + + if (!manifest.permissions.includes('storage')) { + return errorThrower.throw(missingManifestKeyError('permissions.storage')); + } + + if (!manifest.host_permissions) { + return errorThrower.throw(missingManifestKeyError('host_permissions')); + } +} + +export function validateHostPermissionExistence(hostPermissions: string[], hostHint: string): void { + if (!hostPermissions?.length) { + return errorThrower.throw(missingValidManifestHostPermission(hostHint)); + } +} + +export function getValidPossibleManifestHosts(manifest: ValidatedManifest): string[] { + const uniqueHosts = new Set(); + + for (const host of manifest.host_permissions) { + const res = host.match(VALID_HOST_PERMISSION_REGEX)?.[1]; + + if (res) { + uniqueHosts.add(res); + } + } + + return [...uniqueHosts]; +} diff --git a/packages/chrome-extension/src/utils/validation.test.ts b/packages/chrome-extension/src/utils/validation.test.ts deleted file mode 100644 index 115465bfa6f..00000000000 --- a/packages/chrome-extension/src/utils/validation.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import browser, { type Manifest } from 'webextension-polyfill'; - -import { missingManifestKeyError } from './errors'; -import { validateManifest } from './validation'; - -const validClerkManifest = { - permissions: ['cookies', 'storage'], - host_permissions: ['https://*/*'], -} as Manifest.WebExtensionManifest; - -describe('Validation', () => { - describe('validateManifest(manifest)', () => { - test('valid configuration', async () => { - browser.runtime.getManifest = jest.fn().mockReturnValue({ - permissions: ['cookies', 'storage'], - host_permissions: ['https://*/*'], - } as Manifest.WebExtensionManifest); - - expect(() => validateManifest(validClerkManifest)).not.toThrowError(); - }); - - describe('invalid configuration', () => { - describe('permissions', () => { - test('missing root key', async () => { - const manifest = { - host_permissions: ['https://*/*'], - } as Manifest.WebExtensionManifest; - - expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions')); - }); - - test('missing cookies', async () => { - const manifest = { - permissions: ['storage'], - host_permissions: ['https://*/*'], - } as Manifest.WebExtensionManifest; - - expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.cookies')); - }); - - test('missing storage', async () => { - const manifest = { - permissions: ['cookies'], - host_permissions: ['https://*/*'], - } as Manifest.WebExtensionManifest; - - expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('permissions.storage')); - }); - }); - - describe('host_permissions', () => { - test('should work', async () => { - const manifest = { - permissions: ['cookies', 'storage'], - } as Manifest.WebExtensionManifest; - - expect(() => validateManifest(manifest)).toThrowError(missingManifestKeyError('host_permissions')); - }); - }); - }); - }); -}); diff --git a/packages/chrome-extension/src/utils/validation.ts b/packages/chrome-extension/src/utils/validation.ts deleted file mode 100644 index fa1c3516034..00000000000 --- a/packages/chrome-extension/src/utils/validation.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Manifest } from 'webextension-polyfill'; - -import { errorThrower, missingManifestKeyError } from '../utils/errors'; - -export function validateManifest(manifest: Manifest.WebExtensionManifest): void { - if (!manifest.permissions) { - return errorThrower.throw(missingManifestKeyError('permissions')); - } - - if (!manifest.host_permissions) { - return errorThrower.throw(missingManifestKeyError('host_permissions')); - } - - if (!manifest.permissions.includes('cookies')) { - return errorThrower.throw(missingManifestKeyError('permissions.cookies')); - } - - if (!manifest.permissions.includes('storage')) { - return errorThrower.throw(missingManifestKeyError('permissions.storage')); - } - - // TODO: Validate hosts -} From 75c8d364cc64f23263797673c1d3e6a7242b2c08 Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Wed, 13 Dec 2023 10:33:16 -0500 Subject: [PATCH 8/8] chore(repo): Force update --- package-lock.json | 42 +++++++++++----------- package.json | 4 +-- packages/eslint-config-custom/package.json | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index be38c20dcd5..f8b3ae42e56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,8 +25,8 @@ "@testing-library/user-event": "^14.4.3", "@types/cross-spawn": "^6.0.3", "@types/jest": "^29.3.1", - "@types/react": "^18.2.28", - "@types/react-dom": "^18.2.13", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.17", "citty": "^0.1.4", "conventional-changelog-conventionalcommits": "^4.6.3", "cpy-cli": "^5.0.0", @@ -8354,9 +8354,10 @@ } }, "node_modules/@types/react": { - "version": "18.2.28", + "version": "18.2.45", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", + "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", "dev": true, - "license": "MIT", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -8364,9 +8365,10 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.13", + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", "dev": true, - "license": "MIT", "dependencies": { "@types/react": "*" } @@ -9386,6 +9388,19 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@zxcvbn-ts/core": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", + "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", + "dependencies": { + "fastest-levenshtein": "1.0.16" + } + }, + "node_modules/@zxcvbn-ts/language-common": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", + "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==" + }, "node_modules/abab": { "version": "2.0.6", "dev": true, @@ -32995,19 +33010,6 @@ "react-dom": ">=18" } }, - "packages/clerk-js/node_modules/@zxcvbn-ts/core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", - "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", - "dependencies": { - "fastest-levenshtein": "1.0.16" - } - }, - "packages/clerk-js/node_modules/@zxcvbn-ts/language-common": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", - "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==" - }, "packages/clerk-js/node_modules/ajv": { "version": "8.12.0", "dev": true, @@ -33074,7 +33076,7 @@ } }, "packages/eslint-config-custom": { - "version": "0.3.0", + "version": "0.0.0", "license": "MIT", "dependencies": { "@next/eslint-plugin-next": "^12.3.0", diff --git a/package.json b/package.json index 358fe856159..6605b4ed271 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "@testing-library/user-event": "^14.4.3", "@types/cross-spawn": "^6.0.3", "@types/jest": "^29.3.1", - "@types/react": "^18.2.28", - "@types/react-dom": "^18.2.13", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.17", "citty": "^0.1.4", "conventional-changelog-conventionalcommits": "^4.6.3", "cpy-cli": "^5.0.0", diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json index 993fa4888a4..f40de496a8f 100644 --- a/packages/eslint-config-custom/package.json +++ b/packages/eslint-config-custom/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-custom", - "version": "0.3.0", + "version": "0.0.0", "private": true, "license": "MIT", "dependencies": {