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

fluent-typescript

v0.0.6

Published

CLI tool to automatically generate TypeScript declarations for Fluent files

Downloads

3

Readme

fluent-typescript

📦 Generate automatically TypeScript declarations for Fluent files

Fluent is a Mozilla's programming language for natural-sounding translations. And fluent-typescript is a tool to automatically generate type definitions for its mensagens. So you'll have safer changes on your translates messages by types safes provided by TS. Never more will have a missing variable or forget to delete an old message. Sounds like magic, right?

Fluent client supported:

:warning: It's a working in process project! At this moment, you should not use it on production!

How to use

As the first step, you need to install this package, of course:

> npm install fluent-typescript --save-dev
- or -
> yarn add fluent-typescript --dev

The following steps depends on which Fluent client that you are using:

vanilla

You could check a complete example on /example-vanilla folder. Check its readme.

Step by step:

1 - Add this script on your package.json config:

{
  "scripts": {
    "fluent-typescript": "./node_modules/.bin/fluent-typescript vanilla ./assets/locales/"
  }
},

The argument ./assets/locales/ is the path where the type definition file will be saved.

2 - Run fluent-typescript:

> npm run fluent-typescript

Now, your FTL files will be compiled into a .d.ts. The last remaining step is import it on our code.

3 - Add a cast on FluentBundle call:

const bundle = new FluentBundle('pt-br') as FluentBundleTyped

Finish! Now you have amazing types on your translations messages 🎉

react-18next

You could check a complete example on /example-react-18next folder. Check its readme.

1 - You also need to install @fluent/bundle

> npm install @fluent/bundle --save-dev
- or -
> yarn add @fluent/bundle --dev

2 - Add this script on your package.json config:

{
  "scripts": {
    "fluent-typescript": "./node_modules/.bin/fluent-typescript react-18next ./assets/locales/"
  }
},

The argument ./assets/locales/ is the path where the type definition file will be saved.

3 - Run fluent-typescript:

> npm run fluent-typescript

Now, your FTL files will be compiled into a .d.ts, and the type of t function returned by useTranslation will be patched, working out-of-the-box!

:warning: At this moment, it only works with useTranslation. Always when possible, prefer to use that instead of Trans or withTranslation, because you have type safe only with t function.

Finish! Now you have amazing types on your translations messages 🎉

fluent-react

You could check a complete example on /example-fluent-react folder. Check its readme.

1 - Add this script on your package.json config:

{
  "scripts": {
    "fluent-typescript": "./node_modules/.bin/fluent-typescript fluent-react ./assets/locales/"
  }
},

The argument ./assets/locales/ is the path where the type definition file will be saved.

2 - Run fluent-typescript:

> npm run fluent-typescript

Now, your FTL files will be compiled into a .d.ts, and the type of Localized component from @fluent/react will be patched!

To use the patched version of Localized, you should add the prop typed. For example:

-<Localized id='hello' vars={{ firstName, lastName }}>
+<Localized typed id='hello' vars={{ firstName, lastName }}>
  <h1>Hello!</h1>
</Localized>

:warning: At this moment, it only works with Localized. Always when possible, prefer to use that instead of useLocalization, because you have type safe only with Localized component.

Finish! Now you have amazing types on your translations messages 🎉

Flags

--no-watch

If you just want to emit the type definition, without running the watcher, you can use the flag --no-watch.

For instance:

> fluent-typescript vanilla ./assets/locales/ --no-watcha

How types are compiled

Asymmetric translations

tl;dr: You should always use all variables that a message could need.

Detailed explanation:

Let's say that we have a hello message on our application and we should translate that to Japanese and Portuguese. Since in Japanese is more common to use the last name, and in Portuguese is more natural to use the first name, we'll have that:

# locales/jp/translations.ftl
hello = こんにちは{ $lastName }

# locales/pt-br/translations.ftl
hello = Olá { $firstName }

Despite that in practice we could just use firstName or lastName, our type definition file want to be most safe that could, so you'll always need to use all possibles arguments required by a message:

bundle.formatPattern(helloMessage.value, { firstName: 'Macabeus', lastName: 'Aquino' }) // ok
bundle.formatPattern(helloMessage.value, { firstName: 'Macabeus' }) // error
bundle.formatPattern(helloMessage.value, { lastName: 'Aquino' }) // error

Analogously on a message with selector. You should always use all variables:

award =
  { $place ->
     [first]  You won first! Your prize is { $amount } bitcoins
    *[other] You won { $place }! Congratulations!
  }
bundle.formatPattern(helloMessage.value, { place: 'first', amount: 0.1 }) // ok
bundle.formatPattern(helloMessage.value, { place: 'second', amount: 0 }) // ok
bundle.formatPattern(helloMessage.value, { place: 'first' }) // error
bundle.formatPattern(helloMessage.value, { place: 'second' }) // error

Developing fluent-typescript

When developing fluent-typescript, is important to build and watch, so you could check the changes automatically on the examples apps:

> npm run start

Check the readme on each example's folders to learn how to run them.

You also could and run tests:

> npm run test