From a111b1b63156f82e3636c7245732bb5256b3dcce Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Fri, 30 Aug 2024 16:01:34 +0200 Subject: [PATCH] fix: i18n translation - rename directories --- src/localeDetector.ts | 24 +++++++++++++ src/nuxt.config.ts | 6 ++++ src/{ports => repositories}/database.ts | 36 ++++++++++++++++--- .../system/interface.ts | 0 src/{ports => repositories}/system/model.ts | 0 src/{ports => repositories}/types.ts | 0 src/{ports => repositories}/user/interface.ts | 0 src/{ports => repositories}/user/model.ts | 0 src/server/api/account/new.post.ts | 6 ++-- src/server/utils/Database.ts | 2 +- .../database/inmemory.ts | 11 +++--- 11 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 src/localeDetector.ts rename src/{ports => repositories}/database.ts (55%) rename src/{ports => repositories}/system/interface.ts (100%) rename src/{ports => repositories}/system/model.ts (100%) rename src/{ports => repositories}/types.ts (100%) rename src/{ports => repositories}/user/interface.ts (100%) rename src/{ports => repositories}/user/model.ts (100%) rename src/{adapters => services}/database/inmemory.ts (91%) diff --git a/src/localeDetector.ts b/src/localeDetector.ts new file mode 100644 index 00000000..633b2ea4 --- /dev/null +++ b/src/localeDetector.ts @@ -0,0 +1,24 @@ +// https://i18n.nuxtjs.org/docs/guide/server-side-translations +// Detect based on query, cookie, header +export default defineI18nLocaleDetector((event, config) => { + // try to get locale from query + const query = tryQueryLocale(event, { lang: '' }); // disable locale default value with `lang` option + if (query) { + return query.toString(); + } + + // try to get locale from cookie + const cookie = tryCookieLocale(event, { lang: '', name: 'i18n_locale' }); // disable locale default value with `lang` option + if (cookie) { + return cookie.toString(); + } + + // try to get locale from header (`accept-header`) + const header = tryHeaderLocale(event, { lang: '' }); // disable locale default value with `lang` option + if (header) { + return header.toString(); + } + + // If the locale cannot be resolved up to this point, it is resolved with the value `defaultLocale` of the locale config passed to the function + return config.defaultLocale; +}); diff --git a/src/nuxt.config.ts b/src/nuxt.config.ts index 7f4e9165..59648d76 100644 --- a/src/nuxt.config.ts +++ b/src/nuxt.config.ts @@ -17,4 +17,10 @@ export default defineNuxtConfig({ classSuffix: '', cookieName: 'theme', }, + i18n: { + // https://i18n.nuxtjs.org/docs/guide/server-side-translations + experimental: { + localeDetector: './localeDetector.ts', + }, + }, }); diff --git a/src/ports/database.ts b/src/repositories/database.ts similarity index 55% rename from src/ports/database.ts rename to src/repositories/database.ts index 65a626d6..1615d4e4 100644 --- a/src/ports/database.ts +++ b/src/repositories/database.ts @@ -8,7 +8,7 @@ import type { System } from './system/model'; * Abstract class for database operations. * Provides methods to connect, disconnect, and interact with system and user data. * - * *Note : Throw with `DatabaseError` to ensure API handling errors.* + * **Note :** Always throw `DatabaseError` to ensure proper API error handling. * */ export default abstract class DatabaseProvider @@ -37,15 +37,43 @@ export default abstract class DatabaseProvider abstract deleteUser(id: ID): Promise; } +/** + * Represents a specialized error class for database-related operations. + * This class is designed to work with internationalization (i18n) by using message keys. + * The actual error messages are expected to be retrieved using these keys from an i18n system. + * + * ### Usage: + * When throwing a `DatabaseError`, you provide an i18n key as the message. + * The key will be used by the i18n system to retrieve the corresponding localized error message. + * + * Example: + * ```typescript + * throw new DatabaseError(DatabaseError.ERROR_PASSWORD_REQ); + * ... + * if (error instanceof DatabaseError) { + * const t = await useTranslation(event); + * throw createError({ + * statusCode: 400, + * statusMessage: t(error.message), + * message: error.message, + * }); + * } else { + * throw createError('Something happened !'); + * } + * ``` + * + * ### Constructor: + * - `constructor(message: string)`: Creates a new `DatabaseError` with the provided i18n message key. + * + * @extends {Error} + */ export class DatabaseError extends Error { static readonly ERROR_PASSWORD_REQ = 'errorPasswordReq'; static readonly ERROR_USER_EXIST = 'errorUserExist'; static readonly ERROR_DATABASE_CONNECTION = 'errorDatabaseConn'; static readonly ERROR_USERNAME_REQ = 'errorUsernameReq'; - constructor(messageKey: string) { - const { t } = useI18n(); - const message = t(messageKey); + constructor(message: string) { super(message); this.name = 'DatabaseError'; } diff --git a/src/ports/system/interface.ts b/src/repositories/system/interface.ts similarity index 100% rename from src/ports/system/interface.ts rename to src/repositories/system/interface.ts diff --git a/src/ports/system/model.ts b/src/repositories/system/model.ts similarity index 100% rename from src/ports/system/model.ts rename to src/repositories/system/model.ts diff --git a/src/ports/types.ts b/src/repositories/types.ts similarity index 100% rename from src/ports/types.ts rename to src/repositories/types.ts diff --git a/src/ports/user/interface.ts b/src/repositories/user/interface.ts similarity index 100% rename from src/ports/user/interface.ts rename to src/repositories/user/interface.ts diff --git a/src/ports/user/model.ts b/src/repositories/user/model.ts similarity index 100% rename from src/ports/user/model.ts rename to src/repositories/user/model.ts diff --git a/src/server/api/account/new.post.ts b/src/server/api/account/new.post.ts index d812c525..d3cfdc31 100644 --- a/src/server/api/account/new.post.ts +++ b/src/server/api/account/new.post.ts @@ -1,4 +1,4 @@ -import { DatabaseError } from '~/ports/database'; +import { DatabaseError } from '~/repositories/database'; export default defineEventHandler(async (event) => { setHeader(event, 'Content-Type', 'application/json'); @@ -11,9 +11,11 @@ export default defineEventHandler(async (event) => { return { success: true }; } catch (error) { if (error instanceof DatabaseError) { + const t = await useTranslation(event); throw createError({ statusCode: 400, - statusMessage: error.message, + statusMessage: t(error.message), + message: error.message, }); } else { throw createError('Something happened !'); diff --git a/src/server/utils/Database.ts b/src/server/utils/Database.ts index bcb12d8d..409d2314 100644 --- a/src/server/utils/Database.ts +++ b/src/server/utils/Database.ts @@ -4,7 +4,7 @@ * */ -import InMemory from '~/adapters/database/inmemory'; +import InMemory from '~/services/database/inmemory'; const provider = new InMemory(); diff --git a/src/adapters/database/inmemory.ts b/src/services/database/inmemory.ts similarity index 91% rename from src/adapters/database/inmemory.ts rename to src/services/database/inmemory.ts index 032e6f2d..35f64b3d 100644 --- a/src/adapters/database/inmemory.ts +++ b/src/services/database/inmemory.ts @@ -1,13 +1,13 @@ import debug from 'debug'; import packageJson from '@/package.json'; -import DatabaseProvider, { DatabaseError } from '~/ports/database'; -import { ChartType, Lang } from '~/ports/types'; +import DatabaseProvider, { DatabaseError } from '~/repositories/database'; +import { ChartType, Lang } from '~/repositories/types'; import type { SessionConfig } from 'h3'; -import type { ID } from '~/ports/types'; -import type { System } from '~/ports/system/model'; -import type { User } from '~/ports/user/model'; +import type { ID } from '~/repositories/types'; +import type { System } from '~/repositories/system/model'; +import type { User } from '~/repositories/user/model'; import { hashPassword, isPasswordStrong } from '~/server/utils/password'; const DEBUG = debug('InMemoryDB'); @@ -97,6 +97,7 @@ export default class InMemory extends DatabaseProvider { async newUserWithPassword(username: string, password: string) { DEBUG('New User'); + if (username.length < 8) { throw new DatabaseError(DatabaseError.ERROR_USERNAME_REQ); }