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 🙏

© 2026 – Pkg Stats / Ryan Hefner

rclone-i18n

v1.73.5

Published

Translate rclone RC responses (config/providers, options/info) using language packs fetched on demand.

Downloads

128

Readme

Rclone i18n

Translate rclone RC responses on the fly

Rewrites translatable strings in config/providers and options/info responses · Pairs with rclone-sdk · Works with Vanilla Fetch

Install

npm install rclone-i18n

The package ships a single translate function. Pass it either a raw Response or a parsed JSON body, and it returns the same shape with all known translatable fields rewritten into the target language.

Loading translations

Two modes, pick whichever suits you.

Fetch from jsDelivr (lang)

import { translate } from 'rclone-i18n'

const translated = await translate(body, { lang: 'fr' })

The language pack is fetched once from jsDelivr with cache: 'force-cache', so subsequent calls are served from the HTTP cache. Supported codes: fr, ja, zh, es.

Bring your own JSON (messages)

import { translate } from 'rclone-i18n'

const fr = await fetch('/locales/fr.json').then((r) => r.json())

const translated = await translate(body, { messages: fr })

Useful when you want to bundle the language pack, ship it from your own CDN, or override individual strings. Grab the source files from languages/ in this repo.

Vanilla Fetch

Pass the raw Response and get a Response back, with the same status, statusText, and headers:

import { translate } from 'rclone-i18n'

const res = await fetch('http://localhost:5572/config/providers', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: '{}',
})

const translatedRes = await translate(res, { lang: 'fr' })
const { providers } = await translatedRes.json()

console.log(providers.find((p) => p.Name === 'local').Description)
// → "Disque local"

Or pass the parsed body directly:

const body = await res.json()
const translated = await translate(body, { lang: 'fr' })

The original input is never mutated — bodies are deep-cloned, and a fresh Response is returned.

With rclone-sdk

rclone-sdk returns { data, error, response } from each call. Translate data directly:

import createRCDClient from 'rclone-sdk'
import { translate } from 'rclone-i18n'

const rcd = createRCDClient({ baseUrl: 'http://localhost:5572' })

const { data, error } = await rcd.POST('/config/providers')
if (error || !data) throw error

const translated = await translate(data, { lang: 'fr' })

for (const provider of translated.providers ?? []) {
    console.log(provider.Name, '→', provider.Description)
}

Same thing with /options/info:

const { data } = await rcd.POST('/options/info')
const translated = await translate(data, { lang: 'fr' })

const filter = translated.filter
const maxSize = filter?.find((o) => o.Name === 'max_size')
console.log(maxSize?.Help)
// → "Ne transférer que les fichiers plus petits que cette valeur, …"

What gets translated

translate walks the response and rewrites these fields when a matching entry exists in the language pack:

  • /config/providers
    • providers[].Description
    • providers[].Options[].Help (with Provider override)
    • providers[].Options[].Examples[].Help (incl. empty Value: "")
    • providers[].CommandHelp[].Short and .Long
    • providers[].MetadataInfo.Help and MetadataInfo.System[k].Help
  • /options/info
    • <block>[].Help (e.g. filter, main, vfs, …)
    • <block>[].Examples[].Help

Any other field is passed through unchanged. The function also returns the input untouched when:

  • the input is a Response with !ok status, or non-JSON Content-Type
  • the input is a parsed body shaped like an rclone error ({ error: string, … })

Contributing translations

Language packs live in languages/. The English source-of-truth (en.json) is regenerated from a live rclone daemon:

# rclone rcd --rc-no-auth --rc-addr 127.0.0.1:5572 &
npm run extract:i18n

scripts/check-i18n.ts (run via npm run check:i18n) compares the live extraction against languages/en.json and fails CI if keys drift. Two manual workflows wrap it: check-release runs against the latest released rclone, check-build builds rclone from master.

To add a new translation, copy languages/en.json, translate the leaf strings, and open a PR. Keys must match exactly — __empty__ is the sentinel for examples whose Value is "".

Contributing

Contributions = welcome!