Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Tater is an internationalization (i18n) and localization (l10n) library designed for simplicity. It doesn't do everything that other libraries do, but that's by design.
Under the hood, Tater uses a Hash to store the messages, the dig
method
for lookups, strftime
for date and time localizations, and format
for
interpolation. That's probably 90% of what Tater does.
Tater requires Ruby 2.7 or higher. To install Tater, add this line to your application's Gemfile (or gems.rb):
gem 'tater'
And then execute:
bundle
Or install it yourself by running:
gem install tater
require 'tater'
messages = {
'en' => {
'some' => {
'key' => 'This here string!'
},
'interpolated' => 'Hello %{you}!'
}
}
i18n = Tater.new(locale: 'en')
i18n.load(messages: messages)
# OR
i18n = Tater.new(locale: 'en', messages: messages)
# Basic lookup:
i18n.translate('some.key') # => 'This here string!'
# Interpolation:
i18n.translate('interpolated', you: 'world') # => 'Hello world!'
Given an array, Tater will do it's best to join the elements of the array into a sentence based on how many elements there are.
en:
array:
last_word_connector: ", and "
two_words_connector: " and "
words_connector: ", "
i18n.localize(%w[tacos enchiladas burritos]) # => "tacos, enchiladas, and burritos"
Numeric localization (Numeric
, Integer
, Float
, and BigDecimal
) require
filling in a separator and delimiter. For example:
en:
numeric:
delimiter: ','
separator: '.'
With that, you can do things like this:
i18n.localize(1000.2) # => "1,000.20"
The separator and delimiter can also be passed in per-call:
i18n.localize(1000.2, delimiter: '_', separator: '+') # => "1_000+20"
Date and time localization (Date
, Time
, and DateTime
) require filling
in all of the needed names and abbreviations for days and months. Here's the
example for French, which is used in the tests.
fr:
time:
am: 'am'
pm: 'pm'
formats:
default: '%I%P'
loud: '%I%p'
date:
formats:
abbreviated_day: '%a'
day: '%A'
abbreviated_month: '%b'
month: '%B'
days:
- dimanche
- lundi
- mardi
- mercredi
- jeudi
- vendredi
- samedi
abbreviated_days:
- dim
- lun
- mar
- mer
- jeu
- ven
- sam
months:
- janvier
- février
- mars
- avril
- mai
- juin
- juillet
- août
- septembre
- octobre
- novembre
- décembre
abbreviated_months:
- jan.
- fév.
- mar.
- avr.
- mai
- juin
- juil.
- août
- sept.
- oct.
- nov.
- déc.
The statically defined keys for dates are days
, abbreviated_days
, months
,
and abbreviated_months
. Only am
and pm
are needed for times and only if
you plan on using the %p
or %P
format strings.
With all of that, you can do something like:
i18n.localize(Date.new(1970, 1, 1), format: '%A') # => 'jeudi'
# Or, using a key defined in "formats":
i18n.localize(Date.new(1970, 1, 1), format: 'day') # => 'jeudi'
Lookups can be cascaded, i.e. pieces of the scope of the can be lopped off incrementally.
messages = {
'en' => {
'login' => {
'title' => 'Login',
'description' => 'Normal description.'
'special' => {
'title' => 'Special Login'
}
}
}
}
i18n = Tater.new(locale: 'en', messages: messages)
i18n.translate('login.special.title') # => 'Special Login'
i18n.translate('login.special.description') # => 'Tater lookup failed'
i18n.translate('login.special.description', cascade: true) # => 'Normal description.'
With cascade, the final key stays the same, but pieces of the scope get lopped off. In this case, lookups will be tried in this order:
login.special.description
login.description
This can be useful when you want to override some messages but don't want to have to copy all of the other, non-overwritten messages.
Cascading can also be enabled by default when initializing an instance of Tater.
Tater.new(cascade: true)
Cascading is off by default.
If you'd like to default to another value in case of a missed lookup, you can
provide the :default
option to #translate
.
Tater.new.translate('nope', default: 'Yep!') # => 'Yep!'
Ruby files can be used to store messages in addition to YAML, so long as the
Ruby file returns a Hash
when evaluated.
{
'en' => {
ruby: proc do |key, options = {}|
"Hey #{ key }!"
end
}
}
If you would like to check multiple locales and pull the first matching one out,
you can pass the :locales
option to initialization or the translate
method
with an array of top-level locale keys.
messages = {
'en' => {
'title' => 'Login',
'description' => 'English description.'
},
'fr' => {
'title' => 'la connexion'
}
}
i18n = Tater.new(messages: messages)
i18n.translate('title', locales: %w[fr en]) # => 'la connexion'
i18n.translate('description', locales: %w[fr en]) # => 'English description.'
# OR
i18n = Tater.new(messages: messages, locales: %w[fr en])
i18n.translate('title') # => 'la connexion'
i18n.translate('description') # => 'English description.'
Locales will be tried in order and whichever one matches first will be returned.
Because Ruby I18n is amazing and I wanted to try to create a minimum viable implementation of the bits of I18n that I use 90% of the time. Tater is a single file that handles the basics of lookup and interpolation.
I was originally going to call this library "Translator" but with a numeronym like I18n: "t8r". I looked at it for a while but I read it as "tater" instead of "tee-eight-arr" so I figured I'd just name it Tater. Tater the translator.
FAQs
Unknown package
We found that tater demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.