From 55e6149d74b44843c46c497dc3e10c34181fd7e4 Mon Sep 17 00:00:00 2001 From: Manuel S Date: Sat, 16 Apr 2022 22:21:23 +0200 Subject: [PATCH] feat: Migrated to API resolvers (#115) - All data is now fetched from the API instead of the database. - Added staging mode. - Fixed cover images still showing old images when switching pages. - Fixed first letter filter not working. --- README.md | 14 +- next.config.js | 9 +- package-lock.json | 809 ++++++------------ package.json | 6 +- src/components/image/CoverImage.js | 2 +- src/components/search/SearchAnime.js | 2 +- src/components/search/SearchArtist.js | 2 +- src/components/search/SearchSeries.js | 2 +- src/components/search/SearchStudio.js | 2 +- src/components/search/SearchTheme.js | 2 +- src/hooks/useImage.js | 2 - src/lib/server/animethemes/resolvers.js | 802 ++++++++++------- src/lib/server/index.js | 30 +- .../anime/[animeSlug]/[videoSlug]/index.js | 67 +- src/pages/anime/[animeSlug]/index.js | 39 +- src/pages/artist/[artistSlug]/index.js | 32 +- src/pages/index.js | 4 +- src/pages/page/[...pageSlug].js | 35 +- src/pages/series/[seriesSlug]/index.js | 36 +- src/pages/studio/[studioSlug]/index.js | 36 +- src/pages/year/[year]/[season]/index.js | 40 +- src/pages/year/[year]/index.js | 32 +- src/utils/devLog.js | 13 + src/utils/fetchStaticPaths.js | 18 + 24 files changed, 933 insertions(+), 1103 deletions(-) create mode 100644 src/utils/devLog.js create mode 100644 src/utils/fetchStaticPaths.js diff --git a/README.md b/README.md index 3117682..8e2cdee 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,12 @@ root directory. This is a list of all available options: ```ini -; Datebase configuration -; Only username and password are required. -; All other fields take the specified values by default, but can be changed if wanted. -DB_HOST=127.0.0.1 -DB_PORT=3306 -DB_USER=... -DB_PASSWORD=... -DB_DATABASE=animethemes +; Back-end API configuration +; These values are required. +ANIMETHEMES_API_URL=http://localhost +ANIMETHEMES_API_KEY=... -; (Optional) The URL to the AnimeThemes API to use. +; (Optional) The URL to the AnimeThemes API to use on the front-end. ; For development this is "http://localhost" by default. ; For production this is "https://staging.animethemes.moe" by default. NEXT_PUBLIC_API_URL=http://localhost diff --git a/next.config.js b/next.config.js index 281576b..c07dc6e 100644 --- a/next.config.js +++ b/next.config.js @@ -1,12 +1,19 @@ +const { info } = require("next/dist/build/output/log"); + const withBundleAnalyzer = require("@next/bundle-analyzer")({ enabled: process.env.ANALYZE === "true", }); +if (process.env.NEXT_PUBLIC_STAGING) { + info("Running animethemes-web in staging mode!"); +} + module.exports = withBundleAnalyzer({ basePath: process.env.NEXT_PUBLIC_BASE_PATH || "", reactStrictMode: true, compiler: { styledComponents: true }, - swcMinify: true + swcMinify: true, + staticPageGenerationTimeout: 3600 }); diff --git a/package-lock.json b/package-lock.json index 18d54f3..568ebcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,12 +21,12 @@ "common-tags": "^1.8.0", "framer-motion": "^6.2.1", "graphql": "^15.6.1", + "graphql-parse-resolve-info": "^4.12.0", "graphql-tag": "^2.12.6", - "knex": "^0.95.11", "lodash-es": "^4.17.21", "marked": "^4.0.12", - "mysql2": "^2.3.3", - "next": "^12.1.0", + "next": "^12.1.5", + "p-limit": "^3.1.0", "prismjs": "^1.27.0", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -448,11 +448,11 @@ } }, "node_modules/@graphql-tools/merge": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.1.tgz", - "integrity": "sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA==", + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.7.tgz", + "integrity": "sha512-rKxjNogqu1UYAG/y5FOb6lJsmSQbWA+jq4inWjNEVX54VGGE7/WGnmPaqcsyomNOfS3vIRS6NnG+DxiQSqetjg==", "dependencies": { - "@graphql-tools/utils": "^8.5.1", + "@graphql-tools/utils": "8.6.6", "tslib": "~2.3.0" }, "peerDependencies": { @@ -460,12 +460,12 @@ } }, "node_modules/@graphql-tools/schema": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.1.tgz", - "integrity": "sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ==", + "version": "8.3.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.7.tgz", + "integrity": "sha512-7byr9J6rfMPFPfiR4u65dy20xHATTvbgOY7KYd1sYPnMKKfRZe0tUgpnE+noXcfob7N8s366WaVh7bEoztQMwg==", "dependencies": { - "@graphql-tools/merge": "^8.2.1", - "@graphql-tools/utils": "^8.5.1", + "@graphql-tools/merge": "8.2.7", + "@graphql-tools/utils": "8.6.6", "tslib": "~2.3.0", "value-or-promise": "1.0.11" }, @@ -474,9 +474,9 @@ } }, "node_modules/@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "version": "8.6.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.6.tgz", + "integrity": "sha512-wjY2ljKLCnnbRrDNPPgPNqCujou0LFSOWcxAjV6DYUlfFWTsAEvlYmsmY4T+K12wI/fnqoJ2bUwIlap1plFDMg==", "dependencies": { "tslib": "~2.3.0" }, @@ -524,9 +524,9 @@ } }, "node_modules/@next/env": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.0.tgz", - "integrity": "sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==" + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.5.tgz", + "integrity": "sha512-+34yUJslfJi7Lyx6ELuN8nWcOzi27izfYnZIC1Dqv7kmmfiBVxgzR3BXhlvEMTKC2IRJhXVs2FkMY+buQe3k7Q==" }, "node_modules/@next/eslint-plugin-next": { "version": "12.0.8", @@ -537,10 +537,25 @@ "glob": "7.1.7" } }, + "node_modules/@next/swc-android-arm-eabi": { + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.5.tgz", + "integrity": "sha512-SKnGTdYcoN04Y2DvE0/Y7/MjkA+ltsmbuH/y/hR7Ob7tsj+8ZdOYuk+YvW1B8dY20nDPHP58XgDTSm2nA8BzzA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@next/swc-android-arm64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz", - "integrity": "sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.5.tgz", + "integrity": "sha512-YXiqgQ/9Rxg1dXp6brXbeQM1JDx9SwUY/36JiE+36FXqYEmDYbxld9qkX6GEzkc5rbwJ+RCitargnzEtwGW0mw==", "cpu": [ "arm64" ], @@ -553,9 +568,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz", - "integrity": "sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.5.tgz", + "integrity": "sha512-y8mhldb/WFZ6lFeowkGfi0cO/lBdiBqDk4T4LZLvCpoQp4Or/NzUN6P5NzBQZ5/b4oUHM/wQICEM+1wKA4qIVw==", "cpu": [ "arm64" ], @@ -568,9 +583,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz", - "integrity": "sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.5.tgz", + "integrity": "sha512-wqJ3X7WQdTwSGi0kIDEmzw34QHISRIQ5uvC+VXmsIlCPFcMA+zM5723uh8NfuKGquDMiEMS31a83QgkuHMYbwQ==", "cpu": [ "x64" ], @@ -583,9 +598,9 @@ } }, "node_modules/@next/swc-linux-arm-gnueabihf": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz", - "integrity": "sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.5.tgz", + "integrity": "sha512-WnhdM5duONMvt2CncAl+9pim0wBxDS2lHoo7ub/o/i1bRbs11UTzosKzEXVaTDCUkCX2c32lIDi1WcN2ZPkcdw==", "cpu": [ "arm" ], @@ -598,9 +613,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz", - "integrity": "sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.5.tgz", + "integrity": "sha512-Jq2H68yQ4bLUhR/XQnbw3LDW0GMQn355qx6rU36BthDLeGue7YV7MqNPa8GKvrpPocEMW77nWx/1yI6w6J07gw==", "cpu": [ "arm64" ], @@ -613,9 +628,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz", - "integrity": "sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.5.tgz", + "integrity": "sha512-KgPjwdbhDqXI7ghNN8V/WAiLquc9Ebe8KBrNNEL0NQr+yd9CyKJ6KqjayVkmX+hbHzbyvbui/5wh/p3CZQ9xcQ==", "cpu": [ "arm64" ], @@ -628,9 +643,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz", - "integrity": "sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.5.tgz", + "integrity": "sha512-O2ErUTvCJ6DkNTSr9pbu1n3tcqykqE/ebty1rwClzIYdOgpB3T2MfEPP+K7GhUR87wmN/hlihO9ch7qpVFDGKw==", "cpu": [ "x64" ], @@ -643,9 +658,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz", - "integrity": "sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.5.tgz", + "integrity": "sha512-1eIlZmlO/VRjxxzUBcVosf54AFU3ltAzHi+BJA+9U/lPxCYIsT+R4uO3QksRzRjKWhVQMRjEnlXyyq5SKJm7BA==", "cpu": [ "x64" ], @@ -658,9 +673,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz", - "integrity": "sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.5.tgz", + "integrity": "sha512-oromsfokbEuVb0CBLLE7R9qX3KGXucZpsojLpzUh1QJjuy1QkrPJncwr8xmWQnwgtQ6ecMWXgXPB+qtvizT9Tw==", "cpu": [ "arm64" ], @@ -673,9 +688,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz", - "integrity": "sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.5.tgz", + "integrity": "sha512-a/51L5KzBpeZSW9LbekMo3I3Cwul+V+QKwbEIMA+Qwb2qrlcn1L9h3lt8cHqNTFt2y72ce6aTwDTw1lyi5oIRA==", "cpu": [ "ia32" ], @@ -688,9 +703,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz", - "integrity": "sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.5.tgz", + "integrity": "sha512-/SoXW1Ntpmpw3AXAzfDRaQidnd8kbZ2oSni8u5z0yw6t4RwJvmdZy1eOaAADRThWKV+2oU90++LSnXJIwBRWYQ==", "cpu": [ "x64" ], @@ -1436,11 +1451,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" - }, "node_modules/comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", @@ -1450,14 +1460,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, "node_modules/common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", @@ -1559,14 +1561,6 @@ "node": ">= 0.4" } }, - "node_modules/denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -1670,14 +1664,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -2045,14 +2031,6 @@ "node": ">=10" } }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "engines": { - "node": ">=6" - } - }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -2281,7 +2259,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -2289,14 +2268,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "node_modules/generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dependencies": { - "is-property": "^1.0.2" - } - }, "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -2327,11 +2298,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -2414,6 +2380,21 @@ "node": ">= 10.x" } }, + "node_modules/graphql-parse-resolve-info": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/graphql-parse-resolve-info/-/graphql-parse-resolve-info-4.12.0.tgz", + "integrity": "sha512-sQyJeWCzFQwLj8SdgrWeAQG46Nc+VLxof91/AtvEVdbvFCvb+S6OoA4OtIp5OpWBrFo+JzW6LIKifNHXtRKPpA==", + "dependencies": { + "debug": "^4.1.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=8.6" + }, + "peerDependencies": { + "graphql": ">=0.9 <0.14 || ^14.0.2 || ^15.4.0" + } + }, "node_modules/graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", @@ -2446,6 +2427,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -2589,17 +2571,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "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==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -2667,14 +2638,6 @@ "node": ">= 0.4" } }, - "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -2752,6 +2715,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -2848,11 +2812,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -2997,60 +2956,6 @@ "node": ">=4.0" } }, - "node_modules/knex": { - "version": "0.95.14", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.14.tgz", - "integrity": "sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg==", - "dependencies": { - "colorette": "2.0.16", - "commander": "^7.1.0", - "debug": "4.3.2", - "escalade": "^3.1.1", - "esm": "^3.2.25", - "getopts": "2.2.5", - "interpret": "^2.2.0", - "lodash": "^4.17.21", - "pg-connection-string": "2.5.0", - "rechoir": "0.7.0", - "resolve-from": "^5.0.0", - "tarn": "^3.0.1", - "tildify": "2.0.0" - }, - "bin": { - "knex": "bin/cli.js" - }, - "engines": { - "node": ">=10" - }, - "peerDependenciesMeta": { - "mysql": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "pg": { - "optional": true - }, - "pg-native": { - "optional": true - }, - "sqlite3": { - "optional": true - }, - "tedious": { - "optional": true - } - } - }, - "node_modules/knex/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", @@ -3114,11 +3019,6 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3134,6 +3034,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -3221,49 +3122,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/mysql2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", - "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", - "dependencies": { - "denque": "^2.0.1", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", - "dependencies": { - "lru-cache": "^4.1.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/named-placeholders/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/named-placeholders/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, "node_modules/nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", @@ -3290,15 +3148,14 @@ "dev": true }, "node_modules/next": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/next/-/next-12.1.0.tgz", - "integrity": "sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/next/-/next-12.1.5.tgz", + "integrity": "sha512-YGHDpyfgCfnT5GZObsKepmRnne7Kzp7nGrac07dikhutWQug7hHg85/+sPJ4ZW5Q2pDkb+n0FnmLkmd44htIJQ==", "dependencies": { - "@next/env": "12.1.0", + "@next/env": "12.1.5", "caniuse-lite": "^1.0.30001283", "postcss": "8.4.5", - "styled-jsx": "5.0.0", - "use-subscription": "1.5.1" + "styled-jsx": "5.0.1" }, "bin": { "next": "dist/bin/next" @@ -3307,17 +3164,18 @@ "node": ">=12.22.0" }, "optionalDependencies": { - "@next/swc-android-arm64": "12.1.0", - "@next/swc-darwin-arm64": "12.1.0", - "@next/swc-darwin-x64": "12.1.0", - "@next/swc-linux-arm-gnueabihf": "12.1.0", - "@next/swc-linux-arm64-gnu": "12.1.0", - "@next/swc-linux-arm64-musl": "12.1.0", - "@next/swc-linux-x64-gnu": "12.1.0", - "@next/swc-linux-x64-musl": "12.1.0", - "@next/swc-win32-arm64-msvc": "12.1.0", - "@next/swc-win32-ia32-msvc": "12.1.0", - "@next/swc-win32-x64-msvc": "12.1.0" + "@next/swc-android-arm-eabi": "12.1.5", + "@next/swc-android-arm64": "12.1.5", + "@next/swc-darwin-arm64": "12.1.5", + "@next/swc-darwin-x64": "12.1.5", + "@next/swc-linux-arm-gnueabihf": "12.1.5", + "@next/swc-linux-arm64-gnu": "12.1.5", + "@next/swc-linux-arm64-musl": "12.1.5", + "@next/swc-linux-x64-gnu": "12.1.5", + "@next/swc-linux-x64-musl": "12.1.5", + "@next/swc-win32-arm64-msvc": "12.1.5", + "@next/swc-win32-ia32-msvc": "12.1.5", + "@next/swc-win32-x64-msvc": "12.1.5" }, "peerDependencies": { "fibers": ">= 3.1.0", @@ -3489,6 +3347,20 @@ "node": ">= 0.8.0" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", @@ -3568,7 +3440,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -3579,11 +3452,6 @@ "node": ">=8" } }, - "node_modules/pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -3695,11 +3563,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -3796,17 +3659,6 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -3890,6 +3742,7 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -3954,11 +3807,6 @@ "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==" - }, "node_modules/sass": { "version": "1.43.4", "resolved": "https://registry.npmjs.org/sass/-/sass-1.43.4.tgz", @@ -3997,11 +3845,6 @@ "node": ">=10" } }, - "node_modules/seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" - }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -4104,14 +3947,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/sqlstring": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", - "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4276,14 +4111,14 @@ } }, "node_modules/styled-jsx": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz", - "integrity": "sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.1.tgz", + "integrity": "sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw==", "engines": { "node": ">= 12.0.0" }, "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || 18.x.x" + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" }, "peerDependenciesMeta": { "@babel/core": { @@ -4348,28 +4183,12 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/tarn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz", - "integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw==", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "node_modules/tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", - "engines": { - "node": ">=8" - } - }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", @@ -4591,17 +4410,6 @@ "react": ">=16.8.0" } }, - "node_modules/use-subscription": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", - "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", - "dependencies": { - "object-assign": "^4.1.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" - } - }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -4775,7 +4583,19 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -5091,29 +4911,29 @@ } }, "@graphql-tools/merge": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.1.tgz", - "integrity": "sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA==", + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.7.tgz", + "integrity": "sha512-rKxjNogqu1UYAG/y5FOb6lJsmSQbWA+jq4inWjNEVX54VGGE7/WGnmPaqcsyomNOfS3vIRS6NnG+DxiQSqetjg==", "requires": { - "@graphql-tools/utils": "^8.5.1", + "@graphql-tools/utils": "8.6.6", "tslib": "~2.3.0" } }, "@graphql-tools/schema": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.1.tgz", - "integrity": "sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ==", + "version": "8.3.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.7.tgz", + "integrity": "sha512-7byr9J6rfMPFPfiR4u65dy20xHATTvbgOY7KYd1sYPnMKKfRZe0tUgpnE+noXcfob7N8s366WaVh7bEoztQMwg==", "requires": { - "@graphql-tools/merge": "^8.2.1", - "@graphql-tools/utils": "^8.5.1", + "@graphql-tools/merge": "8.2.7", + "@graphql-tools/utils": "8.6.6", "tslib": "~2.3.0", "value-or-promise": "1.0.11" } }, "@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "version": "8.6.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.6.tgz", + "integrity": "sha512-wjY2ljKLCnnbRrDNPPgPNqCujou0LFSOWcxAjV6DYUlfFWTsAEvlYmsmY4T+K12wI/fnqoJ2bUwIlap1plFDMg==", "requires": { "tslib": "~2.3.0" } @@ -5152,9 +4972,9 @@ } }, "@next/env": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.0.tgz", - "integrity": "sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==" + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-12.1.5.tgz", + "integrity": "sha512-+34yUJslfJi7Lyx6ELuN8nWcOzi27izfYnZIC1Dqv7kmmfiBVxgzR3BXhlvEMTKC2IRJhXVs2FkMY+buQe3k7Q==" }, "@next/eslint-plugin-next": { "version": "12.0.8", @@ -5165,70 +4985,76 @@ "glob": "7.1.7" } }, + "@next/swc-android-arm-eabi": { + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.5.tgz", + "integrity": "sha512-SKnGTdYcoN04Y2DvE0/Y7/MjkA+ltsmbuH/y/hR7Ob7tsj+8ZdOYuk+YvW1B8dY20nDPHP58XgDTSm2nA8BzzA==", + "optional": true + }, "@next/swc-android-arm64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz", - "integrity": "sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.1.5.tgz", + "integrity": "sha512-YXiqgQ/9Rxg1dXp6brXbeQM1JDx9SwUY/36JiE+36FXqYEmDYbxld9qkX6GEzkc5rbwJ+RCitargnzEtwGW0mw==", "optional": true }, "@next/swc-darwin-arm64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz", - "integrity": "sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.5.tgz", + "integrity": "sha512-y8mhldb/WFZ6lFeowkGfi0cO/lBdiBqDk4T4LZLvCpoQp4Or/NzUN6P5NzBQZ5/b4oUHM/wQICEM+1wKA4qIVw==", "optional": true }, "@next/swc-darwin-x64": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz", - "integrity": "sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.5.tgz", + "integrity": "sha512-wqJ3X7WQdTwSGi0kIDEmzw34QHISRIQ5uvC+VXmsIlCPFcMA+zM5723uh8NfuKGquDMiEMS31a83QgkuHMYbwQ==", "optional": true }, "@next/swc-linux-arm-gnueabihf": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz", - "integrity": "sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.5.tgz", + "integrity": "sha512-WnhdM5duONMvt2CncAl+9pim0wBxDS2lHoo7ub/o/i1bRbs11UTzosKzEXVaTDCUkCX2c32lIDi1WcN2ZPkcdw==", "optional": true }, "@next/swc-linux-arm64-gnu": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz", - "integrity": "sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.5.tgz", + "integrity": "sha512-Jq2H68yQ4bLUhR/XQnbw3LDW0GMQn355qx6rU36BthDLeGue7YV7MqNPa8GKvrpPocEMW77nWx/1yI6w6J07gw==", "optional": true }, "@next/swc-linux-arm64-musl": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz", - "integrity": "sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.5.tgz", + "integrity": "sha512-KgPjwdbhDqXI7ghNN8V/WAiLquc9Ebe8KBrNNEL0NQr+yd9CyKJ6KqjayVkmX+hbHzbyvbui/5wh/p3CZQ9xcQ==", "optional": true }, "@next/swc-linux-x64-gnu": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz", - "integrity": "sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.5.tgz", + "integrity": "sha512-O2ErUTvCJ6DkNTSr9pbu1n3tcqykqE/ebty1rwClzIYdOgpB3T2MfEPP+K7GhUR87wmN/hlihO9ch7qpVFDGKw==", "optional": true }, "@next/swc-linux-x64-musl": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz", - "integrity": "sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.5.tgz", + "integrity": "sha512-1eIlZmlO/VRjxxzUBcVosf54AFU3ltAzHi+BJA+9U/lPxCYIsT+R4uO3QksRzRjKWhVQMRjEnlXyyq5SKJm7BA==", "optional": true }, "@next/swc-win32-arm64-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz", - "integrity": "sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.5.tgz", + "integrity": "sha512-oromsfokbEuVb0CBLLE7R9qX3KGXucZpsojLpzUh1QJjuy1QkrPJncwr8xmWQnwgtQ6ecMWXgXPB+qtvizT9Tw==", "optional": true }, "@next/swc-win32-ia32-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz", - "integrity": "sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.5.tgz", + "integrity": "sha512-a/51L5KzBpeZSW9LbekMo3I3Cwul+V+QKwbEIMA+Qwb2qrlcn1L9h3lt8cHqNTFt2y72ce6aTwDTw1lyi5oIRA==", "optional": true }, "@next/swc-win32-x64-msvc": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz", - "integrity": "sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.5.tgz", + "integrity": "sha512-/SoXW1Ntpmpw3AXAzfDRaQidnd8kbZ2oSni8u5z0yw6t4RwJvmdZy1eOaAADRThWKV+2oU90++LSnXJIwBRWYQ==", "optional": true }, "@nodelib/fs.scandir": { @@ -5766,21 +5592,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" - }, "comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, "common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", @@ -5857,11 +5673,6 @@ "object-keys": "^1.0.12" } }, - "denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" - }, "detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -5944,11 +5755,6 @@ "is-symbol": "^1.0.2" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -6240,11 +6046,6 @@ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" - }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -6422,7 +6223,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -6430,14 +6232,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -6459,11 +6253,6 @@ "get-intrinsic": "^1.1.1" } }, - "getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -6521,6 +6310,15 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.7.2.tgz", "integrity": "sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A==" }, + "graphql-parse-resolve-info": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/graphql-parse-resolve-info/-/graphql-parse-resolve-info-4.12.0.tgz", + "integrity": "sha512-sQyJeWCzFQwLj8SdgrWeAQG46Nc+VLxof91/AtvEVdbvFCvb+S6OoA4OtIp5OpWBrFo+JzW6LIKifNHXtRKPpA==", + "requires": { + "debug": "^4.1.1", + "tslib": "^2.0.1" + } + }, "graphql-tag": { "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", @@ -6541,6 +6339,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -6645,14 +6444,6 @@ } } }, - "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==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -6705,11 +6496,6 @@ "side-channel": "^1.0.4" } }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" - }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -6752,6 +6538,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -6809,11 +6596,6 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -6919,33 +6701,6 @@ "object.assign": "^4.1.2" } }, - "knex": { - "version": "0.95.14", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.14.tgz", - "integrity": "sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg==", - "requires": { - "colorette": "2.0.16", - "commander": "^7.1.0", - "debug": "4.3.2", - "escalade": "^3.1.1", - "esm": "^3.2.25", - "getopts": "2.2.5", - "interpret": "^2.2.0", - "lodash": "^4.17.21", - "pg-connection-string": "2.5.0", - "rechoir": "0.7.0", - "resolve-from": "^5.0.0", - "tarn": "^3.0.1", - "tildify": "2.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - } - } - }, "language-subtag-registry": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", @@ -7003,11 +6758,6 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7020,6 +6770,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -7083,45 +6834,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "mysql2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", - "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", - "requires": { - "denque": "^2.0.1", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - } - }, - "named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", - "requires": { - "lru-cache": "^4.1.3" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, "nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", @@ -7142,26 +6854,26 @@ "dev": true }, "next": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/next/-/next-12.1.0.tgz", - "integrity": "sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/next/-/next-12.1.5.tgz", + "integrity": "sha512-YGHDpyfgCfnT5GZObsKepmRnne7Kzp7nGrac07dikhutWQug7hHg85/+sPJ4ZW5Q2pDkb+n0FnmLkmd44htIJQ==", "requires": { - "@next/env": "12.1.0", - "@next/swc-android-arm64": "12.1.0", - "@next/swc-darwin-arm64": "12.1.0", - "@next/swc-darwin-x64": "12.1.0", - "@next/swc-linux-arm-gnueabihf": "12.1.0", - "@next/swc-linux-arm64-gnu": "12.1.0", - "@next/swc-linux-arm64-musl": "12.1.0", - "@next/swc-linux-x64-gnu": "12.1.0", - "@next/swc-linux-x64-musl": "12.1.0", - "@next/swc-win32-arm64-msvc": "12.1.0", - "@next/swc-win32-ia32-msvc": "12.1.0", - "@next/swc-win32-x64-msvc": "12.1.0", + "@next/env": "12.1.5", + "@next/swc-android-arm-eabi": "12.1.5", + "@next/swc-android-arm64": "12.1.5", + "@next/swc-darwin-arm64": "12.1.5", + "@next/swc-darwin-x64": "12.1.5", + "@next/swc-linux-arm-gnueabihf": "12.1.5", + "@next/swc-linux-arm64-gnu": "12.1.5", + "@next/swc-linux-arm64-musl": "12.1.5", + "@next/swc-linux-x64-gnu": "12.1.5", + "@next/swc-linux-x64-musl": "12.1.5", + "@next/swc-win32-arm64-msvc": "12.1.5", + "@next/swc-win32-ia32-msvc": "12.1.5", + "@next/swc-win32-x64-msvc": "12.1.5", "caniuse-lite": "^1.0.30001283", "postcss": "8.4.5", - "styled-jsx": "5.0.0", - "use-subscription": "1.5.1" + "styled-jsx": "5.0.1" } }, "normalize-path": { @@ -7273,6 +6985,14 @@ "word-wrap": "^1.2.3" } }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", @@ -7333,7 +7053,8 @@ "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-type": { "version": "4.0.0", @@ -7341,11 +7062,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -7430,11 +7146,6 @@ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==" }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -7490,14 +7201,6 @@ "picomatch": "^2.2.1" } }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "requires": { - "resolve": "^1.9.0" - } - }, "regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -7558,6 +7261,7 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, "requires": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -7592,11 +7296,6 @@ "queue-microtask": "^1.2.2" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, "sass": { "version": "1.43.4", "resolved": "https://registry.npmjs.org/sass/-/sass-1.43.4.tgz", @@ -7623,11 +7322,6 @@ "lru-cache": "^6.0.0" } }, - "seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" - }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -7702,11 +7396,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sqlstring": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", - "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==" - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7833,9 +7522,9 @@ } }, "styled-jsx": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz", - "integrity": "sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.1.tgz", + "integrity": "sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw==", "requires": {} }, "supports-color": { @@ -7884,22 +7573,12 @@ } } }, - "tarn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz", - "integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw==" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" - }, "tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", @@ -8070,14 +7749,6 @@ "integrity": "sha512-fOrzIw2wstbAJuv8PC9Vg4XgwyTLEOdq4y/Z3IhVl8DAE4svRcgyEUvrEXu+BMNgMoc3YND6qLT61kkgEKXh7Q==", "requires": {} }, - "use-subscription": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", - "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", - "requires": { - "object-assign": "^4.1.1" - } - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -8193,7 +7864,13 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/package.json b/package.json index 228389f..3eabef9 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,12 @@ "common-tags": "^1.8.0", "framer-motion": "^6.2.1", "graphql": "^15.6.1", + "graphql-parse-resolve-info": "^4.12.0", "graphql-tag": "^2.12.6", - "knex": "^0.95.11", "lodash-es": "^4.17.21", "marked": "^4.0.12", - "mysql2": "^2.3.3", - "next": "^12.1.0", + "next": "^12.1.5", + "p-limit": "^3.1.0", "prismjs": "^1.27.0", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/src/components/image/CoverImage.js b/src/components/image/CoverImage.js index f050b80..c6c1fbb 100644 --- a/src/components/image/CoverImage.js +++ b/src/components/image/CoverImage.js @@ -7,7 +7,7 @@ export function CoverImage({ resourceWithImages, ...props }) { return ( - + ); } diff --git a/src/components/search/SearchAnime.js b/src/components/search/SearchAnime.js index 6a6c313..15d8dda 100644 --- a/src/components/search/SearchAnime.js +++ b/src/components/search/SearchAnime.js @@ -21,7 +21,7 @@ export function SearchAnime({ searchQuery }) { const entitySearch = useEntitySearch("anime", searchQuery, { filters: { - "name][like": filter.firstLetter ? `${filter.firstLetter}%` : null, + "name-like": filter.firstLetter ? `${filter.firstLetter}%` : null, season: filter.season, year: filter.year }, diff --git a/src/components/search/SearchArtist.js b/src/components/search/SearchArtist.js index 3424f56..4ca3a49 100644 --- a/src/components/search/SearchArtist.js +++ b/src/components/search/SearchArtist.js @@ -14,7 +14,7 @@ export function SearchArtist({ searchQuery }) { const entitySearch = useEntitySearch("artist", searchQuery, { filters: { - "name][like": filter.firstLetter ? `${filter.firstLetter}%` : null, + "name-like": filter.firstLetter ? `${filter.firstLetter}%` : null, }, sortBy: searchQuery ? null : filter.sortBy }); diff --git a/src/components/search/SearchSeries.js b/src/components/search/SearchSeries.js index 11581fc..a20dd44 100644 --- a/src/components/search/SearchSeries.js +++ b/src/components/search/SearchSeries.js @@ -14,7 +14,7 @@ export function SearchSeries({ searchQuery }) { const entitySearch = useEntitySearch("series", searchQuery, { filters: { - "name][like": filter.firstLetter ? `${filter.firstLetter}%` : null, + "name-like": filter.firstLetter ? `${filter.firstLetter}%` : null, }, sortBy: searchQuery ? null : filter.sortBy }); diff --git a/src/components/search/SearchStudio.js b/src/components/search/SearchStudio.js index 4c4bfc6..925660f 100644 --- a/src/components/search/SearchStudio.js +++ b/src/components/search/SearchStudio.js @@ -14,7 +14,7 @@ export function SearchStudio({ searchQuery }) { const entitySearch = useEntitySearch("studio", searchQuery, { filters: { - "name][like": filter.firstLetter ? `${filter.firstLetter}%` : null, + "name-like": filter.firstLetter ? `${filter.firstLetter}%` : null, }, sortBy: searchQuery ? null : filter.sortBy }); diff --git a/src/components/search/SearchTheme.js b/src/components/search/SearchTheme.js index 8167100..7fdd430 100644 --- a/src/components/search/SearchTheme.js +++ b/src/components/search/SearchTheme.js @@ -16,7 +16,7 @@ export function SearchTheme({ searchQuery }) { const entitySearch = useEntitySearch("theme", searchQuery, { filters: { has: "song", - "song][title][like": filter.firstLetter ? `${filter.firstLetter}%` : null, + "song][title-like": filter.firstLetter ? `${filter.firstLetter}%` : null, type: filter.type }, sortBy: searchQuery ? null : filter.sortBy diff --git a/src/hooks/useImage.js b/src/hooks/useImage.js index f2daafc..91a6a01 100644 --- a/src/hooks/useImage.js +++ b/src/hooks/useImage.js @@ -22,8 +22,6 @@ export default function useImage(resourceWithImages) { } useImage.fragment = gql` - #graphql - fragment useImage_resourceWithImages on ResourceWithImages { images { link diff --git a/src/lib/server/animethemes/resolvers.js b/src/lib/server/animethemes/resolvers.js index 0610a1c..7c0fb9b 100644 --- a/src/lib/server/animethemes/resolvers.js +++ b/src/lib/server/animethemes/resolvers.js @@ -1,370 +1,506 @@ -const { videoSource, imageFacet, animeSeason, resourceSite, themeType, videoOverlap } = require("lib/server/animethemes/enums"); +const pLimit = require("p-limit"); +const { parseResolveInfo } = require("graphql-parse-resolve-info"); +const devLog = require("utils/devLog"); -const knex = require("knex")({ - client: "mysql2", - connection: { - host: process.env.DB_HOST || "127.0.0.1", - port: process.env.DB_PORT || 3306, - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_DATABASE || "animethemes" +const limit = pLimit(5); + +const API_BASE_URL = `${process.env.ANIMETHEMES_API_URL}/api`; + +const INCLUDES = { + Anime: { + synonyms: "animesynonyms", + themes: "animethemes", + series: "series", + studios: "studios", + resources: "resources", + images: "images" + }, + Theme: { + song: "song", + anime: "anime", + entries: "animethemeentries" + }, + Artist: { + performances: "songs", + resources: "resources", + images: "images", + groups: "groups", + members: "members" + }, + Song: { + themes: "animethemes", + performances: "artists" + }, + Entry: { + videos: "videos", + theme: "animetheme" + }, + Video: { + entries: "animethemeentries" + }, + Series: { + anime: "anime" + }, + Studio: { + anime: "anime", + resources: "resources" + }, + ResourceWithImages: { + images: "images" + }, + Performance: { + song: "_", + artist: "_" } -}); +}; + +const ALLOWED_INCLUDES = { + Anime: [ + "animesynonyms", + "series", + "animethemes.song.artists", + "animethemes.song.artists.images", + "images", + "resources", + "studios", + "animethemes.animethemeentries.videos.animethemeentries.animetheme.anime", + "animethemes.animethemeentries.videos.animethemeentries.animetheme.anime.images", + "animethemes.animethemeentries.videos.animethemeentries.animetheme.animethemeentries.videos", + "animethemes.animethemeentries.videos.animethemeentries.animetheme.song.artists" + ], + Theme: [ + "anime.images", + "animethemeentries.videos", + "song.artists" + ], + Artist: [ + "songs.animethemes.anime", + "members", + "groups", + "resources", + "images", + "songs.artists", + "songs.animethemes.song", + "songs.animethemes.song.artists", + "songs.animethemes.anime.images", + "songs.animethemes.animethemeentries", + "songs.animethemes.animethemeentries.videos" + ], + Series: [ + "anime", + "anime.images", + "anime.animethemes.animethemeentries.videos", + "anime.animethemes.song" + ], + Studio: [ + "anime", + "anime.images", + "anime.animethemes.animethemeentries.videos", + "anime.animethemes.song", + "resources" + ], + Song: [ + "animethemes.anime", + "artists" + ], + Video: [ + "animethemeentries.animetheme.anime" + ] +}; module.exports = { Query: { - anime: (_, { id, slug }) => knex("anime") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("anime_id", id); - } - if (slug) { - builder.where("slug", slug); - } - }) - .first(), - animeAll: (_, { limit, year, season }) => { - const query = knex("anime"); - - query.where("deleted_at", null); - - if (year) { - query.where("year", year); - } - if (season) { - query.where( - "season", - [ ...animeSeason.values() ] - .findIndex((seasonName) => seasonName.toLowerCase() === season.toLowerCase()) - ); - } - - if (limit) { - query.limit(limit); - } - - return query.select(); - }, - theme: (_, { id }) => knex("anime_themes") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("theme_id", id); - } - }) - .first(), - themeAll: (_, { limit, orderBy, orderDesc }) => { - const query = knex("anime_themes"); - - query.where("deleted_at", null); - - if (orderBy) { - query.orderBy(orderBy, orderDesc ? "desc" : "asc"); - } - - if (limit) { - query.limit(limit); - } - - return query.select(); - }, - artist: (_, { id, slug }) => knex("artists") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("artist_id", id); - } - if (slug) { - builder.where("slug", slug); - } - }) - .first(), - artistAll: (_, { limit }) => { - const query = knex("artists"); - - query.where("deleted_at", null); - - if (limit) { - query.limit(limit); - } - - return query.select(); - }, - series: (_, { id, slug }) => knex("series") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("series_id", id); - } - if (slug) { - builder.where("slug", slug); - } - }) - .first(), - seriesAll: (_, { limit }) => { - const query = knex("series"); - - query.where("deleted_at", null); - - if (limit) { - query.limit(limit); - } - - return query.select(); - }, - studio: (_, { id, slug }) => knex("studios") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("studio_id", id); - } - if (slug) { - builder.where("slug", slug); - } - }) - .first(), - studioAll: (_, { limit }) => { - const query = knex("studios"); - - query.where("deleted_at", null); - - if (limit) { - query.limit(limit); - } - - return query.select(); - }, - year: (_, { value }) => ({ value }), - yearAll: () => knex("anime") - .where("deleted_at", null) - .groupBy("year") - .select("year") - .then((results) => results.map((anime) => ({ value: anime.year }))), - season: (_, { value, year }) => ({ - value: [ ...animeSeason.values() ] - .findIndex((seasonName) => seasonName.toLowerCase() === value.toLowerCase()), - year: { value: year } + anime: apiResolver({ + endpoint: (_, { slug }) => `/anime/${slug}`, + extractor: (result) => result.anime + }), + animeAll: apiResolver({ + endpoint: () => `/anime`, + extractor: (result) => result.anime, + pagination: true + }), + theme: apiResolver({ + endpoint: (_, { id }) => `/animetheme/${id}`, + extractor: (result) => result.animetheme + }), + themeAll: apiResolver({ + endpoint: (_, { limit, orderBy, orderDesc }) => `/animetheme?sort=${orderDesc ? "-" : ""}${orderBy}&page[size]=${limit}`, + extractor: (result) => result.animethemes + }), + artist: apiResolver({ + endpoint: (_, { slug }) => `/artist/${slug}`, + extractor: (result) => result.artist + }), + artistAll: apiResolver({ + endpoint: () => `/artist`, + extractor: (result) => result.artists, + pagination: true + }), + series: apiResolver({ + endpoint: (_, { slug }) => `/series/${slug}`, + extractor: (result) => result.series + }), + seriesAll: apiResolver({ + endpoint: () => `/series`, + extractor: (result) => result.series, + pagination: true + }), + studio: apiResolver({ + endpoint: (_, { slug }) => `/studio/${slug}`, + extractor: (result) => result.studio + }), + studioAll: apiResolver({ + endpoint: () => `/studio`, + extractor: (result) => result.studios, + pagination: true + }), + year: (_, { value }) => ({ value }), + yearAll: apiResolver({ + endpoint: () => `/animeyear`, + transformer: (yearList) => yearList.map((year) => ({ value: year })) + }), + season: (_, { year, value }) => ({ value, year: { value: year } }), + seasonAll: apiResolver({ + endpoint: (_, { year }) => `/animeyear/${year}`, + extractor: (result) => Object.keys(result), + transformer: (seasons, _, { year }) => seasons.map((season) => ({ value: season, year: { value: year } })) + }), + page: apiResolver({ + endpoint: (_, { slug }) => `/page/${slug}`, + extractor: (result) => result.page + }), + pageAll: apiResolver({ + endpoint: () => `/page`, + extractor: (result) => result.pages, + pagination: true }), - seasonAll: (_, { year }) => knex("anime") - .where((builder) => { - builder.where("deleted_at", null); - if (year) { - builder.where("year", year); - } - }) - .groupBy([ "season", "year" ]) - .select([ "season", "year" ]) - .then((results) => results.map((anime) => ({ value: anime.season, year: { value: year } }))), - page: (_, { id, slug }) => knex("pages") - .where((builder) => { - builder.where("deleted_at", null); - if (id) { - builder.where("page_id", id); - } - if (slug) { - builder.where("slug", slug); - } - }) - .first(), - pageAll: () => { - const query = knex("pages"); - - query.where("deleted_at", null); - - return query.select(); - }, counter: () => ({}) }, Year: { - seasons: (year) => knex("anime") - .where("deleted_at", null) - .where("year", year.value) - .groupBy("season") - .select("season") - .then((results) => results.map((anime) => ({ value: anime.season, year }))), + seasons: apiResolver({ + endpoint: (year) => `/animeyear/${year.value}`, + extractor: (result) => Object.keys(result), + transformer: (seasons, year) => seasons.map((season) => ({ value: season, year })) + }), }, Season: { - value: (season) => animeSeason.get(season.value), - anime: (season) => knex("anime") - .where((builder) => { - builder.where("deleted_at", null); - - builder.where("season", season.value); - - if (season.year) { - builder.where("year", season.year.value); - } - }) - .select(), + anime: apiResolver({ + endpoint: (season) => `/anime?filter[year]=${season.year.value}&filter[season]=${season.value}`, + extractor: (result) => result.anime, + pagination: true + }), }, Counter: { - anime: () => knex("anime").where("deleted_at", null).count({ count: "*" }).first().then((first) => first.count), - artist: () => knex("artists").where("deleted_at", null).count({ count: "*" }).first().then((first) => first.count), - series: () => knex("series").where("deleted_at", null).count({ count: "*" }).first().then((first) => first.count), - studio: () => knex("studios").where("deleted_at", null).count({ count: "*" }).first().then((first) => first.count), - video: () => knex("videos").where("deleted_at", null).count({ count: "*" }).first().then((first) => first.count), - year: () => knex("anime").where("deleted_at", null).countDistinct({ count: "year" }).first().then((first) => first.count), - season: () => knex("anime").where("deleted_at", null).countDistinct({ count: [ "year", "season" ] }).first().then((first) => first.count) + anime: () => 0, + artist: () => 0, + series: () => 0, + studio: () => 0, + video: () => 0, + year: () => 0, + season: () => 0, }, Anime: { - id: (anime) => anime.anime_id, - season: (anime) => animeSeason.get(anime.season), - synonyms: (anime) => knex("anime_synonyms").where("deleted_at", null).where({ anime_id: anime.anime_id }).select(), - themes: (anime) => knex("anime_themes").where("deleted_at", null).where({ anime_id: anime.anime_id }).select(), - series: (anime) => knex("series") - .innerJoin("anime_series", "anime_series.series_id", "series.series_id") - .where("deleted_at", null) - .where({ "anime_series.anime_id": anime.anime_id }) - .select("series.*"), - studios: (anime) => knex("studios") - .innerJoin("anime_studio", "anime_studio.studio_id", "studios.studio_id") - .where("deleted_at", null) - .where({ "anime_studio.anime_id": anime.anime_id }) - .select("studios.*"), - resources: (anime) => knex("resources") - .innerJoin("anime_resource", "anime_resource.resource_id", "resources.resource_id") - .where("deleted_at", null) - .where({ "anime_resource.anime_id": anime.anime_id }) - .select("resources.*"), - images: (anime) => knex("images") - .innerJoin("anime_image", "anime_image.image_id", "images.image_id") - .where("deleted_at", null) - .where({ "anime_image.anime_id": anime.anime_id }) - .select("images.*") + synonyms: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "animesynonyms", + extractor: (result) => result.anime.animesynonyms, + type: "Anime", + baseInclude: INCLUDES.Anime.synonyms + }), + themes: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "animethemes", + extractor: (result) => result.anime.animethemes, + transformer: (themes, anime) => themes.map((theme) => ({ ...theme, anime })), + type: "Anime", + baseInclude: INCLUDES.Anime.themes + }), + series: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "series", + extractor: (result) => result.anime.series, + type: "Anime", + baseInclude: INCLUDES.Anime.series + }), + studios: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "studios", + extractor: (result) => result.anime.studios, + type: "Anime", + baseInclude: INCLUDES.Anime.studios + }), + resources: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "resources", + extractor: (result) => result.anime.resources, + type: "Anime", + baseInclude: INCLUDES.Anime.resources + }), + images: apiResolver({ + endpoint: (anime) => `/anime/${anime.slug}`, + field: "images", + extractor: (result) => result.anime.images, + type: "Anime", + baseInclude: INCLUDES.Anime.images + }), }, Theme: { - id: (theme) => theme.theme_id, - type: (theme) => themeType.get(theme.type), sequence: (theme) => theme.sequence || 0, - song: (theme) => knex("songs").where("deleted_at", null).where({ song_id: theme.song_id }).first(), - anime: (theme) => knex("anime").where("deleted_at", null).where({ anime_id: theme.anime_id }).first(), - entries: (theme) => knex("anime_theme_entries").where("deleted_at", null).where({ theme_id: theme.theme_id }).select() + song: apiResolver({ + endpoint: (theme) => `/animetheme/${theme.id}`, + field: "song", + extractor: (result) => result.animetheme.song, + type: "Theme", + baseInclude: INCLUDES.Theme.song + }), + anime: apiResolver({ + endpoint: (theme) => `/animetheme/${theme.id}`, + field: "anime", + extractor: (result) => result.animetheme.anime, + type: "Theme", + baseInclude: INCLUDES.Theme.anime + }), + entries: apiResolver({ + endpoint: (theme) => `/animetheme/${theme.id}`, + field: "animethemeentries", + extractor: (result) => result.animetheme.animethemeentries, + type: "Theme", + baseInclude: INCLUDES.Theme.entries + }), }, Artist: { - performances: (artist) => knex("artist_song") - .innerJoin("songs", "artist_song.song_id", "songs.song_id") - .where("deleted_at", null) - .where({ "artist_song.artist_id": artist.artist_id }) - .select("artist_song.*"), - resources: (artist) => knex("resources") - .innerJoin("artist_resource", "artist_resource.resource_id", "resources.resource_id") - .where("deleted_at", null) - .where({ "artist_resource.artist_id": artist.artist_id }) - .select("resources.*"), - images: (artist) => knex("images") - .innerJoin("artist_image", "artist_image.image_id", "images.image_id") - .where("deleted_at", null) - .where({ "artist_image.artist_id": artist.artist_id }) - .select("images.*"), - groups: (artist) => knex("artists") - .innerJoin("artist_member", "artist_member.artist_id", "artists.artist_id") - .where("deleted_at", null) - .where({ "artist_member.member_id": artist.artist_id }) - .select("artist_member.*"), - members: (artist) => knex("artists") - .innerJoin("artist_member", "artist_member.member_id", "artists.artist_id") - .where("deleted_at", null) - .where({ "artist_member.artist_id": artist.artist_id }) - .select("artist_member.*") - }, - ArtistMembership: { - group: (membership) => knex("artists").where("deleted_at", null).where({ artist_id: membership.artist_id }).first(), - member: (membership) => knex("artists").where("deleted_at", null).where({ artist_id: membership.member_id }).first(), + performances: apiResolver({ + endpoint: (artist) => `/artist/${artist.slug}`, + field: "songs", + extractor: (result) => result.artist.songs, + transformer: (songs, artist) => songs.map(({ as, ...song }) => ({ as, song, artist })), + type: "Artist", + baseInclude: INCLUDES.Artist.performances + }), + resources: apiResolver({ + endpoint: (artist) => `/artist/${artist.slug}`, + field: "resources", + extractor: (result) => result.artist.resources, + type: "Artist", + baseInclude: INCLUDES.Artist.resources + }), + images: apiResolver({ + endpoint: (artist) => `/artist/${artist.slug}`, + field: "images", + extractor: (result) => result.artist.images, + type: "Artist", + baseInclude: INCLUDES.Artist.images + }), + groups: apiResolver({ + endpoint: (artist) => `/artist/${artist.slug}`, + field: "groups", + extractor: (result) => result.artist.groups, + transformer: (groups, artist) => groups.map((group) => ({ group, member: artist })), + type: "Artist", + baseInclude: INCLUDES.Artist.groups + }), + members: apiResolver({ + endpoint: (artist) => `/artist/${artist.slug}`, + field: "members", + extractor: (result) => result.artist.members, + transformer: (members, artist) => members.map((member) => ({ member, group: artist })), + type: "Artist", + baseInclude: INCLUDES.Artist.members + }), }, Song: { - themes: (song) => knex("anime_themes").where("deleted_at", null).where({ song_id: song.song_id }).select(), - performances: (song) => knex("artist_song") - .innerJoin("artists", "artist_song.artist_id", "artists.artist_id") - .where("deleted_at", null) - .where({ "artist_song.song_id": song.song_id }) - .select("artist_song.*"), - }, - Performance: { - artist: (performance) => knex("artists").where("deleted_at", null).where({ artist_id: performance.artist_id }).first(), - song: (performance) => knex("songs").where("deleted_at", null).where({ song_id: performance.song_id }).first() + themes: apiResolver({ + endpoint: (song) => `/song/${song.id}`, + field: "animethemes", + extractor: (result) => result.song.animethemes, + type: "Song", + baseInclude: INCLUDES.Song.themes + }), + performances: apiResolver({ + endpoint: (song) => `/song/${song.id}`, + field: "artists", + extractor: (result) => result.song.artists, + transformer: (artists, song) => artists.map(({ as, ...artist }) => ({ as, artist, song })), + type: "Song", + baseInclude: INCLUDES.Song.performances + }), }, Entry: { version: (entry) => entry.version || 1, - videos: (entry) => knex("videos") - .innerJoin("anime_theme_entry_video", "anime_theme_entry_video.video_id", "videos.video_id") - .where("deleted_at", null) - .where({ "anime_theme_entry_video.entry_id": entry.entry_id }) - .select("videos.*"), - theme: (entry) => knex("anime_themes").where("deleted_at", null).where({ theme_id: entry.theme_id }).first(), + videos: apiResolver({ + endpoint: (entry) => `/animethemeentry/${entry.id}`, + field: "videos", + extractor: (result) => result.animethemeentry.videos, + type: "Entry", + baseInclude: INCLUDES.Entry.videos + }), + theme: apiResolver({ + endpoint: (entry) => `/animethemeentry/${entry.id}`, + field: "animetheme", + extractor: (result) => result.animethemeentry.animetheme, + type: "Entry", + baseInclude: INCLUDES.Entry.theme + }), }, Video: { - source: (video) => videoSource.get(video.source), - overlap: (video) => videoOverlap.get(video.overlap), - tags: (video) => { - const tags = []; - - if (video.nc) { - tags.push("NC"); - } - if (video.source === 2 || video.source === 3) { - tags.push(videoSource.get(video.source)); - } - if (video.resolution && video.resolution !== 720) { - tags.push(video.resolution); - } - - if (video.subbed) { - tags.push("Subbed"); - } else if (video.lyrics) { - tags.push("Lyrics"); - } - - return tags.join(""); - }, - entries: (video) => knex("anime_theme_entries") - .innerJoin("anime_theme_entry_video", "anime_theme_entry_video.entry_id", "anime_theme_entries.entry_id") - .where("deleted_at", null) - .where({ "anime_theme_entry_video.video_id": video.video_id }) - .select("anime_theme_entries.*") - }, - Image: { - facet: (image) => imageFacet.get(image.facet), - link: (image) => `https://animethemes-stag-images.fra1.cdn.digitaloceanspaces.com/${image.path}` - }, - Resource: { - site: (resource) => resourceSite.get(resource.site) + entries: apiResolver({ + endpoint: (video) => `/video/${video.basename}`, + field: "animethemeentries", + extractor: (result) => result.video.animethemeentries, + type: "Video", + baseInclude: INCLUDES.Video.entries + }), }, Series: { - anime: (series) => knex("anime") - .innerJoin("anime_series", "anime_series.anime_id", "anime.anime_id") - .where("deleted_at", null) - .where({ "anime_series.series_id": series.series_id }) - .select("anime.*") + anime: apiResolver({ + endpoint: (series) => `/series/${series.slug}`, + field: "anime", + extractor: (result) => result.series.anime, + type: "Series", + baseInclude: INCLUDES.Series.anime + }), }, Studio: { - anime: (studio) => knex("anime") - .innerJoin("anime_studio", "anime_studio.anime_id", "anime.anime_id") - .where("deleted_at", null) - .where({ "anime_studio.studio_id": studio.studio_id }) - .select("anime.*"), - resources: (studio) => knex("resources") - .innerJoin("studio_resource", "studio_resource.resource_id", "resources.resource_id") - .where("deleted_at", null) - .where({ "studio_resource.studio_id": studio.studio_id }) - .select("resources.*") + anime: apiResolver({ + endpoint: (studio) => `/studio/${studio.slug}`, + field: "anime", + extractor: (result) => result.studio.anime, + type: "Studio", + baseInclude: INCLUDES.Studio.anime + }), + resources: apiResolver({ + endpoint: (studio) => `/studio/${studio.slug}`, + field: "resources", + extractor: (result) => result.studio.resources, + type: "Studio", + baseInclude: INCLUDES.Studio.resources + }), }, BracketCharacter: { - theme: (character) => knex("anime_themes") - .where("deleted_at", null) - .where("theme_id", character.theme) - .first() + theme: apiResolver({ + endpoint: (character) => `/animetheme/${character.theme}`, + extractor: (result) => result.animetheme + }), }, AnimeListEntry: { - anime: (animeListEntry, _, context) => knex("anime") - .innerJoin("anime_resource", "anime_resource.anime_id", "anime.anime_id") - .innerJoin("resources", "resources.resource_id", "anime_resource.resource_id") - .where({ - "anime.deleted_at": null, - "resources.deleted_at": null, - "resources.site": context.externalSite, - "resources.external_id": animeListEntry.externalId - }) - .first("anime.*") + anime: () => null, } }; + +function apiResolver(config) { + const { + endpoint, + field, + extractor = (a) => a, + transformer = (a) => a, + pagination = false, + type: defaultType = null, + baseInclude = null + } = config; + + return async (parent, args, context, info) => { + if (field && parent[field] !== undefined) { + return transformer(parent[field], parent, args); + } + + const type = defaultType || info.returnType.name || info.returnType.ofType.name; + const path = pathToString(info.path); + + if (info.path.prev) { + devLog.warn(`Deep fetch at: ${path}`); + } + + let url = `${API_BASE_URL}${endpoint(parent, args)}`; + + const includes = getIncludes(info, baseInclude); + if (baseInclude) { + includes.push(baseInclude); + } + const allowedIncludes = includes + // Remove includes that are not allowed by the API + .filter((include) => ALLOWED_INCLUDES[type]?.find((allowedInclude) => allowedInclude === include || allowedInclude.startsWith(include + "."))) + // Remove includes which are already included with another include + .filter((include, _, includes) => !includes.find((otherInclude) => otherInclude.startsWith(include + "."))) + // Remove duplicates + .filter((include, index, includes) => includes.lastIndexOf(include) === index); + const disallowedIncludes = includes.filter((include) => !ALLOWED_INCLUDES[type]?.find((allowedInclude) => allowedInclude === include || allowedInclude.startsWith(include + "."))); + + if (disallowedIncludes.length) { + devLog.warn(`Disallowed includes for ${url}:`); + devLog.warn(disallowedIncludes); + devLog.warn(`Or at least:`); + devLog.warn(disallowedIncludes.filter((include, _, includes) => !includes.find((otherInclude) => otherInclude.startsWith(include + ".")))); + } + + if (allowedIncludes.length) { + url += `${url.includes("?") ? "&" : "?"}include=${allowedIncludes.join()}`; + } + + devLog.info(path + ": " + url); + + return await limit(() => (async () => { + if (!pagination) { + const json = await fetchJson(url); + + return transformer(extractor(json, parent, args), parent, args); + } else { + devLog.info(`Collecting: ${url}`); + const results = []; + let nextUrl = `${url}${url.includes("?") ? "&" : "?"}page[size]=100`; + while (nextUrl) { + const json = await fetchJson(nextUrl); + results.push(...transformer(extractor(json, parent, args), parent, args)); + devLog.info(`Collecting: ${url}, Got ${results.length}`); + nextUrl = json.links.next; + } + + return results; + } + })()); + }; +} + +async function fetchJson(url) { + const response = await fetch(url, { + headers: { + Authorization: `Bearer ${process.env.ANIMETHEMES_API_KEY}` + } + }); + if (!response.ok) { + throw new Error(`API returned with non-ok status code: ${response.status} (${response.statusText})`); + } + return await response.json(); +} + +function pathToString(path) { + let parts = []; + for (let part = path; part; part = part.prev) { + parts.push(part.key); + } + return parts.reverse().join("."); +} + +function getIncludes(info, baseInclude = null) { + const infoFragment = parseResolveInfo(info); + return getIncludesRecursive(infoFragment, baseInclude ? (baseInclude + ".") : ""); +} + +function getIncludesRecursive(infoFragment, parent = "") { + const includes = []; + + for (const [type, fields] of Object.entries(infoFragment.fieldsByTypeName)) { + for (const [fieldName, field] of Object.entries(fields)) { + if (INCLUDES[type]?.[fieldName]) { + if (INCLUDES[type][fieldName] === "_") { + includes.push(...getIncludesRecursive(field, parent)); + } else { + const include = parent + INCLUDES[type][fieldName]; + includes.push(include); + includes.push(...getIncludesRecursive(field, include + ".")); + } + } + } + } + + return includes; +} diff --git a/src/lib/server/index.js b/src/lib/server/index.js index 9f6872a..de59f98 100644 --- a/src/lib/server/index.js +++ b/src/lib/server/index.js @@ -1,21 +1,29 @@ -const { graphql, print } = require("graphql"); -const { makeExecutableSchema } = require("@graphql-tools/schema"); -const { mergeTypeDefs, mergeResolvers } = require("@graphql-tools/merge"); +import { graphql, print } from "graphql"; +import { makeExecutableSchema } from "@graphql-tools/schema"; +import { mergeResolvers, mergeTypeDefs } from "@graphql-tools/merge"; + +import typeDefsAnimeThemes from "lib/server/animethemes/type-defs"; +import typeDefsAnimeBracket from "lib/server/animebracket/type-defs"; +import typeDefsAnimeList from "lib/server/animelist/type-defs"; + +import resolversAnimeThemes from "lib/server/animethemes/resolvers"; +import resolversAnimeBracket from "lib/server/animebracket/resolvers"; +import resolversAnimeList from "lib/server/animelist/resolvers"; const schema = makeExecutableSchema({ typeDefs: mergeTypeDefs([ - require("lib/server/animethemes/type-defs"), - require("lib/server/animebracket/type-defs"), - require("lib/server/animelist/type-defs") + typeDefsAnimeThemes, + typeDefsAnimeBracket, + typeDefsAnimeList ]), resolvers: mergeResolvers([ - require("lib/server/animethemes/resolvers"), - require("lib/server/animebracket/resolvers"), - require("lib/server/animelist/resolvers") + resolversAnimeThemes, + resolversAnimeBracket, + resolversAnimeList ]) }); -exports.fetchData = async (query, args = {}) => { +export async function fetchData(query, args = {}) { const result = await graphql(schema, typeof query === "string" ? query : print(query), null, {}, args); if (result.errors) { @@ -23,4 +31,4 @@ exports.fetchData = async (query, args = {}) => { } return result; -}; +} diff --git a/src/pages/anime/[animeSlug]/[videoSlug]/index.js b/src/pages/anime/[animeSlug]/[videoSlug]/index.js index 7967f22..d7e5dd6 100644 --- a/src/pages/anime/[animeSlug]/[videoSlug]/index.js +++ b/src/pages/anime/[animeSlug]/[videoSlug]/index.js @@ -17,6 +17,7 @@ import styled from "styled-components"; import theme from "theme"; import createVideoSlug from "utils/createVideoSlug"; import gql from "graphql-tag"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const StyledVideoInfo = styled.div` display: grid; @@ -106,7 +107,7 @@ export default function VideoPage({ anime, theme, entry, video }) { ] }); } - }, [ anime, theme, smallCover ]); + }, [ anime, theme, smallCover, songTitle ]); const otherEntries = theme.entries.map(otherEntry => { const videos = otherEntry.videos.filter((otherVideo) => otherVideo.filename !== video.filename); @@ -388,44 +389,46 @@ export async function getStaticProps({ params: { animeSlug, videoSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - animeAll { - slug - themes { + return fetchStaticPaths(async (isStaging) => { + const { data } = await fetchData(gql` + query { + animeAll { slug - entries { - id - version - videos { + themes { + slug + entries { id - tags + version + videos { + id + tags + } } } } } - } - `); + `); - const paths = data.animeAll.flatMap( - (anime) => anime.themes.flatMap( - (theme) => theme.entries.flatMap( - (entry) => entry.videos.flatMap( - (video) => ({ - params: { - animeSlug: anime.slug, - videoSlug: createVideoSlug(theme, entry, video) - } - }) + let anime = data.animeAll; + + if (isStaging) { + // In staging, we only want to pre-render the video pages for the neweset 100 anime. + anime = anime.sort((a, b) => b.id - a.id).slice(0, 100); + } + + return anime.flatMap( + (anime) => anime.themes.flatMap( + (theme) => theme.entries.flatMap( + (entry) => entry.videos.flatMap( + (video) => ({ + params: { + animeSlug: anime.slug, + videoSlug: createVideoSlug(theme, entry, video) + } + }) + ) ) ) - ) - ); - - return { - paths, - fallback: "blocking" - }; + ); + }); } diff --git a/src/pages/anime/[animeSlug]/index.js b/src/pages/anime/[animeSlug]/index.js index 59611ae..ecb3a8d 100644 --- a/src/pages/anime/[animeSlug]/index.js +++ b/src/pages/anime/[animeSlug]/index.js @@ -14,6 +14,8 @@ import { fetchData } from "lib/server"; import { SEO } from "components/seo"; import useImage from "hooks/useImage"; import { resourceSiteComparator, seriesNameComparator, studioNameComparator } from "utils/comparators"; +import fetchStaticPaths from "utils/fetchStaticPaths"; +import gql from "graphql-tag"; const StyledList = styled.div` display: flex; @@ -212,24 +214,27 @@ export async function getStaticProps({ params: { animeSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - animeAll { - slug + return fetchStaticPaths(async (isStaging) => { + const { data } = await fetchData(gql` + query { + animeAll { + id + slug + } } - } - `); + `); - const paths = data.animeAll.map((anime) => ({ - params: { - animeSlug: anime.slug - } - })); + let anime = data.animeAll; - return { - paths, - fallback: "blocking" - }; + if (isStaging) { + // In staging, we only want to pre-render the newest 100 anime pages. + anime = anime.sort((a, b) => b.id - a.id).slice(0, 100); + } + + return anime.map((anime) => ({ + params: { + animeSlug: anime.slug + } + })); + }); } diff --git a/src/pages/artist/[artistSlug]/index.js b/src/pages/artist/[artistSlug]/index.js index 65dd6ba..7c8afbb 100644 --- a/src/pages/artist/[artistSlug]/index.js +++ b/src/pages/artist/[artistSlug]/index.js @@ -27,6 +27,7 @@ import { fetchData } from "lib/server"; import { SEO } from "components/seo"; import useImage from "hooks/useImage"; import gql from "graphql-tag"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const StyledList = styled.div` display: flex; @@ -248,24 +249,19 @@ export async function getStaticProps({ params: { artistSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - artistAll { - slug + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + artistAll { + slug + } } - } - `); + `); - const paths = data.artistAll.map((artist) => ({ - params: { - artistSlug: artist.slug - } - })); - - return { - paths, - fallback: "blocking" - }; + return data.artistAll.map((artist) => ({ + params: { + artistSlug: artist.slug + } + })); + }); } diff --git a/src/pages/index.js b/src/pages/index.js index 4457768..5e92ad8 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -198,10 +198,10 @@ export async function getStaticProps() { ${ThemeSummaryCard.fragments.theme} query { - featuredTheme: theme(id: 10968) { + featuredTheme: theme(id: 11388) { ...FeaturedTheme_theme } - recentlyAdded: themeAll(orderBy: "theme_id", orderDesc: true, limit: 10) { + recentlyAdded: themeAll(orderBy: "id", orderDesc: true, limit: 10) { ...ThemeSummaryCard_theme } } diff --git a/src/pages/page/[...pageSlug].js b/src/pages/page/[...pageSlug].js index 65f4328..b1c9b1b 100644 --- a/src/pages/page/[...pageSlug].js +++ b/src/pages/page/[...pageSlug].js @@ -10,6 +10,8 @@ import styled from "styled-components"; import { motion } from "framer-motion"; import theme from "theme"; import { SEO } from "components/seo"; +import fetchStaticPaths from "utils/fetchStaticPaths"; +import gql from "graphql-tag"; const StyledGrid = styled.div` display: flex; @@ -223,7 +225,7 @@ function TableOfContents({ headings }) { return ( {headings.map(({ text, slug, depth }) => ( - + {slug === currentSlug && ( )} @@ -266,24 +268,19 @@ export async function getStaticProps({ params: { pageSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - pageAll { - slug + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + pageAll { + slug + } } - } - `); + `); - const paths = data.pageAll.map((page) => ({ - params: { - pageSlug: page.slug.split("/") - } - })); - - return { - paths, - fallback: "blocking" - }; + return data.pageAll.map((page) => ({ + params: { + pageSlug: page.slug.split("/") + } + })); + }); } diff --git a/src/pages/series/[seriesSlug]/index.js b/src/pages/series/[seriesSlug]/index.js index 764c927..4825681 100644 --- a/src/pages/series/[seriesSlug]/index.js +++ b/src/pages/series/[seriesSlug]/index.js @@ -14,6 +14,7 @@ import { SEO } from "components/seo"; import theme from "theme"; import { MultiCoverImage } from "components/image"; import gql from "graphql-tag"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const StyledDesktopOnly = styled.div` gap: 24px; @@ -97,10 +98,6 @@ export async function getStaticProps({ params: { seriesSlug } }) { } } } - resources { - site - link - } images { facet link @@ -127,24 +124,19 @@ export async function getStaticProps({ params: { seriesSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - seriesAll { - slug + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + seriesAll { + slug + } } - } - `); + `); - const paths = data.seriesAll.map((series) => ({ - params: { - seriesSlug: series.slug - } - })); - - return { - paths, - fallback: "blocking" - }; + return data.seriesAll.map((series) => ({ + params: { + seriesSlug: series.slug + } + })); + }); } diff --git a/src/pages/studio/[studioSlug]/index.js b/src/pages/studio/[studioSlug]/index.js index 92a0307..5426f48 100644 --- a/src/pages/studio/[studioSlug]/index.js +++ b/src/pages/studio/[studioSlug]/index.js @@ -23,6 +23,7 @@ import { SEO } from "components/seo"; import theme from "theme"; import { MultiCoverImage } from "components/image"; import gql from "graphql-tag"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const StyledDesktopOnly = styled.div` @media (max-width: ${theme.breakpoints.tabletMax}) { @@ -127,10 +128,6 @@ export async function getStaticProps({ params: { studioSlug } }) { } } } - resources { - site - link - } images { facet link @@ -161,24 +158,19 @@ export async function getStaticProps({ params: { studioSlug } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - studioAll { - slug + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + studioAll { + slug + } } - } - `); + `); - const paths = data.studioAll.map((studio) => ({ - params: { - studioSlug: studio.slug - } - })); - - return { - paths, - fallback: "blocking" - }; + return data.studioAll.map((studio) => ({ + params: { + studioSlug: studio.slug + } + })); + }); } diff --git a/src/pages/year/[year]/[season]/index.js b/src/pages/year/[year]/[season]/index.js index bcc912e..e82efee 100644 --- a/src/pages/year/[year]/[season]/index.js +++ b/src/pages/year/[year]/[season]/index.js @@ -4,6 +4,7 @@ import { Column } from "components/box"; import { fetchData } from "lib/server"; import { SEO } from "components/seo"; import gql from "graphql-tag"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const seasonOrder = [ "Winter", "Spring", "Summer", "Fall" ]; @@ -82,30 +83,25 @@ export async function getStaticProps({ params: { year, season } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - yearAll { - value - seasons { + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + yearAll { value + seasons { + value + } } } - } - `); + `); - const paths = data.yearAll.flatMap( - (year) => year.seasons.map((season) => ({ - params: { - year: String(year.value), - season: season.value - } - })) - ); - - return { - paths, - fallback: "blocking" - }; + return data.yearAll.flatMap( + (year) => year.seasons.map((season) => ({ + params: { + year: String(year.value), + season: season.value + } + })) + ); + }); } diff --git a/src/pages/year/[year]/index.js b/src/pages/year/[year]/index.js index c0484ba..97ea0dd 100644 --- a/src/pages/year/[year]/index.js +++ b/src/pages/year/[year]/index.js @@ -9,6 +9,7 @@ import { fetchData } from "lib/server"; import { SEO } from "components/seo"; import gql from "graphql-tag"; import { ANIME_A_Z, getComparator } from "utils/comparators"; +import fetchStaticPaths from "utils/fetchStaticPaths"; const seasonOrder = [ "Winter", "Spring", "Summer", "Fall" ]; @@ -101,24 +102,19 @@ export async function getStaticProps({ params: { year } }) { } export async function getStaticPaths() { - const { data } = await fetchData(` - #graphql - - query { - yearAll { - value + return fetchStaticPaths(async () => { + const { data } = await fetchData(gql` + query { + yearAll { + value + } } - } - `); + `); - const paths = data.yearAll.map((year) => ({ - params: { - year: String(year.value) - } - })); - - return { - paths, - fallback: "blocking" - }; + return data.yearAll.map((year) => ({ + params: { + year: String(year.value) + } + })); + }); } diff --git a/src/utils/devLog.js b/src/utils/devLog.js new file mode 100644 index 0000000..9df4d6f --- /dev/null +++ b/src/utils/devLog.js @@ -0,0 +1,13 @@ +const log = require("next/dist/build/output/log"); + +const devLog = {}; + +for (const [name, fn] of Object.entries(log)) { + devLog[name] = (...args) => { + if (process.env.NODE_ENV === "development") { + fn(...args); + } + }; +} + +module.exports = devLog; diff --git a/src/utils/fetchStaticPaths.js b/src/utils/fetchStaticPaths.js new file mode 100644 index 0000000..81267b4 --- /dev/null +++ b/src/utils/fetchStaticPaths.js @@ -0,0 +1,18 @@ +export default async function fetchStaticPaths(fetchPaths) { + // In development all pages should be fetched on-demand. This speeds up page generation a lot. + if (process.env.NODE_ENV === "development") { + return { + paths: [], + fallback: "blocking" + }; + } + + const isStaging = !!process.env.NEXT_PUBLIC_STAGING; + + const paths = await fetchPaths(isStaging); + + return { + paths, + fallback: "blocking" + }; +}