diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..6b10a5b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "next/core-web-vitals", + "next/typescript" + ] +} diff --git a/helpers/functions/__mocks__/apiResponse.ts b/helpers/functions/__mocks__/apiResponse.ts new file mode 100644 index 0000000..5903d44 --- /dev/null +++ b/helpers/functions/__mocks__/apiResponse.ts @@ -0,0 +1,12 @@ +const ApiResponse = { + success: vi.fn(), + badRequest: vi.fn(), + unauthorized: vi.fn(), + forbidden: vi.fn(), + notFound: vi.fn(), + methodNotAllowed: vi.fn(), + validationError: vi.fn(), + serverError: vi.fn(), +}; + +export default ApiResponse; diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index d161fbc..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { JestConfigWithTsJest } from 'ts-jest'; - -const config: JestConfigWithTsJest = { - testEnvironment: 'node', - transform: { - '^.+\\.tsx?$': ['ts-jest', {}], - }, - moduleNameMapper: { - '^~/(.*)$': '/$1', - }, -}; - -export default config; diff --git a/package-lock.json b/package-lock.json index 1861e2e..8b0e5e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,34 +31,16 @@ "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", "@types/bcryptjs": "^2.4.6", - "@types/jest": "^29.5.14", "@types/node": "^22.10.2", "@types/nodemailer": "^6.4.17", "@types/react": "^18.3.18", "@types/supertest": "^6.0.2", "eslint-config-next": "^15.1.6", "husky": "^9.1.7", - "jest": "^29.7.0", "node-mocks-http": "^1.16.2", "prettier": "^3.5.1", - "supertest": "^7.0.0", - "ts-jest": "^29.3.0", - "ts-node": "^10.9.2", - "typescript": "^5.7.2" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "typescript": "^5.7.2", + "vitest": "^3.1.1" } }, "node_modules/@babel/code-frame": { @@ -75,77 +57,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/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==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", @@ -162,50 +73,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", @@ -219,34 +86,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", @@ -265,30 +104,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/parser": { "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", @@ -304,245 +119,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", - "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", - "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/runtime": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", @@ -609,13 +185,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, "node_modules/@commitlint/cli": { "version": "19.7.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.7.1.tgz", @@ -873,30 +442,6 @@ "node": ">=v18" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -1011,6 +556,431 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -1342,542 +1312,6 @@ "@img/sharp-libvips-linuxmusl-x64": "1.0.4" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": 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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core/node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@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==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -2133,6 +1567,286 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz", + "integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz", + "integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz", + "integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz", + "integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz", + "integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz", + "integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz", + "integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz", + "integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz", + "integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz", + "integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz", + "integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz", + "integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz", + "integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz", + "integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz", + "integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz", + "integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz", + "integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz", + "integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz", + "integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz", + "integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -2147,33 +1861,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -2214,79 +1901,6 @@ "react": ">= 16" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, "node_modules/@types/bcryptjs": { "version": "2.4.6", "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", @@ -2312,93 +1926,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/jest/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true, "license": "MIT" }, @@ -2485,13 +2015,6 @@ "@types/react": "*" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/superagent": { "version": "8.1.9", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", @@ -2516,23 +2039,6 @@ "@types/superagent": "^8.1.0" } }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.17.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz", @@ -2787,6 +2293,92 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vitest/expect": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz", + "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.1", + "@vitest/utils": "3.1.1", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz", + "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz", + "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.1.1", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz", + "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz", + "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz", + "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.1", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2807,6 +2399,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2825,19 +2418,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", @@ -2855,22 +2435,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2897,27 +2461,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3100,12 +2643,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12" + } }, "node_modules/ast-types-flow": { "version": "0.0.8", @@ -3114,13 +2660,6 @@ "dev": true, "license": "MIT" }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, "node_modules/async-mutex": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", @@ -3173,105 +2712,6 @@ "node": ">= 0.4" } }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=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==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": 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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -3303,50 +2743,6 @@ "node": ">=10" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3384,69 +2780,6 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -3458,6 +2791,16 @@ "node": ">=10.16.0" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -3517,16 +2860,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001700", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", @@ -3547,6 +2880,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chai": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -3560,16 +2910,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/chart.js": { "version": "4.4.7", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", @@ -3582,29 +2922,16 @@ "pnpm": ">=8" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 16" } }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", - "dev": true, - "license": "MIT" - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -3635,24 +2962,6 @@ "node": ">=6" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -3722,16 +3031,6 @@ "dot-prop": "^5.1.0" } }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3812,13 +3111,6 @@ "node": ">= 0.6" } }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true, - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", @@ -3864,58 +3156,13 @@ "typescript": ">=5" } }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/create-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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4032,19 +3279,14 @@ } } }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } + "engines": { + "node": ">=6" } }, "node_modules/deep-is": { @@ -4055,16 +3297,6 @@ "license": "MIT", "peer": true }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -4139,47 +3371,6 @@ "node": ">=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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -4231,42 +3422,6 @@ "node": ">= 0.4" } }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.103", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.103.tgz", - "integrity": "sha512-P6+XzIkfndgsrjROJWfSvVEgNHtPgbhVyTkwLjUM2HU/h7pZRORgaTlHqfAikqxKmdJMLW8fftrdGWbd/Ds0FA==", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -4415,6 +3570,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -4472,6 +3634,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5045,20 +4248,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -5097,6 +4286,16 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -5107,54 +4306,14 @@ "node": ">=0.10.0" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/expect-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", + "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12.0.0" } }, "node_modules/fast-deep-equal": { @@ -5199,7 +4358,8 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -5209,13 +4369,6 @@ "license": "MIT", "peer": true }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", @@ -5243,16 +4396,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5267,39 +4410,6 @@ "node": ">=16.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -5386,21 +4496,6 @@ "node": ">= 6" } }, - "node_modules/formidable": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz", - "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^2.0.0", - "once": "^1.4.0" - }, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5411,13 +4506,6 @@ "node": ">= 0.6" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -5471,16 +4559,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -5516,16 +4594,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -5540,19 +4608,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5602,28 +4657,6 @@ "node": ">=16" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5728,6 +4761,7 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -5802,16 +4836,6 @@ "node": ">= 0.4" } }, - "node_modules/hexoid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz", - "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -5821,23 +4845,6 @@ "react-is": "^16.7.0" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/husky": { "version": "9.1.7", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", @@ -5889,26 +4896,6 @@ "node": ">=4" } }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/import-meta-resolve": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", @@ -5926,29 +4913,11 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/ini": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", @@ -6152,16 +5121,6 @@ "node": ">=8" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -6302,19 +5261,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz", @@ -6434,88 +5380,8 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "ISC", + "peer": true }, "node_modules/iterator.prototype": { "version": "1.1.3", @@ -6534,1275 +5400,6 @@ "node": ">= 0.4" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-circus/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-config/node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "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==", - "dev": 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==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-runner/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/jiti": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", @@ -7949,16 +5546,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -7979,16 +5566,6 @@ "node": ">=0.10" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8047,13 +5624,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -8108,6 +5678,13 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true, + "license": "MIT" + }, "node_modules/lowdb": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz", @@ -8135,37 +5712,14 @@ "node": ">=10" } }, - "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==", + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/math-intrinsics": { @@ -8217,13 +5771,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8294,16 +5841,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8463,13 +6000,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, "node_modules/node-mocks-http": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.16.2.tgz", @@ -8504,13 +6034,6 @@ } } }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, "node_modules/nodemailer": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz", @@ -8520,29 +6043,6 @@ "node": ">=6.0.0" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", @@ -8685,32 +6185,6 @@ "node": "^10.13.0 || >=12.0.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/openid-client": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz", @@ -8777,16 +6251,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8837,22 +6301,13 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -8872,6 +6327,23 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8891,95 +6363,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -9073,20 +6456,6 @@ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", "license": "MIT" }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -9109,39 +6478,6 @@ "node": ">=6" } }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9364,19 +6700,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -9397,16 +6720,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -9418,6 +6731,46 @@ "node": ">=0.10.0" } }, + "node_modules/rollup": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz", + "integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.39.0", + "@rollup/rollup-android-arm64": "4.39.0", + "@rollup/rollup-darwin-arm64": "4.39.0", + "@rollup/rollup-darwin-x64": "4.39.0", + "@rollup/rollup-freebsd-arm64": "4.39.0", + "@rollup/rollup-freebsd-x64": "4.39.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.39.0", + "@rollup/rollup-linux-arm-musleabihf": "4.39.0", + "@rollup/rollup-linux-arm64-gnu": "4.39.0", + "@rollup/rollup-linux-arm64-musl": "4.39.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.39.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-musl": "4.39.0", + "@rollup/rollup-linux-s390x-gnu": "4.39.0", + "@rollup/rollup-linux-x64-gnu": "4.39.0", + "@rollup/rollup-linux-x64-musl": "4.39.0", + "@rollup/rollup-win32-arm64-msvc": "4.39.0", + "@rollup/rollup-win32-ia32-msvc": "4.39.0", + "@rollup/rollup-win32-x64-msvc": "4.39.0", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9602,6 +6955,7 @@ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9615,6 +6969,7 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -9695,10 +7050,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, @@ -9719,23 +7074,6 @@ "license": "MIT", "optional": true }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -9754,27 +7092,6 @@ "node": ">=0.10.0" } }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/spinners-react": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/spinners-react/-/spinners-react-1.0.10.tgz", @@ -9797,13 +7114,6 @@ "node": ">= 10.x" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/stable-hash": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", @@ -9811,28 +7121,19 @@ "dev": true, "license": "MIT" }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "MIT" }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "license": "MIT" }, "node_modules/steno": { "version": "4.0.2", @@ -9854,20 +7155,6 @@ "node": ">=10.0.0" } }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -10018,22 +7305,13 @@ "node": ">=4" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" }, @@ -10070,60 +7348,13 @@ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", "license": "MIT" }, - "node_modules/superagent": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz", - "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.4", - "debug": "^4.3.4", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", - "formidable": "^3.5.1", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.11.0" - }, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/superagent/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/supertest": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", - "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "methods": "^1.1.2", - "superagent": "^9.0.1" - }, - "engines": { - "node": ">=14.18.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10165,21 +7396,6 @@ "node": ">=6" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/text-extensions": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", @@ -10200,19 +7416,49 @@ "dev": true, "license": "MIT" }, - "node_modules/tinyexec": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, - "license": "BSD-3-Clause" + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -10240,126 +7486,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-jest": { - "version": "29.3.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.0.tgz", - "integrity": "sha512-4bfGBX7Gd1Aqz3SyeDS9O276wEU/BInZxskPrbhZLyv+c1wskDCqDFMJQJLWrIr/fKoAH4GE5dKUlrdyvo+39A==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "^4.1.2", - "make-error": "^1.3.6", - "semver": "^7.7.1", - "type-fest": "^4.37.0", - "yargs-parser": "^21.1.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.38.0.tgz", - "integrity": "sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -10393,29 +7519,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -10558,37 +7661,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -10636,43 +7708,356 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "node_modules/vite-node": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz", + "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==", "dev": true, - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=10.12.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "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==", + "node_modules/vite-node/node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, - "license": "MIT" - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "makeerror": "1.0.12" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/yaml": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vitest": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz", + "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.1.1", + "@vitest/mocker": "3.1.1", + "@vitest/pretty-format": "^3.1.1", + "@vitest/runner": "3.1.1", + "@vitest/snapshot": "3.1.1", + "@vitest/spy": "3.1.1", + "@vitest/utils": "3.1.1", + "chai": "^5.2.0", + "debug": "^4.4.0", + "expect-type": "^1.2.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "std-env": "^3.8.1", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.1.1", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.1.1", + "@vitest/ui": "3.1.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz", + "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.1", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/yaml": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" } }, "node_modules/which": { @@ -10681,6 +8066,7 @@ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -10778,6 +8164,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -10807,27 +8210,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "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==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10882,16 +8264,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", diff --git a/package.json b/package.json index ece18a1..f15d61b 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "test": "jest", - "test:watch": "jest --watch", "lint": "next lint", + "test": "vitest", "setup": "npm install && npm run setup:hooks", "setup:hooks": "npx husky install", "format": "prettier --write \"{Components,Containers,helpers,pages,styles}/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"" @@ -37,19 +36,15 @@ "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", "@types/bcryptjs": "^2.4.6", - "@types/jest": "^29.5.14", "@types/node": "^22.10.2", "@types/nodemailer": "^6.4.17", "@types/react": "^18.3.18", "@types/supertest": "^6.0.2", "eslint-config-next": "^15.1.6", "husky": "^9.1.7", - "jest": "^29.7.0", "node-mocks-http": "^1.16.2", "prettier": "^3.5.1", - "supertest": "^7.0.0", - "ts-jest": "^29.3.0", - "ts-node": "^10.9.2", - "typescript": "^5.7.2" + "typescript": "^5.7.2", + "vitest": "^3.1.1" } } diff --git a/tests/supertest/getAppriseAlert.test.ts b/pages/api/account/getAppriseAlert.test.ts similarity index 67% rename from tests/supertest/getAppriseAlert.test.ts rename to pages/api/account/getAppriseAlert.test.ts index af24381..0d81410 100644 --- a/tests/supertest/getAppriseAlert.test.ts +++ b/pages/api/account/getAppriseAlert.test.ts @@ -3,15 +3,15 @@ import { createMocks } from 'node-mocks-http'; import { getUsersList } from '~/services'; import handler from '~/pages/api/account/getAppriseAlert'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), })); describe('Get Apprise Alert API', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if the method is not GET', async () => { @@ -21,7 +21,7 @@ describe('Get Apprise Alert API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(401); @@ -29,11 +29,20 @@ describe('Get Apprise Alert API', () => { }); it('should return 400 if the user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'nonexistent' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: true }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseAlert: true, + }, + ]); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); @@ -45,11 +54,20 @@ describe('Get Apprise Alert API', () => { }); it('should return appriseAlert value if the user exists', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: true }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseAlert: true, + }, + ]); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); @@ -58,11 +76,11 @@ describe('Get Apprise Alert API', () => { }); it('should return 500 if there is an error reading the file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockImplementation(() => { + vi.mocked(getUsersList).mockImplementation(() => { throw new Error(); }); diff --git a/tests/supertest/getAppriseMode.test.ts b/pages/api/account/getAppriseMode.test.ts similarity index 70% rename from tests/supertest/getAppriseMode.test.ts rename to pages/api/account/getAppriseMode.test.ts index a180a71..d254fc2 100644 --- a/tests/supertest/getAppriseMode.test.ts +++ b/pages/api/account/getAppriseMode.test.ts @@ -2,16 +2,17 @@ import { getServerSession } from 'next-auth/next'; import { createMocks } from 'node-mocks-http'; import { getUsersList } from '~/services'; import handler from '~/pages/api/account/getAppriseMode'; +import { AppriseModeEnum } from '~/types/domain/config.types'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), })); describe('Get Apprise Mode API', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if the method is not GET', async () => { @@ -21,7 +22,7 @@ describe('Get Apprise Mode API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(401); @@ -29,14 +30,18 @@ describe('Get Apprise Mode API', () => { }); it('should return 400 if the user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'nonexistent' }, }); - (getUsersList as jest.Mock).mockResolvedValue([ + vi.mocked(getUsersList).mockResolvedValue([ { + id: 1, username: 'testuser', - appriseMode: 'stateless', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseMode: AppriseModeEnum.STATELESS, appriseStatelessURL: 'https://example.com', }, ]); @@ -51,14 +56,18 @@ describe('Get Apprise Mode API', () => { }); it('should return appriseMode and appriseStatelessURL if the user exists', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockResolvedValue([ + vi.mocked(getUsersList).mockResolvedValue([ { + id: 1, username: 'testuser', - appriseMode: 'stateless', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseMode: AppriseModeEnum.STATELESS, appriseStatelessURL: 'https://example.com', }, ]); @@ -74,11 +83,11 @@ describe('Get Apprise Mode API', () => { }); it('should return 500 if there is an error reading the file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockImplementation(() => { + vi.mocked(getUsersList).mockImplementation(() => { throw new Error(); }); const { req, res } = createMocks({ method: 'GET' }); diff --git a/tests/supertest/getAppriseServices.test.ts b/pages/api/account/getAppriseServices.test.ts similarity index 66% rename from tests/supertest/getAppriseServices.test.ts rename to pages/api/account/getAppriseServices.test.ts index a228c2d..5defe61 100644 --- a/tests/supertest/getAppriseServices.test.ts +++ b/pages/api/account/getAppriseServices.test.ts @@ -3,15 +3,15 @@ import { createMocks } from 'node-mocks-http'; import { getUsersList } from '~/services'; import handler from '~/pages/api/account/getAppriseServices'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), })); describe('Get Apprise Services API', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if the method is not GET', async () => { @@ -21,7 +21,7 @@ describe('Get Apprise Services API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(401); @@ -29,12 +29,19 @@ describe('Get Apprise Services API', () => { }); it('should return 400 if the user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'nonexistent' }, }); - (getUsersList as jest.Mock).mockResolvedValue([ - { username: 'testuser', appriseServices: ['service1', 'service2'] }, + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseServices: ['service1', 'service2'], + }, ]); const { req, res } = createMocks({ method: 'GET' }); @@ -47,12 +54,19 @@ describe('Get Apprise Services API', () => { }); it('should return appriseServices if the user exists', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockResolvedValue([ - { username: 'testuser', appriseServices: ['service1', 'service2'] }, + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseServices: ['service1', 'service2'], + }, ]); const { req, res } = createMocks({ method: 'GET' }); @@ -65,11 +79,11 @@ describe('Get Apprise Services API', () => { }); it('should return 500 if there is an error reading the file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockImplementation(() => { + vi.mocked(getUsersList).mockImplementation(() => { throw new Error(); }); diff --git a/tests/supertest/getEmailAlert.test.ts b/pages/api/account/getEmailAlert.test.ts similarity index 67% rename from tests/supertest/getEmailAlert.test.ts rename to pages/api/account/getEmailAlert.test.ts index ffd7156..372c0de 100644 --- a/tests/supertest/getEmailAlert.test.ts +++ b/pages/api/account/getEmailAlert.test.ts @@ -1,19 +1,17 @@ +import { getServerSession } from 'next-auth/next'; import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/account/getEmailAlert'; -import { getServerSession } from 'next-auth/next'; -import { promises as fs } from 'fs'; -import path from 'path'; import { getUsersList } from '~/services'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), })); describe('Get Email Alert API', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if the method is not GET', async () => { @@ -23,7 +21,7 @@ describe('Get Email Alert API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(401); @@ -31,11 +29,20 @@ describe('Get Email Alert API', () => { }); it('should return 400 if the user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'nonexistent' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', emailAlert: true }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + email: 'testuser@example.com', + password: 'hashedpassword', + roles: ['user'], + emailAlert: true, + }, + ]); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); @@ -47,11 +54,20 @@ describe('Get Email Alert API', () => { }); it('should return emailAlert if the user exists', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', emailAlert: true }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + email: 'testuser@example.com', + password: 'hashedpassword', + roles: ['user'], + emailAlert: true, + }, + ]); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); @@ -63,11 +79,11 @@ describe('Get Email Alert API', () => { }); it('should return 500 if there is an error reading the file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockImplementation(() => { + vi.mocked(getUsersList).mockImplementation(() => { throw new Error(); }); diff --git a/tests/supertest/getWizardEnv.test.ts b/pages/api/account/getWizardEnv.test.ts similarity index 89% rename from tests/supertest/getWizardEnv.test.ts rename to pages/api/account/getWizardEnv.test.ts index 23c972b..c02a606 100644 --- a/tests/supertest/getWizardEnv.test.ts +++ b/pages/api/account/getWizardEnv.test.ts @@ -2,7 +2,7 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/account/getWizardEnv'; import { getServerSession } from 'next-auth/next'; -jest.mock('next-auth/next'); +vi.mock('next-auth/next'); describe('Get Wizard Env API', () => { it('should return 405 if the method is not GET', async () => { @@ -12,14 +12,14 @@ describe('Get Wizard Env API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(401); }); it('should return 200 with wizardEnv if the user is authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } }); process.env.UNIX_USER = 'borgwarehouse'; process.env.FQDN = 'localhost'; diff --git a/tests/supertest/sendTestEmail.test.ts b/pages/api/account/sendTestEmail.test.ts similarity index 64% rename from tests/supertest/sendTestEmail.test.ts rename to pages/api/account/sendTestEmail.test.ts index 38412ab..d0f7b0b 100644 --- a/tests/supertest/sendTestEmail.test.ts +++ b/pages/api/account/sendTestEmail.test.ts @@ -2,34 +2,26 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/account/sendTestEmail'; import { getServerSession } from 'next-auth/next'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), -})); -jest.mock('~/helpers/functions/nodemailerSMTP', () => ({ +vi.mock('next-auth/next', () => ({ __esModule: true, - default: jest.fn(() => ({ - sendMail: jest.fn().mockResolvedValue({ messageId: 'fake-message-id' }), + getServerSession: vi.fn(), +})); + +vi.mock('~/helpers/functions/nodemailerSMTP', () => ({ + __esModule: true, + default: vi.fn(() => ({ + sendMail: vi.fn().mockResolvedValue({ messageId: 'fake-message-id' }), })), })); describe('Email API', () => { beforeEach(() => { - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 401 if not authenticated', async () => { // Mock unauthenticated session - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); // Simulate a POST request const { req, res } = createMocks({ method: 'POST' }); @@ -41,7 +33,7 @@ describe('Email API', () => { it('should send an email if authenticated', async () => { // Mock unauthenticated session - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { email: 'ada-lovelace@example.com', name: 'Lovelace' }, }); diff --git a/pages/api/account/tokenManager.test.ts b/pages/api/account/tokenManager.test.ts new file mode 100644 index 0000000..9fa35e5 --- /dev/null +++ b/pages/api/account/tokenManager.test.ts @@ -0,0 +1,208 @@ +import handler from '~/pages/api/account/tokenManager'; +import { createMocks } from 'node-mocks-http'; +import { getServerSession } from 'next-auth/next'; +import { getUsersList, updateUsersList } from '~/services'; +import ApiResponse from '~/helpers/functions/apiResponse'; + +vi.mock('next-auth/next', () => ({ + __esModule: true, + getServerSession: vi.fn(), +})); + +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), + updateUsersList: vi.fn(), +})); + +vi.mock('~/helpers/functions/apiResponse'); + +describe('Token Manager API', () => { + afterEach(() => { + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); + }); + + it('should return unauthorized if session is not found', async () => { + vi.mocked(getServerSession).mockResolvedValue(null); + + const { req, res } = createMocks({ + method: 'POST', + body: { + name: 'testToken', + permissions: { create: true, read: true, update: true, delete: true }, + }, + }); + + await handler(req, res); + + expect(ApiResponse.unauthorized).toHaveBeenCalledWith(res); + }); + + it('should create a new token if valid data is provided', async () => { + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testUser', + password: 'hashedPassword', + email: 'testUser@example.com', + roles: ['user'], + tokens: [], + }, + ]); + vi.mocked(updateUsersList).mockResolvedValue(); + + const { req, res } = createMocks({ + method: 'POST', + body: { + name: 'testToken', + permissions: { create: true, read: true, update: true, delete: true }, + }, + }); + + await handler(req, res); + + expect(res._getStatusCode()).toBe(200); + const responseData = JSON.parse(res._getData()); + expect(responseData).toHaveProperty('token'); + expect(updateUsersList).toHaveBeenCalled(); + }); + + it('should return bad request if token name already exists', async () => { + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testUser', + password: 'hashedPassword', + email: 'testUser@example.com', + roles: ['user'], + tokens: [ + { + token: 'sampleToken123', + name: 'testToken', + permissions: { create: true, read: true, update: true, delete: true }, + creation: 123, + }, + ], + }, + ]); + + const { req, res } = createMocks({ + method: 'POST', + body: { + name: 'testToken', + permissions: { create: true, read: true, update: true, delete: true }, + }, + }); + + await handler(req, res); + + expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Token name already exists'); + }); + + it('should return token list for GET request', async () => { + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testUser', + password: 'hashedPassword', + email: 'testUser@example.com', + roles: ['user'], + tokens: [ + { + token: 'sampleToken1', + name: 'token1', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 123, + }, + { + token: 'sampleToken2', + name: 'token2', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 456, + }, + ], + }, + ]); + + const { req, res } = createMocks({ method: 'GET' }); + + await handler(req, res); + + expect(res._getStatusCode()).toBe(200); + const responseData = JSON.parse(res._getData()); + expect(responseData).toEqual([ + { + name: 'token1', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 123, + }, + { + name: 'token2', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 456, + }, + ]); + }); + + it('should delete a token for DELETE request', async () => { + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testUser', + password: 'hashedPassword', + email: 'testUser@example.com', + roles: ['user'], + tokens: [ + { + token: 'sampleToken1', + name: 'token1', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 123, + }, + { + token: 'sampleToken2', + name: 'token2', + permissions: { create: false, read: false, update: false, delete: false }, + creation: 456, + }, + ], + }, + ]); + vi.mocked(updateUsersList).mockResolvedValue(); + + const { req, res } = createMocks({ + method: 'DELETE', + body: { name: 'token1' }, + }); + + await handler(req, res); + + expect(ApiResponse.success).toHaveBeenCalledWith(res, 'Token deleted'); + expect(updateUsersList).toHaveBeenCalled(); + }); + + it('should return bad request if token name is missing in DELETE request', async () => { + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } }); + + const { req, res } = createMocks({ + method: 'DELETE', + body: {}, + }); + + await handler(req, res); + + expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Missing token name'); + }); + + it('should return method not allowed for unsupported HTTP methods', async () => { + const { req, res } = createMocks({ method: 'PUT' }); + + await handler(req, res); + + expect(ApiResponse.methodNotAllowed).toHaveBeenCalledWith(res); + }); +}); diff --git a/pages/api/account/tokenManager.ts b/pages/api/account/tokenManager.ts index 313b1dd..3fc08bd 100644 --- a/pages/api/account/tokenManager.ts +++ b/pages/api/account/tokenManager.ts @@ -3,7 +3,7 @@ import { getServerSession } from 'next-auth/next'; import { NextApiRequest, NextApiResponse } from 'next'; import { IntegrationTokenType, TokenPermissionsType } from '~/types/api/integration.types'; import ApiResponse from '~/helpers/functions/apiResponse'; -import { getUsersList, updateUsersList } from '~/helpers/functions'; +import { getUsersList, updateUsersList } from '~/services'; import { getUnixTime } from 'date-fns'; import { v4 as uuidv4 } from 'uuid'; import { BorgWarehouseApiResponse } from '~/types/api/error.types'; diff --git a/tests/supertest/updateAppriseAlert.test.ts b/pages/api/account/updateAppriseAlert.test.ts similarity index 63% rename from tests/supertest/updateAppriseAlert.test.ts rename to pages/api/account/updateAppriseAlert.test.ts index f68d09a..5dc315b 100644 --- a/tests/supertest/updateAppriseAlert.test.ts +++ b/pages/api/account/updateAppriseAlert.test.ts @@ -3,19 +3,19 @@ import handler from '~/pages/api/account/updateAppriseAlert'; import { getServerSession } from 'next-auth/next'; import { getUsersList, updateUsersList } from '~/services'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ __esModule: true, - getUsersList: jest.fn(), - updateUsersList: jest.fn(), + getUsersList: vi.fn(), + updateUsersList: vi.fn(), })); describe('Notifications API', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.resetAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.resetAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if the method is not PUT', async () => { @@ -25,7 +25,7 @@ describe('Notifications API', () => { }); it('should return 401 if the user is not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } }); await handler(req, res); @@ -33,7 +33,7 @@ describe('Notifications API', () => { }); it('should return 422 if the request body is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); @@ -44,11 +44,20 @@ describe('Notifications API', () => { }); it('should return 400 if the user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'nonexistent' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: false }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseAlert: false, + }, + ]); const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } }); await handler(req, res); @@ -59,26 +68,44 @@ describe('Notifications API', () => { }); it('should update appriseAlert and return 200 if everything is correct', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: false }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseAlert: false, + }, + ]); const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } }); await handler(req, res); - expect(updateUsersList).toHaveBeenCalledWith([{ username: 'testuser', appriseAlert: true }]); + expect(updateUsersList).toHaveBeenCalledWith([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseAlert: true, + }, + ]); expect(res._getStatusCode()).toBe(200); expect(res._getJSONData()).toEqual({ message: 'Successful API send' }); }); it('should return 500 if there is an error reading users file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' }, }); - (getUsersList as jest.Mock).mockRejectedValue({ code: 'ENOENT' }); + vi.mocked(getUsersList).mockRejectedValue({ code: 'ENOENT' }); const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } }); await handler(req, res); diff --git a/tests/supertest/updateAppriseMode.test.ts b/pages/api/account/updateAppriseMode.test.ts similarity index 59% rename from tests/supertest/updateAppriseMode.test.ts rename to pages/api/account/updateAppriseMode.test.ts index de20a93..6011d56 100644 --- a/tests/supertest/updateAppriseMode.test.ts +++ b/pages/api/account/updateAppriseMode.test.ts @@ -2,11 +2,12 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/account/updateAppriseMode'; import { getServerSession } from 'next-auth/next'; import { getUsersList, updateUsersList } from '~/services'; +import { AppriseModeEnum } from '~/types/domain/config.types'; -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), - updateUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), + updateUsersList: vi.fn(), })); describe('Apprise Mode API', () => { @@ -17,7 +18,7 @@ describe('Apprise Mode API', () => { }); it('should return 401 if not authenticated', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'PUT' }); await handler(req, res); @@ -26,7 +27,7 @@ describe('Apprise Mode API', () => { }); it('should return 422 if invalid data is provided', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } }); const { req, res } = createMocks({ method: 'PUT', @@ -38,9 +39,16 @@ describe('Apprise Mode API', () => { }); it('should return 400 if user does not exist', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'unknownuser' } }); - (getUsersList as jest.Mock).mockResolvedValue([ - { username: 'testuser', appriseMode: 'package' }, + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'unknownuser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseMode: AppriseModeEnum.PACKAGE, + }, ]); const { req, res } = createMocks({ @@ -53,11 +61,18 @@ describe('Apprise Mode API', () => { }); it('should update user settings and return 200', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } }); - (getUsersList as jest.Mock).mockResolvedValue([ - { username: 'testuser', appriseMode: 'package' }, + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } }); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'testuser', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseMode: AppriseModeEnum.PACKAGE, + }, ]); - (updateUsersList as jest.Mock).mockResolvedValue(null); + vi.mocked(updateUsersList).mockResolvedValue(); const { req, res } = createMocks({ method: 'PUT', @@ -68,8 +83,12 @@ describe('Apprise Mode API', () => { expect(updateUsersList).toHaveBeenCalledWith([ { + id: 1, username: 'testuser', - appriseMode: 'stateless', + password: 'hashedpassword', + roles: ['user'], + email: 'testuser@example.com', + appriseMode: AppriseModeEnum.STATELESS, appriseStatelessURL: 'https://example.com', }, ]); diff --git a/tests/supertest/updateAppriseServices.test.ts b/pages/api/account/updateAppriseServices.test.ts similarity index 68% rename from tests/supertest/updateAppriseServices.test.ts rename to pages/api/account/updateAppriseServices.test.ts index 23e2888..510f5a7 100644 --- a/tests/supertest/updateAppriseServices.test.ts +++ b/pages/api/account/updateAppriseServices.test.ts @@ -3,24 +3,23 @@ import handler from '~/pages/api/account/updateAppriseServices'; import { getServerSession } from 'next-auth/next'; import { getUsersList, updateUsersList } from '~/services'; -// Mock imports -jest.mock('next-auth/next'); -jest.mock('~/services', () => ({ - getUsersList: jest.fn(), - updateUsersList: jest.fn(), +vi.mock('next-auth/next'); +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), + updateUsersList: vi.fn(), })); describe('PUT /api/account/updateAppriseURLs', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.resetAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.resetAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 401 if not authenticated', async () => { // Mock unauthenticated session - (getServerSession as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); const { req, res } = createMocks({ method: 'PUT' }); await handler(req, res); @@ -37,11 +36,19 @@ describe('PUT /api/account/updateAppriseURLs', () => { it('should return 400 if user is not found in the users list', async () => { // Mock authenticated session - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'Lovelace' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'Ada' }]); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'Ada', + password: 'securepassword', + roles: ['user'], + email: 'ada@example.com', + }, + ]); const { req, res } = createMocks({ method: 'PUT', @@ -56,12 +63,21 @@ describe('PUT /api/account/updateAppriseURLs', () => { }); it('should return 200 and successfully update the appriseURLs', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'Lovelace' }, }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'Lovelace', appriseServices: [] }]); - (updateUsersList as jest.Mock).mockResolvedValue(null); + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + username: 'Lovelace', + password: 'securepassword', + roles: ['user'], + email: 'lovelace@example.com', + appriseServices: [], + }, + ]); + vi.mocked(updateUsersList).mockResolvedValue(); const { req, res } = createMocks({ method: 'PUT', @@ -74,11 +90,11 @@ describe('PUT /api/account/updateAppriseURLs', () => { }); it('should return 500 if there is an error reading the users file', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'Lovelace' }, }); - (getUsersList as jest.Mock).mockRejectedValue({ code: 'ENOENT' }); + vi.mocked(getUsersList).mockRejectedValue({ code: 'ENOENT' }); const { req, res } = createMocks({ method: 'PUT', @@ -94,11 +110,11 @@ describe('PUT /api/account/updateAppriseURLs', () => { }); it('should return 500 if there is an API error', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'Lovelace' }, }); - (getUsersList as jest.Mock).mockRejectedValue({ code: 'UNKNOWN_ERROR' }); + vi.mocked(getUsersList).mockRejectedValue({ code: 'UNKNOWN_ERROR' }); const { req, res } = createMocks({ method: 'PUT', diff --git a/pages/api/account/updateEmail.test.ts b/pages/api/account/updateEmail.test.ts new file mode 100644 index 0000000..0b1cb67 --- /dev/null +++ b/pages/api/account/updateEmail.test.ts @@ -0,0 +1,137 @@ +import { describe, it, expect, vi } from 'vitest'; +import handler from './updateEmail'; +import { getUsersList, updateUsersList } from '~/services'; +import { getServerSession } from 'next-auth/next'; +import { NextApiRequest, NextApiResponse } from 'next'; + +vi.mock('~/services', () => ({ + getUsersList: vi.fn(), + updateUsersList: vi.fn(), +})); + +vi.mock('next-auth/next', () => ({ + getServerSession: vi.fn(), +})); + +describe('updateEmail API handler', () => { + const mockReq = { + method: 'PUT', + body: { email: 'newemail@example.com' }, + } as unknown as NextApiRequest; + + const mockRes = { + status: vi.fn().mockReturnThis(), + json: vi.fn(), + } as unknown as NextApiResponse; + + it('should return 405 if method is not PUT', async () => { + mockReq.method = 'GET'; + await handler(mockReq, mockRes); + expect(mockRes.status).toHaveBeenCalledWith(405); + }); + + it('should return 401 if session is not found', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce(null); + await handler(mockReq, mockRes); + expect(mockRes.status).toHaveBeenCalledWith(401); + }); + + it('should return 422 if email is not provided', async () => { + mockReq.body = {}; + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + await handler(mockReq, mockRes); + expect(mockRes.status).toHaveBeenCalledWith(422); + expect(mockRes.json).toHaveBeenCalledWith({ message: 'Unexpected data' }); + }); + + it('should return 400 if user is not found in users list', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + vi.mocked(getUsersList).mockResolvedValueOnce([]); + await handler(mockReq, mockRes); + expect(mockRes.status).toHaveBeenCalledWith(400); + expect(mockRes.json).toHaveBeenCalledWith({ + message: 'User is incorrect. Please, logout to update your session.', + }); + }); + + it('should return 400 if email already exists', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + vi.mocked(getUsersList).mockResolvedValueOnce([ + { + username: 'testuser', + email: 'oldemail@example.com', + id: 1, + password: 'hashedpassword', + roles: ['user'], + }, + { + username: 'otheruser', + email: 'newemail@example.com', + id: 2, + password: 'hashedpassword', + roles: ['user'], + }, + ]); + await handler(mockReq, mockRes); + expect(mockRes.status).toHaveBeenCalledWith(400); + expect(mockRes.json).toHaveBeenCalledWith({ message: 'Email already exists' }); + }); + + it('should update email and return 200 on success', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + vi.mocked(getUsersList).mockResolvedValueOnce([ + { + username: 'testuser', + email: 'oldemail@example.com', + id: 1, + password: 'hashedpassword', + roles: ['user'], + }, + { + username: 'otheruser', + email: 'otheremail@example.com', + id: 2, + password: 'hashedpassword', + roles: ['user'], + }, + ]); + vi.mocked(updateUsersList).mockResolvedValueOnce(undefined); + + await handler(mockReq, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(200); + expect(mockRes.json).toHaveBeenCalledWith({ message: 'Successful API send' }); + expect(updateUsersList).toHaveBeenCalledWith([ + { username: 'testuser', email: 'newemail@example.com' }, + { username: 'otheruser', email: 'otheremail@example.com' }, + ]); + }); + + it('should return 500 if an unexpected error occurs', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + vi.mocked(getUsersList).mockRejectedValueOnce(new Error('Unexpected error')); + + await handler(mockReq, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(500); + expect(mockRes.json).toHaveBeenCalledWith({ + status: 500, + message: 'API error, contact the administrator', + }); + }); + + it('should return 500 with specific message if ENOENT error occurs', async () => { + vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } }); + const enoentError = new Error('No such file or directory'); + (enoentError as any).code = 'ENOENT'; + vi.mocked(getUsersList).mockRejectedValueOnce(enoentError); + + await handler(mockReq, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(500); + expect(mockRes.json).toHaveBeenCalledWith({ + status: 500, + message: 'No such file or directory', + }); + }); +}); diff --git a/pages/api/account/updateEmailAlert.test.ts b/pages/api/account/updateEmailAlert.test.ts new file mode 100644 index 0000000..e69de29 diff --git a/pages/api/account/updatePasssword.test.ts b/pages/api/account/updatePasssword.test.ts new file mode 100644 index 0000000..e69de29 diff --git a/pages/api/account/updatePassword.ts b/pages/api/account/updatePassword.ts index 803c7bd..655d94f 100644 --- a/pages/api/account/updatePassword.ts +++ b/pages/api/account/updatePassword.ts @@ -1,5 +1,6 @@ -import { getUsersList, updateUsersList, hashPassword, verifyPassword } from '~/helpers/functions'; +import { hashPassword, verifyPassword } from '~/helpers/functions'; import { authOptions } from '../auth/[...nextauth]'; +import { getUsersList, updateUsersList } from '~/services'; import { getServerSession } from 'next-auth/next'; import { NextApiRequest, NextApiResponse } from 'next'; import { ErrorResponse } from '~/types/api/error.types'; diff --git a/pages/api/account/updateUsername.test.ts b/pages/api/account/updateUsername.test.ts new file mode 100644 index 0000000..e69de29 diff --git a/pages/api/account/updateUsername.ts b/pages/api/account/updateUsername.ts index ce89953..9c2bd21 100644 --- a/pages/api/account/updateUsername.ts +++ b/pages/api/account/updateUsername.ts @@ -1,4 +1,4 @@ -import { getUsersList, updateUsersList } from '~/helpers/functions'; +import { getUsersList, updateUsersList } from '~/services'; import { authOptions } from '../auth/[...nextauth]'; import { getServerSession } from 'next-auth/next'; import { UsernameSettingDTO } from '~/types/api/setting.types'; diff --git a/tests/supertest/checkStatus.test.ts b/pages/api/cronjob/checkStatus.test.ts similarity index 59% rename from tests/supertest/checkStatus.test.ts rename to pages/api/cronjob/checkStatus.test.ts index 9c7d415..7502959 100644 --- a/tests/supertest/checkStatus.test.ts +++ b/pages/api/cronjob/checkStatus.test.ts @@ -3,33 +3,33 @@ import handler from '~/pages/api/cronjob/checkStatus'; import { getRepoList, getUsersList, updateRepoList } from '~/services'; import { getLastSaveListShell } from '~/helpers/functions/shell.utils'; import nodemailerSMTP from '~/helpers/functions/nodemailerSMTP'; +import { AppriseModeEnum } from '~/types/domain/config.types'; -jest.mock('~/services', () => ({ - getRepoList: jest.fn(), - getUsersList: jest.fn(), - updateRepoList: jest.fn(), +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), + getUsersList: vi.fn(), + updateRepoList: vi.fn(), })); -jest.mock('~/helpers/functions/shell.utils', () => ({ - getLastSaveListShell: jest.fn(), +vi.mock('~/helpers/functions/shell.utils', () => ({ + getLastSaveListShell: vi.fn(), })); -jest.mock('~/helpers/functions/nodemailerSMTP', () => ({ - __esModule: true, - default: jest.fn(() => ({ - sendMail: jest.fn().mockResolvedValue({ messageId: 'fake-message-id' }), +vi.mock('~/helpers/functions/nodemailerSMTP', () => ({ + default: vi.fn(() => ({ + sendMail: vi.fn().mockResolvedValue({ messageId: 'fake-message-id' }), })), })); -jest.mock('~/helpers/templates/emailAlertStatus', () => - jest.fn(() => ({ +vi.mock('~/helpers/templates/emailAlertStatus', () => ({ + default: vi.fn(() => ({ subject: 'Alert', text: 'Alert text', - })) -); + })), +})); -jest.mock('node:child_process', () => ({ - exec: jest.fn( +vi.mock('node:child_process', () => ({ + exec: vi.fn( ( command: string, callback: (err: Error | null, result: { stdout: string; stderr: string }) => void @@ -42,9 +42,9 @@ jest.mock('node:child_process', () => ({ describe('Cronjob API Handler', () => { beforeEach(() => { process.env.CRONJOB_KEY = 'test-key'; - jest.clearAllMocks(); - jest.resetModules(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 401 if no authorization header', async () => { @@ -72,10 +72,8 @@ describe('Cronjob API Handler', () => { }); it('should return 200 with message if no repository to check (empty repoList)', async () => { - (getRepoList as jest.Mock).mockResolvedValue([]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', lastSave: 123 }, - ]); + vi.mocked(getRepoList).mockResolvedValue([]); + vi.mocked(getLastSaveListShell).mockResolvedValue([{ repositoryName: 'repo1', lastSave: 123 }]); const { req, res } = createMocks({ method: 'POST', @@ -91,10 +89,21 @@ describe('Cronjob API Handler', () => { }); it('should return 200 with message if no repository to check (empty lastSaveList)', async () => { - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', alert: 100, alias: 'Repo1' }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + alert: 100, + alias: 'Repo1', + id: 1, + status: true, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([]); + vi.mocked(getLastSaveListShell).mockResolvedValue([]); const { req, res } = createMocks({ method: 'POST', @@ -111,14 +120,25 @@ describe('Cronjob API Handler', () => { it('should execute successfully without alerts if all repositories are OK', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', alert: 1000, alias: 'Repo1', status: true }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + alert: 1000, + alias: 'Repo1', + status: true, + id: 1, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime }, ]); - (updateRepoList as jest.Mock).mockResolvedValue(undefined); - (getUsersList as jest.Mock).mockResolvedValue([]); + vi.mocked(updateRepoList).mockResolvedValue(undefined); + vi.mocked(getUsersList).mockResolvedValue([]); const { req, res } = createMocks({ method: 'POST', @@ -135,7 +155,7 @@ describe('Cronjob API Handler', () => { }); it('should return 500 if an error occurs', async () => { - (getRepoList as jest.Mock).mockRejectedValue(new Error('Test error')); + vi.mocked(getRepoList).mockRejectedValue(new Error('Test error')); const { req, res } = createMocks({ method: 'POST', @@ -153,19 +173,33 @@ describe('Cronjob API Handler', () => { it('should not send email alert if emailAlert is false', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', alert: 100, alias: 'Repo1' }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + alert: 100, + alias: 'Repo1', + id: 1, + status: true, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 200 }, ]); // User has disabled email alert but enabled Apprise alert - (getUsersList as jest.Mock).mockResolvedValue([ + vi.mocked(getUsersList).mockResolvedValue([ { + id: 1, + password: 'hashed-password', + roles: ['user'], emailAlert: false, appriseAlert: true, appriseServices: ['http://example.com'], - appriseMode: 'package', + appriseMode: AppriseModeEnum.PACKAGE, appriseStatelessURL: 'http://example.com', email: 'test@example.com', username: 'testuser', @@ -183,19 +217,33 @@ describe('Cronjob API Handler', () => { it('should not send apprise alert if appriseAlert is false', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', alert: 100, alias: 'Repo1' }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + alert: 100, + alias: 'Repo1', + id: 1, + status: true, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 200 }, ]); // User has disabled Apprise alert but enabled email alert - (getUsersList as jest.Mock).mockResolvedValue([ + vi.mocked(getUsersList).mockResolvedValue([ { + id: 1, + password: 'hashed-password', + roles: ['user'], emailAlert: true, appriseAlert: false, appriseServices: ['http://example.com'], - appriseMode: 'package', + appriseMode: AppriseModeEnum.PACKAGE, appriseStatelessURL: 'http://example.com', email: 'test@example.com', username: 'testuser', @@ -203,7 +251,7 @@ describe('Cronjob API Handler', () => { ]); // Spy on exec to check if it is called - const execSpy = jest.spyOn(require('node:child_process'), 'exec'); + const execSpy = vi.spyOn(require('node:child_process'), 'exec'); const { req, res } = createMocks({ method: 'POST', headers: { authorization: 'Bearer test-key' }, @@ -216,46 +264,68 @@ describe('Cronjob API Handler', () => { it('should not send alert if alert is disabled on repo (repo.alert === 0)', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', alert: 0, alias: 'Repo1' }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + alert: 0, + alias: 'Repo1', + id: 1, + status: false, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 1000 }, ]); - (getUsersList as jest.Mock).mockResolvedValue([ + vi.mocked(getUsersList).mockResolvedValue([ { + id: 1, + password: 'hashed-password', + roles: ['user'], emailAlert: true, appriseAlert: true, appriseServices: ['http://example.com'], - appriseMode: 'package', + appriseMode: AppriseModeEnum.PACKAGE, appriseStatelessURL: 'http://example.com', email: 'test@example.com', username: 'testuser', }, ]); - // Spy on exec to check if it is called - const nodemailerSpy = jest.spyOn(require('~/helpers/functions/nodemailerSMTP'), 'default'); - const execSpy = jest.spyOn(require('node:child_process'), 'exec'); - const { req, res } = createMocks({ method: 'POST', headers: { authorization: 'Bearer test-key' }, }); await handler(req, res); - expect(nodemailerSpy).not.toHaveBeenCalled(); - expect(execSpy).not.toHaveBeenCalled(); + expect(nodemailerSMTP).not.toHaveBeenCalled(); - nodemailerSpy.mockRestore(); - execSpy.mockRestore(); + const childProcess = await import('node:child_process'); + expect(childProcess.exec).not.toHaveBeenCalled(); }); it('should not update lastStatusAlertSend or add to repoListToSendAlert if repo status is OK', async () => { - (getRepoList as jest.Mock).mockResolvedValue([ - { repositoryName: 'repo1', status: true, alert: 100 }, + vi.mocked(getRepoList).mockResolvedValue([ + { + repositoryName: 'repo1', + status: true, + alert: 100, + id: 1, + alias: 'Repo1', + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + lastStatusAlertSend: 1000, + }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(updateRepoList).mockResolvedValue(undefined); + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: Math.floor(Date.now() / 1000) }, ]); @@ -271,7 +341,14 @@ describe('Cronjob API Handler', () => { repositoryName: 'repo1', status: true, alert: 100, + id: 1, + alias: 'Repo1', lastSave: expect.any(Number), + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', + lastStatusAlertSend: 1000, }, ]); expect(res._getStatusCode()).toBe(200); @@ -279,19 +356,32 @@ describe('Cronjob API Handler', () => { it('should update lastStatusAlertSend if repo is down and alert is enabled', async () => { const currentTime = 1741535661; - (getRepoList as jest.Mock).mockResolvedValue([ + vi.mocked(getRepoList).mockResolvedValue([ { repositoryName: 'repo1', alias: 'Repo1', status: false, alert: 100, + id: 1, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 200 }, ]); - (getUsersList as jest.Mock).mockResolvedValue([ - { emailAlert: true, email: 'test@example.com', username: 'TestUser' }, + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + password: 'hashed-password', + roles: ['user'], + emailAlert: true, + email: 'test@example.com', + username: 'TestUser', + }, ]); const { req, res } = createMocks({ @@ -307,8 +397,13 @@ describe('Cronjob API Handler', () => { alias: 'Repo1', status: false, alert: 100, + id: 1, + lastSave: currentTime - 200, lastStatusAlertSend: expect.any(Number), - lastSave: expect.any(Number), + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); expect(res._getStatusCode()).toBe(200); @@ -316,16 +411,22 @@ describe('Cronjob API Handler', () => { it('should not update lastStatusAlertSend or send alerts if alert is disabled', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ + vi.mocked(getRepoList).mockResolvedValue([ { repositoryName: 'repo1', alias: 'Repo1', status: false, alert: 0, - lastStatusAlertSend: null, + lastStatusAlertSend: undefined, + id: 1, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 200 }, ]); @@ -342,8 +443,13 @@ describe('Cronjob API Handler', () => { alias: 'Repo1', status: false, alert: 0, - lastStatusAlertSend: null, + lastStatusAlertSend: undefined, + id: 1, lastSave: currentTime - 200, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); expect(nodemailerSMTP).not.toHaveBeenCalled(); @@ -352,20 +458,33 @@ describe('Cronjob API Handler', () => { it('should update lastStatusAlertSend only if the last alert was sent more than 90000 seconds ago', async () => { const currentTime = Math.floor(Date.now() / 1000); - (getRepoList as jest.Mock).mockResolvedValue([ + vi.mocked(getRepoList).mockResolvedValue([ { repositoryName: 'repo1', alias: 'Repo1', status: false, alert: 100, lastStatusAlertSend: currentTime - 80000, + id: 1, + lastSave: 0, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); - (getLastSaveListShell as jest.Mock).mockResolvedValue([ + vi.mocked(getLastSaveListShell).mockResolvedValue([ { repositoryName: 'repo1', lastSave: currentTime - 200 }, ]); - (getUsersList as jest.Mock).mockResolvedValue([ - { emailAlert: true, email: 'test@example.com', username: 'TestUser' }, + vi.mocked(getUsersList).mockResolvedValue([ + { + id: 1, + password: 'hashed-password', + roles: ['user'], + emailAlert: true, + email: 'test@example.com', + username: 'TestUser', + }, ]); const { req, res } = createMocks({ @@ -382,7 +501,12 @@ describe('Cronjob API Handler', () => { status: false, alert: 100, lastStatusAlertSend: expect.any(Number), + id: 1, lastSave: currentTime - 200, + storageSize: 0, + storageUsed: 0, + sshPublicKey: '', + comment: '', }, ]); expect(res._getStatusCode()).toBe(200); diff --git a/tests/supertest/getStorageUsed.test.ts b/pages/api/cronjob/getStorageUsed.test.ts similarity index 76% rename from tests/supertest/getStorageUsed.test.ts rename to pages/api/cronjob/getStorageUsed.test.ts index 8e55ddc..a8fa170 100644 --- a/tests/supertest/getStorageUsed.test.ts +++ b/pages/api/cronjob/getStorageUsed.test.ts @@ -1,23 +1,21 @@ import handler from '~/pages/api/cronjob/getStorageUsed'; import { createMocks } from 'node-mocks-http'; -import { getRepoList, updateRepoList } from '~/helpers/functions'; +import { getRepoList, updateRepoList } from '~/services'; import { getStorageUsedShell } from '~/helpers/functions/shell.utils'; -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - updateRepoList: jest.fn(), +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), + updateRepoList: vi.fn(), })); -jest.mock('~/helpers/functions/shell.utils', () => ({ - getStorageUsedShell: jest.fn(), +vi.mock('~/helpers/functions/shell.utils', () => ({ + getStorageUsedShell: vi.fn(), })); describe('GET /api/cronjob/getStorageUsed', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.resetAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); const CRONJOB_KEY = 'test-cronjob-key'; @@ -47,7 +45,7 @@ describe('GET /api/cronjob/getStorageUsed', () => { }); it('should return success if no repositories are found', async () => { - (getRepoList as jest.Mock).mockResolvedValue([]); + vi.mocked(getRepoList).mockResolvedValue([]); const { req, res } = createMocks({ method: 'POST', @@ -72,9 +70,9 @@ describe('GET /api/cronjob/getStorageUsed', () => { { name: 'repo2', size: 200 }, ]; - (getRepoList as jest.Mock).mockResolvedValue(mockRepoList); - (getStorageUsedShell as jest.Mock).mockResolvedValue(mockStorageUsed); - (updateRepoList as jest.Mock).mockResolvedValue(undefined); + vi.mocked(getRepoList).mockResolvedValue(mockRepoList); + vi.mocked(getStorageUsedShell).mockResolvedValue(mockStorageUsed); + vi.mocked(updateRepoList).mockResolvedValue(undefined); const { req, res } = createMocks({ method: 'POST', @@ -94,7 +92,7 @@ describe('GET /api/cronjob/getStorageUsed', () => { }); it('should return server error if an exception occurs', async () => { - (getRepoList as jest.Mock).mockRejectedValue(new Error('Test error')); + vi.mocked(getRepoList).mockRejectedValue(new Error('Test error')); const { req, res } = createMocks({ method: 'POST', @@ -115,9 +113,9 @@ describe('GET /api/cronjob/getStorageUsed', () => { ]; const mockStorageUsed = [{ name: 'repo1', size: 100 }]; - (getRepoList as jest.Mock).mockResolvedValue(mockRepoList); - (getStorageUsedShell as jest.Mock).mockResolvedValue(mockStorageUsed); - (updateRepoList as jest.Mock).mockResolvedValue(undefined); + vi.mocked(getRepoList).mockResolvedValue(mockRepoList); + vi.mocked(getStorageUsedShell).mockResolvedValue(mockStorageUsed); + vi.mocked(updateRepoList).mockResolvedValue(undefined); const { req, res } = createMocks({ method: 'POST', diff --git a/pages/api/cronjob/getStorageUsed.ts b/pages/api/cronjob/getStorageUsed.ts index b34f1cb..3ef8643 100644 --- a/pages/api/cronjob/getStorageUsed.ts +++ b/pages/api/cronjob/getStorageUsed.ts @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from 'next'; -import { getRepoList, updateRepoList } from '~/helpers/functions'; +import { getRepoList, updateRepoList } from '~/services'; import ApiResponse from '~/helpers/functions/apiResponse'; import { getStorageUsedShell } from '~/helpers/functions/shell.utils'; import { BorgWarehouseApiResponse } from '~/types/api/error.types'; diff --git a/tests/supertest/add.test.ts b/pages/api/repo/add.test.ts similarity index 66% rename from tests/supertest/add.test.ts rename to pages/api/repo/add.test.ts index 23b3918..8a923fb 100644 --- a/tests/supertest/add.test.ts +++ b/pages/api/repo/add.test.ts @@ -1,45 +1,34 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/repo/add'; import { getServerSession } from 'next-auth/next'; -import { - getRepoList, - updateRepoList, - tokenController, - isSshPubKeyDuplicate, -} from '~/helpers/functions'; +import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions'; +import { getRepoList, updateRepoList } from '~/services'; import { createRepoShell } from '~/helpers/functions/shell.utils'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), +vi.mock('next-auth/next', () => ({ + getServerSession: vi.fn(), })); -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - updateRepoList: jest.fn(), - tokenController: jest.fn(), - isSshPubKeyDuplicate: jest.fn(), +vi.mock('~/helpers/functions', () => ({ + tokenController: vi.fn(), + isSshPubKeyDuplicate: vi.fn(), })); -jest.mock('~/helpers/functions/shell.utils', () => ({ - createRepoShell: jest.fn(), +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), + updateRepoList: vi.fn(), +})); + +vi.mock('~/helpers/functions/shell.utils', () => ({ + createRepoShell: vi.fn(), })); describe('POST /api/repo/add', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.resetAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.resetAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if method is not POST', async () => { @@ -55,8 +44,8 @@ describe('POST /api/repo/add', () => { }); it('should return 401 if API key is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue(null); const { req, res } = createMocks({ method: 'POST', headers: { authorization: 'Bearer INVALID_API_KEY' }, @@ -66,8 +55,8 @@ describe('POST /api/repo/add', () => { }); it('should return 403 if API key does not have create permissions', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ create: false }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ create: false }); const { req, res } = createMocks({ method: 'POST', headers: { authorization: 'Bearer API_KEY' }, @@ -77,9 +66,9 @@ describe('POST /api/repo/add', () => { }); it('should return 409 if SSH key is duplicated', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 1, sshPublicKey: 'duplicate-key' }]); - (isSshPubKeyDuplicate as jest.Mock).mockReturnValue(true); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 1, sshPublicKey: 'duplicate-key' }]); + (isSshPubKeyDuplicate as vi.Mock).mockReturnValue(true); const { req, res } = createMocks({ method: 'POST', body: { alias: 'repo1', sshPublicKey: 'duplicate-key', storageSize: 10 }, @@ -89,9 +78,9 @@ describe('POST /api/repo/add', () => { }); it('should return 500 if createRepoShell fails', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([]); - (createRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([]); + (createRepoShell as vi.Mock).mockResolvedValue({ stderr: 'Error' }); const { req, res } = createMocks({ method: 'POST', body: { alias: 'repo1', sshPublicKey: 'valid-key', storageSize: 10 }, @@ -101,10 +90,10 @@ describe('POST /api/repo/add', () => { }); it('should successfully create a repository with a session', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([]); - (createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([]); + (createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'POST', body: { alias: 'repo1', sshPublicKey: 'valid-key', storageSize: 10 }, @@ -115,10 +104,10 @@ describe('POST /api/repo/add', () => { }); it('should add missing optional properties with default values and update repo list correctly', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([]); - (createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([]); + (createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'POST', @@ -153,16 +142,16 @@ describe('POST /api/repo/add', () => { }); it('should assign the correct ID based on existing repositories', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([ + vi.mocked(getRepoList).mockResolvedValue([ { id: 0, alias: 'repo0', sshPublicKey: 'key0', storageSize: 10 }, { id: 1, alias: 'repo1', sshPublicKey: 'key1', storageSize: 20 }, { id: 3, alias: 'repo3', sshPublicKey: 'key3', storageSize: 30 }, ]); - (createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + (createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'POST', diff --git a/pages/api/repo/add.ts b/pages/api/repo/add.ts index 400f788..7296a4a 100644 --- a/pages/api/repo/add.ts +++ b/pages/api/repo/add.ts @@ -1,16 +1,12 @@ import { authOptions } from '../auth/[...nextauth]'; import { getServerSession } from 'next-auth/next'; -import { - getRepoList, - updateRepoList, - tokenController, - isSshPubKeyDuplicate, -} from '~/helpers/functions'; +import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions'; import { NextApiRequest, NextApiResponse } from 'next'; import ApiResponse from '~/helpers/functions/apiResponse'; import { Repository } from '~/types/domain/config.types'; import { createRepoShell } from '~/helpers/functions/shell.utils'; import { getUnixTime } from 'date-fns'; +import { getRepoList, updateRepoList } from '~/services'; export default async function handler( req: NextApiRequest & { body: Partial }, diff --git a/tests/supertest/delete.test.ts b/pages/api/repo/id/[slug]/delete.test.ts similarity index 68% rename from tests/supertest/delete.test.ts rename to pages/api/repo/id/[slug]/delete.test.ts index cc74baf..2832dff 100644 --- a/tests/supertest/delete.test.ts +++ b/pages/api/repo/id/[slug]/delete.test.ts @@ -2,39 +2,33 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/repo/id/[slug]/delete'; import { getServerSession } from 'next-auth/next'; import { deleteRepoShell } from '~/helpers/functions/shell.utils'; -import { getRepoList, tokenController, updateRepoList } from '~/helpers/functions'; +import { getRepoList, updateRepoList } from '~/services'; +import { tokenController } from '~/helpers/functions'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), +vi.mock('next-auth/next', () => ({ + getServerSession: vi.fn(), })); -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - updateRepoList: jest.fn(), - tokenController: jest.fn(), +vi.mock('~/helpers/functions', () => ({ + tokenController: vi.fn(), })); -jest.mock('~/helpers/functions/shell.utils', () => { +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), + updateRepoList: vi.fn(), +})); + +vi.mock('~/helpers/functions/shell.utils', () => { return { - deleteRepoShell: jest.fn(), + deleteRepoShell: vi.fn(), }; }); describe('DELETE /api/repo/id/[slug]/delete', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if method is not DELETE', async () => { @@ -51,7 +45,7 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { it('should return 403 if deletion is disabled via environment variable', async () => { process.env.DISABLE_DELETE_REPO = 'true'; - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' }, }); const { req, res } = createMocks({ method: 'DELETE' }); @@ -65,7 +59,7 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should return 400 if slug is missing or malformed', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' }, }); const { req, res } = createMocks({ @@ -81,14 +75,14 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should return 404 if repository is not found', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' }, }); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '123' }, }); - (getRepoList as jest.Mock).mockResolvedValue([]); + vi.mocked(getRepoList).mockResolvedValue([]); await handler(req, res); expect(res._getStatusCode()).toBe(404); expect(res._getJSONData()).toEqual({ @@ -98,15 +92,15 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should return 500 if deleteRepo fails', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' }, }); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '123' }, }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); - (deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); + vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: 'Error' }); await handler(req, res); expect(res._getStatusCode()).toBe(500); expect(res._getJSONData()).toEqual({ @@ -117,16 +111,16 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should delete the repository and return 200 on success with a session', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' }, }); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '1234' }, }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 1234, repositoryName: 'test-repo' }]); - (deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: null }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getRepoList).mockResolvedValue([{ id: 1234, repositoryName: 'test-repo' }]); + vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: null }); + vi.mocked(updateRepoList).mockResolvedValue(true); await handler(req, res); expect(res._getStatusCode()).toBe(200); expect(res._getJSONData()).toEqual({ @@ -137,8 +131,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should delete the repository and return 200 on success with an API key', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ delete: true }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ delete: true }); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '12345' }, @@ -146,9 +140,9 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { authorization: 'Bearer API_KEY', }, }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 12345, repositoryName: 'test-repo2' }]); - (deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: null }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getRepoList).mockResolvedValue([{ id: 12345, repositoryName: 'test-repo2' }]); + vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: null }); + vi.mocked(updateRepoList).mockResolvedValue(true); await handler(req, res); expect(res._getStatusCode()).toBe(200); expect(res._getJSONData()).toEqual({ @@ -159,8 +153,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should return 401 if the API key is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue(null); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '12345' }, @@ -177,8 +171,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => { }); it('should return 403 if the API key does not have delete permissions', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ delete: false }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ delete: false }); const { req, res } = createMocks({ method: 'DELETE', query: { slug: '12345' }, diff --git a/pages/api/repo/id/[slug]/delete.ts b/pages/api/repo/id/[slug]/delete.ts index e433f20..1d159d8 100644 --- a/pages/api/repo/id/[slug]/delete.ts +++ b/pages/api/repo/id/[slug]/delete.ts @@ -1,7 +1,8 @@ import { NextApiRequest, NextApiResponse } from 'next'; import { getServerSession } from 'next-auth/next'; -import { getRepoList, updateRepoList, tokenController } from '~/helpers/functions'; +import { tokenController } from '~/helpers/functions'; import { deleteRepoShell } from '~/helpers/functions/shell.utils'; +import { getRepoList, updateRepoList } from '~/services'; import ApiResponse from '~/helpers/functions/apiResponse'; import { BorgWarehouseApiResponse } from '~/types/api/error.types'; diff --git a/tests/supertest/edit.test.ts b/pages/api/repo/id/[slug]/edit.test.ts similarity index 62% rename from tests/supertest/edit.test.ts rename to pages/api/repo/id/[slug]/edit.test.ts index 10c70a6..0dec82d 100644 --- a/tests/supertest/edit.test.ts +++ b/pages/api/repo/id/[slug]/edit.test.ts @@ -2,44 +2,34 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/repo/id/[slug]/edit'; import { getServerSession } from 'next-auth/next'; import { updateRepoShell } from '~/helpers/functions/shell.utils'; -import { - getRepoList, - updateRepoList, - tokenController, - isSshPubKeyDuplicate, -} from '~/helpers/functions'; +import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions'; +import { getRepoList, updateRepoList } from '~/services'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), +vi.mock('next-auth/next', () => ({ + __esModule: true, + getServerSession: vi.fn(), })); -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - updateRepoList: jest.fn(), - tokenController: jest.fn(), - isSshPubKeyDuplicate: jest.fn(), +vi.mock('~/helpers/functions', () => ({ + tokenController: vi.fn(), + isSshPubKeyDuplicate: vi.fn(), })); -jest.mock('~/helpers/functions/shell.utils', () => ({ - updateRepoShell: jest.fn(), +vi.mock('~/helpers/functions/shell.utils', () => ({ + updateRepoShell: vi.fn(), +})); + +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), + updateRepoList: vi.fn(), })); describe('PATCH /api/repo/id/[slug]/edit', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.resetAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.resetAllMocks(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if method is not PATCH', async () => { @@ -55,8 +45,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should return 401 if API key is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue(null); const { req, res } = createMocks({ method: 'PATCH', headers: { authorization: 'Bearer INVALID_API_KEY' }, @@ -66,8 +56,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should return 403 if API key does not have update permissions', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ update: false }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ update: false }); const { req, res } = createMocks({ method: 'PATCH', headers: { authorization: 'Bearer API_KEY' }, @@ -77,24 +67,24 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should return 400 if slug is missing or malformed', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); const { req, res } = createMocks({ method: 'PATCH', query: { slug: undefined } }); await handler(req, res); expect(res._getStatusCode()).toBe(400); }); it('should return 404 if repository is not found', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([]); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([]); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' } }); await handler(req, res); expect(res._getStatusCode()).toBe(404); }); it('should return 409 if SSH key is duplicated', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); - (isSshPubKeyDuplicate as jest.Mock).mockReturnValue(true); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); + (isSshPubKeyDuplicate as vi.Mock).mockReturnValue(true); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' }, @@ -105,9 +95,9 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should return 500 if updateRepoShell fails', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); - (updateRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); + (updateRepoShell as vi.Mock).mockResolvedValue({ stderr: 'Error' }); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' }, @@ -118,10 +108,10 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should successfully update repository with a session', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); - (updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]); + (updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' }, @@ -133,11 +123,11 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should successfully update repository with API key', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ update: true }); - (getRepoList as jest.Mock).mockResolvedValue([{ id: 456, repositoryName: 'repo-key' }]); - (updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ update: true }); + vi.mocked(getRepoList).mockResolvedValue([{ id: 456, repositoryName: 'repo-key' }]); + (updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '456' }, @@ -150,8 +140,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { }); it('should only update the provided fields, keep the rest unchanged and history the modification.', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([ + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([ { id: 123, repositoryName: 'test-repo', @@ -161,8 +151,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => { lanCommand: false, }, ]); - (updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null }); - (updateRepoList as jest.Mock).mockResolvedValue(true); + (updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null }); + vi.mocked(updateRepoList).mockResolvedValue(true); const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' }, diff --git a/pages/api/repo/id/[slug]/edit.ts b/pages/api/repo/id/[slug]/edit.ts index b503973..45e161d 100644 --- a/pages/api/repo/id/[slug]/edit.ts +++ b/pages/api/repo/id/[slug]/edit.ts @@ -1,15 +1,11 @@ import { authOptions } from '../../../auth/[...nextauth]'; import { getServerSession } from 'next-auth/next'; -import { - getRepoList, - updateRepoList, - tokenController, - isSshPubKeyDuplicate, -} from '~/helpers/functions'; +import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions'; import { NextApiRequest, NextApiResponse } from 'next'; import ApiResponse from '~/helpers/functions/apiResponse'; import { Repository } from '~/types/domain/config.types'; import { updateRepoShell } from '~/helpers/functions/shell.utils'; +import { getRepoList, updateRepoList } from '~/services'; export default async function handler( req: NextApiRequest & { body: Partial }, diff --git a/pages/api/repo/id/[slug]/index.ts b/pages/api/repo/id/[slug]/index.ts index 2482eb2..897639b 100644 --- a/pages/api/repo/id/[slug]/index.ts +++ b/pages/api/repo/id/[slug]/index.ts @@ -3,8 +3,9 @@ import { getServerSession } from 'next-auth/next'; import { NextApiRequest, NextApiResponse } from 'next'; import { BorgWarehouseApiResponse } from '~/types/api/error.types'; import ApiResponse from '~/helpers/functions/apiResponse'; -import { getRepoList, tokenController } from '~/helpers/functions'; +import { tokenController } from '~/helpers/functions'; import { Repository } from '~/types/domain/config.types'; +import { getRepoList } from '~/services'; export default async function handler( req: NextApiRequest, diff --git a/tests/supertest/repoIndex.test.ts b/pages/api/repo/id/[slug]/repoIndex.test.ts similarity index 71% rename from tests/supertest/repoIndex.test.ts rename to pages/api/repo/id/[slug]/repoIndex.test.ts index 4b0fa9e..cd5b420 100644 --- a/tests/supertest/repoIndex.test.ts +++ b/pages/api/repo/id/[slug]/repoIndex.test.ts @@ -1,26 +1,20 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/repo/id/[slug]'; import { getServerSession } from 'next-auth/next'; -import { getRepoList, tokenController } from '~/helpers/functions'; +import { tokenController } from '~/helpers/functions'; +import { getRepoList } from '~/services'; import { Repository } from '~/types/domain/config.types'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), +vi.mock('next-auth/next', () => ({ + getServerSession: vi.fn(), })); -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - tokenController: jest.fn(), +vi.mock('~/helpers/functions', () => ({ + tokenController: vi.fn(), +})); + +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), })); const mockRepoList: Repository[] = [ @@ -58,9 +52,9 @@ const mockRepoList: Repository[] = [ describe('GET /api/repo/id/[slug]', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if method is not GET', async () => { @@ -76,8 +70,8 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 401 if API key is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET', headers: { authorization: 'Bearer INVALID_API_KEY' }, @@ -87,8 +81,8 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 403 if API key does not have read permissions', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ read: false }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ read: false }); const { req, res } = createMocks({ method: 'GET', headers: { authorization: 'Bearer API_KEY' }, @@ -98,23 +92,23 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 400 if slug is missing or malformed', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); const { req, res } = createMocks({ method: 'GET', query: { slug: undefined } }); await handler(req, res); expect(res._getStatusCode()).toBe(400); }); it('should return 404 if repository is not found', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue([]); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue([]); const { req, res } = createMocks({ method: 'GET', query: { slug: '3' } }); await handler(req, res); expect(res._getStatusCode()).toBe(404); }); it('should return 200 and the repository data if found', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue(mockRepoList); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue(mockRepoList); const { req, res } = createMocks({ method: 'GET', query: { slug: '1' } }); await handler(req, res); expect(res._getStatusCode()).toBe(200); diff --git a/pages/api/repo/index.ts b/pages/api/repo/index.ts index ee53a4d..c8a1b64 100644 --- a/pages/api/repo/index.ts +++ b/pages/api/repo/index.ts @@ -3,7 +3,8 @@ import { getServerSession } from 'next-auth/next'; import { NextApiRequest, NextApiResponse } from 'next'; import { BorgWarehouseApiResponse } from '~/types/api/error.types'; import ApiResponse from '~/helpers/functions/apiResponse'; -import { getRepoList, tokenController } from '~/helpers/functions'; +import { tokenController } from '~/helpers/functions'; +import { getRepoList } from '~/services'; import { Repository } from '~/types/domain/config.types'; export default async function handler( diff --git a/tests/supertest/repoListIndex.test.ts b/pages/api/repo/repoListIndex.test.ts similarity index 71% rename from tests/supertest/repoListIndex.test.ts rename to pages/api/repo/repoListIndex.test.ts index 0c01a73..24f1a0f 100644 --- a/tests/supertest/repoListIndex.test.ts +++ b/pages/api/repo/repoListIndex.test.ts @@ -1,26 +1,20 @@ import { createMocks } from 'node-mocks-http'; import handler from '~/pages/api/repo'; import { getServerSession } from 'next-auth/next'; -import { getRepoList, tokenController } from '~/helpers/functions'; +import { tokenController } from '~/helpers/functions'; +import { getRepoList } from '~/services'; import { Repository } from '~/types/domain/config.types'; -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), +vi.mock('next-auth/next', () => ({ + getServerSession: vi.fn(), })); -jest.mock('~/helpers/functions', () => ({ - getRepoList: jest.fn(), - tokenController: jest.fn(), +vi.mock('~/helpers/functions', () => ({ + tokenController: vi.fn(), +})); + +vi.mock('~/services', () => ({ + getRepoList: vi.fn(), })); const mockRepoList: Repository[] = [ @@ -58,9 +52,9 @@ const mockRepoList: Repository[] = [ describe('GET /api/repo/id/[slug]', () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.clearAllMocks(); + vi.resetModules(); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); it('should return 405 if method is not GET', async () => { @@ -76,8 +70,8 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 401 if API key is invalid', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue(null); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue(null); const { req, res } = createMocks({ method: 'GET', headers: { authorization: 'Bearer INVALID_API_KEY' }, @@ -87,8 +81,8 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 403 if API key does not have read permissions', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - (tokenController as jest.Mock).mockResolvedValue({ read: false }); + vi.mocked(getServerSession).mockResolvedValue(null); + vi.mocked(tokenController).mockResolvedValue({ read: false }); const { req, res } = createMocks({ method: 'GET', headers: { authorization: 'Bearer API_KEY' }, @@ -98,8 +92,8 @@ describe('GET /api/repo/id/[slug]', () => { }); it('should return 200 and the repoList data if found', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } }); - (getRepoList as jest.Mock).mockResolvedValue(mockRepoList); + vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } }); + vi.mocked(getRepoList).mockResolvedValue(mockRepoList); const { req, res } = createMocks({ method: 'GET' }); await handler(req, res); expect(res._getStatusCode()).toBe(200); diff --git a/tests/README b/tests/README index d473cfd..e9a892c 100644 --- a/tests/README +++ b/tests/README @@ -1,7 +1,3 @@ ## BATS tests against bash scripts From `tests/bats`, launch `docker compose up --build` - -## supertest (Jest) is used to test API endpoints - -Launch `npm test` diff --git a/tests/supertest/tokenManager.test.ts b/tests/supertest/tokenManager.test.ts deleted file mode 100644 index e62ef8e..0000000 --- a/tests/supertest/tokenManager.test.ts +++ /dev/null @@ -1,164 +0,0 @@ -import handler from '~/pages/api/account/tokenManager'; -import { createMocks } from 'node-mocks-http'; -import { getServerSession } from 'next-auth/next'; -import { getUsersList, updateUsersList } from '~/helpers/functions'; -import ApiResponse from '~/helpers/functions/apiResponse'; - -jest.mock('next-auth', () => { - return jest.fn(() => { - return { - auth: { session: {} }, - GET: jest.fn(), - POST: jest.fn(), - }; - }); -}); - -jest.mock('next-auth/next', () => ({ - getServerSession: jest.fn(), -})); - -jest.mock('~/helpers/functions', () => ({ - getUsersList: jest.fn(), - updateUsersList: jest.fn(), -})); - -jest.mock('~/helpers/functions/apiResponse', () => ({ - unauthorized: jest.fn(), - badRequest: jest.fn(), - serverError: jest.fn(), - methodNotAllowed: jest.fn(), - success: jest.fn(), -})); - -describe('Token Manager API', () => { - afterEach(() => { - jest.clearAllMocks(); - jest.spyOn(console, 'log').mockImplementation(() => {}); - }); - - it('should return unauthorized if session is not found', async () => { - (getServerSession as jest.Mock).mockResolvedValue(null); - - const { req, res } = createMocks({ - method: 'POST', - body: { - name: 'testToken', - permissions: { create: true, read: true, update: true, delete: true }, - }, - }); - - await handler(req, res); - - expect(ApiResponse.unauthorized).toHaveBeenCalledWith(res); - }); - - it('should create a new token if valid data is provided', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } }); - (getUsersList as jest.Mock).mockResolvedValue([{ username: 'testUser', tokens: [] }]); - (updateUsersList as jest.Mock).mockResolvedValue(true); - - const { req, res } = createMocks({ - method: 'POST', - body: { - name: 'testToken', - permissions: { create: true, read: true, update: true, delete: true }, - }, - }); - - await handler(req, res); - - expect(res._getStatusCode()).toBe(200); - const responseData = JSON.parse(res._getData()); - expect(responseData).toHaveProperty('token'); - expect(updateUsersList).toHaveBeenCalled(); - }); - - it('should return bad request if token name already exists', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } }); - (getUsersList as jest.Mock).mockResolvedValue([ - { username: 'testUser', tokens: [{ name: 'testToken', permissions: {}, creation: 123 }] }, - ]); - - const { req, res } = createMocks({ - method: 'POST', - body: { - name: 'testToken', - permissions: { create: true, read: true, update: true, delete: true }, - }, - }); - - await handler(req, res); - - expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Token name already exists'); - }); - - it('should return token list for GET request', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } }); - (getUsersList as jest.Mock).mockResolvedValue([ - { - username: 'testUser', - tokens: [ - { name: 'token1', permissions: {}, creation: 123 }, - { name: 'token2', permissions: {}, creation: 456 }, - ], - }, - ]); - - const { req, res } = createMocks({ method: 'GET' }); - - await handler(req, res); - - expect(res._getStatusCode()).toBe(200); - const responseData = JSON.parse(res._getData()); - expect(responseData).toEqual([ - { name: 'token1', permissions: {}, creation: 123 }, - { name: 'token2', permissions: {}, creation: 456 }, - ]); - }); - - it('should delete a token for DELETE request', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } }); - (getUsersList as jest.Mock).mockResolvedValue([ - { - username: 'testUser', - tokens: [ - { name: 'token1', permissions: {}, creation: 123 }, - { name: 'token2', permissions: {}, creation: 456 }, - ], - }, - ]); - (updateUsersList as jest.Mock).mockResolvedValue(true); - - const { req, res } = createMocks({ - method: 'DELETE', - body: { name: 'token1' }, - }); - - await handler(req, res); - - expect(ApiResponse.success).toHaveBeenCalledWith(res, 'Token deleted'); - expect(updateUsersList).toHaveBeenCalled(); - }); - - it('should return bad request if token name is missing in DELETE request', async () => { - (getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } }); - - const { req, res } = createMocks({ - method: 'DELETE', - body: {}, - }); - - await handler(req, res); - - expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Missing token name'); - }); - - it('should return method not allowed for unsupported HTTP methods', async () => { - const { req, res } = createMocks({ method: 'PUT' }); - - await handler(req, res); - - expect(ApiResponse.methodNotAllowed).toHaveBeenCalledWith(res); - }); -}); diff --git a/tsconfig.json b/tsconfig.json index ed1c64d..a79b3fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,8 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "types": ["vitest/globals"] // Auto import vitest types }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..8662105 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,19 @@ +// vitest.config.ts +import { defineConfig } from 'vitest/config'; +import path from 'path'; + +export default defineConfig({ + test: { + environment: 'node', + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + }, + globals: true, + }, + resolve: { + alias: { + '~': path.resolve(__dirname, './'), + }, + }, +});