From 173d295d4ae9ca1d88dbe147a1e29df1271bec26 Mon Sep 17 00:00:00 2001 From: Lyudmil Mitev Date: Fri, 11 Oct 2024 00:52:06 +0200 Subject: [PATCH] add: Basic test coverage with Vitest --- package-lock.json | 2085 +++++++++++++++++++++++++- package.json | 9 +- src/components/LoadingSpinner.tsx | 1 + src/mocks/characterDetail.mock.tsx | 72 + src/mocks/characters.mock.tsx | 667 ++++++++ src/mocks/episodeDetail.mock.tsx | 29 + src/mocks/episodes.mock.tsx | 715 +++++++++ src/mocks/locationDetail.mock.tsx | 37 + src/mocks/locations.mock.tsx | 692 +++++++++ src/routes/CharacterDetails.test.tsx | 42 + src/routes/EpisodeDetails.test.tsx | 42 + src/routes/EpisodeDetails.tsx | 3 +- src/routes/Episodes.test.tsx | 45 + src/routes/ErrorPage.test.tsx | 46 + src/routes/LocationDetails.test.tsx | 42 + src/routes/LocationDetails.tsx | 1 + src/routes/Locations.test.tsx | 48 + src/routes/Root.test.tsx | 48 + vitest.config.ts | 21 + 19 files changed, 4566 insertions(+), 79 deletions(-) create mode 100644 src/mocks/characterDetail.mock.tsx create mode 100644 src/mocks/characters.mock.tsx create mode 100644 src/mocks/episodeDetail.mock.tsx create mode 100644 src/mocks/episodes.mock.tsx create mode 100644 src/mocks/locationDetail.mock.tsx create mode 100644 src/mocks/locations.mock.tsx create mode 100644 src/routes/CharacterDetails.test.tsx create mode 100644 src/routes/EpisodeDetails.test.tsx create mode 100644 src/routes/Episodes.test.tsx create mode 100644 src/routes/ErrorPage.test.tsx create mode 100644 src/routes/LocationDetails.test.tsx create mode 100644 src/routes/Locations.test.tsx create mode 100644 src/routes/Root.test.tsx create mode 100644 vitest.config.ts diff --git a/package-lock.json b/package-lock.json index 813aeba..03dbb95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,20 +16,24 @@ "devDependencies": { "@eslint/js": "^9.11.1", "@tailwindcss/forms": "^0.5.9", + "@testing-library/react": "^16.0.1", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.2", + "@vitest/coverage-v8": "^2.1.2", "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", + "jsdom": "^25.0.1", "postcss": "^8.4.47", "tailwindcss": "^3.4.13", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", "vite": "^5.4.8", - "vitest": "^2.1.2" + "vitest": "^2.1.2", + "vitest-browser-react": "^0.0.1" } }, "node_modules/@alloc/quick-lru": { @@ -312,6 +316,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", @@ -371,6 +388,47 @@ "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/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -948,6 +1006,189 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@inquirer/confirm": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.2.0.tgz", + "integrity": "sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", + "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^22.5.5", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/@inquirer/type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", + "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@inquirer/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@inquirer/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz", + "integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -966,6 +1207,16 @@ "node": ">=12" } }, + "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/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -1019,6 +1270,25 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mswjs/interceptors": { + "version": "0.35.9", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.9.tgz", + "integrity": "sha512-SSnyl/4ni/2ViHKkiZb8eajA/eN1DNFaHjhGiLUdZvDz6PKF4COSf/17xqSz64nOo2Ia29SA6B2KNCsyCbVmaQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1057,6 +1327,34 @@ "node": ">= 8" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1068,6 +1366,14 @@ "node": ">=14" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@remix-run/router": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", @@ -1314,65 +1620,249 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" } }, - "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==", + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" } }, - "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==", + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@babel/types": "^7.0.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "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==", + "node_modules/@testing-library/dom/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", + "peer": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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==", + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@babel/types": "^7.20.7" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "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==", + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.1.tgz", + "integrity": "sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, "node_modules/@types/prop-types": { "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", @@ -1401,6 +1891,30 @@ "@types/react": "*" } }, + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz", @@ -1663,6 +2177,77 @@ "vite": "^4.2.0 || ^5.0.0" } }, + "node_modules/@vitest/browser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-2.1.2.tgz", + "integrity": "sha512-tqpGfz2sfjFFNuZ2iLZ6EGRVnH8z18O93ZIicbLsxDhiLgRNz84UcjSvX4pbheuddW+BJeNbLGdM3BU8vohbEg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.5.2", + "@vitest/mocker": "2.1.2", + "@vitest/utils": "2.1.2", + "magic-string": "^0.30.11", + "msw": "^2.3.5", + "sirv": "^2.0.4", + "tinyrainbow": "^1.2.0", + "ws": "^8.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "2.1.2", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.2.tgz", + "integrity": "sha512-b7kHrFrs2urS0cOk5N10lttI8UdJ/yP3nB4JYTREvR5o18cR99yPpK4gK8oQgI42BVv0ILWYUSYB7AXkAUDc0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.6", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.11", + "magicast": "^0.3.4", + "std-env": "^3.7.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.2", + "vitest": "2.1.2" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, "node_modules/@vitest/expect": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz", @@ -1800,6 +2385,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1817,6 +2415,37 @@ "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", + "peer": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/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)", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -1878,6 +2507,17 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1888,6 +2528,13 @@ "node": ">=12" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -2086,52 +2733,186 @@ "node": ">=4" } }, - "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==", + "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, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">= 16" + "node": ">=8" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">=8" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "ISC", + "license": "MIT", + "peer": true, "dependencies": { - "is-glob": "^4.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/color-convert": { @@ -2151,6 +2932,19 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -2175,6 +2969,17 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2203,6 +3008,19 @@ "node": ">=4" } }, + "node_modules/cssstyle": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.7.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -2210,6 +3028,20 @@ "dev": true, "license": "MIT" }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -2228,6 +3060,13 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true, + "license": "MIT" + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -2245,6 +3084,27 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -2259,6 +3119,14 @@ "dev": true, "license": "MIT" }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2280,6 +3148,19 @@ "dev": true, "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -2758,6 +3639,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -2807,6 +3703,17 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -2887,6 +3794,17 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2910,6 +3828,75 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "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/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3009,6 +3996,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3019,6 +4014,13 @@ "node": ">=0.12.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3026,6 +4028,83 @@ "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-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-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -3058,17 +4137,71 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "argparse": "^2.0.1" + "tldts": "^6.1.32" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=16" } }, "node_modules/jsesc": { @@ -3211,6 +4344,17 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.30.11", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", @@ -3221,6 +4365,47 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3245,6 +4430,29 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mini-svg-data-uri": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", @@ -3278,6 +4486,17 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3285,6 +4504,144 @@ "dev": true, "license": "MIT" }, + "node_modules/msw": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.9.tgz", + "integrity": "sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^3.0.0", + "@mswjs/interceptors": "^0.35.8", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.3.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/msw/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", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/msw/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/msw/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/msw/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -3350,6 +4707,13 @@ "node": ">=0.10.0" } }, + "node_modules/nwsapi": { + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz", + "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3388,6 +4752,14 @@ "node": ">= 0.8.0" } }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3440,6 +4812,19 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3491,6 +4876,14 @@ "dev": true, "license": "ISC" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -3721,6 +5114,55 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3731,6 +5173,14 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3777,6 +5227,14 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -3842,6 +5300,32 @@ "node": ">=8.10.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3926,6 +5410,13 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3950,6 +5441,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -4008,8 +5519,24 @@ "engines": { "node": ">=14" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" } }, "node_modules/source-map-js": { @@ -4029,6 +5556,17 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", @@ -4036,6 +5574,14 @@ "dev": true, "license": "MIT" }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -4202,6 +5748,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/tailwindcss": { "version": "3.4.13", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", @@ -4240,6 +5793,47 @@ "node": ">=14.0.0" } }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/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/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4314,6 +5908,26 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "6.1.50", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.50.tgz", + "integrity": "sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.50" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.50", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.50.tgz", + "integrity": "sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw==", + "dev": true, + "license": "MIT" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -4337,6 +5951,47 @@ "node": ">=8.0" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -4370,6 +6025,20 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "peer": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", @@ -4408,6 +6077,25 @@ } } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -4449,6 +6137,18 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4603,6 +6303,95 @@ } } }, + "node_modules/vitest-browser-react": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/vitest-browser-react/-/vitest-browser-react-0.0.1.tgz", + "integrity": "sha512-075hxhouuuMeCqHRyX4POzZWEDD3aPxFxDcwENN+T2ZlJ4lh5vUlgbkV4C4A0KZWinHb/Wsj3pYEJlDgIO23CQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@types/react": ">18.0.0", + "@types/react-dom": ">18.0.0", + "@vitest/browser": "^2.1.0-beta.4", + "react": ">18.0.0", + "react-dom": ">18.0.0", + "vitest": "^2.1.0-beta.4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4777,6 +6566,56 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -4797,6 +6636,86 @@ "node": ">= 14" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4809,6 +6728,20 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 30b5eed..b2b3e17 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "tsc -b && vite build && cp -v dist/index.html dist/404.html", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "test": "vitest" }, "dependencies": { "react": "^18.3.1", @@ -18,19 +19,23 @@ "devDependencies": { "@eslint/js": "^9.11.1", "@tailwindcss/forms": "^0.5.9", + "@testing-library/react": "^16.0.1", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.2", + "@vitest/coverage-v8": "^2.1.2", "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", + "jsdom": "^25.0.1", "postcss": "^8.4.47", "tailwindcss": "^3.4.13", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", "vite": "^5.4.8", - "vitest": "^2.1.2" + "vitest": "^2.1.2", + "vitest-browser-react": "^0.0.1" } } diff --git a/src/components/LoadingSpinner.tsx b/src/components/LoadingSpinner.tsx index 19bf8d8..c5d2f79 100644 --- a/src/components/LoadingSpinner.tsx +++ b/src/components/LoadingSpinner.tsx @@ -2,6 +2,7 @@ export default function LoadingSpinner() { return (
+ Loading...
); } \ No newline at end of file diff --git a/src/mocks/characterDetail.mock.tsx b/src/mocks/characterDetail.mock.tsx new file mode 100644 index 0000000..106652c --- /dev/null +++ b/src/mocks/characterDetail.mock.tsx @@ -0,0 +1,72 @@ +export default { + "id": 1, + "name": "Rick Sanchez", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (C-137)", + "url": "https://rickandmortyapi.com/api/location/1" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/1", + "https://rickandmortyapi.com/api/episode/2", + "https://rickandmortyapi.com/api/episode/3", + "https://rickandmortyapi.com/api/episode/4", + "https://rickandmortyapi.com/api/episode/5", + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/13", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/17", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/24", + "https://rickandmortyapi.com/api/episode/25", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/27", + "https://rickandmortyapi.com/api/episode/28", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/34", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/37", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/50", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/1", + "created": "2017-11-04T18:48:46.250Z" +} \ No newline at end of file diff --git a/src/mocks/characters.mock.tsx b/src/mocks/characters.mock.tsx new file mode 100644 index 0000000..fc64e07 --- /dev/null +++ b/src/mocks/characters.mock.tsx @@ -0,0 +1,667 @@ +export default { + "pages": 42, + "characters": [ + { + "id": 1, + "name": "Rick Sanchez", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (C-137)", + "url": "https://rickandmortyapi.com/api/location/1" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/1", + "https://rickandmortyapi.com/api/episode/2", + "https://rickandmortyapi.com/api/episode/3", + "https://rickandmortyapi.com/api/episode/4", + "https://rickandmortyapi.com/api/episode/5", + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/13", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/17", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/24", + "https://rickandmortyapi.com/api/episode/25", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/27", + "https://rickandmortyapi.com/api/episode/28", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/34", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/37", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/50", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/1", + "created": "2017-11-04T18:48:46.250Z" + }, + { + "id": 2, + "name": "Morty Smith", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/1", + "https://rickandmortyapi.com/api/episode/2", + "https://rickandmortyapi.com/api/episode/3", + "https://rickandmortyapi.com/api/episode/4", + "https://rickandmortyapi.com/api/episode/5", + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/13", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/17", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/24", + "https://rickandmortyapi.com/api/episode/25", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/27", + "https://rickandmortyapi.com/api/episode/28", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/34", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/37", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/50", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/2", + "created": "2017-11-04T18:50:21.651Z" + }, + { + "id": 3, + "name": "Summer Smith", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Female", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/3.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/17", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/24", + "https://rickandmortyapi.com/api/episode/25", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/27", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/34", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/3", + "created": "2017-11-04T19:09:56.428Z" + }, + { + "id": 4, + "name": "Beth Smith", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Female", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/4.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/24", + "https://rickandmortyapi.com/api/episode/25", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/27", + "https://rickandmortyapi.com/api/episode/28", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/34", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/4", + "created": "2017-11-04T19:22:43.665Z" + }, + { + "id": 5, + "name": "Jerry Smith", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/5.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/6", + "https://rickandmortyapi.com/api/episode/7", + "https://rickandmortyapi.com/api/episode/8", + "https://rickandmortyapi.com/api/episode/9", + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11", + "https://rickandmortyapi.com/api/episode/12", + "https://rickandmortyapi.com/api/episode/13", + "https://rickandmortyapi.com/api/episode/14", + "https://rickandmortyapi.com/api/episode/15", + "https://rickandmortyapi.com/api/episode/16", + "https://rickandmortyapi.com/api/episode/18", + "https://rickandmortyapi.com/api/episode/19", + "https://rickandmortyapi.com/api/episode/20", + "https://rickandmortyapi.com/api/episode/21", + "https://rickandmortyapi.com/api/episode/22", + "https://rickandmortyapi.com/api/episode/23", + "https://rickandmortyapi.com/api/episode/26", + "https://rickandmortyapi.com/api/episode/29", + "https://rickandmortyapi.com/api/episode/30", + "https://rickandmortyapi.com/api/episode/31", + "https://rickandmortyapi.com/api/episode/32", + "https://rickandmortyapi.com/api/episode/33", + "https://rickandmortyapi.com/api/episode/35", + "https://rickandmortyapi.com/api/episode/36", + "https://rickandmortyapi.com/api/episode/38", + "https://rickandmortyapi.com/api/episode/39", + "https://rickandmortyapi.com/api/episode/40", + "https://rickandmortyapi.com/api/episode/41", + "https://rickandmortyapi.com/api/episode/42", + "https://rickandmortyapi.com/api/episode/43", + "https://rickandmortyapi.com/api/episode/44", + "https://rickandmortyapi.com/api/episode/45", + "https://rickandmortyapi.com/api/episode/46", + "https://rickandmortyapi.com/api/episode/47", + "https://rickandmortyapi.com/api/episode/48", + "https://rickandmortyapi.com/api/episode/49", + "https://rickandmortyapi.com/api/episode/50", + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/5", + "created": "2017-11-04T19:26:56.301Z" + }, + { + "id": 6, + "name": "Abadango Cluster Princess", + "status": "Alive", + "species": "Alien", + "type": "", + "gender": "Female", + "origin": { + "name": "Abadango", + "url": "https://rickandmortyapi.com/api/location/2" + }, + "location": { + "name": "Abadango", + "url": "https://rickandmortyapi.com/api/location/2" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/6.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/27" + ], + "url": "https://rickandmortyapi.com/api/character/6", + "created": "2017-11-04T19:50:28.250Z" + }, + { + "id": 7, + "name": "Abradolf Lincler", + "status": "unknown", + "species": "Human", + "type": "Genetic experiment", + "gender": "Male", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Testicle Monster Dimension", + "url": "https://rickandmortyapi.com/api/location/21" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/7.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/11" + ], + "url": "https://rickandmortyapi.com/api/character/7", + "created": "2017-11-04T19:59:20.523Z" + }, + { + "id": 8, + "name": "Adjudicator Rick", + "status": "Dead", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/8.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/28" + ], + "url": "https://rickandmortyapi.com/api/character/8", + "created": "2017-11-04T20:03:34.737Z" + }, + { + "id": 9, + "name": "Agency Director", + "status": "Dead", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/9.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/24" + ], + "url": "https://rickandmortyapi.com/api/character/9", + "created": "2017-11-04T20:06:54.976Z" + }, + { + "id": 10, + "name": "Alan Rails", + "status": "Dead", + "species": "Human", + "type": "Superhuman (Ghost trains summoner)", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Worldender's lair", + "url": "https://rickandmortyapi.com/api/location/4" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/10.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/25" + ], + "url": "https://rickandmortyapi.com/api/character/10", + "created": "2017-11-04T20:19:09.017Z" + }, + { + "id": 11, + "name": "Albert Einstein", + "status": "Dead", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (C-137)", + "url": "https://rickandmortyapi.com/api/location/1" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/11.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/12" + ], + "url": "https://rickandmortyapi.com/api/character/11", + "created": "2017-11-04T20:20:20.965Z" + }, + { + "id": 12, + "name": "Alexander", + "status": "Dead", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (C-137)", + "url": "https://rickandmortyapi.com/api/location/1" + }, + "location": { + "name": "Anatomy Park", + "url": "https://rickandmortyapi.com/api/location/5" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/12.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/3" + ], + "url": "https://rickandmortyapi.com/api/character/12", + "created": "2017-11-04T20:32:33.144Z" + }, + { + "id": 13, + "name": "Alien Googah", + "status": "unknown", + "species": "Alien", + "type": "", + "gender": "unknown", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/13.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/31" + ], + "url": "https://rickandmortyapi.com/api/character/13", + "created": "2017-11-04T20:33:30.779Z" + }, + { + "id": 14, + "name": "Alien Morty", + "status": "unknown", + "species": "Alien", + "type": "", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/14.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/10" + ], + "url": "https://rickandmortyapi.com/api/character/14", + "created": "2017-11-04T20:51:31.373Z" + }, + { + "id": 15, + "name": "Alien Rick", + "status": "unknown", + "species": "Alien", + "type": "", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/15.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/10" + ], + "url": "https://rickandmortyapi.com/api/character/15", + "created": "2017-11-04T20:56:13.215Z" + }, + { + "id": 16, + "name": "Amish Cyborg", + "status": "Dead", + "species": "Alien", + "type": "Parasite", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/16.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/15" + ], + "url": "https://rickandmortyapi.com/api/character/16", + "created": "2017-11-04T21:12:45.235Z" + }, + { + "id": 17, + "name": "Annie", + "status": "Alive", + "species": "Human", + "type": "", + "gender": "Female", + "origin": { + "name": "Earth (C-137)", + "url": "https://rickandmortyapi.com/api/location/1" + }, + "location": { + "name": "Anatomy Park", + "url": "https://rickandmortyapi.com/api/location/5" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/17.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/3" + ], + "url": "https://rickandmortyapi.com/api/character/17", + "created": "2017-11-04T22:21:24.481Z" + }, + { + "id": 18, + "name": "Antenna Morty", + "status": "Alive", + "species": "Human", + "type": "Human with antennae", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Citadel of Ricks", + "url": "https://rickandmortyapi.com/api/location/3" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/18.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/10", + "https://rickandmortyapi.com/api/episode/28" + ], + "url": "https://rickandmortyapi.com/api/character/18", + "created": "2017-11-04T22:25:29.008Z" + }, + { + "id": 19, + "name": "Antenna Rick", + "status": "unknown", + "species": "Human", + "type": "Human with antennae", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "unknown", + "url": "" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/19.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/10" + ], + "url": "https://rickandmortyapi.com/api/character/19", + "created": "2017-11-04T22:28:13.756Z" + }, + { + "id": 20, + "name": "Ants in my Eyes Johnson", + "status": "unknown", + "species": "Human", + "type": "Human with ants in his eyes", + "gender": "Male", + "origin": { + "name": "unknown", + "url": "" + }, + "location": { + "name": "Interdimensional Cable", + "url": "https://rickandmortyapi.com/api/location/6" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/20.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/8" + ], + "url": "https://rickandmortyapi.com/api/character/20", + "created": "2017-11-04T22:34:53.659Z" + } + ] +} \ No newline at end of file diff --git a/src/mocks/episodeDetail.mock.tsx b/src/mocks/episodeDetail.mock.tsx new file mode 100644 index 0000000..ad5669a --- /dev/null +++ b/src/mocks/episodeDetail.mock.tsx @@ -0,0 +1,29 @@ +export default { + "id": 1, + "name": "Pilot", + "air_date": "December 2, 2013", + "episode": "S01E01", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/35", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/62", + "https://rickandmortyapi.com/api/character/92", + "https://rickandmortyapi.com/api/character/127", + "https://rickandmortyapi.com/api/character/144", + "https://rickandmortyapi.com/api/character/158", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/249", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/394", + "https://rickandmortyapi.com/api/character/395", + "https://rickandmortyapi.com/api/character/435" + ], + "url": "https://rickandmortyapi.com/api/episode/1", + "created": "2017-11-10T12:56:33.798Z" +} \ No newline at end of file diff --git a/src/mocks/episodes.mock.tsx b/src/mocks/episodes.mock.tsx new file mode 100644 index 0000000..93be121 --- /dev/null +++ b/src/mocks/episodes.mock.tsx @@ -0,0 +1,715 @@ +export default { + "pages": 3, + "episodes": [ + { + "id": 1, + "name": "Pilot", + "air_date": "December 2, 2013", + "episode": "S01E01", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/35", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/62", + "https://rickandmortyapi.com/api/character/92", + "https://rickandmortyapi.com/api/character/127", + "https://rickandmortyapi.com/api/character/144", + "https://rickandmortyapi.com/api/character/158", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/249", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/394", + "https://rickandmortyapi.com/api/character/395", + "https://rickandmortyapi.com/api/character/435" + ], + "url": "https://rickandmortyapi.com/api/episode/1", + "created": "2017-11-10T12:56:33.798Z" + }, + { + "id": 2, + "name": "Lawnmower Dog", + "air_date": "December 9, 2013", + "episode": "S01E02", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/46", + "https://rickandmortyapi.com/api/character/63", + "https://rickandmortyapi.com/api/character/80", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/221", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/246", + "https://rickandmortyapi.com/api/character/304", + "https://rickandmortyapi.com/api/character/305", + "https://rickandmortyapi.com/api/character/306", + "https://rickandmortyapi.com/api/character/329", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/396", + "https://rickandmortyapi.com/api/character/397", + "https://rickandmortyapi.com/api/character/398", + "https://rickandmortyapi.com/api/character/405" + ], + "url": "https://rickandmortyapi.com/api/episode/2", + "created": "2017-11-10T12:56:33.916Z" + }, + { + "id": 3, + "name": "Anatomy Park", + "air_date": "December 16, 2013", + "episode": "S01E03", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/12", + "https://rickandmortyapi.com/api/character/17", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/45", + "https://rickandmortyapi.com/api/character/96", + "https://rickandmortyapi.com/api/character/97", + "https://rickandmortyapi.com/api/character/98", + "https://rickandmortyapi.com/api/character/99", + "https://rickandmortyapi.com/api/character/100", + "https://rickandmortyapi.com/api/character/101", + "https://rickandmortyapi.com/api/character/108", + "https://rickandmortyapi.com/api/character/112", + "https://rickandmortyapi.com/api/character/114", + "https://rickandmortyapi.com/api/character/169", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/186", + "https://rickandmortyapi.com/api/character/201", + "https://rickandmortyapi.com/api/character/268", + "https://rickandmortyapi.com/api/character/300", + "https://rickandmortyapi.com/api/character/302", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/356" + ], + "url": "https://rickandmortyapi.com/api/episode/3", + "created": "2017-11-10T12:56:34.022Z" + }, + { + "id": 4, + "name": "M. Night Shaym-Aliens!", + "air_date": "January 13, 2014", + "episode": "S01E04", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/87", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/191", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/241", + "https://rickandmortyapi.com/api/character/270", + "https://rickandmortyapi.com/api/character/337", + "https://rickandmortyapi.com/api/character/338" + ], + "url": "https://rickandmortyapi.com/api/episode/4", + "created": "2017-11-10T12:56:34.129Z" + }, + { + "id": 5, + "name": "Meeseeks and Destroy", + "air_date": "January 20, 2014", + "episode": "S01E05", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/41", + "https://rickandmortyapi.com/api/character/89", + "https://rickandmortyapi.com/api/character/116", + "https://rickandmortyapi.com/api/character/117", + "https://rickandmortyapi.com/api/character/120", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/193", + "https://rickandmortyapi.com/api/character/238", + "https://rickandmortyapi.com/api/character/242", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/303", + "https://rickandmortyapi.com/api/character/326", + "https://rickandmortyapi.com/api/character/333", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/343", + "https://rickandmortyapi.com/api/character/399", + "https://rickandmortyapi.com/api/character/400" + ], + "url": "https://rickandmortyapi.com/api/episode/5", + "created": "2017-11-10T12:56:34.236Z" + }, + { + "id": 6, + "name": "Rick Potion #9", + "air_date": "January 27, 2014", + "episode": "S01E06", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/58", + "https://rickandmortyapi.com/api/character/82", + "https://rickandmortyapi.com/api/character/83", + "https://rickandmortyapi.com/api/character/92", + "https://rickandmortyapi.com/api/character/155", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/216", + "https://rickandmortyapi.com/api/character/234", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/249", + "https://rickandmortyapi.com/api/character/251", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/293", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/343", + "https://rickandmortyapi.com/api/character/394" + ], + "url": "https://rickandmortyapi.com/api/episode/6", + "created": "2017-11-10T12:56:34.339Z" + }, + { + "id": 7, + "name": "Raising Gazorpazorp", + "air_date": "March 10, 2014", + "episode": "S01E07", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/59", + "https://rickandmortyapi.com/api/character/151", + "https://rickandmortyapi.com/api/character/168", + "https://rickandmortyapi.com/api/character/211", + "https://rickandmortyapi.com/api/character/230", + "https://rickandmortyapi.com/api/character/258", + "https://rickandmortyapi.com/api/character/329", + "https://rickandmortyapi.com/api/character/376", + "https://rickandmortyapi.com/api/character/401" + ], + "url": "https://rickandmortyapi.com/api/episode/7", + "created": "2017-11-10T12:56:34.441Z" + }, + { + "id": 8, + "name": "Rixty Minutes", + "air_date": "March 17, 2014", + "episode": "S01E08", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/20", + "https://rickandmortyapi.com/api/character/28", + "https://rickandmortyapi.com/api/character/29", + "https://rickandmortyapi.com/api/character/34", + "https://rickandmortyapi.com/api/character/37", + "https://rickandmortyapi.com/api/character/54", + "https://rickandmortyapi.com/api/character/88", + "https://rickandmortyapi.com/api/character/91", + "https://rickandmortyapi.com/api/character/129", + "https://rickandmortyapi.com/api/character/134", + "https://rickandmortyapi.com/api/character/136", + "https://rickandmortyapi.com/api/character/145", + "https://rickandmortyapi.com/api/character/153", + "https://rickandmortyapi.com/api/character/157", + "https://rickandmortyapi.com/api/character/176", + "https://rickandmortyapi.com/api/character/183", + "https://rickandmortyapi.com/api/character/184", + "https://rickandmortyapi.com/api/character/195", + "https://rickandmortyapi.com/api/character/207", + "https://rickandmortyapi.com/api/character/214", + "https://rickandmortyapi.com/api/character/222", + "https://rickandmortyapi.com/api/character/250", + "https://rickandmortyapi.com/api/character/266", + "https://rickandmortyapi.com/api/character/277", + "https://rickandmortyapi.com/api/character/279", + "https://rickandmortyapi.com/api/character/314", + "https://rickandmortyapi.com/api/character/315", + "https://rickandmortyapi.com/api/character/316", + "https://rickandmortyapi.com/api/character/317", + "https://rickandmortyapi.com/api/character/318", + "https://rickandmortyapi.com/api/character/351", + "https://rickandmortyapi.com/api/character/358", + "https://rickandmortyapi.com/api/character/367", + "https://rickandmortyapi.com/api/character/370", + "https://rickandmortyapi.com/api/character/373", + "https://rickandmortyapi.com/api/character/402", + "https://rickandmortyapi.com/api/character/403", + "https://rickandmortyapi.com/api/character/404", + "https://rickandmortyapi.com/api/character/405", + "https://rickandmortyapi.com/api/character/406", + "https://rickandmortyapi.com/api/character/407", + "https://rickandmortyapi.com/api/character/408", + "https://rickandmortyapi.com/api/character/409", + "https://rickandmortyapi.com/api/character/410", + "https://rickandmortyapi.com/api/character/411", + "https://rickandmortyapi.com/api/character/412", + "https://rickandmortyapi.com/api/character/413", + "https://rickandmortyapi.com/api/character/414", + "https://rickandmortyapi.com/api/character/415", + "https://rickandmortyapi.com/api/character/416", + "https://rickandmortyapi.com/api/character/417", + "https://rickandmortyapi.com/api/character/418" + ], + "url": "https://rickandmortyapi.com/api/episode/8", + "created": "2017-11-10T12:56:34.543Z" + }, + { + "id": 9, + "name": "Something Ricked This Way Comes", + "air_date": "March 24, 2014", + "episode": "S01E09", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/88", + "https://rickandmortyapi.com/api/character/192", + "https://rickandmortyapi.com/api/character/240", + "https://rickandmortyapi.com/api/character/243", + "https://rickandmortyapi.com/api/character/251", + "https://rickandmortyapi.com/api/character/272", + "https://rickandmortyapi.com/api/character/307", + "https://rickandmortyapi.com/api/character/419", + "https://rickandmortyapi.com/api/character/420", + "https://rickandmortyapi.com/api/character/421", + "https://rickandmortyapi.com/api/character/422", + "https://rickandmortyapi.com/api/character/826" + ], + "url": "https://rickandmortyapi.com/api/episode/9", + "created": "2017-11-10T12:56:34.645Z" + }, + { + "id": 10, + "name": "Close Rick-counters of the Rick Kind", + "air_date": "April 7, 2014", + "episode": "S01E10", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/7", + "https://rickandmortyapi.com/api/character/14", + "https://rickandmortyapi.com/api/character/15", + "https://rickandmortyapi.com/api/character/18", + "https://rickandmortyapi.com/api/character/19", + "https://rickandmortyapi.com/api/character/21", + "https://rickandmortyapi.com/api/character/22", + "https://rickandmortyapi.com/api/character/27", + "https://rickandmortyapi.com/api/character/39", + "https://rickandmortyapi.com/api/character/53", + "https://rickandmortyapi.com/api/character/77", + "https://rickandmortyapi.com/api/character/78", + "https://rickandmortyapi.com/api/character/79", + "https://rickandmortyapi.com/api/character/82", + "https://rickandmortyapi.com/api/character/83", + "https://rickandmortyapi.com/api/character/84", + "https://rickandmortyapi.com/api/character/85", + "https://rickandmortyapi.com/api/character/86", + "https://rickandmortyapi.com/api/character/103", + "https://rickandmortyapi.com/api/character/113", + "https://rickandmortyapi.com/api/character/118", + "https://rickandmortyapi.com/api/character/119", + "https://rickandmortyapi.com/api/character/152", + "https://rickandmortyapi.com/api/character/164", + "https://rickandmortyapi.com/api/character/177", + "https://rickandmortyapi.com/api/character/209", + "https://rickandmortyapi.com/api/character/215", + "https://rickandmortyapi.com/api/character/232", + "https://rickandmortyapi.com/api/character/242", + "https://rickandmortyapi.com/api/character/274", + "https://rickandmortyapi.com/api/character/290", + "https://rickandmortyapi.com/api/character/294", + "https://rickandmortyapi.com/api/character/295", + "https://rickandmortyapi.com/api/character/298", + "https://rickandmortyapi.com/api/character/299", + "https://rickandmortyapi.com/api/character/329", + "https://rickandmortyapi.com/api/character/330", + "https://rickandmortyapi.com/api/character/339", + "https://rickandmortyapi.com/api/character/349", + "https://rickandmortyapi.com/api/character/359", + "https://rickandmortyapi.com/api/character/381", + "https://rickandmortyapi.com/api/character/389", + "https://rickandmortyapi.com/api/character/405", + "https://rickandmortyapi.com/api/character/424", + "https://rickandmortyapi.com/api/character/425", + "https://rickandmortyapi.com/api/character/426", + "https://rickandmortyapi.com/api/character/427", + "https://rickandmortyapi.com/api/character/428", + "https://rickandmortyapi.com/api/character/429", + "https://rickandmortyapi.com/api/character/430", + "https://rickandmortyapi.com/api/character/431", + "https://rickandmortyapi.com/api/character/432", + "https://rickandmortyapi.com/api/character/433", + "https://rickandmortyapi.com/api/character/434", + "https://rickandmortyapi.com/api/character/663" + ], + "url": "https://rickandmortyapi.com/api/episode/10", + "created": "2017-11-10T12:56:34.747Z" + }, + { + "id": 11, + "name": "Ricksy Business", + "air_date": "April 14, 2014", + "episode": "S01E11", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/7", + "https://rickandmortyapi.com/api/character/35", + "https://rickandmortyapi.com/api/character/47", + "https://rickandmortyapi.com/api/character/58", + "https://rickandmortyapi.com/api/character/88", + "https://rickandmortyapi.com/api/character/180", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/210", + "https://rickandmortyapi.com/api/character/216", + "https://rickandmortyapi.com/api/character/251", + "https://rickandmortyapi.com/api/character/282", + "https://rickandmortyapi.com/api/character/295", + "https://rickandmortyapi.com/api/character/308", + "https://rickandmortyapi.com/api/character/326", + "https://rickandmortyapi.com/api/character/327", + "https://rickandmortyapi.com/api/character/331", + "https://rickandmortyapi.com/api/character/333", + "https://rickandmortyapi.com/api/character/344", + "https://rickandmortyapi.com/api/character/362", + "https://rickandmortyapi.com/api/character/389", + "https://rickandmortyapi.com/api/character/395", + "https://rickandmortyapi.com/api/character/405", + "https://rickandmortyapi.com/api/character/423", + "https://rickandmortyapi.com/api/character/435", + "https://rickandmortyapi.com/api/character/436" + ], + "url": "https://rickandmortyapi.com/api/episode/11", + "created": "2017-11-10T12:56:34.850Z" + }, + { + "id": 12, + "name": "A Rickle in Time", + "air_date": "July 26, 2015", + "episode": "S02E01", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/11", + "https://rickandmortyapi.com/api/character/64", + "https://rickandmortyapi.com/api/character/237", + "https://rickandmortyapi.com/api/character/313", + "https://rickandmortyapi.com/api/character/437", + "https://rickandmortyapi.com/api/character/438", + "https://rickandmortyapi.com/api/character/439", + "https://rickandmortyapi.com/api/character/440" + ], + "url": "https://rickandmortyapi.com/api/episode/12", + "created": "2017-11-10T12:56:34.953Z" + }, + { + "id": 13, + "name": "Mortynight Run", + "air_date": "August 2, 2015", + "episode": "S02E02", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/23", + "https://rickandmortyapi.com/api/character/28", + "https://rickandmortyapi.com/api/character/34", + "https://rickandmortyapi.com/api/character/106", + "https://rickandmortyapi.com/api/character/122", + "https://rickandmortyapi.com/api/character/129", + "https://rickandmortyapi.com/api/character/131", + "https://rickandmortyapi.com/api/character/133", + "https://rickandmortyapi.com/api/character/136", + "https://rickandmortyapi.com/api/character/174", + "https://rickandmortyapi.com/api/character/180", + "https://rickandmortyapi.com/api/character/196", + "https://rickandmortyapi.com/api/character/207", + "https://rickandmortyapi.com/api/character/242", + "https://rickandmortyapi.com/api/character/257", + "https://rickandmortyapi.com/api/character/282", + "https://rickandmortyapi.com/api/character/309", + "https://rickandmortyapi.com/api/character/311", + "https://rickandmortyapi.com/api/character/362", + "https://rickandmortyapi.com/api/character/386", + "https://rickandmortyapi.com/api/character/393", + "https://rickandmortyapi.com/api/character/436", + "https://rickandmortyapi.com/api/character/441", + "https://rickandmortyapi.com/api/character/442", + "https://rickandmortyapi.com/api/character/443", + "https://rickandmortyapi.com/api/character/444", + "https://rickandmortyapi.com/api/character/445", + "https://rickandmortyapi.com/api/character/446", + "https://rickandmortyapi.com/api/character/447", + "https://rickandmortyapi.com/api/character/448", + "https://rickandmortyapi.com/api/character/449", + "https://rickandmortyapi.com/api/character/450", + "https://rickandmortyapi.com/api/character/451" + ], + "url": "https://rickandmortyapi.com/api/episode/13", + "created": "2017-11-10T12:56:35.055Z" + }, + { + "id": 14, + "name": "Auto Erotic Assimilation", + "air_date": "August 9, 2015", + "episode": "S02E03", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/36", + "https://rickandmortyapi.com/api/character/50", + "https://rickandmortyapi.com/api/character/90", + "https://rickandmortyapi.com/api/character/188", + "https://rickandmortyapi.com/api/character/249", + "https://rickandmortyapi.com/api/character/301", + "https://rickandmortyapi.com/api/character/336", + "https://rickandmortyapi.com/api/character/355", + "https://rickandmortyapi.com/api/character/372" + ], + "url": "https://rickandmortyapi.com/api/episode/14", + "created": "2017-11-10T12:56:35.158Z" + }, + { + "id": 15, + "name": "Total Rickall", + "air_date": "August 16, 2015", + "episode": "S02E04", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/16", + "https://rickandmortyapi.com/api/character/31", + "https://rickandmortyapi.com/api/character/32", + "https://rickandmortyapi.com/api/character/76", + "https://rickandmortyapi.com/api/character/109", + "https://rickandmortyapi.com/api/character/128", + "https://rickandmortyapi.com/api/character/141", + "https://rickandmortyapi.com/api/character/154", + "https://rickandmortyapi.com/api/character/169", + "https://rickandmortyapi.com/api/character/236", + "https://rickandmortyapi.com/api/character/244", + "https://rickandmortyapi.com/api/character/248", + "https://rickandmortyapi.com/api/character/259", + "https://rickandmortyapi.com/api/character/262", + "https://rickandmortyapi.com/api/character/280", + "https://rickandmortyapi.com/api/character/324", + "https://rickandmortyapi.com/api/character/329", + "https://rickandmortyapi.com/api/character/352", + "https://rickandmortyapi.com/api/character/391" + ], + "url": "https://rickandmortyapi.com/api/episode/15", + "created": "2017-11-10T12:56:35.261Z" + }, + { + "id": 16, + "name": "Get Schwifty", + "air_date": "August 23, 2015", + "episode": "S02E05", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/24", + "https://rickandmortyapi.com/api/character/47", + "https://rickandmortyapi.com/api/character/115", + "https://rickandmortyapi.com/api/character/124", + "https://rickandmortyapi.com/api/character/138", + "https://rickandmortyapi.com/api/character/161", + "https://rickandmortyapi.com/api/character/162", + "https://rickandmortyapi.com/api/character/172", + "https://rickandmortyapi.com/api/character/182", + "https://rickandmortyapi.com/api/character/199", + "https://rickandmortyapi.com/api/character/212", + "https://rickandmortyapi.com/api/character/213", + "https://rickandmortyapi.com/api/character/240", + "https://rickandmortyapi.com/api/character/241", + "https://rickandmortyapi.com/api/character/253", + "https://rickandmortyapi.com/api/character/255", + "https://rickandmortyapi.com/api/character/272", + "https://rickandmortyapi.com/api/character/309", + "https://rickandmortyapi.com/api/character/329", + "https://rickandmortyapi.com/api/character/331", + "https://rickandmortyapi.com/api/character/344", + "https://rickandmortyapi.com/api/character/346", + "https://rickandmortyapi.com/api/character/347", + "https://rickandmortyapi.com/api/character/395", + "https://rickandmortyapi.com/api/character/452", + "https://rickandmortyapi.com/api/character/454" + ], + "url": "https://rickandmortyapi.com/api/episode/16", + "created": "2017-11-10T12:56:35.364Z" + }, + { + "id": 17, + "name": "The Ricks Must Be Crazy", + "air_date": "August 30, 2015", + "episode": "S02E06", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/28", + "https://rickandmortyapi.com/api/character/34", + "https://rickandmortyapi.com/api/character/65", + "https://rickandmortyapi.com/api/character/129", + "https://rickandmortyapi.com/api/character/159", + "https://rickandmortyapi.com/api/character/160", + "https://rickandmortyapi.com/api/character/180", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/197", + "https://rickandmortyapi.com/api/character/207", + "https://rickandmortyapi.com/api/character/240", + "https://rickandmortyapi.com/api/character/266", + "https://rickandmortyapi.com/api/character/348", + "https://rickandmortyapi.com/api/character/364", + "https://rickandmortyapi.com/api/character/388", + "https://rickandmortyapi.com/api/character/753" + ], + "url": "https://rickandmortyapi.com/api/episode/17", + "created": "2017-11-10T12:56:35.467Z" + }, + { + "id": 18, + "name": "Big Trouble in Little Sanchez", + "air_date": "September 13, 2015", + "episode": "S02E07", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/40", + "https://rickandmortyapi.com/api/character/55", + "https://rickandmortyapi.com/api/character/66", + "https://rickandmortyapi.com/api/character/131", + "https://rickandmortyapi.com/api/character/132", + "https://rickandmortyapi.com/api/character/146", + "https://rickandmortyapi.com/api/character/148", + "https://rickandmortyapi.com/api/character/163", + "https://rickandmortyapi.com/api/character/178", + "https://rickandmortyapi.com/api/character/180", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/240", + "https://rickandmortyapi.com/api/character/272", + "https://rickandmortyapi.com/api/character/310", + "https://rickandmortyapi.com/api/character/353", + "https://rickandmortyapi.com/api/character/354", + "https://rickandmortyapi.com/api/character/358", + "https://rickandmortyapi.com/api/character/374", + "https://rickandmortyapi.com/api/character/386", + "https://rickandmortyapi.com/api/character/387", + "https://rickandmortyapi.com/api/character/453" + ], + "url": "https://rickandmortyapi.com/api/episode/18", + "created": "2017-11-10T12:56:35.569Z" + }, + { + "id": 19, + "name": "Interdimensional Cable 2: Tempting Fate", + "air_date": "September 20, 2015", + "episode": "S02E08", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/23", + "https://rickandmortyapi.com/api/character/35", + "https://rickandmortyapi.com/api/character/49", + "https://rickandmortyapi.com/api/character/51", + "https://rickandmortyapi.com/api/character/105", + "https://rickandmortyapi.com/api/character/121", + "https://rickandmortyapi.com/api/character/126", + "https://rickandmortyapi.com/api/character/133", + "https://rickandmortyapi.com/api/character/153", + "https://rickandmortyapi.com/api/character/173", + "https://rickandmortyapi.com/api/character/199", + "https://rickandmortyapi.com/api/character/205", + "https://rickandmortyapi.com/api/character/223", + "https://rickandmortyapi.com/api/character/224", + "https://rickandmortyapi.com/api/character/225", + "https://rickandmortyapi.com/api/character/254", + "https://rickandmortyapi.com/api/character/260", + "https://rickandmortyapi.com/api/character/263", + "https://rickandmortyapi.com/api/character/264", + "https://rickandmortyapi.com/api/character/275", + "https://rickandmortyapi.com/api/character/312", + "https://rickandmortyapi.com/api/character/321", + "https://rickandmortyapi.com/api/character/334", + "https://rickandmortyapi.com/api/character/362", + "https://rickandmortyapi.com/api/character/371", + "https://rickandmortyapi.com/api/character/383", + "https://rickandmortyapi.com/api/character/384", + "https://rickandmortyapi.com/api/character/435", + "https://rickandmortyapi.com/api/character/454", + "https://rickandmortyapi.com/api/character/455", + "https://rickandmortyapi.com/api/character/456", + "https://rickandmortyapi.com/api/character/457", + "https://rickandmortyapi.com/api/character/458", + "https://rickandmortyapi.com/api/character/459", + "https://rickandmortyapi.com/api/character/460" + ], + "url": "https://rickandmortyapi.com/api/episode/19", + "created": "2017-11-10T12:56:35.669Z" + }, + { + "id": 20, + "name": "Look Who's Purging Now", + "air_date": "September 27, 2015", + "episode": "S02E09", + "characters": [ + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/26", + "https://rickandmortyapi.com/api/character/139", + "https://rickandmortyapi.com/api/character/202", + "https://rickandmortyapi.com/api/character/273", + "https://rickandmortyapi.com/api/character/341" + ], + "url": "https://rickandmortyapi.com/api/episode/20", + "created": "2017-11-10T12:56:35.772Z" + } + ] +} \ No newline at end of file diff --git a/src/mocks/locationDetail.mock.tsx b/src/mocks/locationDetail.mock.tsx new file mode 100644 index 0000000..dffcab3 --- /dev/null +++ b/src/mocks/locationDetail.mock.tsx @@ -0,0 +1,37 @@ +export default { + "id": 1, + "name": "Earth (C-137)", + "type": "Planet", + "dimension": "Dimension C-137", + "residents": [ + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/45", + "https://rickandmortyapi.com/api/character/71", + "https://rickandmortyapi.com/api/character/82", + "https://rickandmortyapi.com/api/character/83", + "https://rickandmortyapi.com/api/character/92", + "https://rickandmortyapi.com/api/character/112", + "https://rickandmortyapi.com/api/character/114", + "https://rickandmortyapi.com/api/character/116", + "https://rickandmortyapi.com/api/character/117", + "https://rickandmortyapi.com/api/character/120", + "https://rickandmortyapi.com/api/character/127", + "https://rickandmortyapi.com/api/character/155", + "https://rickandmortyapi.com/api/character/169", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/186", + "https://rickandmortyapi.com/api/character/201", + "https://rickandmortyapi.com/api/character/216", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/302", + "https://rickandmortyapi.com/api/character/303", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/343", + "https://rickandmortyapi.com/api/character/356", + "https://rickandmortyapi.com/api/character/394" + ], + "url": "https://rickandmortyapi.com/api/location/1", + "created": "2017-11-10T12:42:04.162Z" +} \ No newline at end of file diff --git a/src/mocks/locations.mock.tsx b/src/mocks/locations.mock.tsx new file mode 100644 index 0000000..f648b1c --- /dev/null +++ b/src/mocks/locations.mock.tsx @@ -0,0 +1,692 @@ +export default { + "pages": 7, + "locations": [ + { + "id": 1, + "name": "Earth (C-137)", + "type": "Planet", + "dimension": "Dimension C-137", + "residents": [ + "https://rickandmortyapi.com/api/character/38", + "https://rickandmortyapi.com/api/character/45", + "https://rickandmortyapi.com/api/character/71", + "https://rickandmortyapi.com/api/character/82", + "https://rickandmortyapi.com/api/character/83", + "https://rickandmortyapi.com/api/character/92", + "https://rickandmortyapi.com/api/character/112", + "https://rickandmortyapi.com/api/character/114", + "https://rickandmortyapi.com/api/character/116", + "https://rickandmortyapi.com/api/character/117", + "https://rickandmortyapi.com/api/character/120", + "https://rickandmortyapi.com/api/character/127", + "https://rickandmortyapi.com/api/character/155", + "https://rickandmortyapi.com/api/character/169", + "https://rickandmortyapi.com/api/character/175", + "https://rickandmortyapi.com/api/character/179", + "https://rickandmortyapi.com/api/character/186", + "https://rickandmortyapi.com/api/character/201", + "https://rickandmortyapi.com/api/character/216", + "https://rickandmortyapi.com/api/character/239", + "https://rickandmortyapi.com/api/character/271", + "https://rickandmortyapi.com/api/character/302", + "https://rickandmortyapi.com/api/character/303", + "https://rickandmortyapi.com/api/character/338", + "https://rickandmortyapi.com/api/character/343", + "https://rickandmortyapi.com/api/character/356", + "https://rickandmortyapi.com/api/character/394" + ], + "url": "https://rickandmortyapi.com/api/location/1", + "created": "2017-11-10T12:42:04.162Z" + }, + { + "id": 2, + "name": "Abadango", + "type": "Cluster", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/6" + ], + "url": "https://rickandmortyapi.com/api/location/2", + "created": "2017-11-10T13:06:38.182Z" + }, + { + "id": 3, + "name": "Citadel of Ricks", + "type": "Space station", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/8", + "https://rickandmortyapi.com/api/character/14", + "https://rickandmortyapi.com/api/character/15", + "https://rickandmortyapi.com/api/character/18", + "https://rickandmortyapi.com/api/character/21", + "https://rickandmortyapi.com/api/character/22", + "https://rickandmortyapi.com/api/character/27", + "https://rickandmortyapi.com/api/character/42", + "https://rickandmortyapi.com/api/character/43", + "https://rickandmortyapi.com/api/character/44", + "https://rickandmortyapi.com/api/character/48", + "https://rickandmortyapi.com/api/character/53", + "https://rickandmortyapi.com/api/character/56", + "https://rickandmortyapi.com/api/character/61", + "https://rickandmortyapi.com/api/character/69", + "https://rickandmortyapi.com/api/character/72", + "https://rickandmortyapi.com/api/character/73", + "https://rickandmortyapi.com/api/character/74", + "https://rickandmortyapi.com/api/character/77", + "https://rickandmortyapi.com/api/character/78", + "https://rickandmortyapi.com/api/character/85", + "https://rickandmortyapi.com/api/character/86", + "https://rickandmortyapi.com/api/character/95", + "https://rickandmortyapi.com/api/character/118", + "https://rickandmortyapi.com/api/character/119", + "https://rickandmortyapi.com/api/character/123", + "https://rickandmortyapi.com/api/character/135", + "https://rickandmortyapi.com/api/character/143", + "https://rickandmortyapi.com/api/character/152", + "https://rickandmortyapi.com/api/character/164", + "https://rickandmortyapi.com/api/character/165", + "https://rickandmortyapi.com/api/character/187", + "https://rickandmortyapi.com/api/character/200", + "https://rickandmortyapi.com/api/character/206", + "https://rickandmortyapi.com/api/character/209", + "https://rickandmortyapi.com/api/character/220", + "https://rickandmortyapi.com/api/character/229", + "https://rickandmortyapi.com/api/character/231", + "https://rickandmortyapi.com/api/character/235", + "https://rickandmortyapi.com/api/character/267", + "https://rickandmortyapi.com/api/character/278", + "https://rickandmortyapi.com/api/character/281", + "https://rickandmortyapi.com/api/character/283", + "https://rickandmortyapi.com/api/character/284", + "https://rickandmortyapi.com/api/character/285", + "https://rickandmortyapi.com/api/character/286", + "https://rickandmortyapi.com/api/character/287", + "https://rickandmortyapi.com/api/character/288", + "https://rickandmortyapi.com/api/character/289", + "https://rickandmortyapi.com/api/character/291", + "https://rickandmortyapi.com/api/character/295", + "https://rickandmortyapi.com/api/character/298", + "https://rickandmortyapi.com/api/character/299", + "https://rickandmortyapi.com/api/character/322", + "https://rickandmortyapi.com/api/character/325", + "https://rickandmortyapi.com/api/character/328", + "https://rickandmortyapi.com/api/character/330", + "https://rickandmortyapi.com/api/character/345", + "https://rickandmortyapi.com/api/character/359", + "https://rickandmortyapi.com/api/character/366", + "https://rickandmortyapi.com/api/character/378", + "https://rickandmortyapi.com/api/character/385", + "https://rickandmortyapi.com/api/character/392", + "https://rickandmortyapi.com/api/character/461", + "https://rickandmortyapi.com/api/character/462", + "https://rickandmortyapi.com/api/character/463", + "https://rickandmortyapi.com/api/character/464", + "https://rickandmortyapi.com/api/character/465", + "https://rickandmortyapi.com/api/character/466", + "https://rickandmortyapi.com/api/character/472", + "https://rickandmortyapi.com/api/character/473", + "https://rickandmortyapi.com/api/character/474", + "https://rickandmortyapi.com/api/character/475", + "https://rickandmortyapi.com/api/character/476", + "https://rickandmortyapi.com/api/character/477", + "https://rickandmortyapi.com/api/character/478", + "https://rickandmortyapi.com/api/character/479", + "https://rickandmortyapi.com/api/character/480", + "https://rickandmortyapi.com/api/character/481", + "https://rickandmortyapi.com/api/character/482", + "https://rickandmortyapi.com/api/character/483", + "https://rickandmortyapi.com/api/character/484", + "https://rickandmortyapi.com/api/character/485", + "https://rickandmortyapi.com/api/character/486", + "https://rickandmortyapi.com/api/character/487", + "https://rickandmortyapi.com/api/character/488", + "https://rickandmortyapi.com/api/character/489", + "https://rickandmortyapi.com/api/character/2", + "https://rickandmortyapi.com/api/character/1", + "https://rickandmortyapi.com/api/character/801", + "https://rickandmortyapi.com/api/character/802", + "https://rickandmortyapi.com/api/character/803", + "https://rickandmortyapi.com/api/character/804", + "https://rickandmortyapi.com/api/character/805", + "https://rickandmortyapi.com/api/character/806", + "https://rickandmortyapi.com/api/character/810", + "https://rickandmortyapi.com/api/character/811", + "https://rickandmortyapi.com/api/character/812", + "https://rickandmortyapi.com/api/character/819", + "https://rickandmortyapi.com/api/character/820", + "https://rickandmortyapi.com/api/character/818" + ], + "url": "https://rickandmortyapi.com/api/location/3", + "created": "2017-11-10T13:08:13.191Z" + }, + { + "id": 4, + "name": "Worldender's lair", + "type": "Planet", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/10", + "https://rickandmortyapi.com/api/character/81", + "https://rickandmortyapi.com/api/character/208", + "https://rickandmortyapi.com/api/character/226", + "https://rickandmortyapi.com/api/character/340", + "https://rickandmortyapi.com/api/character/362", + "https://rickandmortyapi.com/api/character/375", + "https://rickandmortyapi.com/api/character/382", + "https://rickandmortyapi.com/api/character/395" + ], + "url": "https://rickandmortyapi.com/api/location/4", + "created": "2017-11-10T13:08:20.569Z" + }, + { + "id": 5, + "name": "Anatomy Park", + "type": "Microverse", + "dimension": "Dimension C-137", + "residents": [ + "https://rickandmortyapi.com/api/character/12", + "https://rickandmortyapi.com/api/character/17", + "https://rickandmortyapi.com/api/character/96", + "https://rickandmortyapi.com/api/character/97", + "https://rickandmortyapi.com/api/character/98", + "https://rickandmortyapi.com/api/character/99", + "https://rickandmortyapi.com/api/character/100", + "https://rickandmortyapi.com/api/character/101", + "https://rickandmortyapi.com/api/character/108", + "https://rickandmortyapi.com/api/character/268", + "https://rickandmortyapi.com/api/character/300" + ], + "url": "https://rickandmortyapi.com/api/location/5", + "created": "2017-11-10T13:08:46.060Z" + }, + { + "id": 6, + "name": "Interdimensional Cable", + "type": "TV", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/20", + "https://rickandmortyapi.com/api/character/28", + "https://rickandmortyapi.com/api/character/29", + "https://rickandmortyapi.com/api/character/34", + "https://rickandmortyapi.com/api/character/49", + "https://rickandmortyapi.com/api/character/51", + "https://rickandmortyapi.com/api/character/54", + "https://rickandmortyapi.com/api/character/121", + "https://rickandmortyapi.com/api/character/126", + "https://rickandmortyapi.com/api/character/129", + "https://rickandmortyapi.com/api/character/134", + "https://rickandmortyapi.com/api/character/136", + "https://rickandmortyapi.com/api/character/145", + "https://rickandmortyapi.com/api/character/157", + "https://rickandmortyapi.com/api/character/173", + "https://rickandmortyapi.com/api/character/184", + "https://rickandmortyapi.com/api/character/205", + "https://rickandmortyapi.com/api/character/207", + "https://rickandmortyapi.com/api/character/214", + "https://rickandmortyapi.com/api/character/222", + "https://rickandmortyapi.com/api/character/223", + "https://rickandmortyapi.com/api/character/224", + "https://rickandmortyapi.com/api/character/225", + "https://rickandmortyapi.com/api/character/250", + "https://rickandmortyapi.com/api/character/254", + "https://rickandmortyapi.com/api/character/260", + "https://rickandmortyapi.com/api/character/264", + "https://rickandmortyapi.com/api/character/266", + "https://rickandmortyapi.com/api/character/275", + "https://rickandmortyapi.com/api/character/277", + "https://rickandmortyapi.com/api/character/279", + "https://rickandmortyapi.com/api/character/312", + "https://rickandmortyapi.com/api/character/314", + "https://rickandmortyapi.com/api/character/315", + "https://rickandmortyapi.com/api/character/316", + "https://rickandmortyapi.com/api/character/317", + "https://rickandmortyapi.com/api/character/318", + "https://rickandmortyapi.com/api/character/334", + "https://rickandmortyapi.com/api/character/351", + "https://rickandmortyapi.com/api/character/358", + "https://rickandmortyapi.com/api/character/367", + "https://rickandmortyapi.com/api/character/370", + "https://rickandmortyapi.com/api/character/373", + "https://rickandmortyapi.com/api/character/403", + "https://rickandmortyapi.com/api/character/406", + "https://rickandmortyapi.com/api/character/407", + "https://rickandmortyapi.com/api/character/408", + "https://rickandmortyapi.com/api/character/409", + "https://rickandmortyapi.com/api/character/410", + "https://rickandmortyapi.com/api/character/411", + "https://rickandmortyapi.com/api/character/412", + "https://rickandmortyapi.com/api/character/413", + "https://rickandmortyapi.com/api/character/414", + "https://rickandmortyapi.com/api/character/415", + "https://rickandmortyapi.com/api/character/416", + "https://rickandmortyapi.com/api/character/417", + "https://rickandmortyapi.com/api/character/418", + "https://rickandmortyapi.com/api/character/457", + "https://rickandmortyapi.com/api/character/458", + "https://rickandmortyapi.com/api/character/459", + "https://rickandmortyapi.com/api/character/709", + "https://rickandmortyapi.com/api/character/711" + ], + "url": "https://rickandmortyapi.com/api/location/6", + "created": "2017-11-10T13:09:09.102Z" + }, + { + "id": 7, + "name": "Immortality Field Resort", + "type": "Resort", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/23", + "https://rickandmortyapi.com/api/character/204", + "https://rickandmortyapi.com/api/character/320" + ], + "url": "https://rickandmortyapi.com/api/location/7", + "created": "2017-11-10T13:09:17.136Z" + }, + { + "id": 8, + "name": "Post-Apocalyptic Earth", + "type": "Planet", + "dimension": "Post-Apocalyptic Dimension", + "residents": [ + "https://rickandmortyapi.com/api/character/25", + "https://rickandmortyapi.com/api/character/52", + "https://rickandmortyapi.com/api/character/68", + "https://rickandmortyapi.com/api/character/110", + "https://rickandmortyapi.com/api/character/111", + "https://rickandmortyapi.com/api/character/140", + "https://rickandmortyapi.com/api/character/156", + "https://rickandmortyapi.com/api/character/228", + "https://rickandmortyapi.com/api/character/323", + "https://rickandmortyapi.com/api/character/342" + ], + "url": "https://rickandmortyapi.com/api/location/8", + "created": "2017-11-10T13:09:22.551Z" + }, + { + "id": 9, + "name": "Purge Planet", + "type": "Planet", + "dimension": "Replacement Dimension", + "residents": [ + "https://rickandmortyapi.com/api/character/26", + "https://rickandmortyapi.com/api/character/139", + "https://rickandmortyapi.com/api/character/202", + "https://rickandmortyapi.com/api/character/273" + ], + "url": "https://rickandmortyapi.com/api/location/9", + "created": "2017-11-10T13:09:29.566Z" + }, + { + "id": 10, + "name": "Venzenulon 7", + "type": "Planet", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/33" + ], + "url": "https://rickandmortyapi.com/api/location/10", + "created": "2017-11-18T11:21:51.643Z" + }, + { + "id": 11, + "name": "Bepis 9", + "type": "Planet", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/35" + ], + "url": "https://rickandmortyapi.com/api/location/11", + "created": "2017-11-18T11:26:03.325Z" + }, + { + "id": 12, + "name": "Cronenberg Earth", + "type": "Planet", + "dimension": "Cronenberg Dimension", + "residents": [], + "url": "https://rickandmortyapi.com/api/location/12", + "created": "2017-11-18T11:29:27.857Z" + }, + { + "id": 13, + "name": "Nuptia 4", + "type": "Planet", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/40", + "https://rickandmortyapi.com/api/character/55", + "https://rickandmortyapi.com/api/character/131", + "https://rickandmortyapi.com/api/character/132", + "https://rickandmortyapi.com/api/character/146", + "https://rickandmortyapi.com/api/character/148", + "https://rickandmortyapi.com/api/character/163", + "https://rickandmortyapi.com/api/character/178", + "https://rickandmortyapi.com/api/character/310", + "https://rickandmortyapi.com/api/character/386", + "https://rickandmortyapi.com/api/character/387" + ], + "url": "https://rickandmortyapi.com/api/location/13", + "created": "2017-11-18T11:30:29.780Z" + }, + { + "id": 14, + "name": "Giant's Town", + "type": "Fantasy town", + "dimension": "Fantasy Dimension", + "residents": [ + "https://rickandmortyapi.com/api/character/89", + "https://rickandmortyapi.com/api/character/399", + "https://rickandmortyapi.com/api/character/400" + ], + "url": "https://rickandmortyapi.com/api/location/14", + "created": "2017-11-18T11:31:15.248Z" + }, + { + "id": 15, + "name": "Bird World", + "type": "Planet", + "dimension": "unknown", + "residents": [], + "url": "https://rickandmortyapi.com/api/location/15", + "created": "2017-11-18T11:32:26.752Z" + }, + { + "id": 16, + "name": "St. Gloopy Noops Hospital", + "type": "Space station", + "dimension": "unknown", + "residents": [ + "https://rickandmortyapi.com/api/character/105", + "https://rickandmortyapi.com/api/character/263", + "https://rickandmortyapi.com/api/character/321", + "https://rickandmortyapi.com/api/character/383", + "https://rickandmortyapi.com/api/character/384", + "https://rickandmortyapi.com/api/character/454", + "https://rickandmortyapi.com/api/character/455", + "https://rickandmortyapi.com/api/character/456", + "https://rickandmortyapi.com/api/character/460" + ], + "url": "https://rickandmortyapi.com/api/location/16", + "created": "2017-11-18T11:43:20.075Z" + }, + { + "id": 17, + "name": "Earth (5-126)", + "type": "Planet", + "dimension": "Dimension 5-126", + "residents": [], + "url": "https://rickandmortyapi.com/api/location/17", + "created": "2017-11-18T11:41:08.486Z" + }, + { + "id": 18, + "name": "Mr. Goldenfold's dream", + "type": "Dream", + "dimension": "Dimension C-137", + "residents": [ + "https://rickandmortyapi.com/api/character/63", + "https://rickandmortyapi.com/api/character/80", + "https://rickandmortyapi.com/api/character/221", + "https://rickandmortyapi.com/api/character/246", + "https://rickandmortyapi.com/api/character/304", + "https://rickandmortyapi.com/api/character/305", + "https://rickandmortyapi.com/api/character/306", + "https://rickandmortyapi.com/api/character/396" + ], + "url": "https://rickandmortyapi.com/api/location/18", + "created": "2017-11-18T11:46:22.933Z" + }, + { + "id": 19, + "name": "Gromflom Prime", + "type": "Planet", + "dimension": "Replacement Dimension", + "residents": [], + "url": "https://rickandmortyapi.com/api/location/19", + "created": "2017-11-18T11:39:52.165Z" + }, + { + "id": 20, + "name": "Earth (Replacement Dimension)", + "type": "Planet", + "dimension": "Replacement Dimension", + "residents": [ + "https://rickandmortyapi.com/api/character/3", + "https://rickandmortyapi.com/api/character/4", + "https://rickandmortyapi.com/api/character/5", + "https://rickandmortyapi.com/api/character/9", + "https://rickandmortyapi.com/api/character/11", + "https://rickandmortyapi.com/api/character/13", + "https://rickandmortyapi.com/api/character/16", + "https://rickandmortyapi.com/api/character/31", + "https://rickandmortyapi.com/api/character/32", + "https://rickandmortyapi.com/api/character/50", + "https://rickandmortyapi.com/api/character/58", + "https://rickandmortyapi.com/api/character/59", + "https://rickandmortyapi.com/api/character/64", + "https://rickandmortyapi.com/api/character/66", + "https://rickandmortyapi.com/api/character/76", + "https://rickandmortyapi.com/api/character/88", + "https://rickandmortyapi.com/api/character/103", + "https://rickandmortyapi.com/api/character/107", + "https://rickandmortyapi.com/api/character/109", + "https://rickandmortyapi.com/api/character/113", + "https://rickandmortyapi.com/api/character/115", + "https://rickandmortyapi.com/api/character/124", + "https://rickandmortyapi.com/api/character/128", + "https://rickandmortyapi.com/api/character/137", + "https://rickandmortyapi.com/api/character/138", + "https://rickandmortyapi.com/api/character/141", + "https://rickandmortyapi.com/api/character/147", + "https://rickandmortyapi.com/api/character/149", + "https://rickandmortyapi.com/api/character/151", + "https://rickandmortyapi.com/api/character/154", + "https://rickandmortyapi.com/api/character/166", + "https://rickandmortyapi.com/api/character/167", + "https://rickandmortyapi.com/api/character/170", + "https://rickandmortyapi.com/api/character/171", + "https://rickandmortyapi.com/api/character/172", + "https://rickandmortyapi.com/api/character/180", + "https://rickandmortyapi.com/api/character/181", + "https://rickandmortyapi.com/api/character/182", + "https://rickandmortyapi.com/api/character/185", + "https://rickandmortyapi.com/api/character/189", + "https://rickandmortyapi.com/api/character/190", + "https://rickandmortyapi.com/api/character/210", + "https://rickandmortyapi.com/api/character/217", + "https://rickandmortyapi.com/api/character/218", + "https://rickandmortyapi.com/api/character/219", + "https://rickandmortyapi.com/api/character/227", + "https://rickandmortyapi.com/api/character/230", + "https://rickandmortyapi.com/api/character/233", + "https://rickandmortyapi.com/api/character/234", + "https://rickandmortyapi.com/api/character/236", + "https://rickandmortyapi.com/api/character/237", + "https://rickandmortyapi.com/api/character/240", + "https://rickandmortyapi.com/api/character/241", + "https://rickandmortyapi.com/api/character/243", + "https://rickandmortyapi.com/api/character/244", + "https://rickandmortyapi.com/api/character/245", + "https://rickandmortyapi.com/api/character/248", + "https://rickandmortyapi.com/api/character/251", + "https://rickandmortyapi.com/api/character/255", + "https://rickandmortyapi.com/api/character/259", + "https://rickandmortyapi.com/api/character/262", + "https://rickandmortyapi.com/api/character/265", + "https://rickandmortyapi.com/api/character/272", + "https://rickandmortyapi.com/api/character/276", + "https://rickandmortyapi.com/api/character/280", + "https://rickandmortyapi.com/api/character/292", + "https://rickandmortyapi.com/api/character/293", + "https://rickandmortyapi.com/api/character/324", + "https://rickandmortyapi.com/api/character/326", + "https://rickandmortyapi.com/api/character/327", + "https://rickandmortyapi.com/api/character/332", + "https://rickandmortyapi.com/api/character/335", + "https://rickandmortyapi.com/api/character/341", + "https://rickandmortyapi.com/api/character/346", + "https://rickandmortyapi.com/api/character/347", + "https://rickandmortyapi.com/api/character/352", + "https://rickandmortyapi.com/api/character/353", + "https://rickandmortyapi.com/api/character/354", + "https://rickandmortyapi.com/api/character/357", + "https://rickandmortyapi.com/api/character/360", + "https://rickandmortyapi.com/api/character/361", + "https://rickandmortyapi.com/api/character/363", + "https://rickandmortyapi.com/api/character/365", + "https://rickandmortyapi.com/api/character/374", + "https://rickandmortyapi.com/api/character/377", + "https://rickandmortyapi.com/api/character/390", + "https://rickandmortyapi.com/api/character/391", + "https://rickandmortyapi.com/api/character/401", + "https://rickandmortyapi.com/api/character/402", + "https://rickandmortyapi.com/api/character/405", + "https://rickandmortyapi.com/api/character/423", + "https://rickandmortyapi.com/api/character/435", + "https://rickandmortyapi.com/api/character/437", + "https://rickandmortyapi.com/api/character/438", + "https://rickandmortyapi.com/api/character/439", + "https://rickandmortyapi.com/api/character/440", + "https://rickandmortyapi.com/api/character/452", + "https://rickandmortyapi.com/api/character/453", + "https://rickandmortyapi.com/api/character/467", + "https://rickandmortyapi.com/api/character/468", + "https://rickandmortyapi.com/api/character/469", + "https://rickandmortyapi.com/api/character/471", + "https://rickandmortyapi.com/api/character/492", + "https://rickandmortyapi.com/api/character/493", + "https://rickandmortyapi.com/api/character/497", + "https://rickandmortyapi.com/api/character/509", + "https://rickandmortyapi.com/api/character/510", + "https://rickandmortyapi.com/api/character/511", + "https://rickandmortyapi.com/api/character/512", + "https://rickandmortyapi.com/api/character/513", + "https://rickandmortyapi.com/api/character/514", + "https://rickandmortyapi.com/api/character/516", + "https://rickandmortyapi.com/api/character/517", + "https://rickandmortyapi.com/api/character/523", + "https://rickandmortyapi.com/api/character/524", + "https://rickandmortyapi.com/api/character/526", + "https://rickandmortyapi.com/api/character/534", + "https://rickandmortyapi.com/api/character/535", + "https://rickandmortyapi.com/api/character/536", + "https://rickandmortyapi.com/api/character/537", + "https://rickandmortyapi.com/api/character/538", + "https://rickandmortyapi.com/api/character/539", + "https://rickandmortyapi.com/api/character/540", + "https://rickandmortyapi.com/api/character/541", + "https://rickandmortyapi.com/api/character/561", + "https://rickandmortyapi.com/api/character/562", + "https://rickandmortyapi.com/api/character/564", + "https://rickandmortyapi.com/api/character/570", + "https://rickandmortyapi.com/api/character/575", + "https://rickandmortyapi.com/api/character/584", + "https://rickandmortyapi.com/api/character/585", + "https://rickandmortyapi.com/api/character/586", + "https://rickandmortyapi.com/api/character/588", + "https://rickandmortyapi.com/api/character/590", + "https://rickandmortyapi.com/api/character/591", + "https://rickandmortyapi.com/api/character/592", + "https://rickandmortyapi.com/api/character/667", + "https://rickandmortyapi.com/api/character/672", + "https://rickandmortyapi.com/api/character/680", + "https://rickandmortyapi.com/api/character/684", + "https://rickandmortyapi.com/api/character/686", + "https://rickandmortyapi.com/api/character/687", + "https://rickandmortyapi.com/api/character/688", + "https://rickandmortyapi.com/api/character/689", + "https://rickandmortyapi.com/api/character/690", + "https://rickandmortyapi.com/api/character/691", + "https://rickandmortyapi.com/api/character/692", + "https://rickandmortyapi.com/api/character/693", + "https://rickandmortyapi.com/api/character/694", + "https://rickandmortyapi.com/api/character/695", + "https://rickandmortyapi.com/api/character/696", + "https://rickandmortyapi.com/api/character/697", + "https://rickandmortyapi.com/api/character/698", + "https://rickandmortyapi.com/api/character/699", + "https://rickandmortyapi.com/api/character/700", + "https://rickandmortyapi.com/api/character/701", + "https://rickandmortyapi.com/api/character/702", + "https://rickandmortyapi.com/api/character/703", + "https://rickandmortyapi.com/api/character/704", + "https://rickandmortyapi.com/api/character/705", + "https://rickandmortyapi.com/api/character/706", + "https://rickandmortyapi.com/api/character/707", + "https://rickandmortyapi.com/api/character/708", + "https://rickandmortyapi.com/api/character/710", + "https://rickandmortyapi.com/api/character/712", + "https://rickandmortyapi.com/api/character/713", + "https://rickandmortyapi.com/api/character/714", + "https://rickandmortyapi.com/api/character/715", + "https://rickandmortyapi.com/api/character/716", + "https://rickandmortyapi.com/api/character/717", + "https://rickandmortyapi.com/api/character/719", + "https://rickandmortyapi.com/api/character/720", + "https://rickandmortyapi.com/api/character/721", + "https://rickandmortyapi.com/api/character/722", + "https://rickandmortyapi.com/api/character/723", + "https://rickandmortyapi.com/api/character/724", + "https://rickandmortyapi.com/api/character/725", + "https://rickandmortyapi.com/api/character/726", + "https://rickandmortyapi.com/api/character/727", + "https://rickandmortyapi.com/api/character/728", + "https://rickandmortyapi.com/api/character/729", + "https://rickandmortyapi.com/api/character/730", + "https://rickandmortyapi.com/api/character/732", + "https://rickandmortyapi.com/api/character/733", + "https://rickandmortyapi.com/api/character/734", + "https://rickandmortyapi.com/api/character/735", + "https://rickandmortyapi.com/api/character/737", + "https://rickandmortyapi.com/api/character/738", + "https://rickandmortyapi.com/api/character/739", + "https://rickandmortyapi.com/api/character/740", + "https://rickandmortyapi.com/api/character/741", + "https://rickandmortyapi.com/api/character/742", + "https://rickandmortyapi.com/api/character/753", + "https://rickandmortyapi.com/api/character/754", + "https://rickandmortyapi.com/api/character/755", + "https://rickandmortyapi.com/api/character/756", + "https://rickandmortyapi.com/api/character/757", + "https://rickandmortyapi.com/api/character/758", + "https://rickandmortyapi.com/api/character/759", + "https://rickandmortyapi.com/api/character/760", + "https://rickandmortyapi.com/api/character/761", + "https://rickandmortyapi.com/api/character/762", + "https://rickandmortyapi.com/api/character/763", + "https://rickandmortyapi.com/api/character/764", + "https://rickandmortyapi.com/api/character/765", + "https://rickandmortyapi.com/api/character/766", + "https://rickandmortyapi.com/api/character/767", + "https://rickandmortyapi.com/api/character/768", + "https://rickandmortyapi.com/api/character/769", + "https://rickandmortyapi.com/api/character/770", + "https://rickandmortyapi.com/api/character/771", + "https://rickandmortyapi.com/api/character/772", + "https://rickandmortyapi.com/api/character/773", + "https://rickandmortyapi.com/api/character/774", + "https://rickandmortyapi.com/api/character/775", + "https://rickandmortyapi.com/api/character/776", + "https://rickandmortyapi.com/api/character/777", + "https://rickandmortyapi.com/api/character/778", + "https://rickandmortyapi.com/api/character/781", + "https://rickandmortyapi.com/api/character/786", + "https://rickandmortyapi.com/api/character/788", + "https://rickandmortyapi.com/api/character/789", + "https://rickandmortyapi.com/api/character/790", + "https://rickandmortyapi.com/api/character/791", + "https://rickandmortyapi.com/api/character/203", + "https://rickandmortyapi.com/api/character/794", + "https://rickandmortyapi.com/api/character/800", + "https://rickandmortyapi.com/api/character/813", + "https://rickandmortyapi.com/api/character/821", + "https://rickandmortyapi.com/api/character/826" + ], + "url": "https://rickandmortyapi.com/api/location/20", + "created": "2017-11-18T19:33:01.173Z" + } + ] +} \ No newline at end of file diff --git a/src/routes/CharacterDetails.test.tsx b/src/routes/CharacterDetails.test.tsx new file mode 100644 index 0000000..1b2c279 --- /dev/null +++ b/src/routes/CharacterDetails.test.tsx @@ -0,0 +1,42 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import CharacterDetails from './CharacterDetails'; +import characterDetailMock from '../mocks/characterDetail.mock'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => characterDetailMock, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have character', async () => { + render() + expect(screen.getByText('Rick Sanchez')).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/EpisodeDetails.test.tsx b/src/routes/EpisodeDetails.test.tsx new file mode 100644 index 0000000..28575d6 --- /dev/null +++ b/src/routes/EpisodeDetails.test.tsx @@ -0,0 +1,42 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import EpisodeDetails from './EpisodeDetails'; +import episodeDetailMock from '../mocks/episodeDetail.mock'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => episodeDetailMock + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have character', async () => { + render() + expect(screen.getByText('Pilot')).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/EpisodeDetails.tsx b/src/routes/EpisodeDetails.tsx index 1e17d18..f629365 100644 --- a/src/routes/EpisodeDetails.tsx +++ b/src/routes/EpisodeDetails.tsx @@ -11,6 +11,7 @@ import Season3 from "/seasons/s03.jpg"; import Season4 from "/seasons/s04.jpg"; import Season5 from "/seasons/s05.jpg"; import Season6 from "/seasons/s06.jpg"; +import LoadingSpinner from "../components/LoadingSpinner"; export default function EpisodeDetails() { const episode = useLoaderData() as Episode; @@ -47,7 +48,7 @@ export default function EpisodeDetails() { - )) : "Loading..."} + )) : <> Loading...} ) } \ No newline at end of file diff --git a/src/routes/Episodes.test.tsx b/src/routes/Episodes.test.tsx new file mode 100644 index 0000000..7a886e5 --- /dev/null +++ b/src/routes/Episodes.test.tsx @@ -0,0 +1,45 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import episodesMock from '../mocks/episodes.mock'; +import Episodes from './Episodes'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => episodesMock, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render() + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have episodes', async () => { + render() + expect(screen.getByText('Pilot')).toBeDefined(); + expect(screen.getByText('A Rickle in Time')).toBeDefined(); + }); + + it('should have pagination', async () => { + render() + expect(screen.getAllByText(`Page 1 of ${episodesMock.pages}`)).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/ErrorPage.test.tsx b/src/routes/ErrorPage.test.tsx new file mode 100644 index 0000000..6c76e3f --- /dev/null +++ b/src/routes/ErrorPage.test.tsx @@ -0,0 +1,46 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import Characters from './Characters'; +import ErrorPage from './ErrorPage'; + +const mockRoutes = [{ + path: '/', + element: , + errorElement: , + children: [ + { + index: true, + element: , + errorElement: , + loader: () => { throw new Error('Force error page') }, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have error message', async () => { + render() + expect(screen.getByText("Looks like something went wrong!")).toBeDefined(); + expect(screen.getByText("Go Back")).toBeDefined(); + }) + + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/LocationDetails.test.tsx b/src/routes/LocationDetails.test.tsx new file mode 100644 index 0000000..5fb6a93 --- /dev/null +++ b/src/routes/LocationDetails.test.tsx @@ -0,0 +1,42 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import LocationDetails from './LocationDetails'; +import locationDetailMock from '../mocks/locationDetail.mock'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => locationDetailMock, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have character', async () => { + render() + expect(screen.getByText('Earth (C-137)')).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/LocationDetails.tsx b/src/routes/LocationDetails.tsx index fd4d8d9..07c7577 100644 --- a/src/routes/LocationDetails.tsx +++ b/src/routes/LocationDetails.tsx @@ -10,6 +10,7 @@ import LoadingSpinner from "../components/LoadingSpinner"; export default function LocationDetails() { const location = useLoaderData() as Location; + console.log(location) const facts:DetailFacts[] = [ { type: "Type", value: location.type }, { type: "Dimension", value: location.dimension }, diff --git a/src/routes/Locations.test.tsx b/src/routes/Locations.test.tsx new file mode 100644 index 0000000..fb432f5 --- /dev/null +++ b/src/routes/Locations.test.tsx @@ -0,0 +1,48 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import locationsMock from '../mocks/locations.mock'; +import Locations from './Locations'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => locationsMock, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have locations', async () => { + render() + expect(screen.getByText('Abadango')).toBeDefined(); + expect(screen.getByText('Anatomy Park')).toBeDefined(); + }); + + it('should have pagination', async () => { + render() + expect(screen.getAllByText(`Page 1 of ${locationsMock.pages}`)).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/routes/Root.test.tsx b/src/routes/Root.test.tsx new file mode 100644 index 0000000..05a08a1 --- /dev/null +++ b/src/routes/Root.test.tsx @@ -0,0 +1,48 @@ +import { describe, it, expect } from 'vitest'; +import { render, screen } from "@testing-library/react"; + +import Root from './Root'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import Characters from './Characters'; +import charactersMock from '../mocks/characters.mock'; + +const mockRoutes = [{ + path: '/', + element: , + children: [ + { + index: true, + element: , + loader: () => charactersMock, + }, + ] +}]; + +describe('Root', () => { + const router = createMemoryRouter(mockRoutes); + it('should have heading title', async () => { + render( + + + ) + expect(screen.getByText('Rick and Morty Explorer')).toBeDefined(); + }); + + it('should have characters', async () => { + render() + expect(screen.getByText('Rick Sanchez')).toBeDefined(); + expect(screen.getByText('Summer Smith')).toBeDefined(); + }); + + it('should have pagination', async () => { + render() + expect(screen.getAllByText(`Page 1 of ${charactersMock.pages}`)).toBeDefined(); + }); + + it('should have tabs', async () => { + render() + expect(screen.getAllByText('Characters')).toBeDefined(); + expect(screen.getAllByText('Episodes')).toBeDefined(); + expect(screen.getAllByText('Locations')).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..fb7630b --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,21 @@ +// vitest.config.ts +import { defineConfig } from 'vitest/config' +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: 'jsdom', + /* + // if the types are not picked up, add `vitest-browser-react` to + // "compilerOptions.types" in your tsconfig or + // import `vitest-browser-react` manually so TypeScript can pick it up + setupFiles: ['vitest-browser-react'], + browser: { + name: 'chromium', + enabled: true, + }, + */ + }, +}) \ No newline at end of file