diff --git a/.github/workflows/status-translation.yml b/.github/workflows/status-translation.yml
new file mode 100644
index 0000000000..03d1a57c05
--- /dev/null
+++ b/.github/workflows/status-translation.yml
@@ -0,0 +1,53 @@
+name: status-translation
+
+on:
+ pull_request:
+ branches:
+ - gh-pages
+ paths:
+ - 'en/**'
+ - 'de/**'
+ - 'es/**'
+ - 'fr/**'
+ - 'it/**'
+ - 'ja/**'
+ - 'ko/**'
+ - 'pt-br/**'
+ - 'ru/**'
+ - 'sk/**'
+ - 'th/**'
+ - 'tr/**'
+ - 'uk/**'
+ - 'uz/**'
+ - 'zh-cn/**'
+ - 'zh-tw/**'
+
+jobs:
+ verify-translation:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ ref: ${{ github.event.pull_request.head.ref }}
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ - run: |
+
+ npm run verify-translation
+
+ git branch --show-current
+
+ git config --global user.name 'GitHub Actions Bot'
+ git config --global user.email "carlosstenzel@hotmail.com"
+ git add .
+ git status
+ git commit -m "generated"
+ git push
+
+
diff --git a/_includes/header/header-en.html b/_includes/header/header-en.html
index f160f6d195..9ba69a855f 100644
--- a/_includes/header/header-en.html
+++ b/_includes/header/header-en.html
@@ -137,6 +137,9 @@
Release Change Log
+
+ Status Translate
+
diff --git a/en/resources/status-translate.md b/en/resources/status-translate.md
new file mode 100644
index 0000000000..1724a61df7
--- /dev/null
+++ b/en/resources/status-translate.md
@@ -0,0 +1,63 @@
+---
+layout: page
+title: Status Translate
+menu: resources
+lang: en
+redirect_from: "/resources/status-translate.html"
+---
+
+# Status Translate
+
+This page shows the status of the translation of the documentation into different languages.
+
+| en | pt-br | es | de | fr | it | ja | ko | ru | tr | th | sk | uz | zh-cn | zh-tw |
+ |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+| guide/behind-proxies.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/database-integration.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/debugging.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/error-handling.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/migrating-4.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/migrating-5.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
+| guide/overriding-express-api.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| guide/routing.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/using-middleware.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/using-template-engines.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| guide/writing-middleware.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
+| resources/community.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| resources/contributing.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/glossary.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| resources/middleware.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| resources/status-translate.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| resources/utils.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/body-parser.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/compression.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/connect-rid.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/cookie-parser.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/cookie-session.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/cors.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/errorhandler.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/method-override.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/morgan.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/multer.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/response-time.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/serve-favicon.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/serve-index.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/serve-static.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/session.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/timeout.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| resources/middleware/vhost.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
+| starter/basic-routing.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| starter/examples.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| starter/faq.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| starter/generator.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| starter/hello-world.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| starter/installing.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| starter/static-files.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| advanced/best-practice-performance.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
+| advanced/best-practice-security.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
+| advanced/developing-template-engines.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| advanced/healthcheck-graceful-shutdown.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
+| advanced/security-updates.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 3x/api.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 4x/api.md | ✅ | ✅ | 🔄 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 5x/api.md | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
diff --git a/package.json b/package.json
index 65bc52a33f..eaf5b0d669 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,8 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "test": "eslint --ignore-path .gitignore --ignore-pattern _includes/readmes/ \"**/*.md\""
+ "test": "eslint --ignore-path .gitignore --ignore-pattern _includes/readmes/ \"**/*.md\"",
+ "verify-translation": "node ./translationStatusScript.js"
},
"devDependencies": {
"eslint": "^8.54.0",
diff --git a/translationStatusScript.js b/translationStatusScript.js
new file mode 100644
index 0000000000..6b7c1ccd96
--- /dev/null
+++ b/translationStatusScript.js
@@ -0,0 +1,109 @@
+const fs = require('node:fs')
+
+const contentBase = `---
+layout: page
+title: Status Translate
+menu: resources
+lang: en
+redirect_from: "/resources/status-translate.html"
+---
+
+# Status Translate
+
+This page shows the status of the translation of the documentation into different languages.
+
+| en |`
+
+let content = contentBase
+
+const languageBase = 'en'
+const verifyLanguage = ['pt-br', 'es', 'de', 'fr', 'it', 'ja', 'ko', 'ru', 'tr', 'th', 'sk', 'uz', 'zh-cn', 'zh-tw']
+
+const statusTranslate = []
+statusTranslate[`${languageBase}`] = []
+
+verifyLanguage.forEach((language) => {
+ content = content + ` ${language} |`
+ statusTranslate[`${language}`] = []
+})
+
+content = content + '\n |---|'
+
+verifyLanguage.forEach(() => {
+ content = content + '---|'
+})
+
+content = content + '\n'
+
+const ignoreFiles = ['resources/status-translate']
+
+const languageBaseFiles = ['guide', 'resources', 'resources/middleware', 'starter', 'advanced', '3x', '4x', '5x']
+
+languageBaseFiles.forEach((pathVerify) => {
+ const files = fs.readdirSync(`./${languageBase}/${pathVerify}`)
+ const filesFiltered = files.filter((file) => file.includes('.md'))
+
+ verifyLanguage.forEach((language) => {
+ const verifyPath = fs.existsSync(`./${language}/${pathVerify}`)
+
+ let filesCompare = []
+ let filesFilteredCompare = []
+
+ if (verifyPath) {
+ filesCompare = fs.readdirSync(`./${language}/${pathVerify}`)
+ filesFilteredCompare = filesCompare.filter((file) => file.includes('.md'))
+ }
+
+ filesFiltered.forEach((file) => {
+ const getFileName = file
+
+ if (ignoreFiles.includes(getFileName)) return
+
+ statusTranslate[languageBase][`${pathVerify}/${getFileName}`] = `${pathVerify}/${getFileName}`
+
+ const getDateModified = fs.statSync(`./${languageBase}/${pathVerify}/${file}`).mtime
+ const dateFile = new Date(getDateModified)
+
+ if (filesFilteredCompare.includes(file)) {
+ const verifyFileToCompare = fs.existsSync(`./${language}/${pathVerify}/${file}`)
+
+ if (!verifyFileToCompare) {
+ statusTranslate[language][`${pathVerify}/${getFileName}`] = '❌'
+ return
+ }
+
+ const getDateModifiedCompare = fs.statSync(`./${language}/${pathVerify}/${file}`).mtime
+ const dateCompare = new Date(getDateModifiedCompare)
+
+ if (dateFile.getTime() <= dateCompare.getTime()) {
+ statusTranslate[language][`${pathVerify}/${getFileName}`] = '✅'
+ } else {
+ statusTranslate[language][`${pathVerify}/${getFileName}`] = '🔄'
+ }
+ } else {
+ statusTranslate[language][`${pathVerify}/${getFileName}`] = '❌'
+ }
+ })
+ })
+})
+
+let createTable = ''
+
+Object.keys(statusTranslate[languageBase]).forEach((key) => {
+ createTable = createTable + `| ${key} | `
+ verifyLanguage.forEach((language) => {
+ createTable = createTable + `${statusTranslate[language][key]} | `
+ })
+ createTable = createTable + '\n'
+})
+
+content = content + `${createTable}`
+
+fs.writeFile('./en/resources/status-translate.md', content, (err) => {
+ if (err) {
+ console.error(err)
+ } else {
+ // file written successfully
+ console.log('Status Translate file created')
+ }
+})