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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@adguard/translate

v1.0.2

Published

Simple internationalization library with React integration

Downloads

1,038

Readme

AdGuard Translate

Simple internationalization library with React integration

Installation

npm

npm install @adguard/translate

Yarn

yarn add @adguard/translate

Usage

Messages format

Library supports messages with placeholders, tags and plural forms

Placeholders

Placeholders should be wrapped in % mark

e.g.

"agreement_consent": {
    "message": "Servers number %count%",
}

Tags support

Library supports open/close tags, and their values should be provided in the translate method

e.g.

<a>link</a> to the text

and void tags

e.g.

<img src="server.jpg" >
Default list of tags

Next tags are not required in the translate, because they are provided by default

    <b>, <p>, <strong>, <tt>, <s>, <i>,

Plural strings

Library supports plural strings translation.

e.g.

Нет серверов | %count% сервер | %count% сервера | %count% серверов

Plural strings should follow simple rules.

  1. Plural forms should be divided by |.
  2. Plural forms count should correspond to the language plural forms count (table) + 1 (zero form).
  3. If first plural form is omitted, for the zero form you'll get empty string
| %count% сервер | %count% сервера | %count% серверов

translate

// import library
import { translate } from '@adguard/translate'

// create i18n object which implements I18nInterface:
interface I18nInterface {
    /**
     * Returns message by key for current locale
     * @param key
     */
    getMessage(key: string): string;

    /**
     * Returns current locale code
     * Locale codes should be in the list of `Locale`s
     */
    getUILanguage(): Locale;

    /**
     * Returns base locale message
     * @param key
     */
    getBaseMessage(key: string): string;

    /**
     * Returns base locale code
     */
    getBaseUILanguage(): Locale;
}

// in the browser extension it will be "browser.i18n"

// create translate function
const translator = translate.createTranslator(i18n)

// e.g.
//  string to translate:
//  "agreement_consent": {
//      "message": "You agree to our <eula>EULA</eula>",
//  }

createTranslator

This method can be used to translate simple strings and Vue template strings

const translator = translate.createTranslator(browser.i18n);
const translatedString = translator.getMessage('agreement_consent', {
    eula: (chunks) => `<button class="privacy-link">${chunks}</button>`,
});

console.log(translatedString); // <button class="privacy-link">EULA</button>

createReactTranslator

const reactTranslator = translate.createReactTranslator(browser.i18n, React);

<div>
    {reactTranslator.getMessage('agreement_consent', {
        eula: (chunks) => (
            <button
                className="auth__term"
                onClick={handleEulaClick}
            >
                {chunks}
            </button>
        ),
    })}
</div>

validator

// import library
import { validator } from '@adguard/translate'

isTranslationValid

const baseMessage = 'test string <a>has node</a>';
const targetMessage = 'тестовая строка <a>с нодой</a>';

validator.isTranslationValid(baseMessage, targetMessage); // true

isPluralFormValid

validator.isPluralFormValid(%count% серверов | %count% сервер | %count% сервера | %count% серверов, 'ru', "servers_count"); // true, all 4 plural forms are provided

validator.isPluralFormValid(%count% сервера | %count% серверов, 'ru', "servers_count"); // false, ru locale awaits for 4 plural forms provided

API

createTranslator

/**
 * Creates translator instance strings, by default for simple strings
 * @param i18n - function which returns translated message by key
 * @param messageConstructor - function that will collect messages
 * @param values - map with default values for tag converters
 */
const createTranslator = (
    i18n: I18nInterface,
    messageConstructor?: MessageConstructorInterface,
    values?: ValuesAny
): Translator

createReactTranslator

/**
 * Creates translation function for strings used in the React components
 * We do not import React directly, because translator module can be used
 * in the modules without React too
 *
 *
 * @param i18n - object with methods which get translated message by key and return current locale
 * @param React - instance of react library
 */
  const createReactTranslator = (i18n: I18nInterface, React: ReactCustom): Translator

getMessage

/**
 * Retrieves message and translates it, substituting parameters where necessary
 * @param key - translation message key
 * @param params - values used to substitute placeholders and tags
 */
public getMessage(key: string, params: ValuesAny = {}): T {

getPlural

/**
 * Retrieves correct plural form and translates it
 * @param key - translation message key
 * @param number - plural form number
 * @param params - values used to substitute placeholders or tags if necessary,
 * if params has "count" property it will be overridden by number (plural form number)
 */
public getPlural(key: string, number: number, params: ValuesAny = {}): T {

isTranslationValid

/**
 * Validates translation against base string by AST (abstract syntax tree) structure.
 *
 * @param baseMessage Base message.
 * @param translatedMessage Translated message.
 * @param locale Locale of `translatedMessage`.
 *
 * @returns True if translated message is valid, false otherwise:
 * - if base message has no plural forms, it will return true if AST structures are same;
 * - if base message has plural forms, first of all
 *   the function checks if the number of plural forms is correct for the `locale`,
 *   and then it validates AST plural forms structures for base and translated messages.
 *
 * @throws Error for invalid tags in base or translated messages,
 * or if translated message has invalid plural forms.
 */
const isTranslationValid = (baseMessage: string, translatedMessage: string, locale: Locale): boolean

isPluralFormValid

/**
 * Checks if plural forms are valid.
 *
 * @param targetStr Translated message with plural forms.
 * @param locale Locale.
 * @param key Optional, message key, used for clearer log message.
 *
 * @returns True if plural forms are valid, false otherwise.
 */
const isPluralFormValid = (targetStr: string, locale: Locale, key: string): boolean

Development

Use yarn to build the library

Build

To build the library run:

yarn build

Build result would be in the dist directory

Lint

To check lint errors run in terminal:

yarn lint

Test

The library uses jest for running unit-tests. To launch the tests, run the following command in the terminal:

yarn test

Docs

To build documentation, run the following command in the terminal:

yarn docs

TODO

  • [ ] Create Vue plugin
  • [ ] Add utility to check if code contains unused or redundant translation messages

License

MIT