pax_global_header 0000666 0000000 0000000 00000000064 14033400100 0014473 g ustar 00root root 0000000 0000000 52 comment=58a9a3c715af18c5d2000eb0adb206cbbc28db82
y18n-5.0.8/ 0000775 0000000 0000000 00000000000 14033400100 0012304 5 ustar 00root root 0000000 0000000 y18n-5.0.8/.eslintrc 0000664 0000000 0000000 00000000710 14033400100 0014126 0 ustar 00root root 0000000 0000000 {
"overrides": [
{
"files": "*.ts",
"parser": "@typescript-eslint/parser",
"rules": {
"no-unused-vars": "off",
"no-useless-constructor": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-useless-constructor": "error"
}
}
],
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint/eslint-plugin"
]
}
y18n-5.0.8/.github/ 0000775 0000000 0000000 00000000000 14033400100 0013644 5 ustar 00root root 0000000 0000000 y18n-5.0.8/.github/workflows/ 0000775 0000000 0000000 00000000000 14033400100 0015701 5 ustar 00root root 0000000 0000000 y18n-5.0.8/.github/workflows/ci.yaml 0000664 0000000 0000000 00000002701 14033400100 0017160 0 ustar 00root root 0000000 0000000 name: ci
on:
push:
branches:
- master
pull_request:
types: [ assigned, opened, synchronize, reopened, labeled ]
env:
CI: true
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [10.x, 12.x, 14.x]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: node --version
- run: npm install
- run: npm test
windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm install
- run: npm test
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14.x'
- run: npm install
- run: npm test
- run: npm run coverage
esm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14.x'
- run: npm install
- run: npm run test:esm
deno:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14
- run: npm install
- run: npm run compile
- uses: denolib/setup-deno@v2
- run: |
deno --version
deno test --allow-read test/deno/y18n-test.ts
y18n-5.0.8/.github/workflows/release-please.yml 0000664 0000000 0000000 00000003116 14033400100 0021314 0 ustar 00root root 0000000 0000000 on:
push:
branches:
- master
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: bcoe/release-please-action@v2.5.5
id: release
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: node
package-name: y18n
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14
- run: npm install
- run: npm run compile
- name: push Deno release
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git remote add gh-token "https://${{ secrets.GITHUB_TOKEN}}@github.com/yargs/y18n.git"
git checkout -b deno
git add -f build
git commit -a -m 'chore: ${{ steps.release.outputs.tag_name }} release'
git push origin +deno
git tag -a ${{ steps.release.outputs.tag_name }}-deno -m 'chore: ${{ steps.release.outputs.tag_name }} release'
git push origin ${{ steps.release.outputs.tag_name }}-deno
if: ${{ steps.release.outputs.release_created }}
- uses: actions/setup-node@v1
with:
node-version: 14
registry-url: 'https://external-dot-oss-automation.appspot.com/'
if: ${{ steps.release.outputs.release_created }}
- run: npm install
if: ${{ steps.release.outputs.release_created }}
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
if: ${{ steps.release.outputs.release_created }}
y18n-5.0.8/.gitignore 0000664 0000000 0000000 00000000116 14033400100 0014272 0 ustar 00root root 0000000 0000000 .DS_Store
node_modules
.nyc_output
build
coverage
package-lock.json
example.*
y18n-5.0.8/.nycrc 0000664 0000000 0000000 00000000235 14033400100 0013423 0 ustar 00root root 0000000 0000000 {
"exclude": [
"test/**"
],
"reporter": [
"html",
"text"
],
"branches": 96.5,
"lines": 100,
"functions": 93,
"statements": 100
}
y18n-5.0.8/CHANGELOG.md 0000664 0000000 0000000 00000007507 14033400100 0014126 0 ustar 00root root 0000000 0000000 # Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [5.0.8](https://www.github.com/yargs/y18n/compare/v5.0.7...v5.0.8) (2021-04-07)
### Bug Fixes
* **deno:** force modern release for Deno ([b1c215a](https://www.github.com/yargs/y18n/commit/b1c215aed714bee5830e76de3e335504dc2c4dab))
### [5.0.7](https://www.github.com/yargs/y18n/compare/v5.0.6...v5.0.7) (2021-04-07)
### Bug Fixes
* **deno:** force release for deno ([#121](https://www.github.com/yargs/y18n/issues/121)) ([d3f2560](https://www.github.com/yargs/y18n/commit/d3f2560e6cedf2bfa2352e9eec044da53f9a06b2))
### [5.0.6](https://www.github.com/yargs/y18n/compare/v5.0.5...v5.0.6) (2021-04-05)
### Bug Fixes
* **webpack:** skip readFileSync if not defined ([#117](https://www.github.com/yargs/y18n/issues/117)) ([6966fa9](https://www.github.com/yargs/y18n/commit/6966fa91d2881cc6a6c531e836099e01f4da1616))
### [5.0.5](https://www.github.com/yargs/y18n/compare/v5.0.4...v5.0.5) (2020-10-25)
### Bug Fixes
* address prototype pollution issue ([#108](https://www.github.com/yargs/y18n/issues/108)) ([a9ac604](https://www.github.com/yargs/y18n/commit/a9ac604abf756dec9687be3843e2c93bfe581f25))
### [5.0.4](https://www.github.com/yargs/y18n/compare/v5.0.3...v5.0.4) (2020-10-16)
### Bug Fixes
* **exports:** node 13.0 and 13.1 require the dotted object form _with_ a string fallback ([#105](https://www.github.com/yargs/y18n/issues/105)) ([4f85d80](https://www.github.com/yargs/y18n/commit/4f85d80dbaae6d2c7899ae394f7ad97805df4886))
### [5.0.3](https://www.github.com/yargs/y18n/compare/v5.0.2...v5.0.3) (2020-10-16)
### Bug Fixes
* **exports:** node 13.0-13.6 require a string fallback ([#103](https://www.github.com/yargs/y18n/issues/103)) ([e39921e](https://www.github.com/yargs/y18n/commit/e39921e1017f88f5d8ea97ddea854ffe92d68e74))
### [5.0.2](https://www.github.com/yargs/y18n/compare/v5.0.1...v5.0.2) (2020-10-01)
### Bug Fixes
* **deno:** update types for deno ^1.4.0 ([#100](https://www.github.com/yargs/y18n/issues/100)) ([3834d9a](https://www.github.com/yargs/y18n/commit/3834d9ab1332f2937c935ada5e76623290efae81))
### [5.0.1](https://www.github.com/yargs/y18n/compare/v5.0.0...v5.0.1) (2020-09-05)
### Bug Fixes
* main had old index path ([#98](https://www.github.com/yargs/y18n/issues/98)) ([124f7b0](https://www.github.com/yargs/y18n/commit/124f7b047ba9596bdbdf64459988304e77f3de1b))
## [5.0.0](https://www.github.com/yargs/y18n/compare/v4.0.0...v5.0.0) (2020-09-05)
### ⚠ BREAKING CHANGES
* exports maps are now used, which modifies import behavior.
* drops Node 6 and 4. begin following Node.js LTS schedule (#89)
### Features
* add support for ESM and Deno [#95](https://www.github.com/yargs/y18n/issues/95)) ([4d7ae94](https://www.github.com/yargs/y18n/commit/4d7ae94bcb42e84164e2180366474b1cd321ed94))
### Build System
* drops Node 6 and 4. begin following Node.js LTS schedule ([#89](https://www.github.com/yargs/y18n/issues/89)) ([3cc0c28](https://www.github.com/yargs/y18n/commit/3cc0c287240727b84eaf1927f903612ec80f5e43))
### 4.0.1 (2020-10-25)
### Bug Fixes
* address prototype pollution issue ([#108](https://www.github.com/yargs/y18n/issues/108)) ([a9ac604](https://www.github.com/yargs/y18n/commit/7de58ca0d315990cdb38234e97fc66254cdbcd71))
## [4.0.0](https://github.com/yargs/y18n/compare/v3.2.1...v4.0.0) (2017-10-10)
### Bug Fixes
* allow support for falsy values like 0 in tagged literal ([#45](https://github.com/yargs/y18n/issues/45)) ([c926123](https://github.com/yargs/y18n/commit/c926123))
### Features
* **__:** added tagged template literal support ([#44](https://github.com/yargs/y18n/issues/44)) ([0598daf](https://github.com/yargs/y18n/commit/0598daf))
### BREAKING CHANGES
* **__:** dropping Node 0.10/Node 0.12 support
y18n-5.0.8/LICENSE 0000664 0000000 0000000 00000001333 14033400100 0013311 0 ustar 00root root 0000000 0000000 Copyright (c) 2015, Contributors
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
y18n-5.0.8/README.md 0000664 0000000 0000000 00000006217 14033400100 0013571 0 ustar 00root root 0000000 0000000 # y18n
[![NPM version][npm-image]][npm-url]
[![js-standard-style][standard-image]][standard-url]
[](https://conventionalcommits.org)
The bare-bones internationalization library used by yargs.
Inspired by [i18n](https://www.npmjs.com/package/i18n).
## Examples
_simple string translation:_
```js
const __ = require('y18n')().__;
console.log(__('my awesome string %s', 'foo'));
```
output:
`my awesome string foo`
_using tagged template literals_
```js
const __ = require('y18n')().__;
const str = 'foo';
console.log(__`my awesome string ${str}`);
```
output:
`my awesome string foo`
_pluralization support:_
```js
const __n = require('y18n')().__n;
console.log(__n('one fish %s', '%d fishes %s', 2, 'foo'));
```
output:
`2 fishes foo`
## Deno Example
As of `v5` `y18n` supports [Deno](https://github.com/denoland/deno):
```typescript
import y18n from "https://deno.land/x/y18n/deno.ts";
const __ = y18n({
locale: 'pirate',
directory: './test/locales'
}).__
console.info(__`Hi, ${'Ben'} ${'Coe'}!`)
```
You will need to run with `--allow-read` to load alternative locales.
## JSON Language Files
The JSON language files should be stored in a `./locales` folder.
File names correspond to locales, e.g., `en.json`, `pirate.json`.
When strings are observed for the first time they will be
added to the JSON file corresponding to the current locale.
## Methods
### require('y18n')(config)
Create an instance of y18n with the config provided, options include:
* `directory`: the locale directory, default `./locales`.
* `updateFiles`: should newly observed strings be updated in file, default `true`.
* `locale`: what locale should be used.
* `fallbackToLanguage`: should fallback to a language-only file (e.g. `en.json`)
be allowed if a file matching the locale does not exist (e.g. `en_US.json`),
default `true`.
### y18n.\_\_(str, arg, arg, arg)
Print a localized string, `%s` will be replaced with `arg`s.
This function can also be used as a tag for a template literal. You can use it
like this: __`hello ${'world'}`
. This will be equivalent to
`__('hello %s', 'world')`.
### y18n.\_\_n(singularString, pluralString, count, arg, arg, arg)
Print a localized string with appropriate pluralization. If `%d` is provided
in the string, the `count` will replace this placeholder.
### y18n.setLocale(str)
Set the current locale being used.
### y18n.getLocale()
What locale is currently being used?
### y18n.updateLocale(obj)
Update the current locale with the key value pairs in `obj`.
## Supported Node.js Versions
Libraries in this ecosystem make a best effort to track
[Node.js' release schedule](https://nodejs.org/en/about/releases/). Here's [a
post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a).
## License
ISC
[npm-url]: https://npmjs.org/package/y18n
[npm-image]: https://img.shields.io/npm/v/y18n.svg
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg
[standard-url]: https://github.com/feross/standard
y18n-5.0.8/deno.ts 0000664 0000000 0000000 00000000362 14033400100 0013602 0 ustar 00root root 0000000 0000000 import { y18n as _y18n } from './build/lib/index.js'
import type { Y18NOpts } from './build/lib/index.d.ts'
import shim from './lib/platform-shims/deno.ts'
const y18n = (opts: Y18NOpts) => {
return _y18n(opts, shim)
}
export default y18n
y18n-5.0.8/index.mjs 0000664 0000000 0000000 00000000267 14033400100 0014133 0 ustar 00root root 0000000 0000000 import shim from './build/lib/platform-shims/node.js'
import { y18n as _y18n } from './build/lib/index.js'
const y18n = (opts) => {
return _y18n(opts, shim)
}
export default y18n
y18n-5.0.8/lib/ 0000775 0000000 0000000 00000000000 14033400100 0013052 5 ustar 00root root 0000000 0000000 y18n-5.0.8/lib/cjs.ts 0000664 0000000 0000000 00000000317 14033400100 0014202 0 ustar 00root root 0000000 0000000 import { y18n as _y18n, Y18NOpts } from './index.js'
import nodePlatformShim from './platform-shims/node.js'
const y18n = (opts: Y18NOpts) => {
return _y18n(opts, nodePlatformShim)
}
export default y18n
y18n-5.0.8/lib/index.ts 0000664 0000000 0000000 00000014233 14033400100 0014534 0 ustar 00root root 0000000 0000000 export interface Y18NOpts {
directory?: string;
updateFiles?: boolean;
locale?: string;
fallbackToLanguage?: boolean;
}
interface Work {
directory: string;
locale: string;
cb: Function
}
export interface Locale {
[key: string]: string
}
interface CacheEntry {
[key: string]: string;
}
export interface PlatformShim {
fs: {
readFileSync: Function,
writeFile: Function
},
exists: Function,
format: Function,
resolve: Function
}
let shim: PlatformShim
class Y18N {
directory: string;
updateFiles: boolean;
locale: string;
fallbackToLanguage: boolean;
writeQueue: Work[];
cache: {[key: string]: {[key: string]: CacheEntry|string}};
constructor (opts: Y18NOpts) {
// configurable options.
opts = opts || {}
this.directory = opts.directory || './locales'
this.updateFiles = typeof opts.updateFiles === 'boolean' ? opts.updateFiles : true
this.locale = opts.locale || 'en'
this.fallbackToLanguage = typeof opts.fallbackToLanguage === 'boolean' ? opts.fallbackToLanguage : true
// internal stuff.
this.cache = Object.create(null)
this.writeQueue = []
}
__ (...args: (string|Function)[]): string {
if (typeof arguments[0] !== 'string') {
return this._taggedLiteral(arguments[0] as string[], ...arguments)
}
const str: string = args.shift() as string
let cb: Function = function () {} // start with noop.
if (typeof args[args.length - 1] === 'function') cb = (args.pop() as Function)
cb = cb || function () {} // noop.
if (!this.cache[this.locale]) this._readLocaleFile()
// we've observed a new string, update the language file.
if (!this.cache[this.locale][str] && this.updateFiles) {
this.cache[this.locale][str] = str
// include the current directory and locale,
// since these values could change before the
// write is performed.
this._enqueueWrite({
directory: this.directory,
locale: this.locale,
cb
})
} else {
cb()
}
return shim.format.apply(shim.format, [this.cache[this.locale][str] || str].concat(args as string[]))
}
__n () {
const args = Array.prototype.slice.call(arguments)
const singular: string = args.shift()
const plural: string = args.shift()
const quantity: number = args.shift()
let cb = function () {} // start with noop.
if (typeof args[args.length - 1] === 'function') cb = args.pop()
if (!this.cache[this.locale]) this._readLocaleFile()
let str = quantity === 1 ? singular : plural
if (this.cache[this.locale][singular]) {
const entry = this.cache[this.locale][singular] as CacheEntry
str = entry[quantity === 1 ? 'one' : 'other']
}
// we've observed a new string, update the language file.
if (!this.cache[this.locale][singular] && this.updateFiles) {
this.cache[this.locale][singular] = {
one: singular,
other: plural
}
// include the current directory and locale,
// since these values could change before the
// write is performed.
this._enqueueWrite({
directory: this.directory,
locale: this.locale,
cb
})
} else {
cb()
}
// if a %d placeholder is provided, add quantity
// to the arguments expanded by util.format.
const values: (string|number)[] = [str]
if (~str.indexOf('%d')) values.push(quantity)
return shim.format.apply(shim.format, values.concat(args))
}
setLocale (locale: string) {
this.locale = locale
}
getLocale () {
return this.locale
}
updateLocale (obj: Locale) {
if (!this.cache[this.locale]) this._readLocaleFile()
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
this.cache[this.locale][key] = obj[key]
}
}
}
_taggedLiteral (parts: string[], ...args: string[]) {
let str = ''
parts.forEach(function (part, i) {
const arg = args[i + 1]
str += part
if (typeof arg !== 'undefined') {
str += '%s'
}
})
return this.__.apply(this, [str].concat([].slice.call(args, 1)))
}
_enqueueWrite (work: Work) {
this.writeQueue.push(work)
if (this.writeQueue.length === 1) this._processWriteQueue()
}
_processWriteQueue () {
const _this = this
const work = this.writeQueue[0]
// destructure the enqueued work.
const directory = work.directory
const locale = work.locale
const cb = work.cb
const languageFile = this._resolveLocaleFile(directory, locale)
const serializedLocale = JSON.stringify(this.cache[locale], null, 2)
shim.fs.writeFile(languageFile, serializedLocale, 'utf-8', function (err: Error) {
_this.writeQueue.shift()
if (_this.writeQueue.length > 0) _this._processWriteQueue()
cb(err)
})
}
_readLocaleFile () {
let localeLookup = {}
const languageFile = this._resolveLocaleFile(this.directory, this.locale)
try {
// When using a bundler such as webpack, readFileSync may not be defined:
if (shim.fs.readFileSync) {
localeLookup = JSON.parse(shim.fs.readFileSync(languageFile, 'utf-8'))
}
} catch (err) {
if (err instanceof SyntaxError) {
err.message = 'syntax error in ' + languageFile
}
if (err.code === 'ENOENT') localeLookup = {}
else throw err
}
this.cache[this.locale] = localeLookup
}
_resolveLocaleFile (directory: string, locale: string) {
let file = shim.resolve(directory, './', locale + '.json')
if (this.fallbackToLanguage && !this._fileExistsSync(file) && ~locale.lastIndexOf('_')) {
// attempt fallback to language only
const languageFile = shim.resolve(directory, './', locale.split('_')[0] + '.json')
if (this._fileExistsSync(languageFile)) file = languageFile
}
return file
}
_fileExistsSync (file: string) {
return shim.exists(file)
}
}
export function y18n (opts: Y18NOpts, _shim: PlatformShim) {
shim = _shim
const y18n = new Y18N(opts)
return {
__: y18n.__.bind(y18n),
__n: y18n.__n.bind(y18n),
setLocale: y18n.setLocale.bind(y18n),
getLocale: y18n.getLocale.bind(y18n),
updateLocale: y18n.updateLocale.bind(y18n),
locale: y18n.locale
}
}
y18n-5.0.8/lib/platform-shims/ 0000775 0000000 0000000 00000000000 14033400100 0016017 5 ustar 00root root 0000000 0000000 y18n-5.0.8/lib/platform-shims/deno.ts 0000664 0000000 0000000 00000001432 14033400100 0017314 0 ustar 00root root 0000000 0000000 /* global Deno */
import { posix } from 'https://deno.land/std/path/mod.ts'
import { sprintf } from 'https://deno.land/std/fmt/printf.ts'
export default {
fs: {
readFileSync: (path: string) => {
try {
return Deno.readTextFileSync(path)
} catch (err) {
// Fake the same error as Node.js, so that it does not bubble.
err.code = 'ENOENT'
throw err
}
},
writeFile: Deno.writeFile
},
format: sprintf,
resolve: (base: string, p1: string, p2: string) => {
try {
return posix.resolve(base, p1, p2)
} catch (err) {
// Most likely we simply don't have --allow-read set.
}
},
exists: (file: string) => {
try {
return Deno.statSync(file).isFile
} catch (err) {
return false
}
}
}
y18n-5.0.8/lib/platform-shims/node.ts 0000664 0000000 0000000 00000000510 14033400100 0017310 0 ustar 00root root 0000000 0000000 import { readFileSync, statSync, writeFile } from 'fs'
import { format } from 'util'
import { resolve } from 'path'
export default {
fs: {
readFileSync,
writeFile
},
format,
resolve,
exists: (file: string) => {
try {
return statSync(file).isFile()
} catch (err) {
return false
}
}
}
y18n-5.0.8/package.json 0000664 0000000 0000000 00000003357 14033400100 0014602 0 ustar 00root root 0000000 0000000 {
"name": "y18n",
"version": "5.0.8",
"description": "the bare-bones internationalization library used by yargs",
"exports": {
".": [
{
"import": "./index.mjs",
"require": "./build/index.cjs"
},
"./build/index.cjs"
]
},
"type": "module",
"module": "./build/lib/index.js",
"keywords": [
"i18n",
"internationalization",
"yargs"
],
"homepage": "https://github.com/yargs/y18n",
"bugs": {
"url": "https://github.com/yargs/y18n/issues"
},
"repository": "yargs/y18n",
"license": "ISC",
"author": "Ben Coe ",
"main": "./build/index.cjs",
"scripts": {
"check": "standardx **/*.ts **/*.cjs **/*.mjs",
"fix": "standardx --fix **/*.ts **/*.cjs **/*.mjs",
"pretest": "rimraf build && tsc -p tsconfig.test.json && cross-env NODE_ENV=test npm run build:cjs",
"test": "c8 --reporter=text --reporter=html mocha test/*.cjs",
"test:esm": "c8 --reporter=text --reporter=html mocha test/esm/*.mjs",
"posttest": "npm run check",
"coverage": "c8 report --check-coverage",
"precompile": "rimraf build",
"compile": "tsc",
"postcompile": "npm run build:cjs",
"build:cjs": "rollup -c",
"prepare": "npm run compile"
},
"devDependencies": {
"@types/node": "^14.6.4",
"@wessberg/rollup-plugin-ts": "^1.3.1",
"c8": "^7.3.0",
"chai": "^4.0.1",
"cross-env": "^7.0.2",
"gts": "^3.0.0",
"mocha": "^8.0.0",
"rimraf": "^3.0.2",
"rollup": "^2.26.10",
"standardx": "^7.0.0",
"ts-transform-default-export": "^1.0.2",
"typescript": "^4.0.0"
},
"files": [
"build",
"index.mjs",
"!*.d.ts"
],
"engines": {
"node": ">=10"
},
"standardx": {
"ignore": [
"build"
]
}
}
y18n-5.0.8/renovate.json 0000664 0000000 0000000 00000000160 14033400100 0015017 0 ustar 00root root 0000000 0000000 {
"extends": [
"config:base"
],
"pinVersions": false,
"rebaseStalePrs": true,
"gitAuthor": null
}
y18n-5.0.8/rollup.config.js 0000664 0000000 0000000 00000000707 14033400100 0015427 0 ustar 00root root 0000000 0000000 import ts from '@wessberg/rollup-plugin-ts'
import transformDefaultExport from 'ts-transform-default-export'
const output = {
format: 'cjs',
file: './build/index.cjs',
exports: 'default'
}
if (process.env.NODE_ENV === 'test') output.sourcemap = true
export default {
input: './lib/cjs.ts',
output,
plugins: [
ts({
transformers: ({ program }) => ({
afterDeclarations: transformDefaultExport(program)
})
}),
]
}
y18n-5.0.8/test/ 0000775 0000000 0000000 00000000000 14033400100 0013263 5 ustar 00root root 0000000 0000000 y18n-5.0.8/test/deno/ 0000775 0000000 0000000 00000000000 14033400100 0014210 5 ustar 00root root 0000000 0000000 y18n-5.0.8/test/deno/y18n-test.ts 0000664 0000000 0000000 00000000546 14033400100 0016341 0 ustar 00root root 0000000 0000000 /* global Deno */
import {
assertEquals
} from 'https://deno.land/std/testing/asserts.ts'
import y18n from '../../deno.ts'
// Parser:
Deno.test('smoke test', () => {
const __ = y18n({
locale: 'pirate',
directory: './test/locales'
}).__
assertEquals(
__`Hi, ${'Ben'} ${'Coe'}!`,
'Yarr! Shiver me timbers, why \'tis Ben Coe!'
)
})
y18n-5.0.8/test/esm/ 0000775 0000000 0000000 00000000000 14033400100 0014047 5 ustar 00root root 0000000 0000000 y18n-5.0.8/test/esm/y18n-test.mjs 0000664 0000000 0000000 00000000572 14033400100 0016342 0 ustar 00root root 0000000 0000000 /* global describe, it */
import * as assert from 'assert'
import y18n from '../../index.mjs'
describe('y18n', function () {
it('__ smoke test', function () {
const __ = y18n({
locale: 'pirate',
directory: './test/locales'
}).__
assert.strictEqual(
__`Hi, ${'Ben'} ${'Coe'}!`,
'Yarr! Shiver me timbers, why \'tis Ben Coe!'
)
})
})
y18n-5.0.8/test/locales/ 0000775 0000000 0000000 00000000000 14033400100 0014705 5 ustar 00root root 0000000 0000000 y18n-5.0.8/test/locales/bad-locale.json 0000664 0000000 0000000 00000000021 14033400100 0017554 0 ustar 00root root 0000000 0000000 {"hello": "worl}
y18n-5.0.8/test/locales/en.json 0000664 0000000 0000000 00000000503 14033400100 0016200 0 ustar 00root root 0000000 0000000 {
"Hello": "Hello!",
"Hello %s %s": "Hello %s %s",
"%d cat": {
"one": "%d cat",
"other": "%d cats"
},
"%d %s cat": {
"one": "%d %s cat",
"other": "%d %s cats"
},
"There is one monkey in the %s": {
"one": "There is one monkey in the %s",
"other": "There are %d monkeys in the %s"
}
}
y18n-5.0.8/test/locales/pirate.json 0000664 0000000 0000000 00000000260 14033400100 0017062 0 ustar 00root root 0000000 0000000 {
"Hello": "Avast ye mateys!",
"Hi, %s %s!": "Yarr! Shiver me timbers, why 'tis %s %s!",
"%d cat": {
"one": "%d land catfish",
"other": "%d land catfishes"
}
}
y18n-5.0.8/test/y18n-test.cjs 0000664 0000000 0000000 00000026151 14033400100 0015545 0 ustar 00root root 0000000 0000000 /* global describe, it, after, beforeEach */
const expect = require('chai').expect
const fs = require('fs')
const rimraf = require('rimraf')
const y18n = require('../build/index.cjs')
const path = require('path')
require('chai').should()
describe('y18n', function () {
describe('configure', function () {
it('allows you to override the default y18n configuration', function () {
const y = y18n({ locale: 'fr' })
y.locale.should.equal('fr')
})
})
describe('_readLocaleFile', function () {
it('throws a helpful error if language file has invalid syntax', function () {
expect(function () {
const __ = y18n({
locale: 'bad-locale',
directory: path.join(__dirname, 'locales')
}).__
__('Hello')
}).to.throw(/syntax error/)
})
})
describe('__', function () {
it('can be used as a tag for template literals', function () {
const __ = y18n({
locale: 'pirate',
directory: path.join(__dirname, 'locales')
}).__
__`Hi, ${'Ben'} ${'Coe'}!`.should.equal('Yarr! Shiver me timbers, why \'tis Ben Coe!')
})
it('can be used as a tag for template literals with falsy arguments', function () {
const __ = y18n({
locale: 'pirate',
directory: path.join(__dirname, 'locales')
}).__
__`Hi, ${'Ben'} ${''}!`.should.equal('Yarr! Shiver me timbers, why \'tis Ben !')
})
it('uses replacements from the default locale if none is configured', function () {
const __ = y18n({
directory: path.join(__dirname, 'locales')
}).__
__('Hello').should.equal('Hello!')
})
it('uses replacements from the configured locale', function () {
const __ = y18n({
locale: 'pirate',
directory: path.join(__dirname, 'locales')
}).__
__('Hello').should.equal('Avast ye mateys!')
})
it('uses language file if language_territory file does not exist', function () {
const __ = y18n({
locale: 'pirate_JM',
directory: path.join(__dirname, 'locales')
}).__
__('Hello').should.equal('Avast ye mateys!')
})
it('does not fallback to language file if fallbackToLanguage is false', function () {
const __ = y18n({
locale: 'pirate_JM',
fallbackToLanguage: false,
updateFiles: false,
directory: path.join(__dirname, 'locales')
}).__
__('Hello').should.equal('Hello')
})
it('uses strings as given if no matching locale files found', function () {
const __ = y18n({
locale: 'zz_ZZ',
updateFiles: false,
directory: path.join(__dirname, 'locales')
}).__
__('Hello').should.equal('Hello')
})
it('expands arguments into %s placeholders', function () {
const __ = y18n({
directory: path.join(__dirname, 'locales')
}).__
__('Hello %s %s', 'Ben', 'Coe').should.equal('Hello Ben Coe')
})
describe('the first time observing a word', function () {
beforeEach(function (done) {
rimraf('./test/locales/fr*.json', function () {
return done()
})
})
it('returns the word immediately', function () {
const __ = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
}).__
__('banana').should.equal('banana')
})
it('writes new word to locale file if updateFiles is true', function (done) {
const __ = y18n({
locale: 'fr_FR',
directory: path.join(__dirname, 'locales')
}).__
__('banana', function (err) {
const locale = JSON.parse(fs.readFileSync('./test/locales/fr_FR.json', 'utf-8'))
locale.banana.should.equal('banana')
return done(err)
})
})
it('writes new word to language file if language_territory file does not exist', function (done) {
fs.writeFileSync('./test/locales/fr.json', '{"meow": "le meow"}', 'utf-8')
const __ = y18n({
locale: 'fr_FR',
directory: path.join(__dirname, 'locales')
}).__
__('meow').should.equal('le meow')
__('banana', function (err) {
const locale = JSON.parse(fs.readFileSync('./test/locales/fr.json', 'utf-8'))
locale.banana.should.equal('banana')
return done(err)
})
})
it('writes word to missing locale file, if no fallback takes place', function (done) {
fs.writeFileSync('./test/locales/fr.json', '{"meow": "le meow"}', 'utf-8')
const __ = y18n({
locale: 'fr_FR',
fallbackToLanguage: false,
directory: path.join(__dirname, 'locales')
}).__
__('banana', function (err) {
// 'banana' should be written to fr_FR.json
const locale = JSON.parse(fs.readFileSync('./test/locales/fr_FR.json', 'utf-8'))
locale.should.deep.equal({
banana: 'banana'
})
// fr.json should remain untouched
const frJson = JSON.parse(fs.readFileSync('./test/locales/fr.json', 'utf-8'))
frJson.should.deep.equal({
meow: 'le meow'
})
return done(err)
})
})
it('handles enqueuing multiple writes at the same time', function (done) {
const __ = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
}).__
__('apple')
__('banana', function () {
__('foo')
__('bar', function (err) {
const locale = JSON.parse(fs.readFileSync('./test/locales/fr.json', 'utf-8'))
locale.apple.should.equal('apple')
locale.banana.should.equal('banana')
locale.foo.should.equal('foo')
locale.bar.should.equal('bar')
return done(err)
})
})
})
it('does not write the locale file if updateFiles is false', function (done) {
const __ = y18n({
locale: 'fr',
updateFiles: false,
directory: path.join(__dirname, 'locales')
}).__
__('banana', function (err) {
fs.existsSync('./test/locales/fr.json').should.equal(false)
return done(err)
})
})
})
})
describe('__n', function () {
it('uses the singular form if quantity is 1', function () {
const __n = y18n({
directory: path.join(__dirname, 'locales')
}).__n
__n('%d cat', '%d cats', 1).should.equal('1 cat')
})
it('uses the plural form if quantity is greater than 1', function () {
const __n = y18n({
directory: path.join(__dirname, 'locales')
}).__n
__n('%d cat', '%d cats', 2).should.equal('2 cats')
})
it('allows additional arguments to be printed', function () {
const __n = y18n({
directory: path.join(__dirname, 'locales')
}).__n
__n('%d %s cat', '%d %s cats', 2, 'black').should.equal('2 black cats')
})
it('allows an alternative locale to be set', function () {
const __n = y18n({
locale: 'pirate',
directory: path.join(__dirname, 'locales')
}).__n
__n('%d cat', '%d cats', 1).should.equal('1 land catfish')
__n('%d cat', '%d cats', 3).should.equal('3 land catfishes')
})
// See: https://github.com/bcoe/yargs/pull/210
it('allows a quantity placeholder to be provided in the plural but not singular form', function () {
const __n = y18n({
directory: path.join(__dirname, 'locales')
}).__n
const singular = __n('There is one monkey in the %s', 'There are %d monkeys in the %s', 1, 'tree')
const plural = __n('There is one monkey in the %s', 'There are %d monkeys in the %s', 3, 'tree')
singular.should.equal('There is one monkey in the tree')
plural.should.equal('There are 3 monkeys in the tree')
})
describe('the first time observing a pluralization', function () {
beforeEach(function (done) {
rimraf('./test/locales/fr.json', function () {
return done()
})
})
it('returns the pluralization immediately', function () {
const __n = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
}).__n
__n('%d le cat', '%d le cats', 1).should.equal('1 le cat')
})
it('writes to the locale file if updateFiles is true', function (done) {
const __n = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
}).__n
__n('%d apple %s', '%d apples %s', 2, 'dude', function (err) {
const locale = JSON.parse(fs.readFileSync('./test/locales/fr.json', 'utf-8'))
locale['%d apple %s'].one.should.equal('%d apple %s')
locale['%d apple %s'].other.should.equal('%d apples %s')
return done(err)
})
})
it('does not write the locale file if updateFiles is false', function (done) {
const __n = y18n({
locale: 'fr',
updateFiles: false,
directory: path.join(__dirname, 'locales')
}).__n
__n('%d apple %s', '%d apples %s', 2, 'dude', function (err) {
fs.existsSync('./test/locales/fr.json').should.equal(false)
return done(err)
})
})
})
})
describe('setLocale', function () {
it('switches the locale', function () {
const i18n = y18n({
directory: path.join(__dirname, 'locales')
})
i18n.__('Hello').should.equal('Hello!')
i18n.setLocale('pirate')
i18n.__('Hello').should.equal('Avast ye mateys!')
})
})
describe('updateLocale', function () {
beforeEach(function (done) {
rimraf('./test/locales/fr.json', function () {
return done()
})
})
it('updates the locale with the new lookups provided', function () {
const i18n = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
})
i18n.updateLocale({
foo: 'le bar'
})
i18n.__('foo').should.equal('le bar')
})
it('loads the locale from disk prior to updating the map', function () {
fs.writeFileSync('./test/locales/fr.json', '{"meow": "le meow"}', 'utf-8')
const i18n = y18n({
locale: 'fr',
directory: path.join(__dirname, 'locales')
})
i18n.updateLocale({
foo: 'le bar'
})
i18n.__('meow').should.equal('le meow')
})
})
describe('getLocale', function () {
it('returns the configured locale', function () {
y18n().getLocale().should.equal('en')
})
})
// See: https://github.com/yargs/y18n/issues/96,
// https://github.com/yargs/y18n/pull/107
describe('prototype pollution', () => {
it('does not pollute prototype, with __proto__ locale', () => {
const y = y18n()
y.setLocale('__proto__')
y.updateLocale({ polluted: '👽' })
y.__('polluted').should.equal('👽')
;(typeof polluted).should.equal('undefined')
})
it('does not pollute prototype, when __ is used with __proto__ locale', () => {
const __ = y18n({ locale: '__proto__' }).__
__('hello')
;(typeof {}.hello).should.equal('undefined')
})
})
after(function () {
rimraf.sync('./test/locales/fr.json')
})
})
y18n-5.0.8/tsconfig.json 0000664 0000000 0000000 00000000505 14033400100 0015013 0 ustar 00root root 0000000 0000000 {
"extends": "./node_modules/gts/tsconfig-google.json",
"compilerOptions": {
"outDir": "build",
"rootDir": ".",
"sourceMap": false,
"target": "es2017",
"moduleResolution": "node",
"module": "es2015"
},
"include": [
"lib/**/*.ts"
],
"exclude": [
"lib/platform-shims/deno.ts"
]
} y18n-5.0.8/tsconfig.test.json 0000664 0000000 0000000 00000000212 14033400100 0015764 0 ustar 00root root 0000000 0000000 {
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": true
},
"exclude": [
"lib/platform-shims/deno.ts"
]
}