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

rosetta

v1.1.0

Published

A general purpose internationalization library in 298 bytes

Downloads

138,200

Readme

Features

  • Simple and Familiar API
  • Unobstrusive and Unopinionated
  • Less than 300 bytes – including dependencies!

Install

$ npm install --save rosetta

Usage

import rosetta from 'rosetta';

const i18n = rosetta({
  en: {
    intro: {
      welcome: 'Welcome, {{username}}!',
      text: 'I hope you find this useful.',
    },
    support(obj) {
      let hour = Math.floor(Math.random() * 3) + 9;
      let str = `For questions, I'm available on ${obj.date.toLocaleDateString()}`;
      str += `, any time after ${hour}:00.`
      return str;
    }
  }
});

// set default language
i18n.locale('en');

// add new language
i18n.set('pt', {
  intro: {
    welcome: obj => `Benvind${obj.feminine ? 'a' : 'o'}, ${obj.username}!`,
    text: 'Espero que você ache isso útil.'
  }
});

// append extra key(s) to existing language
i18n.set('pt', {
  support(obj) {
    let hour = Math.floor(Math.random() * 3) + 9;
    let str = `Se tiver perguntas, estou disponível em ${obj.date.toLocaleDateString()}`;
    str += `, qualquer hora depois às ${hour}:00.`
    return str;
  }
});

const data = {
  feminine: false,
  username: 'lukeed',
  date: new Date()
};

// Retrieve translations
// NOTE: Relies on "en" default
i18n.t('intro.welcome', data); //=> 'Welcome, lukeed!'
i18n.t('intro.text', data); //=> 'I hope you find this useful.'
i18n.t('support', data); //=> 'For questions, I'm available on 4/8/2020, any time after 11:00.'

// Retrieve translations w/ lang override
i18n.t('intro.welcome', data, 'pt'); //=> 'Benvindo, lukeed!'

// Change default language key
i18n.locale('pt');

// Retrieve translations w/ new defaults
i18n.t('intro.text', data); //=> 'Espero que você ache isso útil.'
i18n.t('intro.text', data, 'en'); //=> 'I hope you find this useful.'

API

rosetta(dict?)

Returns: Rosetta

Initializes a new Rosetta instance.You may optionally provide an initial translation object.

rosetta.locale(lang?)

Returns: String

Sets the language code for the Rosetta instance.This will cause all rossetta.t() lookups to assume this lang code.

The function will return the currently active lang code. This means that a setting a new value will reply with the same value. Additionally, calling locale() without any argument will return the lang code that the Rosetta instance was last given.

lang

Type: String Required: false

The language code to choose. If locale() is called without an argument (or with a falsey value), then the current lang code is returned.

rosetta.set(lang, table)

Merge (or override) translation keys into the lang collection.

lang

Type: String

The language code to target.

table

Type: Object

A new record of key-values to merge into the lang's dictionary.

Each key within the table can correspond to a function or a string template.

When using a function, it will receive the entire data input (see params).You are required to ensure the function returns a (string) value of your liking.

When using a string template, anything within double curly brackets ({{ example }}) will be interpreted as a key path and interpolated via templite. The key path can use dot-notation to access nested values from the data input (see params). Additionally, if a key path did not resolve to a value, an empty string is injected.

const ctx = rosetta({
  en: {
    foo: (obj) => `function sees "${obj.value || '~DEFAULT~'}"`,
    bar: 'template sees "{{value}}"'
  }
});

ctx.t('foo', {}, 'en');
//=> 'function sees "~DEFAULT~"
ctx.t('foo', { value: 123 }, 'en');
//=> 'function sees "123"

ctx.t('bar', {}, 'en');
//=> 'template sees ""
ctx.t('bar', { value: 123 }, 'en');
//=> 'template sees "123"

rosetta.table(lang)

Returns: Object or undefined

Retrieve the the lang's full dictionary/table of translation keys.

If the language does not exist (aka, no translations have been provided for it), you'll receive undefined.Otherwise, you'll receive the full object as it exists within the Rosetta instance. See table.

Important: Manipulating this object is any way will mutate and affect your Rosetta instance. Be careful!

lang

Type: String

The language code's table to retrieve.

rosetta.t(key, params?, lang?)

Returns: String

Retrieve the value for a given key.

Important: In the normal/default mode, an empty string will be returned for unknown keys.Conversely, in "debug" mode, an error message will be printed and undefined will be returned for unknown keys.

key

Type: String or Array<String|Number>

The identifier to retrieve.

A key can access nested properties via:

  • a string that with dot notation — 'foo.bar[1].baz'
  • an array of individual key segments — ['foo', 'bar', 1, 'baz']

Important: You are expected to know & traverse your own dictionary structure correctly.

const ctx = rosetta({
  en: {
    fruits: {
      apple: 'apple',
    }
  }
});

ctx.locale('en');

ctx.t('fruits.apple'); //=> 'apple'
ctx.t(['fruits', 'apple']); //=> 'apple'

params

Type: any Optional: true

The data object argument to pass your dictionary keys' string templates and/or functions.

Note: If your string template tries to access a key that doesn't exist, an empty string is injected.

const ctx = rosetta({
  es: {
    hello: '¡Hola {{name}}!'
  },
  en: {
    hello(obj) {
      return obj.name === 'lukeed' ? 'wazzzuppp' : `Hello, ${obj.name}!`;
    },
  },
  pt: {
    hello: 'Oi {{person}}, tudo bem?' // <-- key is wrong
  },
});

const user1 = { name: 'lukeed' };
const user2 = { name: 'Billy' };

ctx.t('hello', user1, 'es'); //=> '¡Hola lukeed!'

ctx.t('hello', user1, 'en'); //=> 'wazzzuppp'
ctx.t('hello', user2, 'en'); //=> 'Hello, Billy!'

ctx.t('hello', user1, 'pt'); //=> 'Oi , tudo bem?'

lang

Type: String Optional: true

A language code override without changing the entire Rosetta instance's default language.

const ctx = rosetta();

ctx.locale('en'); //=> set default

ctx.t('greeting', 'lukeed');
//=> (en) 'Hello lukeed!'
ctx.t('greeting', 'lukeed', 'es');
//=> (es) '¡Hola lukeed!'
ctx.t('bye');
//=> (en) 'Cya'

Debugging

There is a "debug" mode included for development environments.

The only difference with "debug" mode is that rossetta.t() will log an error to the console when attempting to access a key that does not exist. Conversely, the main/default runtime will quietly return an an empty string for consistent output.

Otherwise, the API is exactly the same as the main/default export!This makes it easy to alias or swap the versions for development vs production bundles. Checkout the Configuration section below for recipes.

// debug mode
import rosetta from 'rosetta/debug';

const i18n = rosetta({
  en: {
    hello: 'hello'
  }
});

i18n.locale('en');

i18n.t('hello');
//=> 'hello'

i18n.t('foobar');
// [rosetta] Missing the "foobar" key within the "en" dictionary
//=> undefined

Note: With the non-"debug" runtime, an empty string would be returned for the foobar key.

Configuration

Here are quick configuration recipes for Rollup and webpack that allow you to choose the right version of rosetta for your current environment without changing you application code.

With both recipes, you will import rosetta like this:

import rosetta from 'rosetta';

It is up to the bundler to change what 'rosetta' resolves to...

Rollup

You will need to install @rollup/plugin-alias before continuing.

const isDev = /*custom logic*/ || !!process.env.ROLLUP_WATCH;

export default {
  // ...,
  plugins: [
    // ...
    require('@rollup/plugin-alias')({
      entries: {
        rosetta: isDev ? 'rosetta/debug' : 'rosetta'
      }
    })
  ]
}

webpack

The ability to add aliases within webpack comes by default.One simply needs to add a resolve.alias value depending on the environment:

const isDev = /*specific to your config*/;

module.exports = {
  //...,
  resolve: {
    alias: {
      // ...,
      rosetta: isDev ? 'rosetta/debug' : 'rosetta'
    }
  }
}

Runtime Support

The library makes use of Object shorthand methods and Object.assign.This yields the following support matrix:

| Chrome | Safari | Firefox | Edge | IE | Node.js | |:---:|:--:|:---:|:---:|:---:|:----:| | 45+ | 9+ | 34+ | 12+ | :x: | 4.0+ |

If you need to support older platforms, simply attach rosetta to your project's Babel (or similar) configuration.

Examples

  • Using Next.js — Thank you @SharpTechOfficial Next.js example using React Hooks and Context to provide SSR, SSG, CSR compatible i18n solutions.

Credits

Thank you @7sempra for gifting the rosetta name on npm.

License

MIT © Luke Edwards