An open API service indexing awesome lists of open source software.

https://github.com/bodrovis/ex_lokalise_transfer

ExLokaliseTransfer is a wrapper around Lokalise API download and upload endpoints for Elixir projects.
https://github.com/bodrovis/ex_lokalise_transfer

api client elixir http i18n l10n localization lokalise lokalise-api translation translation-files wrapper

Last synced: about 1 month ago
JSON representation

ExLokaliseTransfer is a wrapper around Lokalise API download and upload endpoints for Elixir projects.

Awesome Lists containing this project

README

          

# ExLokaliseTransfer

![CI](https://github.com/bodrovis/ex_lokalise_transfer/actions/workflows/ci.yml/badge.svg)
[![Coverage Status](https://coveralls.io/repos/github/bodrovis/ex_lokalise_transfer/badge.svg?branch=master)](https://coveralls.io/github/lokalise/ex_lokalise_transfer?branch=master)
[![Module Version](https://img.shields.io/hexpm/v/ex_lokalise_transfer.svg)](https://hex.pm/packages/ex_lokalise_transfer)
[![Total Download](https://img.shields.io/hexpm/dt/ex_lokalise_transfer.svg)](https://hex.pm/packages/ex_lokalise_transfer)

`ExLokaliseTransfer` is a wrapper around Lokalise API download and upload endpoints for Elixir projects.

It provides:

- sync and async download of translation bundles
- async upload of locale files
- retry/backoff handling
- polling for async processes
- local extraction utilities

> Sample app can be found in the [bodrovis/ex_lokalise_transfer_demo](https://github.com/bodrovis/ex_lokalise_transfer_demo) repo.

## Getting started

### Requirements

- Lokalise project
- Lokalise API token with read/write access
(read-only tokens work for downloads only)

### Installation

```elixir
def deps do
[
{:ex_lokalise_transfer, "~> 0.1.0"}
]
end
```

## Required application config

The following config is required globally.

Configure the Lokalise API token:

```elixir
config :elixir_lokalise_api,
api_token: {:system, "LOKALISE_API_TOKEN"}
```

Configure the Lokalise project id:

```elixir
config :ex_lokalise_transfer,
project_id: {:system, "LOKALISE_PROJECT_ID"}
```

## Downloading translation files

### Sync download

Downloads a bundle directly and extracts it locally.

```elixir
# You can also use ExLokaliseTransfer.download_sync()
ExLokaliseTransfer.download(
body: [
format: "json",
original_filenames: false
],
extra: [
extract_to: "./priv/locales"
]
)
```

Returns: `:ok | {:error, reason}`.

### Async download

Enqueues a bundle build in Lokalise, waits for completion, then downloads and extracts it.

```elixir
ExLokaliseTransfer.download_async(
body: [
format: "json"
],
poll: [
max_attempts: 15,
min_sleep_ms: 3_000,
max_sleep_ms: 60_000,
jitter: :centered
],
extra: [
extract_to: "./priv/locales"
]
)
```

## Uploading translations

### Async upload

Uploads multiple locale files and processes them asynchronously.

```elixir
{:ok, summary} =
ExLokaliseTransfer.upload(
body: [
format: "json"
],
extra: [
locales_path: "./priv/locales",
include_patterns: ["*.json"],
exclude_patterns: [],
lang_resolver: :basename
],
poll: [
max_attempts: 10,
min_sleep_ms: 3_000,
max_sleep_ms: 60_000,
jitter: :centered
]
)
```

Returns: `{:ok, summary} | {:error, summary}`

#### Summary structure

```elixir
%{
discovered_entries: [Entry.t()],
enqueue_successes: [
%{entry: Entry.t(), process_id: String.t()}
],
enqueue_errors: [
%{entry: Entry.t(), error: term()}
],
process_results: [
%{
entry: Entry.t(),
process_id: String.t(),
result: {:ok, map()} | {:error, term()}
}
],
errors: [term()]
}
```

## Options

All flows share a common structure of options:

```elixir
[
body: [...],
retry: [...],
poll: [...],
extra: [...]
]
```

### body — Lokalise API options

Passed directly to Lokalise bundle/upload requests.

Example:

```elixir
body: [
format: "json",
original_filenames: true,
directory_prefix: "",
indentation: "2sp"
]
```

- `format` (required for download)
- any other fields supported by Lokalise API

### retry — retry/backoff configuration

Used for API calls and downloads.

```elixir
retry: [
max_attempts: 3,
min_sleep_ms: 1_000,
max_sleep_ms: 60_000,
jitter: :centered
]
```

- `max_attempts` — total attempts (including first)
- `min_sleep_ms` — minimum delay
- `max_sleep_ms` — maximum delay
- `jitter` — `:centered` or `:full`

### poll — async polling configuration

Used only in async flows.

```elixir
poll: [
max_attempts: 10,
min_sleep_ms: 3_000,
max_sleep_ms: 60_000,
jitter: :centered
]
```

Controls how long the system waits for Lokalise async processes.

### extra — local behaviour options

#### Download

```elixir
extra: [
extract_to: "./priv/locales"
]
```

- `extract_to` — target directory for extracted files (automatically expanded to absolute path)

## Testing

Run:

```
mix test
```

To see coverage:

```
mix coveralls.html
```

### Integration testing

To run integration tests:

```
mix test --include integration
```

Note that in this case you'll need to set `LOKALISE_API_TOKEN` and `LOKALISE_PROJECT_ID` environment variables.

## License

BSD-3-Clause (c) [Elijah S. Krukowski](https://bodrovis.tech)