diff --git a/README.md b/README.md index c88da31..c16e467 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ The following environment variables should be provided when running the server ( | `NODE_SMTP_USERNAME` | SMTP username for sending emails. | | `NODE_SMTP_PASSWORD` | SMTP password for sending emails. | | `NODE_SIGHTING_EMAIL` | Email address to send sightings to. | -| `LOGTAIL_SOURCE_TOKEN` | Token for Better Stack Logs. | ## Development diff --git a/eslint.config.mjs b/eslint.config.mjs index b6374fb..69f3259 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,12 +1,31 @@ import globals from 'globals'; -import pluginJs from '@eslint/js'; -import tseslint from 'typescript-eslint'; +import pluginJS from '@eslint/js'; +import pluginTS from 'typescript-eslint'; import pluginReact from 'eslint-plugin-react'; +import pluginReactHooks from 'eslint-plugin-react-hooks'; +import pluginNext from '@next/eslint-plugin-next'; +import pluginJest from 'eslint-plugin-jest'; const recommendedConfigs = [ - pluginJs.configs.recommended, - ...tseslint.configs.recommended, + pluginJS.configs.recommended, + ...pluginTS.configs.recommended, pluginReact.configs.flat.recommended, + pluginJest.configs['flat/recommended'], + + // Custom config until packages support flat configs + { + files: ['src/**/*.{js,ts,jsx,tsx}'], + plugins: { + 'react-hooks': pluginReactHooks, + '@next/next': pluginNext, + }, + rules: { + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + ...pluginReactHooks.configs.recommended.rules, + ...pluginNext.configs.recommended.rules, + }, + }, ]; const customConfigs = [ @@ -15,8 +34,8 @@ const customConfigs = [ }, { ignores: [ - ".next/", - "coverage/", + '.next/', + 'coverage/', ], }, { @@ -27,14 +46,11 @@ const customConfigs = [ }, }, { - languageOptions: { globals: {...globals.browser, ...globals.node} }, - }, - { - rules: { - '@typescript-eslint/no-unsafe-function-type': 'off', - '@typescript-eslint/no-require-imports': 'off', - 'react/prop-types': 'off', - 'react/react-in-jsx-scope': 'off', + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, }, }, ]; diff --git a/jest.setup.ts b/jest.setup.ts index 516cf02..6a8516f 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ + process.env.NODE_CONTENTFUL_SPACE_ID = 'mocked-contentful-space-id'; process.env.NODE_CONTENTFUL_ENVIRONMENT = 'mocked-contentful-environment'; process.env.NODE_CONTENTFUL_DELIVERY_API_TOKEN = 'mocked-contentful-delivery-api-token'; diff --git a/next.config.js b/next.config.ts similarity index 82% rename from next.config.js rename to next.config.ts index 13e1b20..6d149fd 100644 --- a/next.config.js +++ b/next.config.ts @@ -1,10 +1,8 @@ -/** @type {import('next').NextConfig} */ +import type { NextConfig } from 'next'; -const { withLogtail } = require('@logtail/next'); +import redirects from './redirects.json'; -const redirects = require('./redirects.json'); - -const nextConfig = { +const nextConfig: NextConfig = { reactStrictMode: true, poweredByHeader: false, experimental: { @@ -50,4 +48,4 @@ const nextConfig = { }, }; -module.exports = withLogtail(nextConfig); +module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json index 7058d0a..9d25323 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,19 +9,18 @@ "@contentful/live-preview": "^4.5.13", "@contentful/rich-text-plain-text-renderer": "^16.2.10", "@contentful/rich-text-react-renderer": "^15.22.11", - "@logtail/next": "^0.1.5", "contentful": "^11.2.0", "dayjs": "^1.11.13", "joi": "^17.13.3", - "next": "^14.2.15", + "next": "^15.0.1", "next-seo": "^6.6.0", "nodemailer": "^6.9.15", "react": "^18.3.1", - "react-markdown": "^9.0.1", - "sharp": "^0.33.5" + "react-markdown": "^9.0.1" }, "devDependencies": { "@eslint/js": "^9.13.0", + "@next/eslint-plugin-next": "^15.0.1", "@testing-library/jest-dom": "^6.6.2", "@testing-library/react": "^16.0.1", "@types/jest": "^29.5.14", @@ -31,7 +30,9 @@ "@types/react": "^18.3.12", "babel-jest": "^29.7.0", "eslint": "^9.13.0", + "eslint-plugin-jest": "^28.8.3", "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", "globals": "^15.11.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", @@ -2122,30 +2123,55 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@logtail/next": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@logtail/next/-/next-0.1.5.tgz", - "integrity": "sha512-J8m9jGdcGjYfKEbB1pdQj9iaBq9eNtHtqNcrHStjGI1LPiGREwk+HnnpM12yS6teiwlQepcXJDtQ8fk1QHg+jw==", + "node_modules/@next/env": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.1.tgz", + "integrity": "sha512-lc4HeDUKO9gxxlM5G2knTRifqhsY6yYpwuHspBZdboZe0Gp+rZHBNNSIjmQKDJIdRXiXGyVnSD6gafrbQPvILQ==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.0.1.tgz", + "integrity": "sha512-bKWsMaGPbiFAaGqrDJvbE8b4Z0uKicGVcgOI77YM2ui3UfjHMr4emFPrZTLeZVchi7fT1mooG2LxREfUUClIKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, "license": "MIT", "dependencies": { - "whatwg-fetch": "^3.6.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=15" - }, - "peerDependencies": { - "next": "^12.1.4 || ^13 || ^14" + "node": ">=8.6.0" } }, - "node_modules/@next/env": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz", - "integrity": "sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==" + "node_modules/@next/eslint-plugin-next/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz", - "integrity": "sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.1.tgz", + "integrity": "sha512-C9k/Xv4sxkQRTA37Z6MzNq3Yb1BJMmSqjmwowoWEpbXTkAdfOwnoKOpAb71ItSzoA26yUTIo6ZhN8rKGu4ExQw==", "cpu": [ "arm64" ], @@ -2158,9 +2184,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz", - "integrity": "sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.1.tgz", + "integrity": "sha512-uHl13HXOuq1G7ovWFxCACDJHTSDVbn/sbLv8V1p+7KIvTrYQ5HNoSmKBdYeEKRRCbEmd+OohOgg9YOp8Ux3MBg==", "cpu": [ "x64" ], @@ -2173,9 +2199,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz", - "integrity": "sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.1.tgz", + "integrity": "sha512-LvyhvxHOihFTEIbb35KxOc3q8w8G4xAAAH/AQnsYDEnOvwawjL2eawsB59AX02ki6LJdgDaHoTEnC54Gw+82xw==", "cpu": [ "arm64" ], @@ -2188,9 +2214,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz", - "integrity": "sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.1.tgz", + "integrity": "sha512-vFmCGUFNyk/A5/BYcQNhAQqPIw01RJaK6dRO+ZEhz0DncoW+hJW1kZ8aH2UvTX27zPq3m85zN5waMSbZEmANcQ==", "cpu": [ "arm64" ], @@ -2203,9 +2229,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz", - "integrity": "sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.1.tgz", + "integrity": "sha512-5by7IYq0NCF8rouz6Qg9T97jYU68kaClHPfGpQG2lCZpSYHtSPQF1kjnqBTd34RIqPKMbCa4DqCufirgr8HM5w==", "cpu": [ "x64" ], @@ -2218,9 +2244,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz", - "integrity": "sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.1.tgz", + "integrity": "sha512-lmYr6H3JyDNBJLzklGXLfbehU3ay78a+b6UmBGlHls4xhDXBNZfgb0aI67sflrX+cGBnv1LgmWzFlYrAYxS1Qw==", "cpu": [ "x64" ], @@ -2233,9 +2259,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz", - "integrity": "sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.1.tgz", + "integrity": "sha512-DS8wQtl6diAj0eZTdH0sefykm4iXMbHT4MOvLwqZiIkeezKpkgPFcEdFlz3vKvXa2R/2UEgMh48z1nEpNhjeOQ==", "cpu": [ "arm64" ], @@ -2247,25 +2273,10 @@ "node": ">= 10" } }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz", - "integrity": "sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz", - "integrity": "sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.1.tgz", + "integrity": "sha512-4Ho2ggvDdMKlZ/0e9HNdZ9ngeaBwtc+2VS5oCeqrbXqOgutX6I4U2X/42VBw0o+M5evn4/7v3zKgGHo+9v/VjA==", "cpu": [ "x64" ], @@ -2673,16 +2684,13 @@ "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" }, "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", - "license": "Apache-2.0", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", "dependencies": { - "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, @@ -4447,8 +4455,7 @@ "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/cliui": { "version": "8.0.1", @@ -4488,6 +4495,7 @@ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "license": "MIT", + "optional": true, "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -4510,6 +4518,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true, "license": "MIT" }, "node_modules/color-string": { @@ -4517,6 +4526,7 @@ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "license": "MIT", + "optional": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -4527,6 +4537,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", + "optional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -4538,7 +4549,8 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/colord": { "version": "2.9.3", @@ -5099,6 +5111,7 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "license": "Apache-2.0", + "optional": true, "engines": { "node": ">=8" } @@ -5519,6 +5532,32 @@ } } }, + "node_modules/eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "engines": { + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react": { "version": "7.37.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", @@ -5551,6 +5590,19 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, "node_modules/eslint-scope": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", @@ -6361,6 +6413,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -10708,40 +10761,41 @@ } }, "node_modules/next": { - "version": "14.2.15", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.15.tgz", - "integrity": "sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/next/-/next-15.0.1.tgz", + "integrity": "sha512-PSkFkr/w7UnFWm+EP8y/QpHrJXMqpZzAXpergB/EqLPOh4SGPJXv1wj4mslr2hUZBAS9pX7/9YLIdxTv6fwytw==", "dependencies": { - "@next/env": "14.2.15", - "@swc/helpers": "0.5.5", + "@next/env": "15.0.1", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.13", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", "postcss": "8.4.31", - "styled-jsx": "5.1.1" + "styled-jsx": "5.1.6" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=18.17.0" + "node": ">=18.18.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.15", - "@next/swc-darwin-x64": "14.2.15", - "@next/swc-linux-arm64-gnu": "14.2.15", - "@next/swc-linux-arm64-musl": "14.2.15", - "@next/swc-linux-x64-gnu": "14.2.15", - "@next/swc-linux-x64-musl": "14.2.15", - "@next/swc-win32-arm64-msvc": "14.2.15", - "@next/swc-win32-ia32-msvc": "14.2.15", - "@next/swc-win32-x64-msvc": "14.2.15" + "@next/swc-darwin-arm64": "15.0.1", + "@next/swc-darwin-x64": "15.0.1", + "@next/swc-linux-arm64-gnu": "15.0.1", + "@next/swc-linux-arm64-musl": "15.0.1", + "@next/swc-linux-x64-gnu": "15.0.1", + "@next/swc-linux-x64-musl": "15.0.1", + "@next/swc-win32-arm64-msvc": "15.0.1", + "@next/swc-win32-x64-msvc": "15.0.1", + "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-69d4b800-20241021", + "react-dom": "^18.2.0 || 19.0.0-rc-69d4b800-20241021", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -10751,6 +10805,9 @@ "@playwright/test": { "optional": true }, + "babel-plugin-react-compiler": { + "optional": true + }, "sass": { "optional": true } @@ -12011,6 +12068,7 @@ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", "hasInstallScript": true, + "optional": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", @@ -12049,6 +12107,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", + "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -12109,6 +12168,7 @@ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "license": "MIT", + "optional": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -12117,7 +12177,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/sisteransi": { "version": "1.0.5", @@ -12475,10 +12536,9 @@ } }, "node_modules/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", "dependencies": { "client-only": "0.0.1" }, @@ -12486,7 +12546,7 @@ "node": ">= 12.0.0" }, "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" }, "peerDependenciesMeta": { "@babel/core": { @@ -13412,12 +13472,6 @@ "node": ">=12" } }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", - "license": "MIT" - }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", diff --git a/package.json b/package.json index be15a4d..3ea8c4a 100644 --- a/package.json +++ b/package.json @@ -16,19 +16,18 @@ "@contentful/live-preview": "^4.5.13", "@contentful/rich-text-plain-text-renderer": "^16.2.10", "@contentful/rich-text-react-renderer": "^15.22.11", - "@logtail/next": "^0.1.5", "contentful": "^11.2.0", "dayjs": "^1.11.13", "joi": "^17.13.3", - "next": "^14.2.15", + "next": "^15.0.1", "next-seo": "^6.6.0", "nodemailer": "^6.9.15", "react": "^18.3.1", - "react-markdown": "^9.0.1", - "sharp": "^0.33.5" + "react-markdown": "^9.0.1" }, "devDependencies": { "@eslint/js": "^9.13.0", + "@next/eslint-plugin-next": "^15.0.1", "@testing-library/jest-dom": "^6.6.2", "@testing-library/react": "^16.0.1", "@types/jest": "^29.5.14", @@ -38,7 +37,9 @@ "@types/react": "^18.3.12", "babel-jest": "^29.7.0", "eslint": "^9.13.0", + "eslint-plugin-jest": "^28.8.3", "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", "globals": "^15.11.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", diff --git a/src/components/Filters/Filters.tsx b/src/components/Filters/Filters.tsx index a8d2cf3..ab457c9 100644 --- a/src/components/Filters/Filters.tsx +++ b/src/components/Filters/Filters.tsx @@ -1,7 +1,7 @@ import styles from './Filters.module.scss'; interface UseSearchProps { - callback: Function, + callback: Function, // eslint-disable-line @typescript-eslint/no-unsafe-function-type label?: string, defaultValue?: string, } @@ -29,7 +29,7 @@ interface DropdownProps { text: string, value: string, }>, - callback: Function, + callback: Function, // eslint-disable-line @typescript-eslint/no-unsafe-function-type } const UseDropdown = ({ diff --git a/src/helpers/contentful.spec.ts b/src/helpers/contentful.spec.ts index 3ba8252..0faab24 100644 --- a/src/helpers/contentful.spec.ts +++ b/src/helpers/contentful.spec.ts @@ -7,7 +7,7 @@ jest.mock('contentful', () => ({ })); beforeAll(() => { - require('./contentful'); + require('./contentful'); // eslint-disable-line @typescript-eslint/no-require-imports }); afterEach(() => { diff --git a/src/pages/api/catalogues/[catalogue].ts b/src/pages/api/catalogues/[catalogue].ts index b651372..aecc1b3 100644 --- a/src/pages/api/catalogues/[catalogue].ts +++ b/src/pages/api/catalogues/[catalogue].ts @@ -1,15 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { NextApiResponse } from 'next'; -import type { LogtailAPIRequest } from '@logtail/next'; - -import { withLogtail } from '@logtail/next'; +import type { NextApiRequest, NextApiResponse } from 'next'; import { Catalogues } from '@/helpers/constants'; import { getCatalogueList } from '@/helpers/getCatalogue'; const handler = async ( - req: LogtailAPIRequest, + req: NextApiRequest, res: NextApiResponse, ) => { if (req.method !== 'GET') { @@ -52,4 +49,4 @@ const handler = async ( return res.json(data); }; -export default withLogtail(handler); +export default handler; diff --git a/src/pages/api/report-sighting.ts b/src/pages/api/report-sighting.ts index cdb8a45..9b76490 100644 --- a/src/pages/api/report-sighting.ts +++ b/src/pages/api/report-sighting.ts @@ -1,7 +1,4 @@ -import type { NextApiResponse } from 'next'; -import type { LogtailAPIRequest } from '@logtail/next'; - -import { withLogtail } from '@logtail/next'; +import type { NextApiRequest, NextApiResponse } from 'next'; import joi from 'joi'; import nodemailer from 'nodemailer'; @@ -35,7 +32,7 @@ const mailerTransporter = nodemailer.createTransport({ }); const handler = async ( - req: LogtailAPIRequest, + req: NextApiRequest, res: NextApiResponse, ) => { const { headers, body } = req; @@ -91,7 +88,7 @@ const handler = async ( html: Object.entries(body).map(([key, value]) => `${key.toUpperCase()}: ${value}`).join('
'), }); } catch (error) { - req.log.error('Unable to send email:', { error }); + console.error('Unable to send email:', { error }); return res.status(500).json({ success: false, @@ -106,4 +103,4 @@ const handler = async ( }); }; -export default withLogtail(handler); +export default handler;