Update to Next.js 16 and enhance ESLint configuration

- Migrated from Next.js 15 to Next.js 16, updating all related dependencies and configurations.
- Enhanced ESLint setup with stricter rules, expanded plugin support, and improved type-aware linting options.
- Archived middleware by renaming it to `middleware.disabled.ts` for potential future use.
This commit is contained in:
Felipe Cardoso
2025-11-20 12:49:45 +01:00
parent 444d495f83
commit 5a21847382
7 changed files with 277 additions and 148 deletions

View File

@@ -6,7 +6,7 @@ Production-ready Next.js 15 frontend with TypeScript, authentication, admin pane
### Core
-**Next.js 15** - App Router with React Server Components
-**Next.js 16** - App Router with React Server Components
- 📘 **TypeScript** - Full type safety
- 🎨 **Tailwind CSS** - Utility-first styling
- 🧩 **shadcn/ui** - High-quality component library
@@ -218,7 +218,7 @@ npm run test:e2e:debug
## Tech Stack
- **Framework**: Next.js 15 (App Router)
- **Framework**: Next.js 16 (App Router)
- **Language**: TypeScript 5
- **Styling**: Tailwind CSS 3 + shadcn/ui
- **State Management**: Zustand + TanStack Query

View File

@@ -1,18 +1,13 @@
import { FlatCompat } from '@eslint/eslintrc';
import path from 'path';
import { fileURLToPath } from 'url';
import nextPlugin from '@next/eslint-plugin-next';
import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import jsxA11y from 'eslint-plugin-jsx-a11y';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const nextCoreWebVitalsRules = nextPlugin.configs['core-web-vitals']?.rules ?? {};
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends('next/core-web-vitals'),
...compat.extends('next/typescript'),
...compat.extends('prettier'), // Disable ESLint rules that conflict with Prettier
export default [
// Ignores
{
ignores: [
'node_modules/**',
@@ -25,8 +20,43 @@ const eslintConfig = [
'*.gen.ts',
'*.gen.tsx',
'next-env.d.ts', // Auto-generated by Next.js
'eslint.config.mjs', // Do not lint the ESLint config itself
],
},
// TypeScript recommended (non-type-checked) rules for broader compatibility
...tseslint.configs.recommended,
// If you want type-aware linting, uncomment below and switch to `recommendedTypeChecked`
// {
// files: ['**/*.{ts,tsx}'],
// languageOptions: {
// parserOptions: {
// project: ['./tsconfig.json'],
// tsconfigRootDir: new URL('.', import.meta.url).pathname,
// },
// },
// },
// Next.js + React rules (Core Web Vitals)
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: {
'@next/next': nextPlugin,
react: reactPlugin,
'react-hooks': reactHooks,
'jsx-a11y': jsxA11y,
},
settings: {
react: {
version: 'detect',
},
},
rules: {
...nextCoreWebVitalsRules,
},
},
// Base rules for source code
{
files: ['src/**/*.{ts,tsx}'],
@@ -50,6 +80,7 @@ const eslintConfig = [
],
},
},
// Relaxed rules for test files
{
files: ['tests/**/*.{ts,tsx}', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'],
@@ -68,6 +99,7 @@ const eslintConfig = [
],
},
},
// Relaxed rules for E2E tests
{
files: ['e2e/**/*.{ts,tsx}'],
@@ -83,6 +115,7 @@ const eslintConfig = [
],
},
},
// Relaxed rules for scripts and config files
{
files: ['scripts/**/*.{ts,js}', '*.config.{ts,js,mjs}', 'jest.setup.js'],
@@ -101,5 +134,3 @@ const eslintConfig = [
},
},
];
export default eslintConfig;

View File

@@ -15,14 +15,9 @@ const nextConfig: NextConfig = {
},
];
},
// ESLint configuration
eslint: {
ignoreDuringBuilds: false,
dirs: ['src'],
},
// Production optimizations
reactStrictMode: true,
// Note: swcMinify is default in Next.js 15
// Note: SWC minification is default in Next.js 16
};
// Wrap config with next-intl plugin

View File

@@ -30,7 +30,7 @@
"framer-motion": "^12.23.24",
"gray-matter": "^4.0.3",
"lucide-react": "^0.552.0",
"next": "^15.5.6",
"next": "^16",
"next-intl": "^4.5.3",
"next-themes": "^0.4.6",
"react": "^19.0.0",
@@ -63,14 +63,18 @@
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.2.0",
"eslint-config-next": "^16",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0",
"lighthouse": "^12.8.2",
"prettier": "^3.6.2",
"tailwindcss": "^4",
"typescript": "^5",
"typescript-eslint": "^8.15.0",
"whatwg-fetch": "^3.6.20"
}
},
@@ -2313,15 +2317,15 @@
}
},
"node_modules/@next/env": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.6.tgz",
"integrity": "sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.3.tgz",
"integrity": "sha512-IqgtY5Vwsm14mm/nmQaRMmywCU+yyMIYfk3/MHZ2ZTJvwVbBn3usZnjMi1GacrMVzVcAxJShTCpZlPs26EdEjQ==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
"version": "15.2.0",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.2.0.tgz",
"integrity": "sha512-jHFUG2OwmAuOASqq253RAEG/5BYcPHn27p1NoWZDCf4OdvdK0yRYWX92YKkL+Mk2s+GyJrmd/GATlL5b2IySpw==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.0.3.tgz",
"integrity": "sha512-6sPWmZetzFWMsz7Dhuxsdmbu3fK+/AxKRtj7OB0/3OZAI2MHB/v2FeYh271LZ9abvnM1WIwWc/5umYjx0jo5sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2329,9 +2333,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.6.tgz",
"integrity": "sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.3.tgz",
"integrity": "sha512-MOnbd92+OByu0p6QBAzq1ahVWzF6nyfiH07dQDez4/Nku7G249NjxDVyEfVhz8WkLiOEU+KFVnqtgcsfP2nLXg==",
"cpu": [
"arm64"
],
@@ -2345,9 +2349,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.6.tgz",
"integrity": "sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.3.tgz",
"integrity": "sha512-i70C4O1VmbTivYdRlk+5lj9xRc2BlK3oUikt3yJeHT1unL4LsNtN7UiOhVanFdc7vDAgZn1tV/9mQwMkWOJvHg==",
"cpu": [
"x64"
],
@@ -2361,9 +2365,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.6.tgz",
"integrity": "sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.3.tgz",
"integrity": "sha512-O88gCZ95sScwD00mn/AtalyCoykhhlokxH/wi1huFK+rmiP5LAYVs/i2ruk7xST6SuXN4NI5y4Xf5vepb2jf6A==",
"cpu": [
"arm64"
],
@@ -2377,9 +2381,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.6.tgz",
"integrity": "sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.3.tgz",
"integrity": "sha512-CEErFt78S/zYXzFIiv18iQCbRbLgBluS8z1TNDQoyPi8/Jr5qhR3e8XHAIxVxPBjDbEMITprqELVc5KTfFj0gg==",
"cpu": [
"arm64"
],
@@ -2393,9 +2397,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.6.tgz",
"integrity": "sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.3.tgz",
"integrity": "sha512-Tc3i+nwt6mQ+Dwzcri/WNDj56iWdycGVh5YwwklleClzPzz7UpfaMw1ci7bLl6GRYMXhWDBfe707EXNjKtiswQ==",
"cpu": [
"x64"
],
@@ -2409,9 +2413,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.6.tgz",
"integrity": "sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.3.tgz",
"integrity": "sha512-zTh03Z/5PBBPdTurgEtr6nY0vI9KR9Ifp/jZCcHlODzwVOEKcKRBtQIGrkc7izFgOMuXDEJBmirwpGqdM/ZixA==",
"cpu": [
"x64"
],
@@ -2425,9 +2429,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.6.tgz",
"integrity": "sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.3.tgz",
"integrity": "sha512-Jc1EHxtZovcJcg5zU43X3tuqzl/sS+CmLgjRP28ZT4vk869Ncm2NoF8qSTaL99gh6uOzgM99Shct06pSO6kA6g==",
"cpu": [
"arm64"
],
@@ -2441,9 +2445,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.6.tgz",
"integrity": "sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.3.tgz",
"integrity": "sha512-N7EJ6zbxgIYpI/sWNzpVKRMbfEGgsWuOIvzkML7wxAAZhPk1Msxuo/JDu1PKjWGrAoOLaZcIX5s+/pF5LIbBBg==",
"cpu": [
"x64"
],
@@ -4249,13 +4253,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@rushstack/eslint-patch": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz",
"integrity": "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@schummar/icu-type-parser": {
"version": "1.21.5",
"resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz",
@@ -5466,17 +5463,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz",
"integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.47.0.tgz",
"integrity": "sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/type-utils": "8.46.2",
"@typescript-eslint/utils": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"@typescript-eslint/scope-manager": "8.47.0",
"@typescript-eslint/type-utils": "8.47.0",
"@typescript-eslint/utils": "8.47.0",
"@typescript-eslint/visitor-keys": "8.47.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -5490,7 +5487,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.46.2",
"@typescript-eslint/parser": "^8.47.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
@@ -5506,16 +5503,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz",
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.47.0.tgz",
"integrity": "sha512-lJi3PfxVmo0AkEY93ecfN+r8SofEqZNGByvHAI3GBLrvt1Cw6H5k1IM02nSzu0RfUafr2EvFSw0wAsZgubNplQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"@typescript-eslint/scope-manager": "8.47.0",
"@typescript-eslint/types": "8.47.0",
"@typescript-eslint/typescript-estree": "8.47.0",
"@typescript-eslint/visitor-keys": "8.47.0",
"debug": "^4.3.4"
},
"engines": {
@@ -5531,14 +5528,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz",
"integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.47.0.tgz",
"integrity": "sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.46.2",
"@typescript-eslint/types": "^8.46.2",
"@typescript-eslint/tsconfig-utils": "^8.47.0",
"@typescript-eslint/types": "^8.47.0",
"debug": "^4.3.4"
},
"engines": {
@@ -5553,14 +5550,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz",
"integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.47.0.tgz",
"integrity": "sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2"
"@typescript-eslint/types": "8.47.0",
"@typescript-eslint/visitor-keys": "8.47.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -5571,9 +5568,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz",
"integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.47.0.tgz",
"integrity": "sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5588,15 +5585,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz",
"integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.47.0.tgz",
"integrity": "sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2",
"@typescript-eslint/utils": "8.46.2",
"@typescript-eslint/types": "8.47.0",
"@typescript-eslint/typescript-estree": "8.47.0",
"@typescript-eslint/utils": "8.47.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -5613,9 +5610,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz",
"integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.47.0.tgz",
"integrity": "sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5627,16 +5624,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz",
"integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.47.0.tgz",
"integrity": "sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.46.2",
"@typescript-eslint/tsconfig-utils": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/visitor-keys": "8.46.2",
"@typescript-eslint/project-service": "8.47.0",
"@typescript-eslint/tsconfig-utils": "8.47.0",
"@typescript-eslint/types": "8.47.0",
"@typescript-eslint/visitor-keys": "8.47.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -5712,16 +5709,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz",
"integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.47.0.tgz",
"integrity": "sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/typescript-estree": "8.46.2"
"@typescript-eslint/scope-manager": "8.47.0",
"@typescript-eslint/types": "8.47.0",
"@typescript-eslint/typescript-estree": "8.47.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -5736,13 +5733,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.46.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz",
"integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.47.0.tgz",
"integrity": "sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.46.2",
"@typescript-eslint/types": "8.47.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -8351,25 +8348,24 @@
}
},
"node_modules/eslint-config-next": {
"version": "15.2.0",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.2.0.tgz",
"integrity": "sha512-LkG0KKpinAoNPk2HXSx0fImFb/hQ6RnhSxTkpJFTkQ0SmnzsbRsjjN95WC/mDY34nKOenpptYEVvfkCR/h+VjA==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.0.3.tgz",
"integrity": "sha512-5F6qDjcZldf0Y0ZbqvWvap9xzYUxyDf7/of37aeyhvkrQokj/4bT1JYWZdlWUr283aeVa+s52mPq9ogmGg+5dw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@next/eslint-plugin-next": "15.2.0",
"@rushstack/eslint-patch": "^1.10.3",
"@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"@next/eslint-plugin-next": "16.0.3",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.37.0",
"eslint-plugin-react-hooks": "^5.0.0"
"eslint-plugin-react-hooks": "^7.0.0",
"globals": "16.4.0",
"typescript-eslint": "^8.46.0"
},
"peerDependencies": {
"eslint": "^7.23.0 || ^8.0.0 || ^9.0.0",
"eslint": ">=9.0.0",
"typescript": ">=3.3.1"
},
"peerDependenciesMeta": {
@@ -8378,6 +8374,39 @@
}
}
},
"node_modules/eslint-config-next/node_modules/eslint-plugin-react-hooks": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz",
"integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/parser": "^7.24.4",
"hermes-parser": "^0.25.1",
"zod": "^3.25.0 || ^4.0.0",
"zod-validation-error": "^3.5.0 || ^4.0.0"
},
"engines": {
"node": ">=18"
},
"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-config-next/node_modules/globals": {
"version": "16.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
"integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-config-prettier": {
"version": "10.1.8",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
@@ -9814,6 +9843,23 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/hermes-estree": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
"integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
"dev": true,
"license": "MIT"
},
"node_modules/hermes-parser": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
"integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"hermes-estree": "0.25.1"
}
},
"node_modules/highlight.js": {
"version": "11.11.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
@@ -13592,12 +13638,12 @@
}
},
"node_modules/next": {
"version": "15.5.6",
"resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz",
"integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/next/-/next-16.0.3.tgz",
"integrity": "sha512-Ka0/iNBblPFcIubTA1Jjh6gvwqfjrGq1Y2MTI5lbjeLIAfmC+p5bQmojpRZqgHHVu5cG4+qdIiwXiBSm/8lZ3w==",
"license": "MIT",
"dependencies": {
"@next/env": "15.5.6",
"@next/env": "16.0.3",
"@swc/helpers": "0.5.15",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
@@ -13607,18 +13653,18 @@
"next": "dist/bin/next"
},
"engines": {
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
"node": ">=20.9.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "15.5.6",
"@next/swc-darwin-x64": "15.5.6",
"@next/swc-linux-arm64-gnu": "15.5.6",
"@next/swc-linux-arm64-musl": "15.5.6",
"@next/swc-linux-x64-gnu": "15.5.6",
"@next/swc-linux-x64-musl": "15.5.6",
"@next/swc-win32-arm64-msvc": "15.5.6",
"@next/swc-win32-x64-msvc": "15.5.6",
"sharp": "^0.34.3"
"@next/swc-darwin-arm64": "16.0.3",
"@next/swc-darwin-x64": "16.0.3",
"@next/swc-linux-arm64-gnu": "16.0.3",
"@next/swc-linux-arm64-musl": "16.0.3",
"@next/swc-linux-x64-gnu": "16.0.3",
"@next/swc-linux-x64-musl": "16.0.3",
"@next/swc-win32-arm64-msvc": "16.0.3",
"@next/swc-win32-x64-msvc": "16.0.3",
"sharp": "^0.34.4"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -16816,6 +16862,30 @@
"node": ">=14.17"
}
},
"node_modules/typescript-eslint": {
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.47.0.tgz",
"integrity": "sha512-Lwe8i2XQ3WoMjua/r1PHrCTpkubPYJCAfOurtn+mtTzqB6jNd+14n9UN1bJ4s3F49x9ixAm0FLflB/JzQ57M8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.47.0",
"@typescript-eslint/parser": "8.47.0",
"@typescript-eslint/typescript-estree": "8.47.0",
"@typescript-eslint/utils": "8.47.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/uglify-js": {
"version": "3.19.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
@@ -17749,6 +17819,19 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-validation-error": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
"integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
},
"node_modules/zustand": {
"version": "4.5.7",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",

View File

@@ -44,7 +44,7 @@
"framer-motion": "^12.23.24",
"gray-matter": "^4.0.3",
"lucide-react": "^0.552.0",
"next": "^15.5.6",
"next": "^16",
"next-intl": "^4.5.3",
"next-themes": "^0.4.6",
"react": "^19.0.0",
@@ -77,14 +77,18 @@
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.2.0",
"eslint-config-next": "^16",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0",
"lighthouse": "^12.8.2",
"prettier": "^3.6.2",
"tailwindcss": "^4",
"typescript": "^5",
"typescript-eslint": "^8.15.0",
"whatwg-fetch": "^3.6.20"
}
}

View File

@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -11,18 +15,30 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"types": ["@testing-library/jest-dom"],
"types": [
"@testing-library/jest-dom"
],
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
"@/*": [
"./src/*"
]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}