npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jochlain/translations

v2.0.0

Published

Translation module

Readme

Translation module

CI state

From a catalog of translations, translate your content with or not parameters.

Can work with Symfony translations structure in Node environment and/or with Webpack using Babel.
See how to integrate with :

Summary

Installation

npm install --save @jochlain/translations

Usage

const CATALOG = {
    en: {
        messages: {
            hello: "Hi",
            "translations.are.incredible": 'The translations are incredible.',
            very: { compound: { key: "The compound key" } },
        },
        forms: {
            "This field is required.": "This field is required."
        },
    },
    es: {
        messages: {
            hello: "Holà",
            "translations.are.incredible": 'Las traducciones son increíbles.',
            very: { compound: { key: "La llave compuesta" } },
        },
        forms: {
            "This field is required.": "Este campo es obligatorio.",
        },
    },
    fr: {
        messages: {
            hello: "Bonjour",
            "translations.are.incredible": "Les traductions sont incroyables.",
            very: { compound: { key: "La clé composée" } },
        },
        forms: {
            "This field is required.": "Ce champs est obligatoire.",
        },
    },
    it: {
        messages: {
            hello: "Ciao",
            "translations.are.incredible": 'Le traduzioni sono incredibili.',
            very: { compound: { key: "La chiave composta" } },
        },
        forms: {
            "This field is required.": "Questo campo è richiesto.",
        },
    },
};
import Translator, { translate } from "@jochlain/translations";

const translator = Translator(CATALOG);
console.log(translator.translate('hello')); // => "Hi"
console.log(translator.translate('hello', null, null, 'fr')); // => "Bonjour"

// With unknown informations
console.log(translator.translate('hello', null, 'forms')); // => "hello"
console.log(translator.translate('hello', null, 'validators')); // => "hello"
console.log(translator.translate('hello', null, null, 'ar')); // => "hello"

// Compound key
console.log(translator.translate('very.compound.key')); // => "The compound key"
// Fake compound key
console.log(translator.translate('translations.are.incredible')); // => "The translations are incredible."

// Usage of with* helper
const translatorFormsEn = translator.withDomain('forms');
const translatorFormsFr = translatorFormsEn.withLocale('fr');

console.log(translatorFormsEn.translate('This field is required.')); // => "This field is required."
console.log(translatorFormsFr.translate('This field is required.')); // => "Ce champs est obligatoire."

console.log(translate({ en: 'Hello', fr: 'Bonjour' })); // => "Hello"
console.log(translate({ en: 'Hello', fr: 'Bonjour' }, null, 'fr')); // => "Bonjour"

For more usage sample see Jest test

Intl integration

Intl installation

npm i -S intl-messageformat

Usage with Intl

import Translator from "@jochlain/translations";
import { IntlMessageFormat } from "intl-messageformat";

const formatter = { format: (message, replacements, locale) => (new IntlMessageFormat(message, locale).format(replacements)) };
const translator = Translator(CATALOG, { formatter });

Questions and answers

Why ?

Because I can't found a simple and secured way to send translations to front shared by server.

Who ?

For little project directly or bigger project with babel macro.

Where ?

In a node / browser / compiled / SSR.

Documentation

Types

type ReplacementType = { [key: string]: number|string };

type FormatType = (message: string, replacements: ReplacementType, locale: string) => string;  
type FormatterType = { format: FormatType };

type CatalogType = { [key: string]: string|CatalogType };  
type TranslationType = { [locale: string]: { [domain: string]: CatalogType } };

type OptionsType = { locale?: string, domain?: string, formatter?: FormatterType };

Constants

DEFAULT_DOMAIN="messages"  
DEFAULT_LOCALE="en"

Module

| Name | Type | Description | |------------------------------|-------------------------------------------|---------------------------------------------------------------------------------------| | default | Proxy<Translator> | If call like a function it calls create static method, else is the Translation class. | | DEFAULT_DOMAIN | string | Module constant | | DEFAULT_LOCALE | string | Module constant | | Translator | Proxy<Translator> | The default export of the module | | createTranslator | Function | Static method create | | formatMessage | Function | Default format method | | getCatalogValue | Function | Static method getCatalogValue | | mergeCatalogs | Function | Static method mergeCatalogs | | translate | Function | Static method translate |

Translator proxy

If is applied like below, it calls static method create. If is constructed like below, is calls the constructor.

import Translator from "@jochlain/translations";

const domain = 'messages';
const locale = 'en';
const catalogs = new Map();
catalogs.set('messages-en', { hello: 'Hello' });
const translations = { en: { messages: { hello: 'Hello' } } };

const translator_applied = Translator(translations, { domain, locale }); // call static method create.
const translator_constructed = new Translator(catalogs, { domain, locale }); // construct new instance

Translator class

Members

| Name | Type | Default | Description | |----------------|------------------------------------|--------------------------------------------------------------|----------------------------------------------| | catalogs | Map<string, CatalogType> | [] | Translation catalogs | | fallbackDomain | string | 'messages' | Default domain used in translate | | fallbackLocale | string | 'en' | Default locale used in translate | | formatter | FormatterType | { format } | Formate message with locale and replacements | | translations | TranslationType | {} | Translation catalogs formatted as object |

Constructor

Parameters

| Name | Type | Default | |----------|------------------------------------|-----------| | catalogs | Map<string, CatalogType> | Empty Map | | options | OptionsType | {} |

Return value

| Type | |---------------------------------| | Translator |

Static methods

Create Translator instance with another catalogs format and set fallback values.

Parameters

| Name | Type | Default | Description | |--------------|---------------------------|---------|---------------------------------------------| | translations | TranslationType | {} | Translation catalogs by locale and domains | | options | OptionsType | {} | Options to set member default value |

Return value

| Type | Description | |---------------------------------|-----------------------| | Translator | A translator instance |

Browse catalog to find value assigned to key

Parameters

| Name | Type | |---------|----------------------------------------| | catalog | CatalogType | undefined | | key | string |

Return value

| Type | Description | |--------|----------------------------------------------------------------------| | string | The value in the catalog attached to the key or the key if not found |

Format a key from domain and locale.

Parameters

| Name | Type | |--------|--------| | domain | string | | locale | string |

Return value

| Type | Description | |--------|-------------------| | string | The formatted key |

Deep merge many catalogs

Parameters

| Name | Type | |---------|-------------------------| | target | ?CatalogType | | sources | CatalogType[] |

Return value

| Type | Description | |-----------------------|-----------------------------------| | CatalogType | A catalog with deep merged values |

Get domain and locale from key.

Parameters

| Name | Type | |------|--------| | key | string |

Return value

| Type | Description | |------------------|---------------------------| | [string, string] | The domain and the locale |

Translate a message from a simple catalog

Parameters

| Name | Type | Default | |--------------|------------------------------|--------------------------------------------------------------| | catalog | { [locale: string]: string } | {} | | replacements | ?ReplacementType | {} | | locale | string | DEFAULT_LOCALE | | formatter | FormatterType | { format } |

Return value

| Type | Description | |--------|------------------------| | string | The translated message |

Methods

Add a catalog to translations map

Parameters

| Name | Type | Default | |---------|-----------------------|---------------------------------| | catalog | CatalogType | {} | | locale | string | this.fallbackLocale | | domain | string | this.fallbackDomain |

Return value

| Type | Description | |---------------------------------|------------------------------------------| | Translator | The translator instance to chain methods |

Get the catalog attached to domain and locale in catalogs map.
If locale is like en_US it looks first for a en_US catalog and if not looks for a en catalog.

Parameters

| Name | Type | Default | |---------|--------|---------------------------------| | locale | string | this.fallbackLocale | | domain | string | this.fallbackDomain |

Return value

| Type | Description | |----------------------------------------|-------------------------------------------------------| | CatalogType | undefined | The catalog of messages attached to domain and locale |

Get all domains fill in catalogs map

Return value

| Type | Description | |----------|-------------| | string[] | The domains |

Get all locales fill in catalogs map

Return value

| Type | Description | |----------|-------------| | string[] | The locales |

Get message attached to key in catalog attached to domain and locale in catalogs.
See getCatalog and getCatalogValue

Parameters

| Name | Type | Default | |--------|--------|---------------------------------| | key | string | none | | locale | string | this.fallbackLocale | | domain | string | this.fallbackDomain |

Return value

| Type | Description | |--------|---------------------------------------------| | string | Message attached to key or key if not found |

Get messages attached to key

Parameters

| Name | Type | Default | |--------|--------|---------------------------------| | key | string | none | | domain | string | this.fallbackDomain |

Return value

| Type | Description | |------------------------------|------------------------------------| | { [locale: string] :string } | A collection of messages by locale |

Set the fallbackDomain member

Parameters

| Name | Type | Default | |--------|--------|------------------------------| | domain | string | DEFAULT_DOMAIN |

Return value

| Type | Description | |---------------------------------|------------------------------------------| | Translator | The translator instance to chain methods |

Set the fallbackLocale member

Parameters

| Name | Type | Default | |--------|--------|------------------------------| | locale | string | DEFAULT_LOCALE |

Return value

| Type | Description | |---------------------------------|------------------------------------------| | Translator | The translator instance to chain methods |

Set the formatter member

Parameters

| Name | Type | Default | |-----------|-------------------------|--------------------------------------------------------------| | formatter | FormatterType | { format } |

Return value

| Type | Description | |---------------------------------|------------------------------------------| | Translator | The translator instance to chain methods |

Set the formatter member

Parameters

| Name | Type | Default | |--------------|---------------------------|----------------------------| | translations | TranslationType | The translations to append |

Return value

| Type | Description | |---------------------------------|------------------------------------------| | Translator | The translator instance to chain methods |

Clone instance with fallbackDomain domain parameter

Parameters

| Name | Type | |--------|--------| | domain | string |

Return value

| Type | Description | |---------------------------------|---------------------------| | Translator | A new translator instance |

Clone instance with formatter

Parameters

| Name | Type | |-----------|-------------------------| | formatter | FormatterType |

Return value

| Type | Description | |---------------------------------|---------------------------| | Translator | A new translator instance |

Clone instance with fallbackLocale locale parameter

Parameters

| Name | Type | |--------|--------| | locale | string |

Return value

| Type | Description | |---------------------------------|---------------------------| | Translator | A new translator instance |

Clone instance with domain, formatter, locale.

Parameters

| Name | Type | Default | |-----------|---------------|---------------------------------| | domain | string | this.fallbackDomain | | locale | string | this.fallbackLocale | | formatter | FormatterType | this.formatter |

Return value

| Type | Description | |---------------------------------|---------------------------| | Translator | A new translator instance |

Default format method

By default, format method search each replacement key with a RegExp and replace them by their values.
That's the next part I'm going to look at.

function format(message: string, replacements: ReplacementType, locale: string = DEFAULT_LOCALE) {
    let result = message;
    for (let keys = Object.keys(replacements), idx = 0; idx < keys.length; idx++) {
        result = result.replace(new RegExp(`${keys[idx]}`, 'g'), String(replacements[keys[idx]]));
    }

    return result;
}