From 10fd66591e280f3117b1fc41528d97dfaaf8f5f6 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Tue, 14 Nov 2023 22:43:29 -0600 Subject: [PATCH 1/8] Refactor first unstable_cache wrapper --- src/cache/index.ts | 10 ++++------ src/photo/index.ts | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/cache/index.ts b/src/cache/index.ts index cac60b6c..010979f6 100644 --- a/src/cache/index.ts +++ b/src/cache/index.ts @@ -143,13 +143,11 @@ export const getPhotosCached: typeof getPhotos = (...args) => } )().then(parseCachedPhotosDates); -export const getPhotosCountCached: typeof getPhotosCount = (...args) => +export const getPhotosCountCached = unstable_cache( - () => getPhotosCount(...args), - [KEY_PHOTOS, KEY_PHOTOS_COUNT], { - tags: [KEY_PHOTOS, KEY_PHOTOS_COUNT], - } - )(); + (...args: Parameters) => getPhotosCount(...args), + [KEY_PHOTOS, KEY_PHOTOS_COUNT], + ); export const getPhotosCountIncludingHiddenCached: typeof getPhotosCount = (...args) => diff --git a/src/photo/index.ts b/src/photo/index.ts index d92b35c0..dbf4e160 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -97,7 +97,7 @@ export const parseCachedPhotoDates = (photo: Photo) => ({ takenAt: new Date(photo.takenAt), updatedAt: new Date(photo.updatedAt), createdAt: new Date(photo.createdAt), -}); +} as Photo); export const parseCachedPhotosDates = (photos: Photo[]) => photos.map(parseCachedPhotoDates); From 9fedfd5149ce04a94c56ed325472b2fcc6c99361 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Wed, 15 Nov 2023 09:34:57 -0600 Subject: [PATCH 2/8] Moved more functions to unstable_cache format --- src/app/(auth-state)/admin/photos/page.tsx | 2 +- src/app/(auth-state)/admin/tags/page.tsx | 2 +- .../(auth-state)/admin/uploads/blob/route.tsx | 6 +- src/app/(auth-state)/admin/uploads/page.tsx | 2 +- src/cache/index.ts | 73 ++++++------------- src/photo/actions.ts | 2 - 6 files changed, 30 insertions(+), 57 deletions(-) diff --git a/src/app/(auth-state)/admin/photos/page.tsx b/src/app/(auth-state)/admin/photos/page.tsx index b2e121dd..15f2f489 100644 --- a/src/app/(auth-state)/admin/photos/page.tsx +++ b/src/app/(auth-state)/admin/photos/page.tsx @@ -33,7 +33,7 @@ import IconGrSync from '@/site/IconGrSync'; const DEBUG_PHOTO_BLOBS = false; -export default async function AdminTagsPage({ +export default async function AdminPhotosPage({ searchParams, }: PaginationParams) { const { offset, limit } = getPaginationForSearchParams(searchParams); diff --git a/src/app/(auth-state)/admin/tags/page.tsx b/src/app/(auth-state)/admin/tags/page.tsx index 0e29cfdb..4fc1b4a6 100644 --- a/src/app/(auth-state)/admin/tags/page.tsx +++ b/src/app/(auth-state)/admin/tags/page.tsx @@ -14,7 +14,7 @@ import { cc } from '@/utility/css'; export const runtime = 'edge'; -export default async function AdminPhotosPage() { +export default async function AdminTagsPage() { const tags = await getUniqueTagsHiddenCached(); return ( diff --git a/src/app/(auth-state)/admin/uploads/blob/route.tsx b/src/app/(auth-state)/admin/uploads/blob/route.tsx index 74cabd12..63574982 100644 --- a/src/app/(auth-state)/admin/uploads/blob/route.tsx +++ b/src/app/(auth-state)/admin/uploads/blob/route.tsx @@ -1,4 +1,4 @@ -import { revalidatePhotosAndBlobKeys, revalidateAdminPaths } from '@/cache'; +import { revalidateAdminPaths, revalidatePhotosKey } from '@/cache'; import { ACCEPTED_PHOTO_FILE_TYPES } from '@/photo'; import { isUploadPathnameValid } from '@/services/blob'; import { handleUpload, type HandleUploadBody } from '@vercel/blob/client'; @@ -25,11 +25,11 @@ export async function POST(request: Request): Promise { }, // This argument is required, but doesn't seem to fire onUploadCompleted: async () => { - revalidatePhotosAndBlobKeys(); + revalidatePhotosKey(); revalidateAdminPaths(); }, }); - revalidatePhotosAndBlobKeys(); + revalidatePhotosKey(); revalidateAdminPaths(); return NextResponse.json(jsonResponse); } catch (error) { diff --git a/src/app/(auth-state)/admin/uploads/page.tsx b/src/app/(auth-state)/admin/uploads/page.tsx index 2a481463..9e4e281a 100644 --- a/src/app/(auth-state)/admin/uploads/page.tsx +++ b/src/app/(auth-state)/admin/uploads/page.tsx @@ -2,7 +2,7 @@ import BlobUrls from '@/admin/BlobUrls'; import { getBlobUploadUrlsNoStore } from '@/cache'; import SiteGrid from '@/components/SiteGrid'; -export default async function UploadsPage() { +export default async function AdminUploadsPage() { const blobUrls = await getBlobUploadUrlsNoStore(); return ( { const getPhotoCacheKey = (photoId: string) => `photo-${photoId}`; -const getPhotoTagCountKey = (tag: string) => - `${KEY_PHOTOS_COUNT}-${KEY_TAGS}-${tag}`; - const getPhotoCameraCountKey = (camera: Camera) => - `${KEY_PHOTOS_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`; + `${KEY_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`; const getPhotoFilmSimulationCountKey = (simulation: FilmSimulation) => - `${KEY_PHOTOS_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`; + `${KEY_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`; const getPhotoTagDateRangeKey = (tag: string) => - `${KEY_PHOTOS_DATE_RANGE}-${KEY_TAGS}-${tag}`; + `${KEY_DATE_RANGE}-${KEY_TAGS}-${tag}`; const getPhotoCameraDateRangeKey = (camera: Camera) => - `${KEY_PHOTOS_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`; + `${KEY_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`; const getPhotoFilmSimulationDateRangeKey = (simulation: FilmSimulation) => - `${KEY_PHOTOS_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`; + `${KEY_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`; export const revalidatePhotosKey = () => revalidateTag(KEY_PHOTOS); @@ -111,16 +109,8 @@ export const revalidateCamerasKey = () => export const revalidateFilmSimulationsKey = () => revalidateTag(KEY_FILM_SIMULATIONS); -export const revalidateBlobKey = () => - revalidateTag(KEY_BLOB); - -export const revalidatePhotosAndBlobKeys = () => { - revalidatePhotosKey(); - revalidateBlobKey(); -}; - export const revalidateAllKeys = () => { - revalidatePhotosAndBlobKeys(); + revalidatePhotosKey(); revalidateTagsKey(); revalidateCamerasKey(); revalidateFilmSimulationsKey(); @@ -135,36 +125,37 @@ export const revalidateAdminPaths = () => { PATHS_ADMIN.forEach(path => revalidatePath(path)); }; +// TODO: Test behavior +// Consider a wrapper function where this is executed at runtime +// and then parsed for dates export const getPhotosCached: typeof getPhotos = (...args) => unstable_cache( - () => getPhotos(...args), + getPhotos, [KEY_PHOTOS, ...getPhotosCacheKeys(...args)], { tags: [KEY_PHOTOS, ...getPhotosCacheKeys(...args)], } - )().then(parseCachedPhotosDates); + )(...args).then(parseCachedPhotosDates); export const getPhotosCountCached = unstable_cache( - (...args: Parameters) => getPhotosCount(...args), - [KEY_PHOTOS, KEY_PHOTOS_COUNT], + getPhotosCount, + [KEY_PHOTOS, KEY_COUNT], ); export const getPhotosCountIncludingHiddenCached: typeof getPhotosCount = (...args) => unstable_cache( () => getPhotosCountIncludingHidden(...args), - [KEY_PHOTOS, KEY_PHOTOS_COUNT], { - tags: [KEY_PHOTOS, KEY_PHOTOS_COUNT], + [KEY_PHOTOS, KEY_COUNT], { + tags: [KEY_PHOTOS, KEY_COUNT], } )(); -export const getPhotosTagCountCached: typeof getPhotosTagCount = (...args) => +export const getPhotosTagCountCached = unstable_cache( - () => getPhotosTagCount(...args), - [KEY_PHOTOS, getPhotoTagCountKey(...args)], { - tags: [KEY_PHOTOS, getPhotoTagCountKey(...args)], - } - )(); + getPhotosTagCount, + [KEY_PHOTOS, KEY_TAGS], + ); // eslint-disable-next-line max-len export const getPhotosCameraCountCached: typeof getPhotosCameraCount = (...args) => @@ -253,27 +244,11 @@ export const getUniqueFilmSimulationsCached: typeof getUniqueFilmSimulations = ( } )(); -export const getBlobUploadUrlsCached: typeof getBlobUploadUrls = (...args) => - unstable_cache( - () => getBlobUploadUrls(...args), - [KEY_BLOB, 'uploads'], { - tags: [KEY_BLOB, 'uploads'], - } - )(); - export const getBlobUploadUrlsNoStore: typeof getBlobUploadUrls = (...args) => { unstable_noStore(); return getBlobUploadUrls(...args); }; -export const getBlobPhotoUrlsCached: typeof getBlobPhotoUrls = (...args) => - unstable_cache( - () => getBlobPhotoUrls(...args), - [KEY_BLOB, 'photos'], { - tags: [KEY_BLOB, 'photos'], - } - )(); - export const getBlobPhotoUrlsNoStore: typeof getBlobPhotoUrls = (...args) => { unstable_noStore(); return getBlobPhotoUrls(...args); diff --git a/src/photo/actions.ts b/src/photo/actions.ts index 6d30cdce..b18ca5c4 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -21,7 +21,6 @@ import { import { revalidateAdminPaths, revalidateAllKeysAndPaths, - revalidateBlobKey, revalidatePhotosKey, } from '@/cache'; import { PATH_ADMIN_PHOTOS, PATH_ADMIN_TAGS } from '@/site/paths'; @@ -84,7 +83,6 @@ export async function renamePhotoTagGloballyAction(formData: FormData) { export async function deleteBlobPhotoAction(formData: FormData) { await deleteBlobPhoto(formData.get('url') as string); - revalidateBlobKey(); revalidateAdminPaths(); if (formData.get('redirectToPhotos') === 'true') { From c5d411da347689061afca134823d45deed6dd656 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 17 Nov 2023 09:16:11 -0600 Subject: [PATCH 3/8] Bump dependencies --- package.json | 22 ++-- pnpm-lock.yaml | 314 ++++++++++++++++++++++++------------------------- 2 files changed, 168 insertions(+), 168 deletions(-) diff --git a/package.json b/package.json index 8c0d5f5e..1b575c7f 100644 --- a/package.json +++ b/package.json @@ -9,35 +9,35 @@ "analyze": "ANALYZE=true next build" }, "dependencies": { - "@next/bundle-analyzer": "14.0.1", - "@tailwindcss/forms": "^0.5.6", + "@next/bundle-analyzer": "14.0.3", + "@tailwindcss/forms": "^0.5.7", "@testing-library/jest-dom": "^6.1.4", - "@testing-library/react": "^14.1.0", + "@testing-library/react": "^14.1.1", "@types/jest": "^29.5.8", - "@types/node": "^20.9.0", + "@types/node": "^20.9.1", "@types/react": "18.2.37", "@types/react-dom": "18.2.15", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", "@vercel/analytics": "^1.1.1", - "@vercel/blob": "^0.15.0", + "@vercel/blob": "^0.15.1", "@vercel/postgres": "0.5.1", "autoprefixer": "10.4.16", "camelcase-keys": "^9.1.2", "date-fns": "^2.30.0", "eslint": "8.53.0", - "eslint-config-next": "14.0.1", - "framer-motion": "^10.16.4", + "eslint-config-next": "14.0.3", + "framer-motion": "^10.16.5", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "nanoid": "^5.0.3", - "next": "14.0.1", + "next": "14.0.3", "next-auth": "5.0.0-beta.3", "next-themes": "^0.2.1", "postcss": "8.4.31", "react": "18.2.0", "react-dom": "18.2.0", - "react-icons": "^4.11.0", + "react-icons": "^4.12.0", "sonner": "^1.2.0", "tailwindcss": "3.3.5", "ts-exif-parser": "^0.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04603a40..d5bac62f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,23 +6,23 @@ settings: dependencies: '@next/bundle-analyzer': - specifier: 14.0.1 - version: 14.0.1 + specifier: 14.0.3 + version: 14.0.3 '@tailwindcss/forms': - specifier: ^0.5.6 - version: 0.5.6(tailwindcss@3.3.5) + specifier: ^0.5.7 + version: 0.5.7(tailwindcss@3.3.5) '@testing-library/jest-dom': specifier: ^6.1.4 version: 6.1.4(@types/jest@29.5.8)(jest@29.7.0) '@testing-library/react': - specifier: ^14.1.0 - version: 14.1.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^14.1.1 + version: 14.1.1(react-dom@18.2.0)(react@18.2.0) '@types/jest': specifier: ^29.5.8 version: 29.5.8 '@types/node': - specifier: ^20.9.0 - version: 20.9.0 + specifier: ^20.9.1 + version: 20.9.1 '@types/react': specifier: 18.2.37 version: 18.2.37 @@ -30,17 +30,17 @@ dependencies: specifier: 18.2.15 version: 18.2.15 '@typescript-eslint/eslint-plugin': - specifier: ^6.10.0 - version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.11.0 + version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^6.10.0 - version: 6.10.0(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.11.0 + version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@vercel/analytics': specifier: ^1.1.1 version: 1.1.1 '@vercel/blob': - specifier: ^0.15.0 - version: 0.15.0 + specifier: ^0.15.1 + version: 0.15.1 '@vercel/postgres': specifier: 0.5.1 version: 0.5.1 @@ -57,14 +57,14 @@ dependencies: specifier: 8.53.0 version: 8.53.0 eslint-config-next: - specifier: 14.0.1 - version: 14.0.1(eslint@8.53.0)(typescript@5.2.2) + specifier: 14.0.3 + version: 14.0.3(eslint@8.53.0)(typescript@5.2.2) framer-motion: - specifier: ^10.16.4 - version: 10.16.4(react-dom@18.2.0)(react@18.2.0) + specifier: ^10.16.5 + version: 10.16.5(react-dom@18.2.0)(react@18.2.0) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.9.0) + version: 29.7.0(@types/node@20.9.1) jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 @@ -72,14 +72,14 @@ dependencies: specifier: ^5.0.3 version: 5.0.3 next: - specifier: 14.0.1 - version: 14.0.1(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) + specifier: 14.0.3 + version: 14.0.3(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) next-auth: specifier: 5.0.0-beta.3 - version: 5.0.0-beta.3(next@14.0.1)(react@18.2.0) + version: 5.0.0-beta.3(next@14.0.3)(react@18.2.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.0.1)(react-dom@18.2.0)(react@18.2.0) + version: 0.2.1(next@14.0.3)(react-dom@18.2.0)(react@18.2.0) postcss: specifier: 8.4.31 version: 8.4.31 @@ -90,8 +90,8 @@ dependencies: specifier: 18.2.0 version: 18.2.0(react@18.2.0) react-icons: - specifier: ^4.11.0 - version: 4.11.0(react@18.2.0) + specifier: ^4.12.0 + version: 4.12.0(react@18.2.0) sonner: specifier: ^1.2.0 version: 1.2.0(react-dom@18.2.0)(react@18.2.0) @@ -578,7 +578,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -599,14 +599,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.9.0) + jest-config: 29.7.0(@types/node@20.9.1) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -634,7 +634,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-mock: 29.7.0 dev: false @@ -661,7 +661,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -694,7 +694,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.20 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -782,7 +782,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.9.0 + '@types/node': 20.9.1 '@types/yargs': 17.0.31 chalk: 4.1.2 dev: false @@ -823,8 +823,8 @@ packages: '@types/pg': 8.6.6 dev: false - /@next/bundle-analyzer@14.0.1: - resolution: {integrity: sha512-AbZZnj4gZ1ZQFppZxAC9e8+skj0rFiSvY6E6Ut+ydS1r6oizR7PMu/7o02psIm4ekAsmp2O1Eq8IowHQgPWPCQ==} + /@next/bundle-analyzer@14.0.3: + resolution: {integrity: sha512-+UriXNEn2vGR2IxTiiuen45G7lXUbtMh0hgS/UH2o2E4TnScwjEEepqT76pY8fdpa5JEZ+gvBy6aSnrw4G2P2w==} dependencies: webpack-bundle-analyzer: 4.7.0 transitivePeerDependencies: @@ -832,18 +832,18 @@ packages: - utf-8-validate dev: false - /@next/env@14.0.1: - resolution: {integrity: sha512-Ms8ZswqY65/YfcjrlcIwMPD7Rg/dVjdLapMcSHG26W6O67EJDF435ShW4H4LXi1xKO1oRc97tLXUpx8jpLe86A==} + /@next/env@14.0.3: + resolution: {integrity: sha512-7xRqh9nMvP5xrW4/+L0jgRRX+HoNRGnfJpD+5Wq6/13j3dsdzxO3BCXn7D3hMqsDb+vjZnJq+vI7+EtgrYZTeA==} dev: false - /@next/eslint-plugin-next@14.0.1: - resolution: {integrity: sha512-bLjJMwXdzvhnQOnxvHoTTUh/+PYk6FF/DCgHi4BXwXCINer+o1ZYfL9aVeezj/oI7wqGJOqwGIXrlBvPbAId3w==} + /@next/eslint-plugin-next@14.0.3: + resolution: {integrity: sha512-j4K0n+DcmQYCVnSAM+UByTVfIHnYQy2ODozfQP+4RdwtRDfobrIvKq1K4Exb2koJ79HSSa7s6B2SA8T/1YR3RA==} dependencies: glob: 7.1.7 dev: false - /@next/swc-darwin-arm64@14.0.1: - resolution: {integrity: sha512-JyxnGCS4qT67hdOKQ0CkgFTp+PXub5W1wsGvIq98TNbF3YEIN7iDekYhYsZzc8Ov0pWEsghQt+tANdidITCLaw==} + /@next/swc-darwin-arm64@14.0.3: + resolution: {integrity: sha512-64JbSvi3nbbcEtyitNn2LEDS/hcleAFpHdykpcnrstITFlzFgB/bW0ER5/SJJwUPj+ZPY+z3e+1jAfcczRLVGw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -851,8 +851,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.0.1: - resolution: {integrity: sha512-625Z7bb5AyIzswF9hvfZWa+HTwFZw+Jn3lOBNZB87lUS0iuCYDHqk3ujuHCkiyPtSC0xFBtYDLcrZ11mF/ap3w==} + /@next/swc-darwin-x64@14.0.3: + resolution: {integrity: sha512-RkTf+KbAD0SgYdVn1XzqE/+sIxYGB7NLMZRn9I4Z24afrhUpVJx6L8hsRnIwxz3ERE2NFURNliPjJ2QNfnWicQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -860,8 +860,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.0.1: - resolution: {integrity: sha512-iVpn3KG3DprFXzVHM09kvb//4CNNXBQ9NB/pTm8LO+vnnnaObnzFdS5KM+w1okwa32xH0g8EvZIhoB3fI3mS1g==} + /@next/swc-linux-arm64-gnu@14.0.3: + resolution: {integrity: sha512-3tBWGgz7M9RKLO6sPWC6c4pAw4geujSwQ7q7Si4d6bo0l6cLs4tmO+lnSwFp1Tm3lxwfMk0SgkJT7EdwYSJvcg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -869,8 +869,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.0.1: - resolution: {integrity: sha512-mVsGyMxTLWZXyD5sen6kGOTYVOO67lZjLApIj/JsTEEohDDt1im2nkspzfV5MvhfS7diDw6Rp/xvAQaWZTv1Ww==} + /@next/swc-linux-arm64-musl@14.0.3: + resolution: {integrity: sha512-v0v8Kb8j8T23jvVUWZeA2D8+izWspeyeDGNaT2/mTHWp7+37fiNfL8bmBWiOmeumXkacM/AB0XOUQvEbncSnHA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -878,8 +878,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.0.1: - resolution: {integrity: sha512-wMqf90uDWN001NqCM/auRl3+qVVeKfjJdT9XW+RMIOf+rhUzadmYJu++tp2y+hUbb6GTRhT+VjQzcgg/QTD9NQ==} + /@next/swc-linux-x64-gnu@14.0.3: + resolution: {integrity: sha512-VM1aE1tJKLBwMGtyBR21yy+STfl0MapMQnNrXkxeyLs0GFv/kZqXS5Jw/TQ3TSUnbv0QPDf/X8sDXuMtSgG6eg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -887,8 +887,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.0.1: - resolution: {integrity: sha512-ol1X1e24w4j4QwdeNjfX0f+Nza25n+ymY0T2frTyalVczUmzkVD7QGgPTZMHfR1aLrO69hBs0G3QBYaj22J5GQ==} + /@next/swc-linux-x64-musl@14.0.3: + resolution: {integrity: sha512-64EnmKy18MYFL5CzLaSuUn561hbO1Gk16jM/KHznYP3iCIfF9e3yULtHaMy0D8zbHfxset9LTOv6cuYKJgcOxg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -896,8 +896,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.0.1: - resolution: {integrity: sha512-WEmTEeWs6yRUEnUlahTgvZteh5RJc4sEjCQIodJlZZ5/VJwVP8p2L7l6VhzQhT4h7KvLx/Ed4UViBdne6zpIsw==} + /@next/swc-win32-arm64-msvc@14.0.3: + resolution: {integrity: sha512-WRDp8QrmsL1bbGtsh5GqQ/KWulmrnMBgbnb+59qNTW1kVi1nG/2ndZLkcbs2GX7NpFLlToLRMWSQXmPzQm4tog==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -905,8 +905,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.0.1: - resolution: {integrity: sha512-oFpHphN4ygAgZUKjzga7SoH2VGbEJXZa/KL8bHCAwCjDWle6R1SpiGOdUdA8EJ9YsG1TYWpzY6FTbUA+iAJeww==} + /@next/swc-win32-ia32-msvc@14.0.3: + resolution: {integrity: sha512-EKffQeqCrj+t6qFFhIFTRoqb2QwX1mU7iTOvMyLbYw3QtqTw9sMwjykyiMlZlrfm2a4fA84+/aeW+PMg1MjuTg==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -914,8 +914,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.0.1: - resolution: {integrity: sha512-FFp3nOJ/5qSpeWT0BZQ+YE1pSMk4IMpkME/1DwKBwhg4mJLB9L+6EXuJi4JEwaJdl5iN+UUlmUD3IsR1kx5fAg==} + /@next/swc-win32-x64-msvc@14.0.3: + resolution: {integrity: sha512-ERhKPSJ1vQrPiwrs15Pjz/rvDHZmkmvbf/BjPN/UCOI++ODftT0GtasDPi0j+y6PPJi5HsXw+dpRaXUaw4vjuQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -978,8 +978,8 @@ packages: tslib: 2.6.2 dev: false - /@tailwindcss/forms@0.5.6(tailwindcss@3.3.5): - resolution: {integrity: sha512-Fw+2BJ0tmAwK/w01tEFL5TiaJBX1NLT1/YbWgvm7ws3Qcn11kiXxzNTEQDMs5V3mQemhB56l3u0i9dwdzSQldA==} + /@tailwindcss/forms@0.5.7(tailwindcss@3.3.5): + resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' dependencies: @@ -1026,13 +1026,13 @@ packages: chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.5.16 - jest: 29.7.0(@types/node@20.9.0) + jest: 29.7.0(@types/node@20.9.1) lodash: 4.17.21 redent: 3.0.0 dev: false - /@testing-library/react@14.1.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-hcvfZEEyO0xQoZeHmUbuMs7APJCGELpilL7bY+BaJaMP57aWc6q1etFwScnoZDheYjk4ESdlzPdQ33IbsKAK/A==} + /@testing-library/react@14.1.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-XN9qioSzyYvfH+O09pzc9HAhZ2dSuTZLh+EmHkp1OKKxe13wAf617EKLuQ5l5S5dlfgPf/p0MHTeRkqO8Xz8qw==} engines: {node: '>=14'} peerDependencies: react: ^18.0.0 @@ -1086,7 +1086,7 @@ packages: /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.1 dev: false /@types/istanbul-lib-coverage@2.0.6: @@ -1115,7 +1115,7 @@ packages: /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.1 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 dev: false @@ -1128,8 +1128,8 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: false - /@types/node@20.9.0: - resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} + /@types/node@20.9.1: + resolution: {integrity: sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==} dependencies: undici-types: 5.26.5 dev: false @@ -1137,7 +1137,7 @@ packages: /@types/pg@8.6.6: resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.1 pg-protocol: 1.6.0 pg-types: 2.2.0 dev: false @@ -1186,8 +1186,8 @@ packages: '@types/yargs-parser': 21.0.3 dev: false - /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==} + /@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1198,11 +1198,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4 eslint: 8.53.0 graphemer: 1.4.0 @@ -1215,8 +1215,8 @@ packages: - supports-color dev: false - /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==} + /@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1225,10 +1225,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4 eslint: 8.53.0 typescript: 5.2.2 @@ -1236,16 +1236,16 @@ packages: - supports-color dev: false - /@typescript-eslint/scope-manager@6.10.0: - resolution: {integrity: sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==} + /@typescript-eslint/scope-manager@6.11.0: + resolution: {integrity: sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/visitor-keys': 6.11.0 dev: false - /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==} + /@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1254,8 +1254,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.53.0 ts-api-utils: 1.0.3(typescript@5.2.2) @@ -1264,13 +1264,13 @@ packages: - supports-color dev: false - /@typescript-eslint/types@6.10.0: - resolution: {integrity: sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==} + /@typescript-eslint/types@6.11.0: + resolution: {integrity: sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==} engines: {node: ^16.0.0 || >=18.0.0} dev: false - /@typescript-eslint/typescript-estree@6.10.0(typescript@5.2.2): - resolution: {integrity: sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==} + /@typescript-eslint/typescript-estree@6.11.0(typescript@5.2.2): + resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1278,8 +1278,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/visitor-keys': 6.11.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1290,8 +1290,8 @@ packages: - supports-color dev: false - /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==} + /@typescript-eslint/utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1299,9 +1299,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.5 - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.11.0 + '@typescript-eslint/types': 6.11.0 + '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) eslint: 8.53.0 semver: 7.5.4 transitivePeerDependencies: @@ -1309,11 +1309,11 @@ packages: - typescript dev: false - /@typescript-eslint/visitor-keys@6.10.0: - resolution: {integrity: sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==} + /@typescript-eslint/visitor-keys@6.11.0: + resolution: {integrity: sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/types': 6.11.0 eslint-visitor-keys: 3.4.3 dev: false @@ -1327,8 +1327,8 @@ packages: server-only: 0.0.1 dev: false - /@vercel/blob@0.15.0: - resolution: {integrity: sha512-bWTuln4nkMG7APvcqIA2y5YCYKnmpUdzoITRdJOpDVeRSVoyVFwYOZleb/bj7UWDGfRN7P2JJ2mMMQ2nrpysEQ==} + /@vercel/blob@0.15.1: + resolution: {integrity: sha512-Wo7VU9/tM8kkv7krvxGoDeu/Li0h7PYR/TB1TEiyJZzACruA0jWqj44OGokJQCYN3ZvV5tXHpTAN6pImIBCrUw==} engines: {node: '>=16.14'} dependencies: jest-environment-jsdom: 29.7.0 @@ -1895,7 +1895,7 @@ packages: engines: {node: '>= 0.6'} dev: false - /create-jest@29.7.0(@types/node@20.9.0): + /create-jest@29.7.0(@types/node@20.9.1): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -1904,7 +1904,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.9.0) + jest-config: 29.7.0(@types/node@20.9.1) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -2293,8 +2293,8 @@ packages: source-map: 0.6.1 dev: false - /eslint-config-next@14.0.1(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-QfIFK2WD39H4WOespjgf6PLv9Bpsd7KGGelCtmq4l67nGvnlsGpuvj0hIT+aIy6p5gKH+lAChYILsyDlxP52yg==} + /eslint-config-next@14.0.3(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-IKPhpLdpSUyKofmsXUfrvBC49JMUTdeaD8ZIH4v9Vk0sC1X6URTuTJCLtA0Vwuj7V/CQh0oISuSTvNn5//Buew==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -2302,13 +2302,13 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 14.0.1 + '@next/eslint-plugin-next': 14.0.3 '@rushstack/eslint-patch': 1.5.1 - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.53.0) eslint-plugin-react: 7.33.2(eslint@8.53.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.53.0) @@ -2328,7 +2328,7 @@ packages: - supports-color dev: false - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0): + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -2338,8 +2338,8 @@ packages: debug: 4.3.4 enhanced-resolve: 5.15.0 eslint: 8.53.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -2351,7 +2351,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -2372,16 +2372,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) debug: 3.2.7 eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0) transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} engines: {node: '>=4'} peerDependencies: @@ -2391,7 +2391,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -2400,7 +2400,7 @@ packages: doctrine: 2.1.0 eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.11.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -2702,8 +2702,8 @@ packages: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: false - /framer-motion@10.16.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-p9V9nGomS3m6/CALXqv6nFGMuFOxbWsmaOrdmhyQimMIlLl3LC7h7l86wge/Js/8cRu5ktutS/zlzgR7eBOtFA==} + /framer-motion@10.16.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GEzVjOYP2MIpV9bT/GbhcsBNoImG3/2X3O/xVNWmktkv9MdJ7P/44zELm/7Fjb+O3v39SmKFnoDQB32giThzpg==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -3322,7 +3322,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -3343,7 +3343,7 @@ packages: - supports-color dev: false - /jest-cli@29.7.0(@types/node@20.9.0): + /jest-cli@29.7.0(@types/node@20.9.1): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3357,10 +3357,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.9.0) + create-jest: 29.7.0(@types/node@20.9.1) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.9.0) + jest-config: 29.7.0(@types/node@20.9.1) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -3371,7 +3371,7 @@ packages: - ts-node dev: false - /jest-config@29.7.0(@types/node@20.9.0): + /jest-config@29.7.0(@types/node@20.9.1): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -3386,7 +3386,7 @@ packages: '@babel/core': 7.23.3 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 babel-jest: 29.7.0(@babel/core@7.23.3) chalk: 4.1.2 ci-info: 3.9.0 @@ -3452,7 +3452,7 @@ packages: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -3469,7 +3469,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-mock: 29.7.0 jest-util: 29.7.0 dev: false @@ -3485,7 +3485,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.9.0 + '@types/node': 20.9.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -3536,7 +3536,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-util: 29.7.0 dev: false @@ -3591,7 +3591,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -3622,7 +3622,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -3674,7 +3674,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -3699,7 +3699,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.9.0 + '@types/node': 20.9.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -3711,13 +3711,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.1 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: false - /jest@29.7.0(@types/node@20.9.0): + /jest@29.7.0(@types/node@20.9.1): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3730,7 +3730,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.9.0) + jest-cli: 29.7.0(@types/node@20.9.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -4052,7 +4052,7 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: false - /next-auth@5.0.0-beta.3(next@14.0.1)(react@18.2.0): + /next-auth@5.0.0-beta.3(next@14.0.3)(react@18.2.0): resolution: {integrity: sha512-WOKhATBFGeONV+29HzFmspNmL7NXxrsCWLfaDKmAd/4DD1nqXE0BzNFH8t3SJBx7PUDMnB6F7xB76LM/AaV1MQ==} peerDependencies: next: ^14 @@ -4063,24 +4063,24 @@ packages: optional: true dependencies: '@auth/core': 0.0.0-manual.e9863699 - next: 14.0.1(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) + next: 14.0.3(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 dev: false - /next-themes@0.2.1(next@14.0.1)(react-dom@18.2.0)(react@18.2.0): + /next-themes@0.2.1(next@14.0.3)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==} peerDependencies: next: '*' react: '*' react-dom: '*' dependencies: - next: 14.0.1(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) + next: 14.0.3(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /next@14.0.1(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-s4YaLpE4b0gmb3ggtmpmV+wt+lPRuGtANzojMQ2+gmBpgX9w5fTbjsy6dXByBuENsdCX5pukZH/GxdFgO62+pA==} + /next@14.0.3(@babel/core@7.23.3)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-AbYdRNfImBr3XGtvnwOxq8ekVCwbFTv/UJoLwmaX89nk9i051AEY4/HAWzU0YpaTDw8IofUpmuIlvzWF13jxIw==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -4094,7 +4094,7 @@ packages: sass: optional: true dependencies: - '@next/env': 14.0.1 + '@next/env': 14.0.3 '@swc/helpers': 0.5.2 busboy: 1.6.0 caniuse-lite: 1.0.30001561 @@ -4104,15 +4104,15 @@ packages: styled-jsx: 5.1.1(@babel/core@7.23.3)(react@18.2.0) watchpack: 2.4.0 optionalDependencies: - '@next/swc-darwin-arm64': 14.0.1 - '@next/swc-darwin-x64': 14.0.1 - '@next/swc-linux-arm64-gnu': 14.0.1 - '@next/swc-linux-arm64-musl': 14.0.1 - '@next/swc-linux-x64-gnu': 14.0.1 - '@next/swc-linux-x64-musl': 14.0.1 - '@next/swc-win32-arm64-msvc': 14.0.1 - '@next/swc-win32-ia32-msvc': 14.0.1 - '@next/swc-win32-x64-msvc': 14.0.1 + '@next/swc-darwin-arm64': 14.0.3 + '@next/swc-darwin-x64': 14.0.3 + '@next/swc-linux-arm64-gnu': 14.0.3 + '@next/swc-linux-arm64-musl': 14.0.3 + '@next/swc-linux-x64-gnu': 14.0.3 + '@next/swc-linux-x64-musl': 14.0.3 + '@next/swc-win32-arm64-msvc': 14.0.3 + '@next/swc-win32-ia32-msvc': 14.0.3 + '@next/swc-win32-x64-msvc': 14.0.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -4576,8 +4576,8 @@ packages: scheduler: 0.23.0 dev: false - /react-icons@4.11.0(react@18.2.0): - resolution: {integrity: sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==} + /react-icons@4.12.0(react@18.2.0): + resolution: {integrity: sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==} peerDependencies: react: '*' dependencies: From 5279d651f7f67424a9f84e4ba87cc0905c6650be Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 17 Nov 2023 21:17:34 -0600 Subject: [PATCH 4/8] Refactor remaining unstable_cache functions --- .../admin/photos/[photoId]/edit/page.tsx | 4 +- src/cache/index.ts | 169 +++++++----------- src/photo/actions.ts | 2 +- 3 files changed, 68 insertions(+), 107 deletions(-) diff --git a/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx b/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx index 2db76096..5c51f491 100644 --- a/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx +++ b/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx @@ -1,5 +1,5 @@ import { redirect } from 'next/navigation'; -import { getPhotoCached } from '@/cache'; +import { getPhotoNoStore } from '@/cache'; import { PATH_ADMIN } from '@/site/paths'; import PhotoEditPageClient from '@/photo/PhotoEditPageClient'; @@ -8,7 +8,7 @@ export default async function PhotoEditPage({ }: { params: { photoId: string } }) { - const photo = await getPhotoCached(photoId); + const photo = await getPhotoNoStore(photoId); if (!photo) { redirect(PATH_ADMIN); } diff --git a/src/cache/index.ts b/src/cache/index.ts index b61bee7a..0065894a 100644 --- a/src/cache/index.ts +++ b/src/cache/index.ts @@ -21,21 +21,22 @@ import { getPhotosFilmSimulationDateRange, getPhotosFilmSimulationCount, } from '@/services/postgres'; -import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo'; +import { parseCachedPhotoDates, parseCachedPhotosDates } from '@/photo'; import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob'; import type { Session } from 'next-auth'; -import { Camera, createCameraKey } from '@/camera'; +import { createCameraKey } from '@/camera'; import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths'; -import { FilmSimulation } from '@/simulation'; // Table key const KEY_PHOTOS = 'photos'; +const KEY_PHOTO = 'photo'; // Field keys const KEY_TAGS = 'tags'; const KEY_CAMERAS = 'cameras'; const KEY_FILM_SIMULATIONS = 'film-simulations'; // Type keys const KEY_COUNT = 'count'; +const KEY_HIDDEN = 'hidden'; const KEY_DATE_RANGE = 'date-range'; const getPhotosCacheKeyForOption = ( @@ -80,23 +81,6 @@ const getPhotosCacheKeys = (options: GetPhotosOptions = {}) => { return tags; }; -const getPhotoCacheKey = (photoId: string) => `photo-${photoId}`; - -const getPhotoCameraCountKey = (camera: Camera) => - `${KEY_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`; - -const getPhotoFilmSimulationCountKey = (simulation: FilmSimulation) => - `${KEY_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`; - -const getPhotoTagDateRangeKey = (tag: string) => - `${KEY_DATE_RANGE}-${KEY_TAGS}-${tag}`; - -const getPhotoCameraDateRangeKey = (camera: Camera) => - `${KEY_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`; - -const getPhotoFilmSimulationDateRangeKey = (simulation: FilmSimulation) => - `${KEY_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`; - export const revalidatePhotosKey = () => revalidateTag(KEY_PHOTOS); @@ -125,16 +109,14 @@ export const revalidateAdminPaths = () => { PATHS_ADMIN.forEach(path => revalidatePath(path)); }; -// TODO: Test behavior -// Consider a wrapper function where this is executed at runtime -// and then parsed for dates -export const getPhotosCached: typeof getPhotos = (...args) => - unstable_cache( - getPhotos, - [KEY_PHOTOS, ...getPhotosCacheKeys(...args)], { - tags: [KEY_PHOTOS, ...getPhotosCacheKeys(...args)], - } - )(...args).then(parseCachedPhotosDates); +// Cache + +export const getPhotosCached = ( + ...args: Parameters +) => unstable_cache( + getPhotos, + [KEY_PHOTOS, ...getPhotosCacheKeys(...args)], +)(...args).then(parseCachedPhotosDates); export const getPhotosCountCached = unstable_cache( @@ -142,14 +124,11 @@ export const getPhotosCountCached = [KEY_PHOTOS, KEY_COUNT], ); -export const getPhotosCountIncludingHiddenCached: typeof getPhotosCount = - (...args) => +export const getPhotosCountIncludingHiddenCached = unstable_cache( - () => getPhotosCountIncludingHidden(...args), - [KEY_PHOTOS, KEY_COUNT], { - tags: [KEY_PHOTOS, KEY_COUNT], - } - )(); + getPhotosCountIncludingHidden, + [KEY_PHOTOS, KEY_COUNT, KEY_HIDDEN], + ); export const getPhotosTagCountCached = unstable_cache( @@ -157,92 +136,74 @@ export const getPhotosTagCountCached = [KEY_PHOTOS, KEY_TAGS], ); -// eslint-disable-next-line max-len -export const getPhotosCameraCountCached: typeof getPhotosCameraCount = (...args) => +export const getPhotosCameraCountCached = ( + ...args: Parameters +) => unstable_cache( - () => getPhotosCameraCount(...args), - [KEY_PHOTOS, getPhotoCameraCountKey(...args)], { - tags: [KEY_PHOTOS, getPhotoCameraCountKey(...args)], - } - )(); + getPhotosCameraCount, + [KEY_PHOTOS, KEY_COUNT, createCameraKey(...args)], + )(...args); -// eslint-disable-next-line max-len -export const getPhotosFilmSimulationCountCached: typeof getPhotosFilmSimulationCount = (...args) => +export const getPhotosFilmSimulationCountCached = unstable_cache( - () => getPhotosFilmSimulationCount(...args), - [KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)], { - tags: [KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)], - } - )(); + getPhotosFilmSimulationCount, + [KEY_PHOTOS, KEY_FILM_SIMULATIONS, KEY_COUNT], + ); -// eslint-disable-next-line max-len -export const getPhotosTagDateRangeCached: typeof getPhotosTagDateRange = (...args) => +export const getPhotosTagDateRangeCached = unstable_cache( - () => getPhotosTagDateRange(...args), - [KEY_PHOTOS, getPhotoTagDateRangeKey(...args)], { - tags: [KEY_PHOTOS, getPhotoTagDateRangeKey(...args)], - } - )(); + getPhotosTagDateRange, + [KEY_PHOTOS, KEY_TAGS, KEY_DATE_RANGE], + ); -// eslint-disable-next-line max-len -export const getPhotosCameraDateRangeCached: typeof getPhotosCameraDateRange = (...args) => +export const getPhotosCameraDateRangeCached = unstable_cache( - () => getPhotosCameraDateRange(...args), - [KEY_PHOTOS, getPhotoCameraDateRangeKey(...args)], { - tags: [KEY_PHOTOS, getPhotoCameraDateRangeKey(...args)], - } - )(); + getPhotosCameraDateRange, + [KEY_PHOTOS, KEY_CAMERAS, KEY_DATE_RANGE], + ); -// eslint-disable-next-line max-len -export const getPhotosFilmSimulationDateRangeCached: typeof getPhotosFilmSimulationDateRange = (...args) => +export const getPhotosFilmSimulationDateRangeCached = unstable_cache( - () => getPhotosFilmSimulationDateRange(...args), - [KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)], { - tags: [KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)], - } - )(); + getPhotosFilmSimulationDateRange, + [KEY_PHOTOS, KEY_FILM_SIMULATIONS, KEY_DATE_RANGE], + ); -export const getPhotoCached: typeof getPhoto = (...args) => +export const getPhotoCached = (...args: Parameters) => unstable_cache( - () => getPhoto(...args), - [KEY_PHOTOS, getPhotoCacheKey(...args)], { - tags: [KEY_PHOTOS, getPhotoCacheKey(...args)], - } - )().then(photo => photo ? parseCachedPhotoDates(photo) : undefined); + getPhoto, + [KEY_PHOTOS, KEY_PHOTO] + )(...args).then(photo => photo ? parseCachedPhotoDates(photo) : undefined); -export const getUniqueTagsCached: typeof getUniqueTags = (...args) => +export const getUniqueTagsCached = unstable_cache( - () => getUniqueTags(...args), - [KEY_PHOTOS, KEY_TAGS], { - tags: [KEY_PHOTOS, KEY_TAGS], - } - )(); + getUniqueTags, + [KEY_PHOTOS, KEY_TAGS], + ); -// eslint-disable-next-line max-len -export const getUniqueTagsHiddenCached: typeof getUniqueTagsHidden = (...args) => +export const getUniqueTagsHiddenCached = unstable_cache( - () => getUniqueTagsHidden(...args), - [KEY_PHOTOS, KEY_TAGS], { - tags: [KEY_PHOTOS, KEY_TAGS], - } - )(); + getUniqueTagsHidden, + [KEY_PHOTOS, KEY_TAGS, KEY_HIDDEN] + ); -export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) => +export const getUniqueCamerasCached = unstable_cache( - () => getUniqueCameras(...args), - [KEY_PHOTOS, KEY_CAMERAS], { - tags: [KEY_PHOTOS, KEY_CAMERAS], - } - )(); + getUniqueCameras, + [KEY_PHOTOS, KEY_CAMERAS] + ); -// eslint-disable-next-line max-len -export const getUniqueFilmSimulationsCached: typeof getUniqueFilmSimulations = (...args) => +export const getUniqueFilmSimulationsCached = unstable_cache( - () => getUniqueFilmSimulations(...args), - [KEY_PHOTOS, KEY_FILM_SIMULATIONS], { - tags: [KEY_PHOTOS, KEY_FILM_SIMULATIONS], - } - )(); + getUniqueFilmSimulations, + [KEY_PHOTOS, KEY_FILM_SIMULATIONS], + ); + +// No Store + +export const getPhotoNoStore = (...args: Parameters) => { + unstable_noStore(); + return getPhoto(...args); +}; export const getBlobUploadUrlsNoStore: typeof getBlobUploadUrls = (...args) => { unstable_noStore(); diff --git a/src/photo/actions.ts b/src/photo/actions.ts index b18ca5c4..4e42d949 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -45,7 +45,7 @@ export async function updatePhotoAction(formData: FormData) { await sqlUpdatePhoto(photo); - revalidatePhotosKey(); + revalidateAllKeysAndPaths(); redirect(PATH_ADMIN_PHOTOS); } From ad2ee853311883511335b76aaa969022d3dfd607 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 17 Nov 2023 21:22:30 -0600 Subject: [PATCH 5/8] Remove generateStaticParams --- .../film/[simulation]/[photoId]/layout.tsx | 15 ------------ .../[simulation]/[photoId]/share/page.tsx | 23 +++---------------- src/app/(static)/p/[photoId]/layout.tsx | 18 ++++----------- .../shot-on/[camera]/[photoId]/layout.tsx | 18 --------------- .../shot-on/[camera]/[photoId]/share/page.tsx | 23 +++---------------- .../(static)/tag/[tag]/[photoId]/layout.tsx | 15 ------------ .../tag/[tag]/[photoId]/share/page.tsx | 23 +++---------------- 7 files changed, 14 insertions(+), 121 deletions(-) diff --git a/src/app/(static)/film/[simulation]/[photoId]/layout.tsx b/src/app/(static)/film/[simulation]/[photoId]/layout.tsx index 53b8a6d7..96546472 100644 --- a/src/app/(static)/film/[simulation]/[photoId]/layout.tsx +++ b/src/app/(static)/film/[simulation]/[photoId]/layout.tsx @@ -11,7 +11,6 @@ import { } from '@/site/paths'; import PhotoDetailPage from '@/photo/PhotoDetailPage'; import { getPhotoCached } from '@/cache'; -import { getPhotos, getUniqueFilmSimulations } from '@/services/postgres'; import { ReactNode } from 'react'; import { FilmSimulation } from '@/simulation'; import { getPhotosFilmSimulationDataCached } from '@/simulation/data'; @@ -20,20 +19,6 @@ interface PhotoFilmSimulationProps { params: { photoId: string, simulation: FilmSimulation } } -export async function generateStaticParams() { - const params: PhotoFilmSimulationProps[] = []; - - const simulations = await getUniqueFilmSimulations(); - simulations.forEach(async ({ simulation }) => { - const photos = await getPhotos({ simulation }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, simulation }, - }))); - }); - - return params; -} - export async function generateMetadata({ params: { photoId, simulation }, }: PhotoFilmSimulationProps): Promise { diff --git a/src/app/(static)/film/[simulation]/[photoId]/share/page.tsx b/src/app/(static)/film/[simulation]/[photoId]/share/page.tsx index 0b0b493f..782e14df 100644 --- a/src/app/(static)/film/[simulation]/[photoId]/share/page.tsx +++ b/src/app/(static)/film/[simulation]/[photoId]/share/page.tsx @@ -1,31 +1,14 @@ import { getPhotoCached } from '@/cache'; import PhotoShareModal from '@/photo/PhotoShareModal'; -import { getPhotos, getUniqueFilmSimulations } from '@/services/postgres'; import { FilmSimulation } from '@/simulation'; import { PATH_ROOT } from '@/site/paths'; import { redirect } from 'next/navigation'; -interface PhotoFilmSimulationProps { - params: { photoId: string, simulation: FilmSimulation } -} - -export async function generateStaticParams() { - const params: PhotoFilmSimulationProps[] = []; - - const simulations = await getUniqueFilmSimulations(); - simulations.forEach(async ({ simulation }) => { - const photos = await getPhotos({ simulation }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, simulation }, - }))); - }); - - return params; -} - export default async function Share({ params: { photoId, simulation }, -}: PhotoFilmSimulationProps) { +}: { + params: { photoId: string, simulation: FilmSimulation } +}) { const photo = await getPhotoCached(photoId); if (!photo) { return redirect(PATH_ROOT); } diff --git a/src/app/(static)/p/[photoId]/layout.tsx b/src/app/(static)/p/[photoId]/layout.tsx index 834f561b..1664732b 100644 --- a/src/app/(static)/p/[photoId]/layout.tsx +++ b/src/app/(static)/p/[photoId]/layout.tsx @@ -12,20 +12,14 @@ import { } from '@/site/paths'; import PhotoDetailPage from '@/photo/PhotoDetailPage'; import { getPhotoCached, getPhotosCached } from '@/cache'; -import { getPhotos } from '@/services/postgres'; -export async function generateStaticParams() { - const photos = await getPhotos(); - return photos.map(photo => ({ - params: { photoId: photo.id }, - })); +interface PhotoProps { + params: { photoId: string } } export async function generateMetadata({ params: { photoId }, -}: { - params: { photoId: string } -}): Promise { +}:PhotoProps): Promise { const photo = await getPhotoCached(photoId); if (!photo) { return {}; } @@ -56,10 +50,8 @@ export async function generateMetadata({ export default async function PhotoPage({ params: { photoId }, children, -}: { - params: { photoId: string } - children: React.ReactNode -}) { +}: + PhotoProps & { children: React.ReactNode }) { const photo = await getPhotoCached(photoId); if (!photo) { redirect(PATH_ROOT); } diff --git a/src/app/(static)/shot-on/[camera]/[photoId]/layout.tsx b/src/app/(static)/shot-on/[camera]/[photoId]/layout.tsx index 71f63ee0..6080421e 100644 --- a/src/app/(static)/shot-on/[camera]/[photoId]/layout.tsx +++ b/src/app/(static)/shot-on/[camera]/[photoId]/layout.tsx @@ -11,10 +11,6 @@ import { } from '@/site/paths'; import PhotoDetailPage from '@/photo/PhotoDetailPage'; import { getPhotoCached } from '@/cache'; -import { - getPhotos, - getUniqueCameras, -} from '@/services/postgres'; import { cameraFromPhoto } from '@/camera'; import { getPhotosCameraDataCached } from '@/camera/data'; import { ReactNode } from 'react'; @@ -23,20 +19,6 @@ interface PhotoCameraProps { params: { photoId: string, camera: string } } -export async function generateStaticParams() { - const params: PhotoCameraProps[] = []; - - const cameras = await getUniqueCameras(); - cameras.forEach(async ({ cameraKey, camera }) => { - const photos = await getPhotos({ camera }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, camera: cameraKey }, - }))); - }); - - return params; -} - export async function generateMetadata({ params: { photoId, camera }, }: PhotoCameraProps): Promise { diff --git a/src/app/(static)/shot-on/[camera]/[photoId]/share/page.tsx b/src/app/(static)/shot-on/[camera]/[photoId]/share/page.tsx index 0b3f76d8..d6bc9ec9 100644 --- a/src/app/(static)/shot-on/[camera]/[photoId]/share/page.tsx +++ b/src/app/(static)/shot-on/[camera]/[photoId]/share/page.tsx @@ -1,31 +1,14 @@ import { getPhotoCached } from '@/cache'; import { cameraFromPhoto } from '@/camera'; import PhotoShareModal from '@/photo/PhotoShareModal'; -import { getPhotos, getUniqueCameras } from '@/services/postgres'; import { PATH_ROOT } from '@/site/paths'; import { redirect } from 'next/navigation'; -interface PhotoCameraParams { - params: { photoId: string, camera: string } -} - -export async function generateStaticParams() { - const params: PhotoCameraParams[] = []; - - const cameras = await getUniqueCameras(); - cameras.forEach(async ({ cameraKey, camera }) => { - const photos = await getPhotos({ camera }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, camera: cameraKey }, - }))); - }); - - return params; -} - export default async function Share({ params: { photoId, camera: cameraProp }, -}: PhotoCameraParams) { +}: { + params: { photoId: string, camera: string } +}) { const photo = await getPhotoCached(photoId); if (!photo) { return redirect(PATH_ROOT); } diff --git a/src/app/(static)/tag/[tag]/[photoId]/layout.tsx b/src/app/(static)/tag/[tag]/[photoId]/layout.tsx index 5e3c4e14..95403949 100644 --- a/src/app/(static)/tag/[tag]/[photoId]/layout.tsx +++ b/src/app/(static)/tag/[tag]/[photoId]/layout.tsx @@ -11,7 +11,6 @@ import { } from '@/site/paths'; import PhotoDetailPage from '@/photo/PhotoDetailPage'; import { getPhotoCached } from '@/cache'; -import { getPhotos, getUniqueTags } from '@/services/postgres'; import { getPhotosTagDataCached } from '@/tag/data'; import { ReactNode } from 'react'; @@ -19,20 +18,6 @@ interface PhotoTagProps { params: { photoId: string, tag: string } } -export async function generateStaticParams() { - const params: PhotoTagProps[] = []; - - const tags = await getUniqueTags(); - tags.forEach(async ({ tag }) => { - const photos = await getPhotos({ tag }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, tag }, - }))); - }); - - return params; -} - export async function generateMetadata({ params: { photoId, tag }, }: PhotoTagProps): Promise { diff --git a/src/app/(static)/tag/[tag]/[photoId]/share/page.tsx b/src/app/(static)/tag/[tag]/[photoId]/share/page.tsx index 0a892186..4ae863a0 100644 --- a/src/app/(static)/tag/[tag]/[photoId]/share/page.tsx +++ b/src/app/(static)/tag/[tag]/[photoId]/share/page.tsx @@ -1,30 +1,13 @@ import { getPhotoCached } from '@/cache'; import PhotoShareModal from '@/photo/PhotoShareModal'; -import { getPhotos, getUniqueTags } from '@/services/postgres'; import { PATH_ROOT } from '@/site/paths'; import { redirect } from 'next/navigation'; -interface PhotoTagProps { - params: { photoId: string, tag: string } -} - -export async function generateStaticParams() { - const params: PhotoTagProps[] = []; - - const tags = await getUniqueTags(); - tags.forEach(async ({ tag }) => { - const photos = await getPhotos({ tag }); - params.push(...photos.map(photo => ({ - params: { photoId: photo.id, tag }, - }))); - }); - - return params; -} - export default async function Share({ params: { photoId, tag }, -}: PhotoTagProps) { +}: { + params: { photoId: string, tag: string } +}) { const photo = await getPhotoCached(photoId); if (!photo) { return redirect(PATH_ROOT); } From 186752c177e7f605f9b7928280b1f8d4654ad87d Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 18 Nov 2023 00:27:18 -0600 Subject: [PATCH 6/8] Refine page validation --- src/cache/index.ts | 12 ++++++------ src/photo/actions.ts | 3 +-- src/site/paths.ts | 8 +++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/cache/index.ts b/src/cache/index.ts index 0065894a..042554df 100644 --- a/src/cache/index.ts +++ b/src/cache/index.ts @@ -25,7 +25,7 @@ import { parseCachedPhotoDates, parseCachedPhotosDates } from '@/photo'; import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob'; import type { Session } from 'next-auth'; import { createCameraKey } from '@/camera'; -import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths'; +import { PATHS_ADMIN } from '@/site/paths'; // Table key const KEY_PHOTOS = 'photos'; @@ -102,7 +102,7 @@ export const revalidateAllKeys = () => { export const revalidateAllKeysAndPaths = () => { revalidateAllKeys(); - PATHS_TO_CACHE.forEach(path => revalidatePath(path)); + revalidatePath('/', 'layout'); }; export const revalidateAdminPaths = () => { @@ -125,10 +125,10 @@ export const getPhotosCountCached = ); export const getPhotosCountIncludingHiddenCached = - unstable_cache( - getPhotosCountIncludingHidden, - [KEY_PHOTOS, KEY_COUNT, KEY_HIDDEN], - ); + unstable_cache( + getPhotosCountIncludingHidden, + [KEY_PHOTOS, KEY_COUNT, KEY_HIDDEN], + ); export const getPhotosTagCountCached = unstable_cache( diff --git a/src/photo/actions.ts b/src/photo/actions.ts index 4e42d949..6cf42747 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -56,8 +56,7 @@ export async function deletePhotoAction(formData: FormData) { sqlDeletePhoto(formData.get('id') as string), ]); - revalidatePhotosKey(); - revalidateAdminPaths(); + revalidateAllKeysAndPaths(); }; export async function deletePhotoTagGloballyAction(formData: FormData) { diff --git a/src/site/paths.ts b/src/site/paths.ts index 9acce12f..77c8d9f2 100644 --- a/src/site/paths.ts +++ b/src/site/paths.ts @@ -22,9 +22,10 @@ export const PREFIX_CAMERA = '/shot-on'; export const PREFIX_FILM_SIMULATION = '/film'; // Dynamic paths -const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/:photoId`; -const PATH_TAG_DYNAMIC = `${PREFIX_TAG}/:tag`; -const PATH_CAMERA_DYNAMIC = `${PREFIX_CAMERA}/:camera`; +const PATH_PHOTO_DYNAMIC = `${PREFIX_PHOTO}/[photoId]`; +const PATH_TAG_DYNAMIC = `${PREFIX_TAG}/[tag]`; +const PATH_CAMERA_DYNAMIC = `${PREFIX_CAMERA}/[camera]`; +const PATH_FILM_SIMULATION_DYNAMIC = `${PREFIX_FILM_SIMULATION}/[simulation]`; // Admin paths export const PATH_ADMIN_PHOTOS = `${PATH_ADMIN}/photos`; @@ -55,6 +56,7 @@ export const PATHS_TO_CACHE = [ PATH_PHOTO_DYNAMIC, PATH_TAG_DYNAMIC, PATH_CAMERA_DYNAMIC, + PATH_FILM_SIMULATION_DYNAMIC, ...PATHS_ADMIN, ]; From 20590f6c29b938af97f88a523faf4c33c41ba924 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 18 Nov 2023 11:10:19 -0600 Subject: [PATCH 7/8] Use proper camera-to-key utility --- src/cache/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache/index.ts b/src/cache/index.ts index 042554df..9776b78e 100644 --- a/src/cache/index.ts +++ b/src/cache/index.ts @@ -62,7 +62,7 @@ const getPhotosCacheKeyForOption = ( // Complex keys case 'camera': { const value = options[option]; - return value ? `${option}-${value.make}-${value.model}` : null; + return value ? `${option}-${createCameraKey(value)}` : null; } } }; From 8f45c9efc850379aeae68632e558e09964f444fb Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 18 Nov 2023 14:29:50 -0600 Subject: [PATCH 8/8] Remove edge runtimes --- src/app/(auth-state)/admin/configuration/page.tsx | 2 -- src/app/(auth-state)/admin/tags/[tag]/edit/page.tsx | 2 -- src/app/(auth-state)/admin/tags/page.tsx | 2 -- src/app/(auth-state)/admin/uploads/blob/route.tsx | 2 -- src/app/(static)/film/[simulation]/image/route.tsx | 2 -- src/app/(static)/film/[simulation]/page.tsx | 2 -- src/app/(static)/film/[simulation]/share/page.tsx | 2 -- src/app/(static)/grid/page.tsx | 2 -- src/app/(static)/home-image/route.tsx | 2 -- src/app/(static)/og/page.tsx | 2 -- src/app/(static)/p/[photoId]/image/route.tsx | 2 -- src/app/(static)/p/[photoId]/share/page.tsx | 2 -- src/app/(static)/page.tsx | 2 -- src/app/(static)/sets/page.tsx | 2 -- src/app/(static)/shot-on/[camera]/image/route.tsx | 2 -- src/app/(static)/shot-on/[camera]/page.tsx | 2 -- src/app/(static)/shot-on/[camera]/share/page.tsx | 2 -- src/app/(static)/tag/[tag]/image/route.tsx | 2 -- src/app/(static)/tag/[tag]/page.tsx | 2 -- src/app/(static)/tag/[tag]/share/page.tsx | 2 -- src/app/(static)/template-image-tight/route.tsx | 2 -- src/app/(static)/template-image/route.tsx | 2 -- src/app/sign-in/page.tsx | 2 -- 23 files changed, 46 deletions(-) diff --git a/src/app/(auth-state)/admin/configuration/page.tsx b/src/app/(auth-state)/admin/configuration/page.tsx index aae1e69c..236ee07d 100644 --- a/src/app/(auth-state)/admin/configuration/page.tsx +++ b/src/app/(auth-state)/admin/configuration/page.tsx @@ -5,8 +5,6 @@ import { syncCacheAction } from '@/photo/actions'; import SiteChecklist from '@/site/SiteChecklist'; import { BiTrash } from 'react-icons/bi'; -export const runtime = 'edge'; - export default async function AdminConfigurationPage() { return ( { const body = (await request.json()) as HandleUploadBody; diff --git a/src/app/(static)/film/[simulation]/image/route.tsx b/src/app/(static)/film/[simulation]/image/route.tsx index fafe45ad..538e59c3 100644 --- a/src/app/(static)/film/[simulation]/image/route.tsx +++ b/src/app/(static)/film/[simulation]/image/route.tsx @@ -10,8 +10,6 @@ import { FilmSimulation } from '@/simulation'; import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET( _: Request, context: { params: { simulation: FilmSimulation } }, diff --git a/src/app/(static)/film/[simulation]/page.tsx b/src/app/(static)/film/[simulation]/page.tsx index c80bbade..df7b5f4b 100644 --- a/src/app/(static)/film/[simulation]/page.tsx +++ b/src/app/(static)/film/[simulation]/page.tsx @@ -8,8 +8,6 @@ import { import { PaginationParams } from '@/site/pagination'; import { Metadata } from 'next'; -export const runtime = 'edge'; - interface FilmSimulationProps { params: { simulation: FilmSimulation } } diff --git a/src/app/(static)/film/[simulation]/share/page.tsx b/src/app/(static)/film/[simulation]/share/page.tsx index b26320c3..ca1b82f0 100644 --- a/src/app/(static)/film/[simulation]/share/page.tsx +++ b/src/app/(static)/film/[simulation]/share/page.tsx @@ -9,8 +9,6 @@ import { import { PaginationParams } from '@/site/pagination'; import { Metadata } from 'next'; -export const runtime = 'edge'; - interface FilmSimulationProps { params: { simulation: FilmSimulation } } diff --git a/src/app/(static)/grid/page.tsx b/src/app/(static)/grid/page.tsx index e400c6ba..b2e9b78e 100644 --- a/src/app/(static)/grid/page.tsx +++ b/src/app/(static)/grid/page.tsx @@ -19,8 +19,6 @@ import { import PhotoGridSidebar from '@/photo/PhotoGridSidebar'; import { SHOW_FILM_SIMULATIONS } from '@/site/config'; -export const runtime = 'edge'; - export async function generateMetadata(): Promise { const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }); return generateOgImageMetaForPhotos(photos); diff --git a/src/app/(static)/home-image/route.tsx b/src/app/(static)/home-image/route.tsx index 28a29351..b66b8759 100644 --- a/src/app/(static)/home-image/route.tsx +++ b/src/app/(static)/home-image/route.tsx @@ -8,8 +8,6 @@ import HomeImageResponse from '@/photo/image-response/HomeImageResponse'; import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET() { const [ photos, diff --git a/src/app/(static)/og/page.tsx b/src/app/(static)/og/page.tsx index 11ad9f75..a9f9e2b8 100644 --- a/src/app/(static)/og/page.tsx +++ b/src/app/(static)/og/page.tsx @@ -7,8 +7,6 @@ import { } from '@/site/pagination'; import { pathForOg } from '@/site/paths'; -export const runtime = 'edge'; - export default async function GridPage({ searchParams }: PaginationParams) { const { offset, limit } = getPaginationForSearchParams(searchParams); diff --git a/src/app/(static)/p/[photoId]/image/route.tsx b/src/app/(static)/p/[photoId]/image/route.tsx index ae887b7e..17cc6c29 100644 --- a/src/app/(static)/p/[photoId]/image/route.tsx +++ b/src/app/(static)/p/[photoId]/image/route.tsx @@ -5,8 +5,6 @@ import PhotoImageResponse from '@/photo/image-response/PhotoImageResponse'; import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET( _: Request, context: { params: { photoId: string } }, diff --git a/src/app/(static)/p/[photoId]/share/page.tsx b/src/app/(static)/p/[photoId]/share/page.tsx index 0ffe0e2d..fff8c1ba 100644 --- a/src/app/(static)/p/[photoId]/share/page.tsx +++ b/src/app/(static)/p/[photoId]/share/page.tsx @@ -3,8 +3,6 @@ import PhotoShareModal from '@/photo/PhotoShareModal'; import { PATH_ROOT } from '@/site/paths'; import { redirect } from 'next/navigation'; -export const runtime = 'edge'; - export default async function Share({ params: { photoId }, }: { diff --git a/src/app/(static)/page.tsx b/src/app/(static)/page.tsx index 78fbea0b..39d1c4f8 100644 --- a/src/app/(static)/page.tsx +++ b/src/app/(static)/page.tsx @@ -13,8 +13,6 @@ import { pathForRoot } from '@/site/paths'; import { Metadata } from 'next'; import { MAX_PHOTOS_TO_SHOW_OG } from '@/photo/image-response'; -export const runtime = 'edge'; - export async function generateMetadata(): Promise { const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }); return generateOgImageMetaForPhotos(photos); diff --git a/src/app/(static)/sets/page.tsx b/src/app/(static)/sets/page.tsx index 7a848ee0..9427e65d 100644 --- a/src/app/(static)/sets/page.tsx +++ b/src/app/(static)/sets/page.tsx @@ -15,8 +15,6 @@ import { SHOW_FILM_SIMULATIONS } from '@/site/config'; import { PATH_GRID } from '@/site/paths'; import { Metadata } from 'next'; -export const runtime = 'edge'; - export async function generateMetadata(): Promise { const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }); return generateOgImageMetaForPhotos(photos); diff --git a/src/app/(static)/shot-on/[camera]/image/route.tsx b/src/app/(static)/shot-on/[camera]/image/route.tsx index a453f2a4..78fdd64d 100644 --- a/src/app/(static)/shot-on/[camera]/image/route.tsx +++ b/src/app/(static)/shot-on/[camera]/image/route.tsx @@ -9,8 +9,6 @@ import CameraImageResponse from '@/photo/image-response/CameraImageResponse'; import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET( _: Request, context: { params: { camera: string } }, diff --git a/src/app/(static)/shot-on/[camera]/page.tsx b/src/app/(static)/shot-on/[camera]/page.tsx index ca213df1..c726f350 100644 --- a/src/app/(static)/shot-on/[camera]/page.tsx +++ b/src/app/(static)/shot-on/[camera]/page.tsx @@ -9,8 +9,6 @@ import { } from '@/camera/data'; import CameraOverview from '@/camera/CameraOverview'; -export const runtime = 'edge'; - interface CameraProps { params: { camera: string }, } diff --git a/src/app/(static)/shot-on/[camera]/share/page.tsx b/src/app/(static)/shot-on/[camera]/share/page.tsx index 1c8b51f2..cc684ea7 100644 --- a/src/app/(static)/shot-on/[camera]/share/page.tsx +++ b/src/app/(static)/shot-on/[camera]/share/page.tsx @@ -10,8 +10,6 @@ import { } from '@/camera/data'; import CameraOverview from '@/camera/CameraOverview'; -export const runtime = 'edge'; - interface CameraProps { params: { camera: string } } diff --git a/src/app/(static)/tag/[tag]/image/route.tsx b/src/app/(static)/tag/[tag]/image/route.tsx index 76c76d5d..5a55db79 100644 --- a/src/app/(static)/tag/[tag]/image/route.tsx +++ b/src/app/(static)/tag/[tag]/image/route.tsx @@ -8,8 +8,6 @@ import TagImageResponse from '@/photo/image-response/TagImageResponse'; import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET( _: Request, context: { params: { tag: string } }, diff --git a/src/app/(static)/tag/[tag]/page.tsx b/src/app/(static)/tag/[tag]/page.tsx index 30e1193b..72f74459 100644 --- a/src/app/(static)/tag/[tag]/page.tsx +++ b/src/app/(static)/tag/[tag]/page.tsx @@ -8,8 +8,6 @@ import { } from '@/tag/data'; import { Metadata } from 'next'; -export const runtime = 'edge'; - interface TagProps { params: { tag: string } } diff --git a/src/app/(static)/tag/[tag]/share/page.tsx b/src/app/(static)/tag/[tag]/share/page.tsx index ace9bc48..a7f3caba 100644 --- a/src/app/(static)/tag/[tag]/share/page.tsx +++ b/src/app/(static)/tag/[tag]/share/page.tsx @@ -9,8 +9,6 @@ import { } from '@/tag/data'; import { Metadata } from 'next'; -export const runtime = 'edge'; - interface TagProps { params: { tag: string } } diff --git a/src/app/(static)/template-image-tight/route.tsx b/src/app/(static)/template-image-tight/route.tsx index 3808d205..10434ab9 100644 --- a/src/app/(static)/template-image-tight/route.tsx +++ b/src/app/(static)/template-image-tight/route.tsx @@ -9,8 +9,6 @@ import TemplateImageResponse from import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET() { const [ photos, diff --git a/src/app/(static)/template-image/route.tsx b/src/app/(static)/template-image/route.tsx index a852fc7e..b07df965 100644 --- a/src/app/(static)/template-image/route.tsx +++ b/src/app/(static)/template-image/route.tsx @@ -9,8 +9,6 @@ import TemplateImageResponse from import { getIBMPlexMonoMedium } from '@/site/font'; import { ImageResponse } from 'next/og'; -export const runtime = 'edge'; - export async function GET() { const [ photos, diff --git a/src/app/sign-in/page.tsx b/src/app/sign-in/page.tsx index c193da1f..61d6dd11 100644 --- a/src/app/sign-in/page.tsx +++ b/src/app/sign-in/page.tsx @@ -4,8 +4,6 @@ import { PATH_ADMIN } from '@/site/paths'; import { cc } from '@/utility/css'; import { redirect } from 'next/navigation'; -export const runtime = 'edge'; - export default async function SignInPage() { const session = await auth();