Docs/API Reference/Packages

@veap/translatable

Inspected version: 0.1.0 (private) · Part of the veap-repo monorepo (packages/veap-translatable).

4 min read

Inspected version: 0.1.0 (private) · Part of the veap-repo monorepo (packages/veap-translatable).

@veap/translatable adds multilingual field storage to any @veap/database model. Instead of a translation table per model, it stores all translations for all models in one polymorphic translations table reached through a morphMany relation.

Entry points#

The manifest exports ., ./migrations, ./ui and ./package.json.

Locale management#

A process-global locale plus an AsyncLocalStorage scope:

ExportBehavior
getLocale()Current locale; the AsyncLocalStorage store wins, otherwise the global current locale.
setLocale(locale)Sets the global current locale.
getDefaultLocale() / setDefaultLocale(locale)The default locale (initial value "en").
getFallbackLocale() / setFallbackLocale(locale)The fallback locale used when a requested translation is missing (initial value "en").
withLocale(locale, callback)Runs callback with locale scoped through AsyncLocalStorage; returns its result.

The locale state is global, not request-scoped, unless you wrap work in withLocale().

Models and mixins#

  • Translation — the translations model (static table = "translations"), with translatable() (morphTo) and date casts. Registered in MorphMap as translation/translations.
  • TranslatableModel — a base class extending Model that overrides query() to return TranslatableQueryBuilder and getAttribute/setAttribute/toJSON to route translatable fields through the translation store.
  • Translatable(Base) — a mixin adding the same behavior to a class that already extends another base.
  • ITranslatableModel / TranslatableClass — the typing helpers for both forms.

Declare translatable fields on the class with static translatable = ["title", "slug", "content"].

Instance API#

MethodBehavior
translations()The morphMany(Translation, "translatable") relation.
getTranslation(field, locale?, fallback = true)Value for a locale, falling back to the fallback locale, default locale, then the physical column.
setTranslation(field, locale, value)Stages a translation (a null/undefined value deletes it on save).
getTranslations(field?)One field as { locale: value }, or all fields as { field: { locale: value } }.
setTranslations(field, { locale: value })Stages several locales for a field.
fillTranslations(map)Accepts either { field: { locale: value } } or { locale: { field: value } }.
loadTranslations(locales?)Loads translations from the database into the in-memory cache and relation.
saveTranslations() / deleteTranslations()Persist or remove staged/owned translations.
getAttribute / setAttribute / toJSONOverridden so translatable fields behave like normal properties.

setAttribute also accepts an object to set several locales at once (post.title = { pl, en }). For non-object values it stages the value for the active locale.

Lifecycle: saved() calls saveTranslations() and deleted() calls deleteTranslations().

Query builder#

TranslatableQueryBuilder extends ModelQueryBuilder and eager-loads translations by default. Methods:

  • whereTranslation(key, value, locale?), orWhereTranslation(...)
  • whereTranslationLike(key, pattern, locale?), orWhereTranslationLike(...)
  • whereTranslationIn(key, values, locale?)
  • withTranslations() / withoutTranslations()
  • orderByTranslation(key, direction?, locale?) — orders by a correlated subquery against the translations table.

Migrations#

The /migrations entry point exports a migration that creates the translations table (translatable_type, translatable_id, locale, key, value, timestamps), a unique constraint on (translatable_type, translatable_id, locale, key) and two lookup indexes. The down() intentionally does not drop the shared table because several packages share it.

UI (./ui)#

  • TranslatableField — a single field with a locale switcher (value/onChange operate on Record<locale, string>).
  • TranslatableFormCard — a card of translatable fields keyed by locale ({ locale: { field: value } }), with per-locale completion tracking.
  • TranslatableTabs — the locale tab strip (locales, activeLocale, onChange, completedMap).

TranslatableField and TranslatableTabs default to ["pl", "en"], while the locale manager defaults to "en"; set the locale explicitly when the two must agree.

veap
Preparing0%