From 783ed2baf7f0f77d078e06a280f84252c39cf2d2 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 13:12:42 +0100 Subject: [PATCH 01/18] feat: init typesafe-i18n --- frontend/.typesafe-i18n.json | 7 +++++ frontend/package.json | 4 ++- frontend/pnpm-lock.yaml | 13 +++++++- frontend/src/translations/cs/index.ts | 8 +++++ frontend/src/translations/de/index.ts | 8 +++++ frontend/src/translations/formatters.ts | 11 +++++++ frontend/src/translations/i18n-svelte.ts | 12 +++++++ frontend/src/translations/i18n-types.ts | 19 +++++++++++ frontend/src/translations/i18n-util.async.ts | 25 +++++++++++++++ frontend/src/translations/i18n-util.sync.ts | 21 +++++++++++++ frontend/src/translations/i18n-util.ts | 33 ++++++++++++++++++++ 11 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 frontend/.typesafe-i18n.json create mode 100644 frontend/src/translations/cs/index.ts create mode 100644 frontend/src/translations/de/index.ts create mode 100644 frontend/src/translations/formatters.ts create mode 100644 frontend/src/translations/i18n-svelte.ts create mode 100644 frontend/src/translations/i18n-types.ts create mode 100644 frontend/src/translations/i18n-util.async.ts create mode 100644 frontend/src/translations/i18n-util.sync.ts create mode 100644 frontend/src/translations/i18n-util.ts diff --git a/frontend/.typesafe-i18n.json b/frontend/.typesafe-i18n.json new file mode 100644 index 0000000..12eb8a1 --- /dev/null +++ b/frontend/.typesafe-i18n.json @@ -0,0 +1,7 @@ +{ + "baseLocale": "cs", + "adapter": "svelte", + "esmImports": true, + "outputPath": "./src/translations", + "$schema": "https://unpkg.com/typesafe-i18n@5.20.0/schema/typesafe-i18n.json" +} \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 2c1e416..f10de62 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,7 +10,8 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --plugin-search-dir . --check . && eslint .", - "format": "prettier --plugin-search-dir . --write ." + "format": "prettier --plugin-search-dir . --write .", + "typesafe-i18n": "typesafe-i18n" }, "devDependencies": { "@playwright/test": "^1.29.2", @@ -46,6 +47,7 @@ "svelte-tippy": "^1.3.2", "swiper": "^8.4.6", "tippy.js": "^6.3.7", + "typesafe-i18n": "^5.20.0", "yup": "^0.32.11" } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index d76650e..774c62b 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -34,6 +34,9 @@ dependencies: tippy.js: specifier: ^6.3.7 version: 6.3.7 + typesafe-i18n: + specifier: ^5.20.0 + version: 5.20.0(typescript@4.9.4) yup: specifier: ^0.32.11 version: 0.32.11 @@ -2385,11 +2388,19 @@ packages: engines: {node: '>=10'} dev: true + /typesafe-i18n@5.20.0(typescript@4.9.4): + resolution: {integrity: sha512-uOvKnVkp1tXRDNBz9Aom54qs0LP2xWrtDliMPdKm9Scsnvn0DC7ZqjSGdOWxVplpbFbqYWNZuzx5Q5jWOjnBTA==} + hasBin: true + peerDependencies: + typescript: '>=3.5.1' + dependencies: + typescript: 4.9.4 + dev: false + /typescript@4.9.4: resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /unconfig@0.2.2: resolution: {integrity: sha512-JN1MeYJ/POnjBj7NgOJJxPp6+NcD6Nd0hEuK0D89kjm9GvQQUq8HeE2Eb7PZgtu+64mWkDiqeJn1IZoLH7htPg==} diff --git a/frontend/src/translations/cs/index.ts b/frontend/src/translations/cs/index.ts new file mode 100644 index 0000000..71ee449 --- /dev/null +++ b/frontend/src/translations/cs/index.ts @@ -0,0 +1,8 @@ +import type { BaseTranslation } from '../i18n-types.js' + +const cs: BaseTranslation = { + // TODO: your translations go here + HI: 'Hi {name:string}! Please leave a star if you like this project: https://github.com/ivanhofer/typesafe-i18n', +} + +export default cs diff --git a/frontend/src/translations/de/index.ts b/frontend/src/translations/de/index.ts new file mode 100644 index 0000000..eaae244 --- /dev/null +++ b/frontend/src/translations/de/index.ts @@ -0,0 +1,8 @@ +import type { Translation } from '../i18n-types.js' + +const de: Translation = { + // this is an example Translation, just rename or delete this folder if you want + HI: 'Hallo {name}! Bitte hinterlasse einen Stern, wenn dir das Projekt gefällt: https://github.com/ivanhofer/typesafe-i18n', +} + +export default de diff --git a/frontend/src/translations/formatters.ts b/frontend/src/translations/formatters.ts new file mode 100644 index 0000000..9e0741e --- /dev/null +++ b/frontend/src/translations/formatters.ts @@ -0,0 +1,11 @@ +import type { FormattersInitializer } from 'typesafe-i18n' +import type { Locales, Formatters } from './i18n-types.js' + +export const initFormatters: FormattersInitializer = (locale: Locales) => { + + const formatters: Formatters = { + // add your formatter functions here + } + + return formatters +} diff --git a/frontend/src/translations/i18n-svelte.ts b/frontend/src/translations/i18n-svelte.ts new file mode 100644 index 0000000..23d478d --- /dev/null +++ b/frontend/src/translations/i18n-svelte.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. +/* eslint-disable */ + +import { initI18nSvelte } from 'typesafe-i18n/svelte' +import type { Formatters, Locales, TranslationFunctions, Translations } from './i18n-types.js' +import { loadedFormatters, loadedLocales } from './i18n-util.js' + +const { locale, LL, setLocale } = initI18nSvelte(loadedLocales, loadedFormatters) + +export { locale, LL, setLocale } + +export default LL diff --git a/frontend/src/translations/i18n-types.ts b/frontend/src/translations/i18n-types.ts new file mode 100644 index 0000000..9ae0378 --- /dev/null +++ b/frontend/src/translations/i18n-types.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. +/* eslint-disable */ +import type { BaseTranslation as BaseTranslationType } from 'typesafe-i18n' + +export type BaseTranslation = BaseTranslationType +export type BaseLocale = 'cs' + +export type Locales = + | 'cs' + +export type Translation = RootTranslation + +export type Translations = RootTranslation + +type RootTranslation = {} + +export type TranslationFunctions = {} + +export type Formatters = {} diff --git a/frontend/src/translations/i18n-util.async.ts b/frontend/src/translations/i18n-util.async.ts new file mode 100644 index 0000000..5d4505a --- /dev/null +++ b/frontend/src/translations/i18n-util.async.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. +/* eslint-disable */ + +import { initFormatters } from './formatters.js' +import type { Locales, Translations } from './i18n-types.js' +import { loadedFormatters, loadedLocales, locales } from './i18n-util.js' + +const localeTranslationLoaders = { +} + +const updateDictionary = (locale: Locales, dictionary: Partial): Translations => + loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary } + +export const importLocaleAsync = async (locale: Locales): Promise => + (await localeTranslationLoaders[locale]()).default as unknown as Translations + +export const loadLocaleAsync = async (locale: Locales): Promise => { + updateDictionary(locale, await importLocaleAsync(locale)) + loadFormatters(locale) +} + +export const loadAllLocalesAsync = (): Promise => Promise.all(locales.map(loadLocaleAsync)) + +export const loadFormatters = (locale: Locales): void => + void (loadedFormatters[locale] = initFormatters(locale)) diff --git a/frontend/src/translations/i18n-util.sync.ts b/frontend/src/translations/i18n-util.sync.ts new file mode 100644 index 0000000..523c1eb --- /dev/null +++ b/frontend/src/translations/i18n-util.sync.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. +/* eslint-disable */ + +import { initFormatters } from './formatters.js' +import type { Locales, Translations } from './i18n-types.js' +import { loadedFormatters, loadedLocales, locales } from './i18n-util.js' + +const localeTranslations = { +} + +export const loadLocale = (locale: Locales): void => { + if (loadedLocales[locale]) return + + loadedLocales[locale] = localeTranslations[locale] as unknown as Translations + loadFormatters(locale) +} + +export const loadAllLocales = (): void => locales.forEach(loadLocale) + +export const loadFormatters = (locale: Locales): void => + void (loadedFormatters[locale] = initFormatters(locale)) diff --git a/frontend/src/translations/i18n-util.ts b/frontend/src/translations/i18n-util.ts new file mode 100644 index 0000000..109c3be --- /dev/null +++ b/frontend/src/translations/i18n-util.ts @@ -0,0 +1,33 @@ +// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. +/* eslint-disable */ + +import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n' +import type { LocaleDetector } from 'typesafe-i18n/detectors' +import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n' +import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors' +import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types.js' + +export const baseLocale: Locales = 'cs' + +export const locales: Locales[] = [ +] + +export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales) + +export const loadedLocales: Record = {} as Record + +export const loadedFormatters: Record = {} as Record + +export const i18nString = (locale: Locales): TranslateByString => initI18nString(locale, loadedFormatters[locale]) + +export const i18nObject = (locale: Locales): TranslationFunctions => + initI18nObject( + locale, + loadedLocales[locale], + loadedFormatters[locale] + ) + +export const i18n = (): LocaleTranslationFunctions => + initI18n(loadedLocales, loadedFormatters) + +export const detectLocale = (...detectors: LocaleDetector[]): Locales => detectLocaleFn(baseLocale, locales, ...detectors) From e83805743a5daa8c41a0e44a4282d6e9eb8b3d89 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 13:12:56 +0100 Subject: [PATCH 02/18] chore: add VSCode i18n ally settings --- .../.vscode/i18n-ally-custom-framework.yml | 18 ++++++++++++++++++ frontend/.vscode/settings.json | 6 ++++++ 2 files changed, 24 insertions(+) create mode 100644 frontend/.vscode/i18n-ally-custom-framework.yml create mode 100644 frontend/.vscode/settings.json diff --git a/frontend/.vscode/i18n-ally-custom-framework.yml b/frontend/.vscode/i18n-ally-custom-framework.yml new file mode 100644 index 0000000..c17d03b --- /dev/null +++ b/frontend/.vscode/i18n-ally-custom-framework.yml @@ -0,0 +1,18 @@ +languageIds: + - typescript + - javascript + - typescriptreact + - javascriptreact + - svelte + - html + +usageMatchRegex: + - "\\$?LL\\.({key})\\(((\\{.*\\})|([^)]*))\\)" + +refactorTemplates: + - '{$LL.$1()}' + - '{LL.$1()}' + - '$LL.$1()' + - 'LL.$1()' + +monopoly: true diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json new file mode 100644 index 0000000..c7be7fc --- /dev/null +++ b/frontend/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "i18n-ally.pathMatcher": "{locale}/index.{ext}", + "i18n-ally.enabledParsers": ["ts", "js"], + "i18n-ally.keystyle": "nested", + "i18n-ally.localesPaths": ["src/translations"] +} From 474caab0e1e3df4a199ad539625940ff8c358e38 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 13:19:11 +0100 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20deportace=20N=C4=9Bmc=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/translations/cs/index.ts | 2 -- frontend/src/translations/de/index.ts | 8 -------- frontend/src/translations/i18n-util.async.ts | 1 + frontend/src/translations/i18n-util.sync.ts | 3 +++ frontend/src/translations/i18n-util.ts | 1 + 5 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 frontend/src/translations/de/index.ts diff --git a/frontend/src/translations/cs/index.ts b/frontend/src/translations/cs/index.ts index 71ee449..7c0994b 100644 --- a/frontend/src/translations/cs/index.ts +++ b/frontend/src/translations/cs/index.ts @@ -1,8 +1,6 @@ import type { BaseTranslation } from '../i18n-types.js' const cs: BaseTranslation = { - // TODO: your translations go here - HI: 'Hi {name:string}! Please leave a star if you like this project: https://github.com/ivanhofer/typesafe-i18n', } export default cs diff --git a/frontend/src/translations/de/index.ts b/frontend/src/translations/de/index.ts deleted file mode 100644 index eaae244..0000000 --- a/frontend/src/translations/de/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Translation } from '../i18n-types.js' - -const de: Translation = { - // this is an example Translation, just rename or delete this folder if you want - HI: 'Hallo {name}! Bitte hinterlasse einen Stern, wenn dir das Projekt gefällt: https://github.com/ivanhofer/typesafe-i18n', -} - -export default de diff --git a/frontend/src/translations/i18n-util.async.ts b/frontend/src/translations/i18n-util.async.ts index 5d4505a..e9e06f8 100644 --- a/frontend/src/translations/i18n-util.async.ts +++ b/frontend/src/translations/i18n-util.async.ts @@ -6,6 +6,7 @@ import type { Locales, Translations } from './i18n-types.js' import { loadedFormatters, loadedLocales, locales } from './i18n-util.js' const localeTranslationLoaders = { + cs: () => import('./cs/index.js'), } const updateDictionary = (locale: Locales, dictionary: Partial): Translations => diff --git a/frontend/src/translations/i18n-util.sync.ts b/frontend/src/translations/i18n-util.sync.ts index 523c1eb..5ad0a1d 100644 --- a/frontend/src/translations/i18n-util.sync.ts +++ b/frontend/src/translations/i18n-util.sync.ts @@ -5,7 +5,10 @@ import { initFormatters } from './formatters.js' import type { Locales, Translations } from './i18n-types.js' import { loadedFormatters, loadedLocales, locales } from './i18n-util.js' +import cs from './cs/index.js' + const localeTranslations = { + cs, } export const loadLocale = (locale: Locales): void => { diff --git a/frontend/src/translations/i18n-util.ts b/frontend/src/translations/i18n-util.ts index 109c3be..bbd277a 100644 --- a/frontend/src/translations/i18n-util.ts +++ b/frontend/src/translations/i18n-util.ts @@ -10,6 +10,7 @@ import type { Formatters, Locales, Translations, TranslationFunctions } from './ export const baseLocale: Locales = 'cs' export const locales: Locales[] = [ + 'cs' ] export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales) From 02c2953b64b87f10e8b957152143fc9c161c680b Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 13:23:35 +0100 Subject: [PATCH 04/18] feat: aliases for paths --- frontend/svelte.config.js | 7 ++++++- frontend/tsconfig.json | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js index 2ef33af..a3f4721 100644 --- a/frontend/svelte.config.js +++ b/frontend/svelte.config.js @@ -1,5 +1,6 @@ import adapter from '@sveltejs/adapter-node'; import preprocess from 'svelte-preprocess'; +import path from "path"; import { windi } from 'svelte-windicss-preprocess'; /** @type {import('@sveltejs/kit').Config} */ @@ -8,7 +9,11 @@ const config = { // for more information about preprocessors preprocess: [preprocess(), windi({})], kit: { - adapter: adapter({ out: 'build' }) + adapter: adapter({ out: 'build' }), + alias: { + $i18n: path.resolve('./src/translations'), + } + } }; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 8793475..7176a96 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -9,6 +9,13 @@ "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, - "strict": true + "strict": true, + "paths": { + "$lib": ["src/lib"], + "$lib/*": ["src/lib/*"], + "$i18n": ["src/translations"], + "$i18n/*": ["src/translations/*"], + "$params": ["src/params"], + } } } From b658532f1fe906535da2b59f6d4ea08598b60956 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 14:13:54 +0100 Subject: [PATCH 05/18] chore: remove broken config overrides --- .../.vscode/i18n-ally-custom-framework.yml | 18 ------------------ frontend/.vscode/settings.json | 6 ------ 2 files changed, 24 deletions(-) delete mode 100644 frontend/.vscode/i18n-ally-custom-framework.yml delete mode 100644 frontend/.vscode/settings.json diff --git a/frontend/.vscode/i18n-ally-custom-framework.yml b/frontend/.vscode/i18n-ally-custom-framework.yml deleted file mode 100644 index c17d03b..0000000 --- a/frontend/.vscode/i18n-ally-custom-framework.yml +++ /dev/null @@ -1,18 +0,0 @@ -languageIds: - - typescript - - javascript - - typescriptreact - - javascriptreact - - svelte - - html - -usageMatchRegex: - - "\\$?LL\\.({key})\\(((\\{.*\\})|([^)]*))\\)" - -refactorTemplates: - - '{$LL.$1()}' - - '{LL.$1()}' - - '$LL.$1()' - - 'LL.$1()' - -monopoly: true diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json deleted file mode 100644 index c7be7fc..0000000 --- a/frontend/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "i18n-ally.pathMatcher": "{locale}/index.{ext}", - "i18n-ally.enabledParsers": ["ts", "js"], - "i18n-ally.keystyle": "nested", - "i18n-ally.localesPaths": ["src/translations"] -} From 14c334bb5570af50cb4a1462accecb90f79aa700 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 14:14:07 +0100 Subject: [PATCH 06/18] chore: fix tsconfig --- frontend/tsconfig.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 7176a96..ab896ad 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -10,12 +10,5 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "paths": { - "$lib": ["src/lib"], - "$lib/*": ["src/lib/*"], - "$i18n": ["src/translations"], - "$i18n/*": ["src/translations/*"], - "$params": ["src/params"], - } } } From cbb1a9a29e2bad486ce229e842afe9fe8030a604 Mon Sep 17 00:00:00 2001 From: EETagent Date: Fri, 20 Jan 2023 14:14:19 +0100 Subject: [PATCH 07/18] feat? initial translation --- .../(candidate)/auth/login/+page.svelte | 6 +-- frontend/src/translations/cs/index.ts | 15 ++++++-- frontend/src/translations/i18n-types.ts | 38 +++++++++++++++++-- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/frontend/src/routes/(candidate)/auth/login/+page.svelte b/frontend/src/routes/(candidate)/auth/login/+page.svelte index cff8cc5..3f1bd4c 100644 --- a/frontend/src/routes/(candidate)/auth/login/+page.svelte +++ b/frontend/src/routes/(candidate)/auth/login/+page.svelte @@ -1,4 +1,5 @@ @@ -431,10 +432,9 @@