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

echo-handler

v1.8.2

Published

A NodeJS i18n-friendly way of managing messages stored in discrete JSON files

Downloads

17

Readme

Build Status

echo-handler

A NodeJS i18n-friendly way of managing messages stored in simple JSON files. Allows you to store i18n message files (delineated by international language code) in one discrete location and access them by language based on preferences at either compiletime or runtime. For example, say your web app has detected that a user's IP is in Spain, perhaps you want to serve them corresponding 'es' (language code for 'Español') messages rather than the standard 'en' ('English'). Setting things up is a piece of cake!

Installation

You can install echo-handler via npm. Add echo-handler to the package.json of your app or install it via the command-line: npm i --save echo-handler

Synopsis

Given 2 files at: <YourProjectRoot>/messages/:

  • en.exampleMessages.json (English file)
  • es.exampleMessages.json (Spanish file)

en.exampleMessages.json file contains:

{
  "test": "I am a test message"
}

and es.exampleMessages.json file contains:

{
  "test": "soy un mensaje de prueba"
}

to call them from your project's root directory you could do as follows:

// SETUP
let echoHandler = require('echo-handler').configure({ messageFolder: `${__dirname}/messages` });
let echo = echoHandler.load('exampleMessages', 'en'); // load the English message set

// IMPLEMENTATION
echo.log('test'); // console log,
echo.error('test'); // console.error(...)
let test = echo.raw('test'); // assign 'I am a test message' string to the `test` variable
if (test !== 'I am a test message') {
  echo.throw('test'); // throw test as an Error, setting error instance's .message equal to 'I am a test message'
}

echo = echoHandler.load('exampleMessages', 'es'); // load the spanish message set
echo.log('test'); // console will log: 'soy un mensaje de prueba'

messages can be printf-like

messages behave like good ol' printf; that is to say, given a message such as:

{
  "say": "I would like to say: {0} {1}!"
}

when echo is called...

...
echo.log('say', 'hello', 'world');

... console will log: I would like to say: hello world!

Configuration Options

  • As a minimum, the .configure() method demoed above must be supplied with an object containing a messageFolder property. The messageFolder must be an absolute address.

  • before echo can be called it must be initialised by calling .load(). load takes 2 arguments: the name of the message file with neither i18n code nor extension; and optionally, the language code of the message file you'd like to return (will default to .i18n from initial configuration or 'en' if all else fails).

Example

given a file called fr.someMessages.json, echo should be defined as follows:

let echo = echoHandler.load('someMessages', 'fr');

Custom Filename regionalization

By default, messages saved on disk must be preceded with their language code; e.g. 'en.someMessages.json'. This can be altered however by supplying an alternative regionalizer method in your .configure({ ... }) call's configuration object.

Let's suppose you wanted to delineate your language types by i18n coded folders rather than prefixes:

./messages/en/someMessage.json
          /es/someMessage.json
          /de/someMessage.json

you could do so as follows:

let echoHandler =
  require('echo-handler')
    .configure({
      messageFolder:`${__dirname}/messages`,
      regionalizer: (item, language) => {
        return item.replace(
          /([a-z\d._-]+$)/gi, // generally, this regex pattern is safe enough for most use-cases.
          (match, fileName) => { return `${language}/${fileName}`;
      });
    });

Likewise, suppose you wanted the following setup:

./messages/someMessage.en.json
          /someMessage.fr.json
          /someMessage.de.json

you could do so as follows:

let echoHandler =
  require('echo-handler')
    .configure({
      messageFolder:`${__dirname}/messages`,
      regionalizer: (item, language) => {
        return item.replace(
          /([a-z\d._-]+$)/gi,
          (match, fileName) => { return `${fileName}.${language}`;
      });
    });

Overriding the EchoHandlerFactory

In more complex builds, there may be instances where you do not wish to have the module build you an echoHandler via its factory. For example, say you have a separate set of messages in a different location that are only seen by a small number of stakeholders.

A raw EchoHandler can be instantiated as below:

let rawEcho = require('echo-handler').configure({ factoryOverride: `${__dirname}/otherFolder/en.someExampleMessages.json` });
rawEcho.log('someMessage');
  • The full file path must be provided and no provision will be made for delineating i18n so use this functionality carefully!
  • A logger object may still be provided in the configuration object. All other properties will be ignored.

Supplying custom Errors

When throwing an error, you may supply an object to setup a Crockford-inspired custom Error Handler. This object should adhere to the rules described in the example below:

const errorObject = {
  name: 'MockException', // NB: the NAME of your custom Exception and NOT the name of your error message!
  level: 'Mock', // this property is at your discretion.
  message: 'test', // NB: the NAME of the error message to load with echo-handler!
  htmlMessage: '<div>#test#</div>', // the name of the error message encapsulated in "#" tags will be replaced with the desired echo-handler error message.  You may use the #placeHolder# variable multiple times in an htmlMessage should you wish.
  toString: function () { ... } // optional toString call, if you don't supply, it'll defer to the default Error object;  
};

you may supply the above object with additional methods and properties as you see fit. They will be exposed in catch blocks accordingly. Simply supply the custom error object to the echo throw call and echo-handler will do the rest!

const conf = {
  i18n: 'en',
  messageFolder:`${__dirname}/messages`
};
let echo = require('echo-handler').configure(conf);
try {
  echo.throw(errorObject, 'a', 'b', 'c');
} catch (e) {
  console.error(e.stack);
}

Note: ExceptionClass and exceptionOptions are deprecated in favour of the approach supplied above. Though neither will be removed in the near-future, it is strongly advised that you swap them out where applicable.

Default Configuration

these are the default configuration options for this application

{
  *DEPRECATED* ExceptionClass: undefined, // specify a custom Exception class to throw in place of the default JS Error class. The first option of which MUST be the string message from the echo-handler
  *DEPRECATED* exceptionOptions: undefined, // specify additional options for the ExceptionClass here.
  factoryOverride: undefined, // if supplied with an absolute file path, this will allow you to return a new instance of Echo-Handler, see above.
  i18n: 'en', // Default language used if client doesn't provide language code. Will also try to set echo-handler's own messages to that language (PLEASE FORK AND ADD MESSAGES!)    
  logger: console, // supply an object that has a .log(string) method and .error(string) method; echo.log() and echo.error() will use that object instead of console.
  messageFolder: undefined, // MANDATORY: the absolute location of your message files

  regionalizer: (item, language) => { // the default regionalizer as an aide to understanding.
    return item.replace(
      /([a-z\d._-]+$)/gi,
      (match, fileName) => { return `${language}.${fileName}`; });
  };
};