From b32852188798b07c2074aa44cc037c56e3d380c9 Mon Sep 17 00:00:00 2001 From: samwisekind Date: Mon, 28 Oct 2024 13:22:47 +0000 Subject: [PATCH] Updates --- README.md | 1 - eslint.config.mjs | 44 ++++++--- jest.setup.ts | 2 + next.config.js => next.config.ts | 10 +- package-lock.json | 117 +++++++++++++++++++----- package.json | 7 +- src/components/Filters/Filters.tsx | 4 +- src/helpers/contentful.spec.ts | 2 +- src/pages/api/catalogues/[catalogue].ts | 9 +- src/pages/api/report-sighting.ts | 11 +-- 10 files changed, 143 insertions(+), 64 deletions(-) rename next.config.js => next.config.ts (82%) 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 f7f1b17..9d25323 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "@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", @@ -17,11 +16,11 @@ "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,25 +2123,50 @@ "@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": { - "whatwg-fetch": "^3.6.2" + "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": { + "@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": "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/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": "15.0.1", @@ -4469,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" @@ -4491,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": { @@ -4498,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" @@ -4508,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" }, @@ -4519,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", @@ -5080,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" } @@ -5500,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", @@ -5532,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", @@ -11997,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", @@ -12035,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" }, @@ -12095,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" } @@ -12103,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", @@ -13397,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 92db560..3ea8c4a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "@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", @@ -24,11 +23,11 @@ "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;