Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.
/ i18n-tag-schema Public archive

Generates a json schema for all i18n tagged template literals in your project

License

Notifications You must be signed in to change notification settings

skolmer/i18n-tag-schema

Repository files navigation

🌍 i18n Tagged Template Literals - Schema Generator

All Contributors Build Status Coverage Status npm version Dependencies semantic-release Commitizen friendly MIT License

NPM

i18n Tagged Template Literals

📄 Table of Contents

🗂 Overview

This node module generates a JSON Schema of all i18n tagged template literals in a JavaScript project. A JSON schema can add key validation and autocompletion to your JSON based translation files (See IDE Integration). The tool will only detect template literals that are tagged with i18n (See es2015-i18n-tag). It has support for Custom Translation Groups and generated File Module Groups. __translationGroup constants in your code will be resolved relative to rootPath.

The following repository provides examples for use with npm scripts or gulp: https://github.com/skolmer/i18n-tag-examples

i18n-tag-schema can also be used to export translation keys into a simple json format (See Additional Features). This can be useful if you want to import your translation keys into a 3rd party tool. (Other export formats might be added later. Pull requests are welcome!)

This module does include a JSON validator that helps you keep track of missing or invalid keys in your translation files and shows you the current translation coverage of your project. A translation file is considered valid if it covers 100% of the translation keys defined in the JSON schema. This feature can be integrated into an automated build pipeline to check the translation coverage of a build. It can also be used to write unit tests that fail if your modules are not fully translated.

⚠️ Known Limitations

You cannot use variables for grouping.

/***** example 1 ******/
import _i18n from 'es2015-i18n-tag'
const i18n = _i18n('common')
const example1 = i18n`test` // ⚠️ i18n-tag-schema will not detect the "common" group.

/***** example 2 ******/
import i18n from 'es2015-i18n-tag'
const groupName = 'common'
const example2 = i18n(groupName)`test` // ⚠️ will not be detected. variables as groupName params are currently not supported.
const example2b = i18n('common')`test` // ✔️ this group name will be detected by i18n-tag-schema.

/***** example 3 *****/
import { i18nGroup } from 'es2015-i18n-tag'
const groupName = 'common'
@i18nGroup(groupName) // ⚠️ will not be detected. variables as groupName params are currently not supported.
class example3 {
}
@i18nGroup('common') // ✔️ this group name will be detected by i18n-tag-schema.
class example3b {
}

📦 Installation

$ npm install i18n-tag-schema --save-dev

💻 Examples

🎩 Key detection for i18n.translate()

If you are using i18n.translate() to translate variables you can add comments telling i18n-tag-schema the possible values of your variables. The comment should be a string or string[] in valid JSON syntax.

i18n.translate(myVariable1 /* "possible value ${0}" */, 'expression value')
i18n.translate(myVariable2 /* ["possible value 1", "another value"] */)

See i18n.translate()

📒 Usage

import { generateTranslationSchema } from 'i18n-tag-schema'

generateTranslationSchema({rootPath: './src', schemaPath: './translation.schema.json'}).then((result) => {
    console.log(result)
}).catch((err) => {
    console.error(err.message)
})

See docs

Via npm

package.json

{
  "scripts": {
    "generate-schema": "i18n-tag-schema ./src --schema ./translation.schema.json",
    "validate-german-translation": "i18n-tag-schema ./translations/translation.de.json --validate --schema ./translation.schema.json",
    "validate-translations": "i18n-tag-schema ./translations --validate --schema ./translation.schema.json"
  }
}
$ npm run generate-schema
$ npm run validate-german-translation
$ npm run validate-translations

Via Gulp

var gulp = require('gulp')
var generateTranslationSchema = require('i18n-tag-schema').generateTranslationSchema
var validateTranslations = require('i18n-tag-schema').validateTranslations

gulp.task('generate-translation-schema', function (cb) {
  generateTranslationSchema({ rootPath: './src', schemaPath: './translation.schema.json' }).then((result) => {
    cb(); // finished task
  }).catch((err) => {
    console.error(err.message)
    cb(err.message); // task failed
  })
})

gulp.task('validate-german-translation', function (cb) {
  validateTranslations({ rootPath: './translations/translation.de.json', schemaPath: './translation.schema.json' }).then((result) => {
    console.log(result)
    cb(); // finished task
  }).catch((err) => {
    console.error(err.message)
    cb(err.message); // task failed
  })
})

gulp.task('validate-translations', function (cb) {
  validateTranslations({ rootPath: './translations', schemaPath: './translation.schema.json' }).then((result) => {
    console.log(result)
    cb(); // finished task
  }).catch((err) => {
    console.error(err.message)
    cb(err.message); // task failed
  })
})

Via Command-line

Install i18n-tag-schema as global package to use it as command-line tool

$ npm install i18n-tag-schema -g
Usage: i18n-tag-schema <path> [options]

  Options:

    -h, --help                 output usage information
    -V, --version              output the version number
    -p, --preprocessor <name>  the name of a preprocessor node module. for typescript use './preprocessors/typescript'
    -o, --postprocessor <name> the name of a postprocessor node module. for PO export file format use './postprocessors/po'
    -s, --schema <path>        set path of the schema to create or validate against.
                               If --schema is not set, JSON will be printed to the output.
    -f, --filter <regex>       a regular expression to filter source files. defaults to \.jsx?$
    -v, --validate             use to validate translation file(s). path has to be a JSON file or directory. requires --schema <path>
    -e, --export <path>        export all translation keys FROM a JavaScript file or directory.
    -t, --target <path>        export all translation keys TO a JSON file. requires --export <path>.
                               If --target is not set, JSON will be printed to the output.
    -i, --indention <number>   the number of spaces to be used instead of tabs. if not set, tabs will be used.

Reference schema in translation.json file

{
    "$schema": "./translation.schema.json",
    "key": "value"
}

✔️ Validation Rules

The generated Schema checks

  • if your translation file is missing some of your project's translation keys.
  • if a translation key or group is unknown.
  • if a translation value contains all parameters defined in the translation key (e.g. ${0}, ${1}).

Some IDEs can also provide auto completion for translation keys and groups

⚙ Preprocessors

This library has support for custom preprocessors. It ships with a typescript preprocessor out of the box. Please make sure typescript npm package is installed if you want to parse typescript code.

$ i18n-tag-schema ./src -e ./typescript.ts -p ./preprocessors/typescript -f \.ts

Custom preprocessors can be added as npm packages

$ npm install my-preprocessor --save-dev
$ i18n-tag-schema ./src -e ./file.myext -p my-preprocessor -f \.myext

A preprocessor is a function that receives file content as an argument and returns the processed source code in ES2015 syntax. An example can be found at ./lib/preprocessors/typescript.js

⚙ Postprocessors

This library has support for custom postprocessors that can be used to transform the export file format. It ships with a PO file format postprocessor out of the box.

$ i18n-tag-schema ./src -e . -o ./postprocessors/po -t ./translation.po

Custom postprocessors can be added as npm packages

$ npm install my-postprocessor --save-dev
$ i18n-tag-schema ./src -e . -o my-postprocessor -t ./translation.myext

A postprocessor is a function that receives an array of translation keys and groups as an argument and returns the processed output. An example can be found at ./lib/postprocessors/po.js

⌨ IDE Integration

Webstorm / PhpStorm

Webstorm and PhpStorm support JSON Schemas since version 2016.1. For more details please see: Add JSON Schema Mapping Dialog

Visual Studio Code

For Visual Studio Code you can install the i18n-tag-schema extension from Visual Studio Code Marketplace

🎁 Additional Features

Export translation keys

export translation keys

Read all i18n tagged template literals from a JavaScript file or directory

import { exportTranslationKeys } from 'i18n-tag-schema'

exportTranslationKeys({ rootPath: './samples' }).then((result) => {
    console.log(result)
    /**
    * result: [
    *     '\n        <user name="${0}">${1}</user>\n    ',
    *     '\n    <users>\n    ${0}\n    </users>\n'
    * ]
    */
}).catch((err) => {
    console.error(err.message)
})

See docs

Validate translation file

validate translation cli

The validation function checks

  • if your translation files are missing some of your project's translation keys.
  • if a translation key or group is unknown.
  • if a translation value contains all parameters defined in the translation key (e.g. ${0}, ${1}).
import { validateTranslations } from 'i18n-tag-schema'

validateTranslations({ rootPath: './translations', schemaPath: './translation.schema.json' }).then((result) => {
    // translations are valid
    console.log(result)
}).catch((err) => {
    // translations are invalid
    console.error(err.message)
})

See docs

🛠 Tools

Run time translation and localization

  • es2015-i18n-tag: ES2015 template literal tag for i18n and l10n (translation and internationalization) using Intl npm version

Build time translation

Schema based translations

  • vscode-18n-tag-schema: Visual Studio Code Extension for JSON Schema based translation validation and tools Marketplace Version

📃 License

Copyright (c) 2016 Steffen Kolmer

This software is licensed under the MIT license. See the LICENSE file accompanying this software for terms of use.

Contributors

Thanks goes to these wonderful people (emoji key):

Michael Morton
Michael Morton

🚇 ⚠️ 💻

This project follows the all-contributors specification. Contributions of any kind welcome!