diff --git a/.changeset/itchy-glasses-end.md b/.changeset/itchy-glasses-end.md new file mode 100644 index 000000000..d2fc86c05 --- /dev/null +++ b/.changeset/itchy-glasses-end.md @@ -0,0 +1,7 @@ +--- +'@verdaccio/ui-theme': minor +'@verdaccio/ui-components': minor +'@verdaccio/ui-i18n': minor +--- + +feat: new i18n package for ui diff --git a/.gitignore b/.gitignore index 6458612f2..a878d6858 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ packages/standalone/dist/ packages/plugins/ui-theme/static /packages/plugins/ui-theme/src/i18n/download_translations/ !/packages/plugins/ui-theme/src/i18n/crowdin/ui.json +/packages/core/**/download_translations/ ## ui tests !/packages/ui-components/vitest/api/*.tgz diff --git a/crowdin.yaml b/crowdin.yaml index b213af434..8e0b46827 100644 --- a/crowdin.yaml +++ b/crowdin.yaml @@ -6,6 +6,8 @@ api_token_env: CROWDIN_VERDACCIO_API_KEY preserve_hierarchy: true files: + - source: /packages/core/i18n/src/crowdin/*.json + translation: '/packages/core/i18n/src/download_translations/%locale%/%original_file_name%' - source: /packages/plugins/ui-theme/src/i18n/crowdin/*.json translation: '/packages/plugins/ui-theme/src/i18n/download_translations/%locale%/%original_file_name%' - source: /website/i18n/en/**/* @@ -16,4 +18,3 @@ files: - source: /website/versioned_docs/**/* translation: /website/i18n/%locale%/docusaurus-plugin-content-docs/**/%original_file_name% ignore: [/website/versioned_docs/version-6.x/api/**/*] - \ No newline at end of file diff --git a/packages/core/i18n/.babelrc b/packages/core/i18n/.babelrc new file mode 100644 index 000000000..3738648ed --- /dev/null +++ b/packages/core/i18n/.babelrc @@ -0,0 +1,14 @@ +{ + "extends": "../../../.babelrc", + "presets": [ + [ + "@babel/env", + { + "targets": { + "node": 18 + } + } + ], + "@babel/typescript" + ] +} diff --git a/packages/core/i18n/.eslintignore b/packages/core/i18n/.eslintignore new file mode 100644 index 000000000..acf8e826f --- /dev/null +++ b/packages/core/i18n/.eslintignore @@ -0,0 +1,6 @@ +node_modules +coverage/ +lib/ +.nyc_output +tests-report/ +build/ diff --git a/packages/core/i18n/.eslintrc.json b/packages/core/i18n/.eslintrc.json new file mode 100644 index 000000000..3e8a7bcd4 --- /dev/null +++ b/packages/core/i18n/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "@typescript-eslint/no-use-before-define": "off" + } +} diff --git a/packages/core/i18n/package.json b/packages/core/i18n/package.json new file mode 100644 index 000000000..b30d720e2 --- /dev/null +++ b/packages/core/i18n/package.json @@ -0,0 +1,47 @@ +{ + "name": "@verdaccio/ui-i18n", + "version": "8.0.0-next-8.10", + "description": "ui i18n", + "keywords": [ + "private", + "package", + "repository", + "registry", + "enterprise", + "modules", + "proxy", + "server", + "verdaccio" + ], + "main": "./build/index.js", + "types": "./build/index.d.ts", + "author": "Juan Picado ", + "license": "MIT", + "homepage": "https://verdaccio.org", + "engines": { + "node": ">=18" + }, + "repository": { + "type": "https", + "url": "https://github.com/verdaccio/verdaccio", + "directory": "packages/core/url-resolver" + }, + "bugs": { + "url": "https://github.com/verdaccio/verdaccio/issues" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "clean": "rimraf ./build", + "test": "echo \"Error: no test specified\"", + "type-check": "tsc --noEmit -p tsconfig.build.json", + "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json", + "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps", + "build": "pnpm run build:js && pnpm run build:types" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } +} diff --git a/packages/ui-components/.storybook/i18n/ui.json b/packages/core/i18n/src/crowdin/ui.json similarity index 100% rename from packages/ui-components/.storybook/i18n/ui.json rename to packages/core/i18n/src/crowdin/ui.json diff --git a/packages/core/i18n/src/index.ts b/packages/core/i18n/src/index.ts new file mode 100644 index 000000000..15e566f75 --- /dev/null +++ b/packages/core/i18n/src/index.ts @@ -0,0 +1 @@ +export { loadTranslationFile as default } from './loadTranslationFile'; diff --git a/packages/plugins/ui-theme/src/i18n/loadTranslationFile.ts b/packages/core/i18n/src/loadTranslationFile.ts similarity index 100% rename from packages/plugins/ui-theme/src/i18n/loadTranslationFile.ts rename to packages/core/i18n/src/loadTranslationFile.ts diff --git a/packages/core/i18n/tsconfig.build.json b/packages/core/i18n/tsconfig.build.json new file mode 100644 index 000000000..79f1f81e0 --- /dev/null +++ b/packages/core/i18n/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./build" + }, + "include": ["src/**/*"], + "exclude": ["src/**/*.test.ts"] +} diff --git a/packages/core/i18n/tsconfig.json b/packages/core/i18n/tsconfig.json new file mode 100644 index 000000000..35b3cee58 --- /dev/null +++ b/packages/core/i18n/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.reference.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./build" + }, + "include": ["src/**/*"], + "exclude": ["src/**/*.test.ts"] +} diff --git a/packages/plugins/ui-theme/package.json b/packages/plugins/ui-theme/package.json index ccdf1a57c..9f36db17d 100644 --- a/packages/plugins/ui-theme/package.json +++ b/packages/plugins/ui-theme/package.json @@ -30,6 +30,7 @@ "@verdaccio/node-api": "workspace:8.0.0-next-8.10", "@verdaccio/types": "workspace:*", "@verdaccio/ui-components": "workspace:4.0.0-next-8.5", + "@verdaccio/ui-i18n": "workspace:8.0.0-next-8.10", "@vitejs/plugin-react": "4.3.4", "babel-loader": "8.4.1", "babel-plugin-dynamic-import-node": "2.3.3", diff --git a/packages/plugins/ui-theme/src/i18n/config.ts b/packages/plugins/ui-theme/src/i18n/config.ts index 5a3cba2b0..b8a541996 100644 --- a/packages/plugins/ui-theme/src/i18n/config.ts +++ b/packages/plugins/ui-theme/src/i18n/config.ts @@ -1,18 +1,21 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; +import loadTranslationFile from '@verdaccio/ui-i18n'; + import { DEFAULT_LANGUAGE, LanguageConfiguration, listLanguages, listLanguagesAsString, } from './enabledLanguages'; -import { loadTranslationFile } from './loadTranslationFile'; const languages = listLanguages.reduce((acc, item: LanguageConfiguration) => { acc[item.lng] = { translation: - item.lng === DEFAULT_LANGUAGE ? require(`./crowdin/ui.json`) : loadTranslationFile(item.lng), + item.lng === DEFAULT_LANGUAGE + ? loadTranslationFile(DEFAULT_LANGUAGE) + : loadTranslationFile(item.lng), }; return acc; }, {}); diff --git a/packages/ui-components/.storybook/i18n/index.ts b/packages/ui-components/.storybook/i18n/index.ts index c8d5a3156..09a2c9942 100644 --- a/packages/ui-components/.storybook/i18n/index.ts +++ b/packages/ui-components/.storybook/i18n/index.ts @@ -2,6 +2,8 @@ import * as Flags from 'country-flag-icons/react/3x2'; import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; +import loadTranslation from '@verdaccio/ui-i18n'; + const DEFAULT_LANGUAGE = 'en-US'; export const listLanguages = [ @@ -19,7 +21,7 @@ const whitelist = listLanguages.reduce((acc, item) => { const resources = listLanguages.reduce((acc, item) => { // Use English for all languages - acc[item.lng] = { translation: require(`./ui.json`) }; + acc[item.lng] = { translation: loadTranslation(item.lng) }; return acc; }, {}); diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index b72d59a1d..f1b48b466 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -32,6 +32,7 @@ "@rematch/core": "2.2.0", "@rematch/loading": "2.1.2", "@rematch/persist": "2.1.2", + "@verdaccio/ui-i18n": "workspace:8.0.0-next-8.10", "country-flag-icons": "1.5.16", "dayjs": "1.11.13", "dompurify": "3.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98913eea0..6c59b4748 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,6 +741,8 @@ importers: specifier: workspace:13.0.0-next-8.3 version: link:../types + packages/core/i18n: {} + packages/core/tarball: dependencies: '@verdaccio/core': @@ -1228,6 +1230,9 @@ importers: '@verdaccio/ui-components': specifier: workspace:4.0.0-next-8.5 version: link:../../ui-components + '@verdaccio/ui-i18n': + specifier: workspace:8.0.0-next-8.10 + version: link:../../core/i18n '@vitejs/plugin-react': specifier: 4.3.4 version: 4.3.4(vite@5.3.1(@types/node@22.10.5)(sass@1.83.4)(terser@5.31.3)) @@ -1932,6 +1937,9 @@ importers: '@rematch/persist': specifier: 2.1.2 version: 2.1.2(@rematch/core@2.2.0(redux@4.2.1))(react@18.3.1)(redux@4.2.1) + '@verdaccio/ui-i18n': + specifier: workspace:8.0.0-next-8.10 + version: link:../core/i18n country-flag-icons: specifier: 1.5.16 version: 1.5.16 @@ -26419,7 +26427,7 @@ snapshots: i18next@20.6.1: dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.26.7 iconv-lite@0.4.24: dependencies: