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

Compare commits

...

10 Commits

13 changed files with 2394 additions and 1661 deletions

View File

@ -10,10 +10,10 @@ jobs:
build: build:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.3' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.7.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '20.x' node-version: '20.x'
cache: 'npm' cache: 'npm'

View File

@ -10,10 +10,10 @@ jobs:
lint: lint:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.3' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.7.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '20.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
@ -37,6 +37,6 @@ jobs:
run: 'npm run lint:prettier' run: 'npm run lint:prettier'
- name: 'lint:dotenv' - name: 'lint:dotenv'
uses: 'dotenv-linter/action-dotenv-linter@v2' uses: 'dotenv-linter/action-dotenv-linter@v2.18.0'
with: with:
github_token: ${{ secrets.github_token }} github_token: ${{ secrets.github_token }}

View File

@ -8,20 +8,20 @@ jobs:
release: release:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.3' - uses: 'actions/checkout@v4.0.0'
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: 'Import GPG key' - name: 'Import GPG key'
uses: 'crazy-max/ghaction-import-gpg@v5.3.0' uses: 'crazy-max/ghaction-import-gpg@v6.0.0'
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
git_user_signingkey: true git_user_signingkey: true
git_commit_gpgsign: true git_commit_gpgsign: true
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.7.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '20.x' node-version: '20.x'
cache: 'npm' cache: 'npm'

View File

@ -10,10 +10,10 @@ jobs:
test-unit: test-unit:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.3' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.7.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '20.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
@ -27,10 +27,10 @@ jobs:
test-e2e: test-e2e:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.3' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.7.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '20.x' node-version: '20.x'
cache: 'npm' cache: 'npm'

View File

@ -1,9 +1,9 @@
FROM node:20.5.0 AS builder-dependencies FROM node:20.6.1 AS builder-dependencies
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./package*.json ./ COPY ./package*.json ./
RUN npm clean-install RUN npm clean-install
FROM node:20.5.0 AS builder FROM node:20.6.1 AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules
COPY ./ ./ COPY ./ ./
@ -12,6 +12,7 @@ RUN npm run build
FROM gcr.io/distroless/nodejs20-debian11:latest AS runner FROM gcr.io/distroless/nodejs20-debian11:latest AS runner
WORKDIR /usr/src/application WORKDIR /usr/src/application
ENV NODE_ENV=production ENV NODE_ENV=production
ENV HOSTNAME=0.0.0.0
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules
COPY --from=builder /usr/src/application/.next/standalone ./ COPY --from=builder /usr/src/application/.next/standalone ./

View File

@ -13,6 +13,19 @@
"summary": "Je suis étudiant à l'université suivant la formation \"BUT Informatique\" et me forme en autodidacte dans l'informatique en suivant des formations en ligne. <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets (disponible sur <a href=\"https://theoludwig.fr\">theoludwig.fr</a>)." "summary": "Je suis étudiant à l'université suivant la formation \"BUT Informatique\" et me forme en autodidacte dans l'informatique en suivant des formations en ligne. <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets (disponible sur <a href=\"https://theoludwig.fr\">theoludwig.fr</a>)."
}, },
"education": [ "education": [
{
"startDate": "2023",
"endDate": "2024",
"studyType": "Bachelor Universitaire de Technologie (BUT) Informatique",
"institution": "IUT Robert Schuman à Illkirch-Graffenstaden",
"score": "3ème année",
"courses": [
"Développement Web en Node.js et React.js",
"Intégration/Déploiement Continue et Docker",
"Projet développement LLM (Large Language Model) et NLP (Natural Language Processing)",
"Base de données NoSQL (MongoDB)"
]
},
{ {
"startDate": "2022", "startDate": "2022",
"endDate": "2023", "endDate": "2023",
@ -21,10 +34,10 @@
"score": "2ème année", "score": "2ème année",
"courses": [ "courses": [
"Développement Web avec le framework Laravel en PHP", "Développement Web avec le framework Laravel en PHP",
"Qualité de développement et Tests unitaires, d'intégration, fonctionnels/systèmes, d'acceptation etc.",
"Patrons et Principes de conceptions (Code maintenable et réutilisable) en UML", "Patrons et Principes de conceptions (Code maintenable et réutilisable) en UML",
"Programmation systèmes en C (Multi-Thread, Serveur/Client UDP/TCP)", "Programmation systèmes en C (Multi-Thread, Serveur/Client UDP/TCP)",
"Sécurisation des accès à la base de données et PL/SQL", "Sécurisation des accès à la base de données et PL/SQL"
"Projet développement d'une application web en React.js en équipe de 3 personnes pendant 3 mois"
] ]
}, },
{ {
@ -56,29 +69,39 @@
// } // }
], ],
"work": [ "work": [
{
"summary": "Développement de WebSurg, une université virtuelle consacrée à la formation médico-chirurgicale, en React.js/Next.js et API Platform avec Symfony.",
"website": "https://ircad.fr/",
"name": "IRCAD",
"location": "1 Place de l'Hôpital, 67000 Strasbourg",
"position": "Alternant Développeur Web Full Stack",
"startDate": "2023-08-28",
"endDate": "2024-09-02",
"duration": "1 an"
},
{ {
"summary": "Développement d'un outil GED (Gestion Électronique de Documents) en React.js, Laravel et GraphQL.", "summary": "Développement d'un outil GED (Gestion Électronique de Documents) en React.js, Laravel et GraphQL.",
"website": "https://numerize.com/", "website": "https://numerize.com/",
"name": "Numerize", "name": "Numerize",
"location": "4 Rue Sophie Germain, 67720 Hœrdt", "location": "4 Rue Sophie Germain, 67720 Hœrdt",
"position": "Stagiaire Développeur Web", "position": "Stagiaire Développeur Web Full Stack",
"startDate": "2023-04-11", "startDate": "2023-04-11",
"endDate": "2023-07-26", "endDate": "2023-07-26",
"duration": "4 mois" "duration": "4 mois"
}, },
{ // {
"summary": "Agent administratif - Numérisation et archivage des plans électriques initialement sous format papier calque.", // "summary": "Agent administratif - Numérisation et archivage des plans électriques initialement sous format papier calque.",
"website": "https://www.es.fr/", // "website": "https://www.es.fr/",
"name": "ÉS (Électricité de Strasbourg)", // "name": "ÉS (Électricité de Strasbourg)",
"location": "5 Rue André Marie Ampère, 67450 Mundolsheim", // "location": "5 Rue André Marie Ampère, 67450 Mundolsheim",
"position": "Emploi d'été en qualité d'agent administratif", // "position": "Emploi d'été en qualité d'agent administratif",
"startDate": "2021-07-07", // "startDate": "2021-07-07",
"endDate": "2021-07-30", // "endDate": "2021-07-30",
"duration": "1 mois" // "duration": "1 mois"
}, // },
{ {
"summary": "Développement d'un site web pour trouver un restaurant à la pause repas.", "summary": "Développement d'un site web pour trouver un restaurant à la pause repas.",
"website": "https://www.itpartners.fr/", "website": "https://itpartners.fr/",
"name": "Tribe | IT Partners", "name": "Tribe | IT Partners",
"location": "16 Rue du Parc, 67205 Oberhausbergen", "location": "16 Rue du Parc, 67205 Oberhausbergen",
"position": "Stage initiation métier développeur web", "position": "Stage initiation métier développeur web",
@ -88,8 +111,8 @@
}, },
{ {
"description": "interests", "description": "interests",
"summary": "Développement site web en React.js et Strapi.<br /> Classé n°1 en France sur le Défi de l'entreprise <a href=\"https://www.toolpad.fr/\">ToolPad</a>.", "summary": "Développement site web en React.js et Strapi.<br /> Classé n°1 en France sur le Défi de l'entreprise <a href=\"https://toolpad.fr/\">ToolPad</a>.",
"website": "https://www.nuitdelinfo.com/", "website": "https://nuitdelinfo.com/",
"name": "La Nuit de l'info 2021", "name": "La Nuit de l'info 2021",
"position": "Participation en équipe de 5 personnes", "position": "Participation en équipe de 5 personnes",
"startDate": "2021-12-02", "startDate": "2021-12-02",
@ -99,7 +122,7 @@
{ {
"description": "interests", "description": "interests",
"summary": "Hackathon développement d'une landing page et web scraping.", "summary": "Hackathon développement d'une landing page et web scraping.",
"website": "https://www.wildcodeschool.fr/", "website": "https://wildcodeschool.fr/",
"name": "Wild Code School", "name": "Wild Code School",
"location": "32 Rue du Bass. d'Austerlitz, 67100 Strasbourg", "location": "32 Rue du Bass. d'Austerlitz, 67100 Strasbourg",
"position": "Initiation métier Développeur web", "position": "Initiation métier Développeur web",
@ -109,7 +132,7 @@
} }
// { // {
// "summary": "Apprentissage du métier \"Chargé de communication\" et des logiciels de graphisme tels que \"Adobe Photoshop\".", // "summary": "Apprentissage du métier \"Chargé de communication\" et des logiciels de graphisme tels que \"Adobe Photoshop\".",
// "website": "https://www.es.fr/", // "website": "https://es.fr/",
// "name": "ÉS (Électricité de Strasbourg)", // "name": "ÉS (Électricité de Strasbourg)",
// "location": "26 Bd du Président-Wilson, 67000 Strasbourg", // "location": "26 Bd du Président-Wilson, 67000 Strasbourg",
// "position": "Stage de découverte (3ème)", // "position": "Stage de découverte (3ème)",

View File

@ -12,16 +12,256 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.4.5", "@types/node": "20.6.2",
"date-and-time": "3.0.2", "date-and-time": "3.0.3",
"vite": "4.4.7", "vite": "4.4.9",
"vite-plugin-html": "3.2.0" "vite-plugin-html": "3.2.0"
} }
}, },
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.18.17", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -34,6 +274,102 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/gen-mapping": { "node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@ -49,9 +385,9 @@
} }
}, },
"node_modules/@jridgewell/resolve-uri": { "node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=6.0.0" "node": ">=6.0.0"
@ -83,21 +419,15 @@
"dev": true "dev": true
}, },
"node_modules/@jridgewell/trace-mapping": { "node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18", "version": "0.3.19",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
"integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "3.1.0", "@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
"dev": true
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -147,9 +477,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.4.5", "version": "20.6.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz",
"integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==", "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==",
"dev": true "dev": true
}, },
"node_modules/acorn": { "node_modules/acorn": {
@ -346,9 +676,9 @@
} }
}, },
"node_modules/date-and-time": { "node_modules/date-and-time": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.2.tgz", "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.3.tgz",
"integrity": "sha512-MOqlRertOQmQI7ySbz6dKLM7Rxm9dgcPuBI9IL7NVe0UGqHPK+6hWSKVhLrVHxlSgQQtocE2R7+HFOf5aMz8vw==", "integrity": "sha512-CmHCeTixc3KA5pcLTVs9JCFhmJMFTBsmSsgHnNed4YDNw9yUOrjjRn3zALy8eMgqmTO+4U8k5jl1peC7IoezfA==",
"dev": true "dev": true
}, },
"node_modules/dom-serializer": { "node_modules/dom-serializer": {
@ -462,9 +792,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.18.17", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
"integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"bin": { "bin": {
@ -474,28 +804,28 @@
"node": ">=12" "node": ">=12"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/android-arm": "0.18.17", "@esbuild/android-arm": "0.18.20",
"@esbuild/android-arm64": "0.18.17", "@esbuild/android-arm64": "0.18.20",
"@esbuild/android-x64": "0.18.17", "@esbuild/android-x64": "0.18.20",
"@esbuild/darwin-arm64": "0.18.17", "@esbuild/darwin-arm64": "0.18.20",
"@esbuild/darwin-x64": "0.18.17", "@esbuild/darwin-x64": "0.18.20",
"@esbuild/freebsd-arm64": "0.18.17", "@esbuild/freebsd-arm64": "0.18.20",
"@esbuild/freebsd-x64": "0.18.17", "@esbuild/freebsd-x64": "0.18.20",
"@esbuild/linux-arm": "0.18.17", "@esbuild/linux-arm": "0.18.20",
"@esbuild/linux-arm64": "0.18.17", "@esbuild/linux-arm64": "0.18.20",
"@esbuild/linux-ia32": "0.18.17", "@esbuild/linux-ia32": "0.18.20",
"@esbuild/linux-loong64": "0.18.17", "@esbuild/linux-loong64": "0.18.20",
"@esbuild/linux-mips64el": "0.18.17", "@esbuild/linux-mips64el": "0.18.20",
"@esbuild/linux-ppc64": "0.18.17", "@esbuild/linux-ppc64": "0.18.20",
"@esbuild/linux-riscv64": "0.18.17", "@esbuild/linux-riscv64": "0.18.20",
"@esbuild/linux-s390x": "0.18.17", "@esbuild/linux-s390x": "0.18.20",
"@esbuild/linux-x64": "0.18.17", "@esbuild/linux-x64": "0.18.20",
"@esbuild/netbsd-x64": "0.18.17", "@esbuild/netbsd-x64": "0.18.20",
"@esbuild/openbsd-x64": "0.18.17", "@esbuild/openbsd-x64": "0.18.20",
"@esbuild/sunos-x64": "0.18.17", "@esbuild/sunos-x64": "0.18.20",
"@esbuild/win32-arm64": "0.18.17", "@esbuild/win32-arm64": "0.18.20",
"@esbuild/win32-ia32": "0.18.17", "@esbuild/win32-ia32": "0.18.20",
"@esbuild/win32-x64": "0.18.17" "@esbuild/win32-x64": "0.18.20"
} }
}, },
"node_modules/estree-walker": { "node_modules/estree-walker": {
@ -585,6 +915,20 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/glob-parent": { "node_modules/glob-parent": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -856,9 +1200,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.27", "version": "8.4.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
"integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -923,9 +1267,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "3.26.3", "version": "3.29.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz",
"integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==",
"dev": true, "dev": true,
"bin": { "bin": {
"rollup": "dist/bin/rollup" "rollup": "dist/bin/rollup"
@ -1002,9 +1346,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.19.2", "version": "5.19.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz",
"integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
@ -1038,9 +1382,9 @@
} }
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.6.1", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"dev": true "dev": true
}, },
"node_modules/universalify": { "node_modules/universalify": {
@ -1053,14 +1397,14 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "4.4.7", "version": "4.4.9",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
"integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.18.10", "esbuild": "^0.18.10",
"postcss": "^8.4.26", "postcss": "^8.4.27",
"rollup": "^3.25.2" "rollup": "^3.27.1"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"

View File

@ -13,9 +13,9 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.4.5", "@types/node": "20.6.2",
"date-and-time": "3.0.2", "date-and-time": "3.0.3",
"vite": "4.4.7", "vite": "4.4.9",
"vite-plugin-html": "3.2.0" "vite-plugin-html": "3.2.0"
} }
} }

View File

@ -17,12 +17,16 @@ export const middleware = (request: NextRequest): NextResponse => {
let locale = request.cookies.get('locale')?.value let locale = request.cookies.get('locale')?.value
if (locale == null || !LOCALES.includes(locale as Locale)) { if (locale == null || !LOCALES.includes(locale as Locale)) {
const headers = { try {
'accept-language': const headers = {
request.headers.get('accept-language') ?? DEFAULT_LOCALE 'accept-language':
request.headers.get('accept-language') ?? DEFAULT_LOCALE
}
const languages = new Negotiator({ headers }).languages()
locale = match(languages, LOCALES.slice(), DEFAULT_LOCALE)
} catch {
locale = DEFAULT_LOCALE
} }
const languages = new Negotiator({ headers }).languages()
locale = match(languages, LOCALES.slice(), DEFAULT_LOCALE)
response.cookies.set('locale', locale, { response.cookies.set('locale', locale, {
path: '/', path: '/',
maxAge: COOKIE_MAX_AGE maxAge: COOKIE_MAX_AGE

View File

@ -2,6 +2,9 @@
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: true,
output: 'standalone', output: 'standalone',
eslint: {
ignoreDuringBuilds: true
},
experimental: { experimental: {
serverActions: true serverActions: true
} }

3390
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "theoludwig", "name": "theoludwig",
"version": "3.0.0", "version": "3.1.0",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
@ -29,72 +29,72 @@
"postinstall": "husky install" "postinstall": "husky install"
}, },
"dependencies": { "dependencies": {
"@fontsource/montserrat": "5.0.5", "@fontsource/montserrat": "5.0.8",
"@formatjs/intl-localematcher": "0.4.0", "@formatjs/intl-localematcher": "0.4.2",
"@fortawesome/fontawesome-svg-core": "6.4.0", "@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-brands-svg-icons": "6.4.0", "@fortawesome/free-brands-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.0", "@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/react-fontawesome": "0.2.0", "@fortawesome/react-fontawesome": "0.2.0",
"@giscus/react": "2.3.0", "@giscus/react": "2.3.0",
"clsx": "2.0.0", "clsx": "2.0.0",
"date-and-time": "3.0.2", "date-and-time": "3.0.3",
"gray-matter": "4.0.3", "gray-matter": "4.0.3",
"html-react-parser": "4.2.0", "html-react-parser": "4.2.2",
"i18n-js": "4.3.0", "i18n-js": "4.3.2",
"katex": "0.16.8", "katex": "0.16.8",
"negotiator": "0.6.3", "negotiator": "0.6.3",
"next": "13.4.12", "next": "13.4.19",
"next-mdx-remote": "4.4.1", "next-mdx-remote": "4.4.1",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"read-pkg": "8.0.0", "read-pkg": "8.1.0",
"rehype-katex": "6.0.3", "rehype-katex": "6.0.3",
"rehype-raw": "6.1.1", "rehype-raw": "6.1.1",
"rehype-slug": "5.1.0", "rehype-slug": "5.1.0",
"remark-gfm": "3.0.1", "remark-gfm": "3.0.1",
"remark-math": "5.1.1", "remark-math": "5.1.1",
"sharp": "0.32.4", "sharp": "0.32.5",
"shiki": "0.14.3", "shiki": "0.14.4",
"unified": "10.1.2", "unified": "10.1.2",
"unist-util-visit": "5.0.0", "unist-util-visit": "5.0.0",
"universal-cookie": "4.0.4" "universal-cookie": "6.1.1"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "17.6.7", "@commitlint/cli": "17.7.1",
"@commitlint/config-conventional": "17.6.7", "@commitlint/config-conventional": "17.7.0",
"@saithodev/semantic-release-backmerge": "3.2.0", "@saithodev/semantic-release-backmerge": "3.2.0",
"@semantic-release/git": "10.0.1", "@semantic-release/git": "10.0.1",
"@tailwindcss/typography": "0.5.9", "@tailwindcss/typography": "0.5.10",
"@tsconfig/strictest": "2.0.1", "@tsconfig/strictest": "2.0.2",
"@types/negotiator": "0.6.1", "@types/negotiator": "0.6.1",
"@types/node": "20.4.5", "@types/node": "20.6.2",
"@types/react": "18.2.18", "@types/react": "18.2.22",
"@types/unist": "3.0.0", "@types/unist": "3.0.0",
"@typescript-eslint/eslint-plugin": "6.2.1", "@typescript-eslint/eslint-plugin": "6.7.2",
"@typescript-eslint/parser": "6.2.1", "@typescript-eslint/parser": "6.7.2",
"autoprefixer": "10.4.14", "autoprefixer": "10.4.15",
"curriculum-vitae": "file:./curriculum-vitae", "curriculum-vitae": "file:./curriculum-vitae",
"cypress": "12.17.2", "cypress": "13.2.0",
"editorconfig-checker": "5.1.1", "editorconfig-checker": "5.1.1",
"eslint": "8.46.0", "eslint": "8.49.0",
"eslint-config-conventions": "11.0.1", "eslint-config-conventions": "11.0.1",
"eslint-config-next": "13.4.12", "eslint-config-next": "13.4.19",
"eslint-config-prettier": "8.9.0", "eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.0", "eslint-plugin-import": "2.28.1",
"eslint-plugin-prettier": "5.0.0", "eslint-plugin-prettier": "5.0.0",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-unicorn": "48.0.1", "eslint-plugin-unicorn": "48.0.1",
"html-w3c-validator": "1.4.0", "html-w3c-validator": "1.5.0",
"husky": "8.0.3", "husky": "8.0.3",
"lint-staged": "13.2.3", "lint-staged": "14.0.1",
"markdownlint-cli2": "0.8.1", "markdownlint-cli2": "0.10.0",
"markdownlint-rule-relative-links": "2.1.0", "markdownlint-rule-relative-links": "2.1.0",
"postcss": "8.4.27", "postcss": "8.4.29",
"prettier": "3.0.0", "prettier": "3.0.3",
"prettier-plugin-tailwindcss": "0.4.1", "prettier-plugin-tailwindcss": "0.5.4",
"semantic-release": "21.0.7", "semantic-release": "21.1.2",
"start-server-and-test": "2.0.0", "start-server-and-test": "2.0.0",
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"typescript": "5.1.6" "typescript": "5.2.2"
} }
} }

View File

@ -3,6 +3,7 @@
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node",
"lib": ["dom", "dom.iterable", "ESNext"], "lib": ["dom", "dom.iterable", "ESNext"],
"allowJs": true, "allowJs": true,
"baseUrl": ".", "baseUrl": ".",
@ -11,7 +12,6 @@
}, },
"types": ["cypress"], "types": ["cypress"],
"noEmit": true, "noEmit": true,
"moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
"jsx": "preserve", "jsx": "preserve",
"incremental": true, "incremental": true,