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

lokalise-file-exchange

v1.0.0

Published

Exchange translation files with Lokalise TMS

Downloads

98

Readme

Lokalise translation file exchange for Node

CI

This package enables you to easily exchange translation files between your JavaScript/TypeScript project and Lokalise TMS.

Prerequisites

Before using this package, ensure you have the following:

Quickstart

Installation

Install the package via npm:

npm install --save lokalise-file-exchange

Uploading translation files

Use the LokaliseUpload class to upload translation files from your project to Lokalise:

import { LokaliseUpload } from "lokalise-file-exchange";

const apiKey = "YOUR_LOKALISE_API_TOKEN";
const projectId = "YOUR_LOKALISE_PROJECT_ID";

const lokaliseUploader = new LokaliseUpload(
  {
    apiKey,
  },
  {
    projectId,
  },
);

// Upload all files from the `./locales` directory:
const { processes, errors } = await lokaliseUploader.uploadTranslations();

console.log(processes); // Array of QueuedProcess objects
console.log(errors); // Array of errors (if any)

Downloading translation files

Use the LokaliseDownload class to download translation files from Lokalise into your project:

import { LokaliseDownload } from "lokalise-file-exchange";
import type { DownloadFileParams } from "@lokalise/node-api";

const apiKey = "YOUR_LOKALISE_API_TOKEN";
const projectId = "YOUR_LOKALISE_PROJECT_ID";

const lokaliseDownloader = new LokaliseDownload(
  {
    apiKey,
  },
  {
    projectId,
  },
);

const downloadFileParams: DownloadFileParams = {
  // Format is mandatory!
  format: "json", // Output format for the downloaded files

  // Other params are optional
  original_filenames: true, // Preserve original filenames from Lokalise
  indentation: "2sp", // Indentation style for the downloaded files
  directory_prefix: "", // Optional prefix for output directory structure
};

// Download all translations into the project root while preserving original filenames
await lokaliseDownloader.downloadTranslations({ downloadFileParams });

Creating and configuring client

The first step is to create an upload or download client. Both clients accept two configuration objects.

import { LokaliseUpload } from "lokalise-file-exchange";
// OR
import { LokaliseDownload } from "lokalise-file-exchange";

const lokaliseUploader = new LokaliseUpload({apiKey}, {projectId});
// OR
const lokaliseDownloader = new LokaliseDownload({apiKey}, {projectId});

If you're using OAuth2 flow, set useOAuth2 option to true:

const lokaliseUploader = new LokaliseUpload({apiKey}, {projectId, useOAuth2: true});
// OR
const lokaliseDownloader = new LokaliseDownload({apiKey}, {projectId, useOAuth2: true});

In this case make sure to provide access token for the apiKey.

ClientParams configuration

The first object is ClientParams, used to instantiate the node-lokalise-api client internally for sending API requests. The only mandatory parameter is apiKey, which should contain a string with your Lokalise API token. Other parameters are optional and can be used to:

LokaliseExchangeConfig configuration

The second object, LokaliseExchangeConfig, contains additional parameters:

  • projectId (string, required): Your Lokalise project ID. If you're using project branching, provide the branch name after semicolon, for example "123.abc:my_branch".
  • retryParams (RetryParams, optional): Retry parameters for failed API requests. By default, the library performs up to 3 retries for 408 (timeout) and 429 (too many requests) errors. Exponential backoff is applied, with an initial sleep time of 1000 ms. Parameters include:
    • maxRetries (number): Maximum number of retries. If set to 0, the client will send only a single request without any retries.
    • initialSleepTime (number): The initial value for the sleep time in milliseconds. Subsequent sleep times are calculated using the formula initialSleepTime * 2 ** (attempt - 1), where attempt > 0.

Performing translation file downloads

To download translation files from Lokalise into your project, use the downloadTranslations() method on the client.

await lokaliseDownloader.downloadTranslations({ downloadFileParams, extractParams });

downloadTranslations() accepts a single object, DownloadTranslationParams, with two attributes.

DownloadFileParams

The DownloadFileParams attribute contains all download parameters passed directly to the download() function. For details about supported parameters, refer to the DownloadFiles endpoint documentation.

Required parameter:

  • format (string): Specifies the download format (e.g., json, xml, etc.).

ExtractParams

After downloading the translation bundle, the client extracts it automatically. You can control the extraction process with the following parameter:

  • outputDir (string, optional): Specifies the directory where the archive is extracted. The default value is "./" (project root).

Recommendations for downloading

To preserve original filenames assigned to translation keys during the download, use configurations that align with your project structure. For example:

  • If your translations are located in a ./locales directory
  • Keys have filenames assigned in the format locales/%LANG_ISO%.json or locales/some_nested_dir/%LANG_ISO%.json
import type { DownloadFileParams } from "@lokalise/node-api";
import type { ExtractParams } from "lokalise-file-exchange";

const downloadFileParams: DownloadFileParams = {
  format: "json",
  original_filenames: true,
  directory_prefix: "",
};

try {
  await lokaliseDownloader.downloadTranslations({ downloadFileParams });
} catch (err) {
  console.error(err);
}

You can configure your download to maintain this structure by specifying original_filenames and directory_prefix.

Performing translation file uploads

To upload translation files from Lokalise into your project, use the uploadTranslations() method.

const { processes, errors } = await lokaliseUploader.uploadTranslations({ uploadFileParams, collectFileParams, processUploadFileParams });

File uploading happens in the background so this method will return an array of QueuedProcesses and an array of errors that happened during uploading.

This method accepts an optional UploadTranslationParams object for further customization. It consists of three main attributes.

UploadFileParams

This attribute contains parameters passed to the upload() function. For details, refer to the UploadFile endpoint documentation.

The client automatically provides the following required parameters:

  • data
  • filename
  • lang_iso

You do not need to set these manually.

CollectFileParams

This attribute determines which files are included or excluded from the upload. All parameters are optional.

  • inputDirs (string[]): Directories to upload translations from. Default: ["./locales"].
  • extensions (string[]): File extensions to include. Default: [".*"] (all extensions). For example, set to [".json", ".xml"] to include only JSON and XML files.
  • excludePatterns (string[]): Patterns to exclude. Default: ["node_modules", "dist"].
  • recursive (boolean): Whether to include files from nested directories. Default: true.
  • fileNamePattern (string): Pattern for filenames to upload. Default: * (all files). For example, set to "^en.*" to upload files starting with "en.".

ProcessUploadFileParams

This attribute provides advanced configuration for the upload process.

  • languageInferer: A function to infer the language ISO code for uploaded files.
  • pollStatuses (boolean): Whether to wait for Lokalise to process the uploaded files. Default: false.
  • pollInitialWaitTime (number): Initial wait time (in milliseconds) before polling upload statuses.
  • pollMaximumWaitTime (number): Maximum wait time (in milliseconds) for polling.

Inferring language ISO code

Lokalise requires a lang_iso parameter for every file. By default, the client infers this from the filename (e.g., en.json > lang_iso: "en", fr_FR.xml > lang_iso: "fr_FR"). If the project lacks the corresponding language, the upload fails.

For custom logic, use the languageInferer function, which has the signature:
(filePath: string) => Promise<string> | string. This function returns a language ISO code or uses the filename if it fails or returns an empty string.

Example: Inferring from file content

Suppose the file's first key contains the language code:

{
  "en": {
    "key": "translation value"
  }
}

You can infer the language with:

const { processes, errors } = await lokaliseUpload.uploadTranslations({
  processUploadFileParams: {
    languageInferer: async (filePath) => {
      // Provide any conditions as needed
      if (path.extname(filePath) === ".json") {
        const fileData = await fs.promises.readFile(filePath);
        const jsonContent = JSON.parse(fileData.toString());
        return Object.keys(jsonContent)[0];
      }
      return "";
    },
  },
});

Example: Inferring from parent folder

If translation files are stored in language-named folders (/locales/en/main.json), use:

const { processes, errors } = await lokaliseUploader.uploadTranslations({
  processUploadFileParams: {
    languageInferer: (filePath) => {
      try {
        const parentDir = path.dirname(filePath);
        return path.basename(parentDir);
      } catch (_error) {
        return "";
      }
    },
  }
});

Polling for upload statuses

All translation files are uploaded to Lokalise in the background, which is why the uploadTranslations() method returns an array of processes containing QueuedProcess[] objects. By default, the client does not wait for Lokalise to complete the upload process or report the success or failure of each file.

To ensure the client waits until all files are fully processed by Lokalise, you can set the pollStatuses option to true. This enables the client to poll the status of each file until it is marked as completed, cancelled, or failed. Additionally, you can fine-tune the polling behavior by configuring the pollInitialWaitTime (initial wait time before polling starts) and pollMaximumWaitTime (maximum duration to wait for all uploads to be processed).

const { processes, errors } = await lokaliseUploader.uploadTranslations({
  processUploadFileParams: {
    pollStatuses: true,
    pollInitialWaitTime: 2e3,
    pollMaximumWaitTime: 150e3,
  }
});

Now the function will wait up to 150 seconds for all processes to be completed (or marked as cancelled or failed).

Samples

Find the sample usage at github.com/bodrovis/lokalise-node-file-exchange-samples.

License

Licensed under BSD 3 Clause

(c) Ilya Krukowski