1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-05-29 22:37:44 +02:00

build(deps): update Next.js to v15 and ESLint to v9

This commit is contained in:
2024-11-09 19:50:22 +01:00
parent 59153a7a69
commit 9e840b8dae
74 changed files with 3206 additions and 3749 deletions

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config/nextjs/.eslintrc.json"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import configNextjs from "@repo/eslint-config/nextjs"
export default typescriptESLint.config(...configNextjs, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -9,7 +9,7 @@
"./BlogPostUI": "./src/BlogPostUI.tsx"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
@ -49,6 +49,7 @@
"eslint": "catalog:",
"postcss": "catalog:",
"tailwindcss": "catalog:",
"typescript-eslint": "catalog:",
"typescript": "catalog:"
}
}

View File

@ -9,7 +9,7 @@ import rehypeSlug from "rehype-slug"
import remarkGfm from "remark-gfm"
import remarkMath from "remark-math"
import { Link } from "@repo/i18n/navigation"
import { Link } from "@repo/i18n/routing"
import "katex/dist/katex.min.css"
import { BlogPostComments } from "./BlogPostComments.tsx"

View File

@ -1,4 +1,4 @@
import { Link } from "@repo/i18n/navigation"
import { Link } from "@repo/i18n/routing"
import { Typography } from "@repo/ui/Design/Typography"
import { Section, SectionContent } from "@repo/ui/Layout/Section"
import { getISODate } from "@repo/utils/dates"

View File

@ -1,26 +0,0 @@
{
"extends": ["conventions"],
"plugins": ["import-x"],
"rules": {
"import-x/no-absolute-path": "error",
"import-x/no-webpack-loader-syntax": "error",
"import-x/no-self-import": "error",
"import-x/no-useless-path-segments": "error",
"import-x/export": "error",
"import-x/no-duplicates": "error",
"import-x/no-named-default": "error",
"import-x/no-empty-named-blocks": "error",
"import-x/no-anonymous-default-export": "error",
"import-x/extensions": [
"error",
"ignorePackages",
{
"ts": "always",
"tsx": "always",
"js": "never",
"jsx": "never"
}
],
"import-x/consistent-type-specifier-style": ["error", "prefer-top-level"]
}
}

View File

@ -0,0 +1,40 @@
import typescriptESLint from "typescript-eslint"
import configConventions from "eslint-config-conventions"
import importX from "eslint-plugin-import-x"
import unicorn from "eslint-plugin-unicorn"
export default typescriptESLint.config(
{
ignores: [
".next",
"**/next.config.js",
"**/eslint.config.js",
"**/tailwind.config.js",
"**/postcss.config.js",
"**/vitest.config.ts",
"**/kysely.config.ts",
],
},
...configConventions,
{
name: "config-eslint",
plugins: {
"import-x": importX,
unicorn,
},
rules: {
"import-x/extensions": [
"error",
"ignorePackages",
{
ts: "always",
tsx: "always",
js: "never",
jsx: "never",
},
],
"unicorn/explicit-length-check": "error",
"unicorn/consistent-destructuring": "off",
},
},
)

7
packages/config-eslint/index.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import type typescriptESLint from "typescript-eslint"
declare const eslintConfigConventions: ReturnType<
typeof typescriptESLint.config
>
export default eslintConfigConventions

View File

@ -1,57 +0,0 @@
{
"extends": [
"../.eslintrc.json",
"next/core-web-vitals",
"plugin:tailwindcss/recommended",
"plugin:storybook/recommended"
],
"ignorePatterns": [
"next.config.js",
"tailwind.config.js",
"postcss.config.js",
"vitest.config.ts"
],
"settings": {
"tailwindcss": {
"callees": ["classNames", "cva"]
},
"react": {
"version": "detect"
}
},
"rules": {
"tailwindcss/classnames-order": "off",
"tailwindcss/no-custom-classname": "off",
"@next/next/no-html-link-for-pages": "off",
"react/self-closing-comp": [
"error",
{
"component": true,
"html": true
}
],
"react/void-dom-elements-no-children": "error",
"react/jsx-boolean-value": "error",
"no-restricted-imports": [
"error",
{
"paths": [
{
"name": "next/link",
"message": "Please import from `@repo/i18n/navigation` instead."
},
{
"name": "next/navigation",
"importNames": [
"redirect",
"permanentRedirect",
"useRouter",
"usePathname"
],
"message": "Please import from `@repo/i18n/navigation` instead."
}
]
}
]
}
}

View File

@ -0,0 +1,61 @@
import { FlatCompat } from "@eslint/eslintrc"
import storybook from "eslint-plugin-storybook"
import tailwind from "eslint-plugin-tailwindcss"
import typescriptESLint from "typescript-eslint"
import config from "../eslint.config.js"
const flatCompat = new FlatCompat()
export default typescriptESLint.config(
...config,
...flatCompat.extends("next/core-web-vitals"),
...tailwind.configs["flat/recommended"],
...storybook.configs["flat/recommended"],
{
name: "config-eslint/nextjs",
settings: {
tailwindcss: {
callees: ["classNames", "cva"],
},
react: {
version: "detect",
},
},
rules: {
"tailwindcss/classnames-order": "off",
"tailwindcss/no-custom-classname": "off",
"@next/next/no-html-link-for-pages": "off",
"@next/next/no-img-element": "off",
"react/self-closing-comp": [
"error",
{
component: true,
html: true,
},
],
"react/void-dom-elements-no-children": "error",
"react/jsx-boolean-value": "error",
"no-restricted-imports": [
"error",
{
paths: [
{
name: "next/link",
message: "Please import from `@repo/i18n/routing` instead.",
},
{
name: "next/navigation",
importNames: [
"redirect",
"permanentRedirect",
"useRouter",
"usePathname",
],
message: "Please import from `@repo/i18n/routing` instead.",
},
],
},
],
},
},
)

View File

@ -2,14 +2,24 @@
"name": "@repo/eslint-config",
"version": "4.0.0",
"private": true,
"main": ".eslintrc.json",
"files": [
".eslintrc.json",
"nextjs/.eslintrc.json"
],
"type": "module",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./eslint.config.js",
"require": "./eslint.config.js",
"default": "./eslint.config.js"
},
"./nextjs": {
"types": "./index.d.ts",
"import": "./nextjs/eslint.config.js",
"require": "./nextjs/eslint.config.js",
"default": "./nextjs/eslint.config.js"
}
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "catalog:",
"@typescript-eslint/parser": "catalog:",
"@eslint/eslintrc": "catalog:",
"typescript-eslint": "catalog:",
"eslint": "catalog:",
"eslint-config-conventions": "catalog:",
"eslint-plugin-promise": "catalog:",
@ -18,6 +28,7 @@
"eslint-plugin-storybook": "catalog:",
"eslint-plugin-tailwindcss": "catalog:",
"eslint-plugin-import-x": "catalog:",
"typescript": "catalog:"
"typescript": "catalog:",
"globals": "catalog:"
}
}

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import config from "@repo/eslint-config"
export default typescriptESLint.config(...config, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -24,6 +24,7 @@
"@repo/eslint-config": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@tailwindcss/typography": "catalog:",
"typescript-eslint": "catalog:",
"eslint": "catalog:",
"postcss": "catalog:",
"tailwindcss": "catalog:"

View File

@ -24,9 +24,6 @@
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"resolveJsonModule": true
}
}

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import config from "@repo/eslint-config"
export default typescriptESLint.config(...config, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -5,13 +5,12 @@
"type": "module",
"exports": {
"./translations/*.json": "./src/translations/*.json",
"./config": "./src/config.tsx",
"./i18n": "./src/i18n.ts",
"./messages.d.ts": "./src/messages.d.ts",
"./navigation": "./src/navigation.ts"
"./request": "./src/request.ts",
"./routing": "./src/routing.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit",
"test": "vitest run"
},
@ -30,6 +29,7 @@
"@types/react-dom": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"eslint": "catalog:",
"typescript-eslint": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
}

View File

@ -1,26 +0,0 @@
import type { Locale } from "@repo/utils/constants"
import type { RichTranslationValues } from "next-intl"
export interface LocaleProps {
params: {
locale: Locale
}
}
export const defaultTranslationValues: RichTranslationValues = {
br: () => {
return <br />
},
strong: (children) => {
return <strong>{children}</strong>
},
em: (children) => {
return <em>{children}</em>
},
s: (children) => {
return <s>{children}</s>
},
u: (children) => {
return <u>{children}</u>
},
}

View File

@ -1,9 +0,0 @@
import { createSharedPathnamesNavigation } from "next-intl/navigation"
import { LOCALES, LOCALE_PREFIX } from "@repo/utils/constants"
export const { Link, redirect, usePathname, useRouter, permanentRedirect } =
createSharedPathnamesNavigation({
locales: LOCALES,
localePrefix: LOCALE_PREFIX,
})

View File

@ -1,15 +1,14 @@
import deepmerge from "deepmerge"
import type { AbstractIntlMessages } from "next-intl"
import { getRequestConfig } from "next-intl/server"
import { notFound } from "next/navigation"
import type { Locale } from "@repo/utils/constants"
import { LOCALE_DEFAULT, LOCALES } from "@repo/utils/constants"
import { defaultTranslationValues } from "./config.tsx"
export default getRequestConfig(async ({ locale }) => {
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale
if (!LOCALES.includes(locale as Locale)) {
return notFound()
locale = LOCALE_DEFAULT
}
const userMessages = (await import(`./translations/${locale}.json`)).default
@ -22,7 +21,7 @@ export default getRequestConfig(async ({ locale }) => {
)
return {
locale,
messages,
defaultTranslationValues,
}
})

View File

@ -0,0 +1,26 @@
import { createNavigation } from "next-intl/navigation"
import { LOCALES, LOCALE_DEFAULT, LOCALE_PREFIX } from "@repo/utils/constants"
import { defineRouting } from "next-intl/routing"
import type { Locale } from "@repo/utils/constants"
export interface LocaleProps {
params: Promise<{
locale: Locale
}>
}
export const routing = defineRouting({
locales: LOCALES,
defaultLocale: LOCALE_DEFAULT,
localePrefix: LOCALE_PREFIX,
})
export const {
Link,
redirect,
usePathname,
useRouter,
getPathname,
permanentRedirect,
} = createNavigation(routing)

View File

@ -10,10 +10,10 @@
"institution": "Conservatoire National des Arts et Métiers (CNAM), in Eckbolsheim - UIMM Alsace - ITII Alsace",
"study-type": "Engineer in Computer Science and Information Systems (IS)",
"years": {
"2024-2025": {
"2024-2027": {
"courses": {},
"description": "1st year",
"title": "2024 - 2025"
"description": "",
"title": "2024 - 2027"
}
}
},

View File

@ -10,10 +10,10 @@
"institution": "Conservatoire National des Arts et Métiers (CNAM) à Eckbolsheim - UIMM Alsace - ITII Alsace",
"study-type": "Ingénieur en Informatique et Systèmes d'Information (SI)",
"years": {
"2024-2025": {
"2024-2027": {
"courses": {},
"description": "1ère année",
"title": "2024 - 2025"
"description": "",
"title": "2024 - 2027"
}
}
},

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config/nextjs/.eslintrc.json"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import configNextjs from "@repo/eslint-config/nextjs"
export default typescriptESLint.config(...configNextjs, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -8,7 +8,7 @@
"./useIsMounted": "./src/useIsMounted.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit",
"test": "vitest run --browser.headless",
"test:ui": "vitest --ui --no-open"
@ -25,10 +25,11 @@
"@types/react-dom": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"@vitest/browser": "catalog:",
"@vitest/coverage-istanbul": "catalog:",
"@vitest/coverage-v8": "catalog:",
"@vitest/ui": "catalog:",
"eslint": "catalog:",
"playwright": "catalog:",
"typescript-eslint": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
}

View File

@ -1,15 +1,19 @@
import { defineConfig } from "vitest/config"
export default defineConfig({
optimizeDeps: {
include: ["@vitest/coverage-v8/browser"],
},
test: {
browser: {
provider: "playwright",
enabled: true,
name: "chromium",
screenshotFailures: false,
},
coverage: {
enabled: true,
provider: "istanbul",
provider: "v8",
},
},
})

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config/nextjs/.eslintrc.json"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import configNextjs from "@repo/eslint-config/nextjs"
export default typescriptESLint.config(...configNextjs, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -23,7 +23,7 @@
"./Layout/Section": "./src/Layout/Section/Section.tsx"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
@ -51,6 +51,7 @@
"eslint": "catalog:",
"postcss": "catalog:",
"tailwindcss": "catalog:",
"typescript-eslint": "catalog:",
"typescript": "catalog:"
}
}

View File

@ -13,7 +13,13 @@ export const CurriculumVitaeAbout: React.FC<CurriculumVitaeAboutProps> = () => {
title={t("curriculum-vitae.about.title")}
icon={<FaUser size={24} />}
>
<p>{t.rich("curriculum-vitae.about.description")}</p>
<p>
{t.rich("curriculum-vitae.about.description", {
br: () => {
return <br />
},
})}
</p>
</CurriculumVitaeSection>
)
}

View File

@ -11,10 +11,10 @@ export const CurriculumVitaeEducation: React.FC<
const educations = [
{
years: t("curriculum-vitae.education.cnam.years.2024-2025.title"),
years: t("curriculum-vitae.education.cnam.years.2024-2027.title"),
studyType: t("curriculum-vitae.education.cnam.study-type"),
institution: t("curriculum-vitae.education.cnam.institution"),
score: t("curriculum-vitae.education.cnam.years.2024-2025.description"),
score: t("curriculum-vitae.education.cnam.years.2024-2027.description"),
courses: [],
},
{

View File

@ -1,4 +1,4 @@
import { Link } from "@repo/i18n/navigation"
import { Link } from "@repo/i18n/routing"
import { useTranslations } from "next-intl"
import Image from "next/image"
import { BirthDate } from "../Home/About/AboutList/BirthDate.tsx"

View File

@ -1,5 +1,5 @@
import { classNames } from "@repo/config-tailwind/classNames"
import { Link as NextLink } from "@repo/i18n/navigation"
import { Link as NextLink } from "@repo/i18n/routing"
import type { VariantProps } from "cva"
import { cva } from "cva"

View File

@ -1,5 +1,5 @@
import { classNames } from "@repo/config-tailwind/classNames"
import { Link as NextLink } from "@repo/i18n/navigation"
import { Link as NextLink } from "@repo/i18n/routing"
import { FiExternalLink } from "react-icons/fi"
export interface LinkProps extends React.ComponentProps<typeof NextLink> {

View File

@ -1,6 +1,6 @@
"use client"
import { useRouter } from "@repo/i18n/navigation"
import { useRouter } from "@repo/i18n/routing"
import { useTranslations } from "next-intl"
import { useEffect, useTransition } from "react"
import { Button } from "../../Design/Button/Button.tsx"

View File

@ -10,7 +10,11 @@ export const AboutDescription: React.FC<AboutDescriptionProps> = () => {
return (
<div className="dark:text-gray my-6 max-w-md text-center text-black">
<Typography as="p" variant="text1" className="my-6">
{t.rich("home.about.description")}
{t.rich("home.about.description", {
strong: (children) => {
return <strong>{children}</strong>
},
})}
</Typography>
<Button href="/curriculum-vitae" variant="outline">

View File

@ -19,6 +19,12 @@ export const Interests: React.FC<InterestsProps> = () => {
id: "code",
title: t("home.interests.code.title"),
description: t.rich("home.interests.code.description", {
br: () => {
return <br />
},
strong: (children) => {
return <strong>{children}</strong>
},
"abbr-ux": (children) => {
return <abbr title="User Experience">{children}</abbr>
},
@ -29,6 +35,12 @@ export const Interests: React.FC<InterestsProps> = () => {
id: "open-source",
title: t("home.interests.open-source.title"),
description: t.rich("home.interests.open-source.description", {
br: () => {
return <br />
},
strong: (children) => {
return <strong>{children}</strong>
},
"github-link": (children) => {
return (
<Link href={GIT_REPO_LINK} target="_blank">

View File

@ -1,7 +1,7 @@
"use client"
import { classNames } from "@repo/config-tailwind/classNames"
import { usePathname, useRouter } from "@repo/i18n/navigation"
import { usePathname, useRouter } from "@repo/i18n/routing"
import type { Locale } from "@repo/utils/constants"
import { LOCALES } from "@repo/utils/constants"
import { useLocale } from "next-intl"

View File

@ -1,14 +0,0 @@
{
"root": true,
"extends": ["@repo/eslint-config"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"projectService": true
}
}
]
}

View File

@ -0,0 +1,13 @@
import typescriptESLint from "typescript-eslint"
import config from "@repo/eslint-config"
export default typescriptESLint.config(...config, {
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
})

View File

@ -9,7 +9,7 @@
"./strings": "./src/strings.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:eslint": "eslint src --max-warnings 0",
"lint:typescript": "tsc --noEmit",
"test": "vitest run",
"test:ui": "vitest --ui --no-open"
@ -19,9 +19,10 @@
"@repo/config-typescript": "workspace:*",
"@types/node": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"@vitest/coverage-istanbul": "catalog:",
"@vitest/coverage-v8": "catalog:",
"@vitest/ui": "catalog:",
"eslint": "catalog:",
"typescript-eslint": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
}

View File

@ -1,10 +1,7 @@
import packageJSON from "../package.json"
export const VERSION =
process.env["NODE_ENV"] === "development"
? "0.0.0-development"
: packageJSON.version
import packageJSON from "../package.json" with { type: "json" }
export const IS_PRODUCTION = process.env["NODE_ENV"] === "production"
export const VERSION = IS_PRODUCTION ? packageJSON.version : "0.0.0-development"
export const GIT_REPO_LINK = "https://github.com/theoludwig/theoludwig"
export const LOCALES = ["en-US", "fr-FR"] as const
@ -16,6 +13,8 @@ export const THEMES = ["light", "dark"] as const
export type Theme = (typeof THEMES)[number]
export const THEME_DEFAULT = "light" as Theme
export const TIMEZONE = process.env["TZ"] ?? "UTC"
export const BIRTH_DATE_DAY = "31"
export const BIRTH_DATE_MONTH = "03"
export const BIRTH_DATE_YEAR = "2003"

View File

@ -4,7 +4,7 @@ export default defineConfig({
test: {
coverage: {
enabled: true,
provider: "istanbul",
provider: "v8",
},
},
})