JWT Autorization / Logging in and registering
This commit is contained in:
3
node_modules/translate/.babelrc
generated
vendored
Normal file
3
node_modules/translate/.babelrc
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["env"]
|
||||
}
|
||||
2
node_modules/translate/.env.example
generated
vendored
Normal file
2
node_modules/translate/.env.example
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
GOOGLE_KEY=ABCD
|
||||
YANDEX_KEY=EFGH
|
||||
1
node_modules/translate/.github/FUNDING.yml
generated
vendored
Normal file
1
node_modules/translate/.github/FUNDING.yml
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
custom: https://www.paypal.me/franciscopresencia/19
|
||||
21
node_modules/translate/LICENSE
generated
vendored
Normal file
21
node_modules/translate/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
158
node_modules/translate/README.md
generated
vendored
Normal file
158
node_modules/translate/README.md
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
# Translate
|
||||
|
||||
Convert text to different languages on Node.js and the browser. Flexible package and powerful back-end using Google (default) or Yandex:
|
||||
|
||||
```js
|
||||
// async/await. Options can be a language name (ISO 639)
|
||||
const text = await translate('Hello world', 'es');
|
||||
console.log(text); // Hola mundo
|
||||
|
||||
// Promises with .then(). Options can also be an object
|
||||
translate('こんにちは世界', { from: 'ja', to: 'es' }).then(text => {
|
||||
console.log(text); // Hola mundo
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
This package can be used in Node.js and on the browser. For the browser we are using `fetch`, so you might want to [polyfill it](https://polyfill.io/v2/docs/) depending on [the browsers you support](https://caniuse.com/#feat=fetch).
|
||||
|
||||
To use it in `node.js` first install it:
|
||||
|
||||
```bash
|
||||
npm install translate
|
||||
```
|
||||
|
||||
Then import it to use it:
|
||||
|
||||
```js
|
||||
const translate = require('translate'); // Old school
|
||||
import translate from 'translate'; // New wave
|
||||
```
|
||||
|
||||
To use it in the browser download the main `translate.min.js` file and include it:
|
||||
|
||||
```html
|
||||
<script src="translate.min.js"></script>
|
||||
```
|
||||
|
||||
Or use the awesome [Jsdelivr **CDN**](https://www.jsdelivr.com/package/npm/translate):
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/translate@1/translate.min.js"></script>
|
||||
```
|
||||
|
||||
After including translate the usage is similar for both Node.js and the browser.
|
||||
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
The first parameter is the **string** that you want to translate. Right now only a single string of text is accepted.
|
||||
|
||||
The second parameter is the options. It accepts either a `String` of the language to translate **to** or a simple `Object` with these options:
|
||||
|
||||
- **`to`**: the string of the language to translate to. It can be in any of the two ISO 639 (1 or 2) or the full name in English like `Spanish`. Defaults to **en**.
|
||||
- **`from`**: the string of the language to translate to. It can be in any of the two ISO 639 (1 or 2) or the full name in English like `Spanish`. Also defaults to **en**.
|
||||
- **`cache`**: a `Number` with the milliseconds that each translation should be cached. Leave it undefined to cache it indefinitely (until a server/browser restart).
|
||||
- **`engine`**: a `String` containing the name of the engine to use for translation. Right now it defaults to `google`. Read more [in the engine section](#engines).
|
||||
- **`key`**: the API Key for the engine of your choice. Read more [in the engine section](#engines).
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
// Translate from English (default) to Spanish (specified)
|
||||
const foo = await translate('Hello world', 'es');
|
||||
|
||||
// Same as this:
|
||||
const bar = await translate('Hello world', { to: 'es' });
|
||||
```
|
||||
|
||||
> On both `to` and `from` defaulting to `en`: while I _am_ Spanish and was quite tempted to set this as one of those, English is the main language of the Internet and the main secondary language for those who have a different native language. This is why most of the translations will happen either to or from English.
|
||||
|
||||
|
||||
### Default options
|
||||
|
||||
You can change the default options for anything by calling the root library and the option name:
|
||||
|
||||
```js
|
||||
translate.from = 'es';
|
||||
```
|
||||
|
||||
This can be applied to any of the options enumerated above.
|
||||
|
||||
|
||||
|
||||
## Engines
|
||||
|
||||
Several translating engines are available to translate your text:
|
||||
|
||||
- **`google`**: ([demo](https://translate.google.com/) | [docs](https://cloud.google.com/translate/docs/)): Google Translate.
|
||||
- **`yandex`**: ([demo](https://translate.yandex.com/) | [docs](https://tech.yandex.com/translate/) | [API Key](https://translate.yandex.com/developers/keys)): Yandex Translate
|
||||
|
||||
> To get the API Key you will be signing some contract with these services; it's your responsibility to follow these and we are not liable if you don't as explained in our MIT License.
|
||||
|
||||
Once you get the API key and if you are only going to be using one engine (very likely), we recommend setting this globally for your whole project:
|
||||
|
||||
```js
|
||||
// ... include translate
|
||||
|
||||
translate.engine = 'google';
|
||||
translate.key = 'YOUR-KEY-HERE';
|
||||
|
||||
// ... use translate()
|
||||
```
|
||||
|
||||
If you are in Node.js, this likely comes from an environment variable:
|
||||
|
||||
```js
|
||||
// ... include translate
|
||||
|
||||
translate.engine = 'google';
|
||||
translate.key = process.env.TRANSLATE_KEY;
|
||||
|
||||
// ... use translate()
|
||||
```
|
||||
|
||||
|
||||
To pass it per-translation, you can add it to your arguments:
|
||||
|
||||
```js
|
||||
translate('Hello world', { to: 'en', engine: 'google', key: 'YOUR-KEY-HERE' });
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Promises
|
||||
|
||||
Working with Promises and specially with [async/await](https://ponyfoo.com/articles/understanding-javascript-async-await) reduces [Callback Hell](http://callbackhell.com/). To see it in action, first you'll need an `async` function. Then put your `await` calls inside:
|
||||
|
||||
```js
|
||||
// Browser; jQuery for demonstration purposes
|
||||
$('#translate').submit(async e => {
|
||||
e.preventDefault();
|
||||
const text = $('.text').text();
|
||||
const spanish = await translate(text, { to: 'es' });
|
||||
alert(spanish);
|
||||
});
|
||||
|
||||
// Node.js; serverjs.io example for demonstration purposes
|
||||
const route = async ctx => {
|
||||
const spanish = await translate(ctx.body, { to: 'es' });
|
||||
return send(spanish);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Authors and thanks
|
||||
|
||||
Current package and development: [Francisco Presencia](https://francisco.io/)
|
||||
|
||||
Original package and idea: Andrew Lunny (alunny), Marak Squires, Google
|
||||
|
||||
Testing in Internet Explorer supported by BrowserStack:
|
||||
|
||||
[](https://browserstack.com/)
|
||||
17
node_modules/translate/data/iso.js
generated
vendored
Normal file
17
node_modules/translate/data/iso.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
export default [
|
||||
"aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "ba",
|
||||
"be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce", "ch", "co",
|
||||
"cr", "cs", "cu", "cv", "cy", "da", "de", "dv", "dz", "ee", "el", "en", "eo",
|
||||
"es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr", "fy", "ga", "gd", "gl",
|
||||
"gn", "gu", "gv", "ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz", "ia",
|
||||
"id", "ie", "ig", "ii", "ik", "io", "is", "it", "iu", "ja", "jv", "ka", "kg",
|
||||
"ki", "kj", "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky",
|
||||
"la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk",
|
||||
"ml", "mn", "mr", "ms", "mt", "my", "na", "nb", "nd", "ne", "ng", "nl", "nn",
|
||||
"no", "nr", "nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl", "ps",
|
||||
"pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si",
|
||||
"sk", "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta",
|
||||
"te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty",
|
||||
"ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh", "yi", "yo", "za",
|
||||
"zh", "zu"
|
||||
];
|
||||
33
node_modules/translate/data/iso2.js
generated
vendored
Normal file
33
node_modules/translate/data/iso2.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
export default {
|
||||
"aar": "aa", "abk": "ab", "afr": "af", "aka": "ak", "alb": "sq", "amh": "am",
|
||||
"ara": "ar", "arg": "an", "arm": "hy", "asm": "as", "ava": "av", "ave": "ae",
|
||||
"aym": "ay", "aze": "az", "bak": "ba", "bam": "bm", "baq": "eu", "bel": "be",
|
||||
"ben": "bn", "bih": "bh", "bis": "bi", "bos": "bs", "bre": "br", "bul": "bg",
|
||||
"bur": "my", "cat": "ca", "cha": "ch", "che": "ce", "chi": "zh", "chu": "cu",
|
||||
"chv": "cv", "cor": "kw", "cos": "co", "cre": "cr", "cze": "cs", "dan": "da",
|
||||
"div": "dv", "dut": "nl", "dzo": "dz", "eng": "en", "epo": "eo", "est": "et",
|
||||
"ewe": "ee", "fao": "fo", "fij": "fj", "fin": "fi", "fre": "fr", "fry": "fy",
|
||||
"ful": "ff", "geo": "ka", "ger": "de", "gla": "gd", "gle": "ga", "glg": "gl",
|
||||
"glv": "gv", "gre": "el", "grn": "gn", "guj": "gu", "hat": "ht", "hau": "ha",
|
||||
"heb": "he", "her": "hz", "hin": "hi", "hmo": "ho", "hrv": "hr", "hun": "hu",
|
||||
"ibo": "ig", "ice": "is", "ido": "io", "iii": "ii", "iku": "iu", "ile": "ie",
|
||||
"ina": "ia", "ind": "id", "ipk": "ik", "ita": "it", "jav": "jv", "jpn": "ja",
|
||||
"kal": "kl", "kan": "kn", "kas": "ks", "kau": "kr", "kaz": "kk", "khm": "km",
|
||||
"kik": "ki", "kin": "rw", "kir": "ky", "kom": "kv", "kon": "kg", "kor": "ko",
|
||||
"kua": "kj", "kur": "ku", "lao": "lo", "lat": "la", "lav": "lv", "lim": "li",
|
||||
"lin": "ln", "lit": "lt", "ltz": "lb", "lub": "lu", "lug": "lg", "mac": "mk",
|
||||
"mah": "mh", "mal": "ml", "mao": "mi", "mar": "mr", "may": "ms", "mlg": "mg",
|
||||
"mlt": "mt", "mon": "mn", "nau": "na", "nav": "nv", "nbl": "nr", "nde": "nd",
|
||||
"ndo": "ng", "nep": "ne", "nno": "nn", "nob": "nb", "nor": "no", "nya": "ny",
|
||||
"oci": "oc", "oji": "oj", "ori": "or", "orm": "om", "oss": "os", "pan": "pa",
|
||||
"per": "fa", "pli": "pi", "pol": "pl", "por": "pt", "pus": "ps", "que": "qu",
|
||||
"roh": "rm", "rum": "ro", "run": "rn", "rus": "ru", "sag": "sg", "san": "sa",
|
||||
"sin": "si", "slo": "sk", "slv": "sl", "sme": "se", "smo": "sm", "sna": "sn",
|
||||
"snd": "sd", "som": "so", "sot": "st", "spa": "es", "srd": "sc", "srp": "sr",
|
||||
"ssw": "ss", "sun": "su", "swa": "sw", "swe": "sv", "tah": "ty", "tam": "ta",
|
||||
"tat": "tt", "tel": "te", "tgk": "tg", "tgl": "tl", "tha": "th", "tib": "bo",
|
||||
"tir": "ti", "ton": "to", "tsn": "tn", "tso": "ts", "tuk": "tk", "tur": "tr",
|
||||
"twi": "tw", "uig": "ug", "ukr": "uk", "urd": "ur", "uzb": "uz", "ven": "ve",
|
||||
"vie": "vi", "vol": "vo", "wel": "cy", "wln": "wa", "wol": "wo", "xho": "xh",
|
||||
"yid": "yi", "yor": "yo", "zha": "za", "zul": "zu"
|
||||
}
|
||||
221
node_modules/translate/data/map.js
generated
vendored
Normal file
221
node_modules/translate/data/map.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
export default {
|
||||
"afar": "aa",
|
||||
"abkhazian": "ab",
|
||||
"afrikaans": "af",
|
||||
"akan": "ak",
|
||||
"albanian": "sq",
|
||||
"amharic": "am",
|
||||
"arabic": "ar",
|
||||
"aragonese": "an",
|
||||
"armenian": "hy",
|
||||
"assamese": "as",
|
||||
"avaric": "av",
|
||||
"avestan": "ae",
|
||||
"aymara": "ay",
|
||||
"azerbaijani": "az",
|
||||
"bashkir": "ba",
|
||||
"bambara": "bm",
|
||||
"basque": "eu",
|
||||
"belarusian": "be",
|
||||
"bengali": "bn",
|
||||
"bihari languages": "bh",
|
||||
"bislama": "bi",
|
||||
"tibetan": "bo",
|
||||
"bosnian": "bs",
|
||||
"breton": "br",
|
||||
"bulgarian": "bg",
|
||||
"burmese": "my",
|
||||
"catalan": "ca",
|
||||
"valencian": "ca",
|
||||
"czech": "cs",
|
||||
"chamorro": "ch",
|
||||
"chechen": "ce",
|
||||
"chinese": "zh",
|
||||
"church slavic": "cu",
|
||||
"old slavonic": "cu",
|
||||
"church slavonic": "cu",
|
||||
"old bulgarian": "cu",
|
||||
"old church slavonic": "cu",
|
||||
"chuvash": "cv",
|
||||
"cornish": "kw",
|
||||
"corsican": "co",
|
||||
"cree": "cr",
|
||||
"welsh": "cy",
|
||||
"danish": "da",
|
||||
"german": "de",
|
||||
"divehi": "dv",
|
||||
"dhivehi": "dv",
|
||||
"maldivian": "dv",
|
||||
"dutch": "nl",
|
||||
"flemish": "nl",
|
||||
"dzongkha": "dz",
|
||||
"greek": "el",
|
||||
"english": "en",
|
||||
"esperanto": "eo",
|
||||
"estonian": "et",
|
||||
"ewe": "ee",
|
||||
"faroese": "fo",
|
||||
"persian": "fa",
|
||||
"fijian": "fj",
|
||||
"finnish": "fi",
|
||||
"french": "fr",
|
||||
"western frisian": "fy",
|
||||
"fulah": "ff",
|
||||
"georgian": "ka",
|
||||
"gaelic": "gd",
|
||||
"scottish gaelic": "gd",
|
||||
"irish": "ga",
|
||||
"galician": "gl",
|
||||
"manx": "gv",
|
||||
"guarani": "gn",
|
||||
"gujarati": "gu",
|
||||
"haitian": "ht",
|
||||
"haitian creole": "ht",
|
||||
"hausa": "ha",
|
||||
"hebrew": "he",
|
||||
"herero": "hz",
|
||||
"hindi": "hi",
|
||||
"hiri motu": "ho",
|
||||
"croatian": "hr",
|
||||
"hungarian": "hu",
|
||||
"igbo": "ig",
|
||||
"icelandic": "is",
|
||||
"ido": "io",
|
||||
"sichuan yi": "ii",
|
||||
"nuosu": "ii",
|
||||
"inuktitut": "iu",
|
||||
"interlingue": "ie",
|
||||
"occidental": "ie",
|
||||
"interlingua": "ia",
|
||||
"indonesian": "id",
|
||||
"inupiaq": "ik",
|
||||
"italian": "it",
|
||||
"javanese": "jv",
|
||||
"japanese": "ja",
|
||||
"kalaallisut": "kl",
|
||||
"greenlandic": "kl",
|
||||
"kannada": "kn",
|
||||
"kashmiri": "ks",
|
||||
"kanuri": "kr",
|
||||
"kazakh": "kk",
|
||||
"central khmer": "km",
|
||||
"kikuyu": "ki",
|
||||
"gikuyu": "ki",
|
||||
"kinyarwanda": "rw",
|
||||
"kirghiz": "ky",
|
||||
"kyrgyz": "ky",
|
||||
"komi": "kv",
|
||||
"kongo": "kg",
|
||||
"korean": "ko",
|
||||
"kuanyama": "kj",
|
||||
"kwanyama": "kj",
|
||||
"kurdish": "ku",
|
||||
"lao": "lo",
|
||||
"latin": "la",
|
||||
"latvian": "lv",
|
||||
"limburgan": "li",
|
||||
"limburger": "li",
|
||||
"limburgish": "li",
|
||||
"lingala": "ln",
|
||||
"lithuanian": "lt",
|
||||
"luxembourgish": "lb",
|
||||
"letzeburgesch": "lb",
|
||||
"luba-katanga": "lu",
|
||||
"ganda": "lg",
|
||||
"macedonian": "mk",
|
||||
"marshallese": "mh",
|
||||
"malayalam": "ml",
|
||||
"maori": "mi",
|
||||
"marathi": "mr",
|
||||
"malay": "ms",
|
||||
"malagasy": "mg",
|
||||
"maltese": "mt",
|
||||
"mongolian": "mn",
|
||||
"nauru": "na",
|
||||
"navajo": "nv",
|
||||
"navaho": "nv",
|
||||
"ndebele, south": "nr",
|
||||
"south ndebele": "nr",
|
||||
"ndebele, north": "nd",
|
||||
"north ndebele": "nd",
|
||||
"ndonga": "ng",
|
||||
"nepali": "ne",
|
||||
"norwegian nynorsk": "nn",
|
||||
"nynorsk, norwegian": "nn",
|
||||
"norwegian bokmål": "nb",
|
||||
"bokmål, norwegian": "nb",
|
||||
"norwegian": "no",
|
||||
"chichewa": "ny",
|
||||
"chewa": "ny",
|
||||
"nyanja": "ny",
|
||||
"occitan": "oc",
|
||||
"ojibwa": "oj",
|
||||
"oriya": "or",
|
||||
"oromo": "om",
|
||||
"ossetian": "os",
|
||||
"ossetic": "os",
|
||||
"panjabi": "pa",
|
||||
"punjabi": "pa",
|
||||
"pali": "pi",
|
||||
"polish": "pl",
|
||||
"portuguese": "pt",
|
||||
"pushto": "ps",
|
||||
"pashto": "ps",
|
||||
"quechua": "qu",
|
||||
"romansh": "rm",
|
||||
"romanian": "ro",
|
||||
"moldavian": "ro",
|
||||
"moldovan": "ro",
|
||||
"rundi": "rn",
|
||||
"russian": "ru",
|
||||
"sango": "sg",
|
||||
"sanskrit": "sa",
|
||||
"sinhala": "si",
|
||||
"sinhalese": "si",
|
||||
"slovak": "sk",
|
||||
"slovenian": "sl",
|
||||
"northern sami": "se",
|
||||
"samoan": "sm",
|
||||
"shona": "sn",
|
||||
"sindhi": "sd",
|
||||
"somali": "so",
|
||||
"sotho, southern": "st",
|
||||
"spanish": "es",
|
||||
"castilian": "es",
|
||||
"sardinian": "sc",
|
||||
"serbian": "sr",
|
||||
"swati": "ss",
|
||||
"sundanese": "su",
|
||||
"swahili": "sw",
|
||||
"swedish": "sv",
|
||||
"tahitian": "ty",
|
||||
"tamil": "ta",
|
||||
"tatar": "tt",
|
||||
"telugu": "te",
|
||||
"tajik": "tg",
|
||||
"tagalog": "tl",
|
||||
"thai": "th",
|
||||
"tigrinya": "ti",
|
||||
"tonga": "to",
|
||||
"tswana": "tn",
|
||||
"tsonga": "ts",
|
||||
"turkmen": "tk",
|
||||
"turkish": "tr",
|
||||
"twi": "tw",
|
||||
"uighur": "ug",
|
||||
"uyghur": "ug",
|
||||
"ukrainian": "uk",
|
||||
"urdu": "ur",
|
||||
"uzbek": "uz",
|
||||
"venda": "ve",
|
||||
"vietnamese": "vi",
|
||||
"volapük": "vo",
|
||||
"walloon": "wa",
|
||||
"wolof": "wo",
|
||||
"xhosa": "xh",
|
||||
"yiddish": "yi",
|
||||
"yoruba": "yo",
|
||||
"zhuang": "za",
|
||||
"chuang": "za",
|
||||
"zulu": "zu"
|
||||
}
|
||||
29
node_modules/translate/index.html
generated
vendored
Normal file
29
node_modules/translate/index.html
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<!-- Small manual front-end test to see it all works -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Translate example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p class="greeting">
|
||||
Input the key manually in the console like this:
|
||||
|
||||
<code>translate.key = 'KEYHERE';</code>
|
||||
|
||||
Then call test() from the console.
|
||||
</p>
|
||||
|
||||
<script src="translate.js"></script>
|
||||
<script>
|
||||
const test = async () => {
|
||||
const text = await translate('Hello world', { from: 'en', to: 'es' });
|
||||
document.querySelector('.greeting').innerText = `Hello world => ${text}`;
|
||||
console.log('Done! Look at the website :)');
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
192
node_modules/translate/lib/cache.js
generated
vendored
Normal file
192
node_modules/translate/lib/cache.js
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// From https://www.npmjs.com/package/memory-cache (Rollup didn't want to bundle it otherwise)
|
||||
'use strict';
|
||||
|
||||
function Cache () {
|
||||
var _cache = Object.create(null);
|
||||
var _hitCount = 0;
|
||||
var _missCount = 0;
|
||||
var _size = 0;
|
||||
var _debug = false;
|
||||
|
||||
this.put = function(key, value, time, timeoutCallback) {
|
||||
if (_debug) {
|
||||
console.log('caching: %s = %j (@%s)', key, value, time);
|
||||
}
|
||||
|
||||
if (typeof time !== 'undefined' && (typeof time !== 'number' || isNaN(time) || time <= 0)) {
|
||||
throw new Error('Cache timeout must be a positive number');
|
||||
} else if (typeof timeoutCallback !== 'undefined' && typeof timeoutCallback !== 'function') {
|
||||
throw new Error('Cache timeout callback must be a function');
|
||||
}
|
||||
|
||||
var oldRecord = _cache[key];
|
||||
if (oldRecord) {
|
||||
clearTimeout(oldRecord.timeout);
|
||||
} else {
|
||||
_size++;
|
||||
}
|
||||
|
||||
var record = {
|
||||
value: value,
|
||||
expire: time + Date.now()
|
||||
};
|
||||
|
||||
if (!isNaN(record.expire)) {
|
||||
record.timeout = setTimeout(function() {
|
||||
_del(key);
|
||||
if (timeoutCallback) {
|
||||
timeoutCallback(key, value);
|
||||
}
|
||||
}.bind(this), time);
|
||||
}
|
||||
|
||||
_cache[key] = record;
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
this.del = function(key) {
|
||||
var canDelete = true;
|
||||
|
||||
var oldRecord = _cache[key];
|
||||
if (oldRecord) {
|
||||
clearTimeout(oldRecord.timeout);
|
||||
if (!isNaN(oldRecord.expire) && oldRecord.expire < Date.now()) {
|
||||
canDelete = false;
|
||||
}
|
||||
} else {
|
||||
canDelete = false;
|
||||
}
|
||||
|
||||
if (canDelete) {
|
||||
_del(key);
|
||||
}
|
||||
|
||||
return canDelete;
|
||||
};
|
||||
|
||||
function _del(key){
|
||||
_size--;
|
||||
delete _cache[key];
|
||||
}
|
||||
|
||||
this.clear = function() {
|
||||
for (var key in _cache) {
|
||||
clearTimeout(_cache[key].timeout);
|
||||
}
|
||||
_size = 0;
|
||||
_cache = Object.create(null);
|
||||
if (_debug) {
|
||||
_hitCount = 0;
|
||||
_missCount = 0;
|
||||
}
|
||||
};
|
||||
|
||||
this.get = function(key) {
|
||||
var data = _cache[key];
|
||||
if (typeof data != "undefined") {
|
||||
if (isNaN(data.expire) || data.expire >= Date.now()) {
|
||||
if (_debug) _hitCount++;
|
||||
return data.value;
|
||||
} else {
|
||||
// free some space
|
||||
if (_debug) _missCount++;
|
||||
_size--;
|
||||
delete _cache[key];
|
||||
}
|
||||
} else if (_debug) {
|
||||
_missCount++;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.size = function() {
|
||||
return _size;
|
||||
};
|
||||
|
||||
this.memsize = function() {
|
||||
var size = 0,
|
||||
key;
|
||||
for (key in _cache) {
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
};
|
||||
|
||||
this.debug = function(bool) {
|
||||
_debug = bool;
|
||||
};
|
||||
|
||||
this.hits = function() {
|
||||
return _hitCount;
|
||||
};
|
||||
|
||||
this.misses = function() {
|
||||
return _missCount;
|
||||
};
|
||||
|
||||
this.keys = function() {
|
||||
return Object.keys(_cache);
|
||||
};
|
||||
|
||||
this.exportJson = function() {
|
||||
var plainJsCache = {};
|
||||
|
||||
// Discard the `timeout` property.
|
||||
// Note: JSON doesn't support `NaN`, so convert it to `'NaN'`.
|
||||
for (var key in _cache) {
|
||||
var record = _cache[key];
|
||||
plainJsCache[key] = {
|
||||
value: record.value,
|
||||
expire: record.expire || 'NaN',
|
||||
};
|
||||
}
|
||||
|
||||
return JSON.stringify(plainJsCache);
|
||||
};
|
||||
|
||||
this.importJson = function(jsonToImport, options) {
|
||||
var cacheToImport = JSON.parse(jsonToImport);
|
||||
var currTime = Date.now();
|
||||
|
||||
var skipDuplicates = options && options.skipDuplicates;
|
||||
|
||||
for (var key in cacheToImport) {
|
||||
if (cacheToImport.hasOwnProperty(key)) {
|
||||
if (skipDuplicates) {
|
||||
var existingRecord = _cache[key];
|
||||
if (existingRecord) {
|
||||
if (_debug) {
|
||||
console.log('Skipping duplicate imported key \'%s\'', key);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var record = cacheToImport[key];
|
||||
|
||||
// record.expire could be `'NaN'` if no expiry was set.
|
||||
// Try to subtract from it; a string minus a number is `NaN`, which is perfectly fine here.
|
||||
var remainingTime = record.expire - currTime;
|
||||
|
||||
if (remainingTime <= 0) {
|
||||
// Delete any record that might exist with the same key, since this key is expired.
|
||||
this.del(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remaining time must now be either positive or `NaN`,
|
||||
// but `put` will throw an error if we try to give it `NaN`.
|
||||
remainingTime = remainingTime > 0 ? remainingTime : undefined;
|
||||
|
||||
this.put(key, record.value, remainingTime);
|
||||
}
|
||||
}
|
||||
|
||||
return this.size();
|
||||
};
|
||||
}
|
||||
|
||||
const exp = new Cache();
|
||||
exp.Cache = Cache;
|
||||
export default exp;
|
||||
10
node_modules/translate/node.js
generated
vendored
Normal file
10
node_modules/translate/node.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Small manual test to see that it all works
|
||||
const translate = require('./translate');
|
||||
require('dotenv').load();
|
||||
|
||||
translate.engine = 'yandex';
|
||||
translate.key = process.env.YANDEX_KEY;
|
||||
|
||||
translate('Hello world', 'es').then(res => {
|
||||
console.log(res);
|
||||
});
|
||||
79
node_modules/translate/package.json
generated
vendored
Normal file
79
node_modules/translate/package.json
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"_from": "translate",
|
||||
"_id": "translate@1.1.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-3RlVAzzcNuZ7dDfYk2qsQTxJLSeIQ06bMrYYkBneLHtewV0JGaKSP0GjTKHJn/vYwr18bvHEgdmjfg8B0DFuWw==",
|
||||
"_location": "/translate",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "translate",
|
||||
"name": "translate",
|
||||
"escapedName": "translate",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/translate/-/translate-1.1.2.tgz",
|
||||
"_shasum": "719665e7f324cfc28619726fc1d97f5a633c37e3",
|
||||
"_spec": "translate",
|
||||
"_where": "D:\\WORK\\Menui\\menui_backend",
|
||||
"author": {
|
||||
"name": "Francisco Presencia",
|
||||
"email": "public@francisco.io",
|
||||
"url": "https://francisco.io/"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/franciscop/translate/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"node-fetch": "^1.7.3"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Translate text to different languages on node.js and the browser",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-jest": "^21.2.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"dotenv": "^4.0.0",
|
||||
"fetch-mock": "^5.13.1",
|
||||
"jest": "^23.6.0",
|
||||
"rollup": "^0.50.0",
|
||||
"uglify-es": "^3.1.3"
|
||||
},
|
||||
"engine": [
|
||||
"node >=4.0.0"
|
||||
],
|
||||
"funding": "https://www.paypal.me/franciscopresencia/19",
|
||||
"homepage": "https://github.com/franciscop/translate#readme",
|
||||
"keywords": [
|
||||
"translate",
|
||||
"languages",
|
||||
"i18n",
|
||||
"internationalization",
|
||||
"async",
|
||||
"google",
|
||||
"yandex"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "translate.min.js",
|
||||
"name": "translate",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/franciscop/translate.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup src/index.js -o translate.js --name translate --output.format umd && uglifyjs translate.js -o translate.min.js",
|
||||
"gzip": "gzip -c translate.min.js | wc -c && echo 'bytes' # Only for Unix",
|
||||
"start": "npm run watch # Start ~= Start dev",
|
||||
"test": "jest --coverage --collectCoverageFrom=src/**/*.js --detectOpenHandles",
|
||||
"watch": "nodemon --exec \"npm run build && npm test && npm run gzip\" --watch src --watch test --watch webpack.config.js --watch package.json"
|
||||
},
|
||||
"version": "1.1.2"
|
||||
}
|
||||
39
node_modules/translate/src/engines.js
generated
vendored
Normal file
39
node_modules/translate/src/engines.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Translation engines
|
||||
// Handle different translations differently to allow for extra flexibility
|
||||
|
||||
|
||||
const google = {
|
||||
needkey: true,
|
||||
fetch: ({ key, from, to, text }) => [
|
||||
`https://translation.googleapis.com/language/translate/v2?key=${key}&format=text&source=${from}&target=${to}&q=${encodeURIComponent(text)}`,
|
||||
{ method: 'POST' }
|
||||
],
|
||||
parse: res => res.json().then(body => {
|
||||
if (body.error) {
|
||||
throw new Error(body.error.errors[0].message);
|
||||
}
|
||||
body = body.data.translations[0];
|
||||
if (!body) {
|
||||
throw new Error('Translation not found');
|
||||
}
|
||||
return body.translatedText;
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
const yandex = {
|
||||
needkey: true,
|
||||
fetch: ({ key, from, to, text }) => [
|
||||
`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${key}&lang=${from}-${to}&text=${encodeURIComponent(text)}`,
|
||||
{ method: 'POST', body: '' }
|
||||
],
|
||||
parse: res => res.json().then(body => {
|
||||
if (body.code !== 200) {
|
||||
throw new Error(body.message);
|
||||
}
|
||||
return body.text[0];
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
export default { google, yandex };
|
||||
92
node_modules/translate/src/index.js
generated
vendored
Normal file
92
node_modules/translate/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// translate.js
|
||||
// Translate text into different languages;
|
||||
|
||||
// Load a language parser to allow for more flexibility in the language choice
|
||||
import language from "./language";
|
||||
|
||||
// Load the default engines for translation
|
||||
import engines from "./engines";
|
||||
|
||||
// Cache the different translations to avoid resending requests
|
||||
import cache from "../lib/cache";
|
||||
|
||||
// Main function
|
||||
const Translate = function(options = {}) {
|
||||
if (!(this instanceof Translate)) {
|
||||
return new Translate(options);
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
from: "en",
|
||||
to: "en",
|
||||
cache: undefined,
|
||||
language: language,
|
||||
engines: engines,
|
||||
engine: "google",
|
||||
keys: {}
|
||||
};
|
||||
|
||||
const translate = (text, opts = {}) => {
|
||||
// Load all of the appropriate options (verbose but fast)
|
||||
// Note: not all of those *should* be documented since some are internal only
|
||||
if (typeof opts === "string") opts = { to: opts };
|
||||
opts.text = text;
|
||||
opts.from = language(opts.from || translate.from);
|
||||
opts.to = language(opts.to || translate.to);
|
||||
opts.cache = opts.cache || translate.cache;
|
||||
opts.engines = opts.engines || {};
|
||||
opts.engine = opts.engine || translate.engine;
|
||||
opts.id = opts.id || `${opts.from}:${opts.to}:${opts.engine}:${opts.text}`;
|
||||
opts.keys = opts.keys || translate.keys || {};
|
||||
for (let name in translate.keys) {
|
||||
// The options has stronger preference than the global value
|
||||
opts.keys[name] = opts.keys[name] || translate.keys[name];
|
||||
}
|
||||
opts.key = opts.key || translate.key || opts.keys[opts.engine];
|
||||
|
||||
// TODO: validation for few of those
|
||||
|
||||
// Use the desired engine
|
||||
const engine = opts.engines[opts.engine] || translate.engines[opts.engine];
|
||||
|
||||
// If it is cached return ASAP
|
||||
const cached = cache.get(opts.id);
|
||||
if (cached) return Promise.resolve(cached);
|
||||
|
||||
// Target is the same as origin, just return the string
|
||||
if (opts.to === opts.from) {
|
||||
return Promise.resolve(opts.text);
|
||||
}
|
||||
|
||||
// Will load only for Node.js and use the native function on the browser
|
||||
if (typeof fetch === "undefined") {
|
||||
try {
|
||||
global.fetch = require("node-fetch");
|
||||
} catch (error) {
|
||||
console.warn("Please make sure node-fetch is available");
|
||||
}
|
||||
}
|
||||
|
||||
if (engine.needkey && !opts.key) {
|
||||
throw new Error(
|
||||
`The engine "${opts.engine}" needs a key, please provide it`
|
||||
);
|
||||
}
|
||||
|
||||
const fetchOpts = engine.fetch(opts);
|
||||
return fetch(...fetchOpts)
|
||||
.then(engine.parse)
|
||||
.then(translated => cache.put(opts.id, translated, opts.cache));
|
||||
};
|
||||
|
||||
for (let key in defaults) {
|
||||
translate[key] =
|
||||
typeof options[key] === "undefined" ? defaults[key] : options[key];
|
||||
}
|
||||
return translate;
|
||||
};
|
||||
|
||||
// Small hack needed for Webpack/Babel: https://github.com/webpack/webpack/issues/706
|
||||
const exp = new Translate();
|
||||
exp.Translate = Translate;
|
||||
export default exp;
|
||||
42
node_modules/translate/src/language.js
generated
vendored
Normal file
42
node_modules/translate/src/language.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Relevant ISO: ISO 639-1 & ISO 639-2. Google uses the ISO 639-1.
|
||||
// Valid ISO 639-1 codes
|
||||
// https://www.loc.gov/standards/iso639-2/php/code_list.php
|
||||
// Extract these with this code (after loading https://superdom.site/ )
|
||||
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map((row, i) => `"${row.querySelector('td:nth-child(2)').textContent}", ${i % 12 === 11 ? '\n' : ''}`).join('');
|
||||
import iso from '../data/iso';
|
||||
|
||||
// Parsed from here: https://github.com/wooorm/iso-639-2/blob/master/index.json
|
||||
import iso2 from '../data/iso2';
|
||||
|
||||
// Extract these with this code (after loading https://superdom.site/ ) + a lot of manual clean up
|
||||
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map(row =>
|
||||
// ` "${row.querySelector('td:nth-child(3)').textContent.toLowerCase()}": "${row.querySelector('td:nth-child(2)').textContent.toLowerCase()}",`
|
||||
// ).join('\n');
|
||||
import map from '../data/map';
|
||||
|
||||
// Language parser
|
||||
// @name: a string to be parsed
|
||||
// @output: the normalized language string
|
||||
export default name => {
|
||||
|
||||
// Validate the name string
|
||||
if (typeof name !== 'string') {
|
||||
throw new Error(`The language must be a string, received ${typeof name}`);
|
||||
}
|
||||
// Possible overflow errors
|
||||
if (name.length > 100) {
|
||||
throw new Error(`The language must be a string under 100 characters, received ${name.length}`);
|
||||
}
|
||||
|
||||
// Let's work with lowercase for everything
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Pass it through several possible maps to try to find the right one
|
||||
name = map[name] || iso2[name] || name;
|
||||
|
||||
// Make sure we have the correct name or throw
|
||||
if (!iso.includes(name)) {
|
||||
throw new Error(`The name "${name}" is not part of the ISO 639-1 and we couldn't automatically parse it :(`);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
14
node_modules/translate/test/mock.js
generated
vendored
Normal file
14
node_modules/translate/test/mock.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Utility method to mock responses from fetch()
|
||||
const fetchMock = require('fetch-mock');
|
||||
|
||||
module.exports = (url, content, throws) => {
|
||||
fetchMock.post(url, () => new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
throws ? reject(content) : resolve(content);
|
||||
}, 500);
|
||||
}));
|
||||
};
|
||||
|
||||
module.exports.end = () => {
|
||||
fetchMock.restore();
|
||||
};
|
||||
236
node_modules/translate/test/translate.test.js
generated
vendored
Normal file
236
node_modules/translate/test/translate.test.js
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
import translate from '../src';
|
||||
import mock from './mock';
|
||||
import fs from 'fs';
|
||||
|
||||
// Quickly load .env files into the environment
|
||||
require('dotenv').load();
|
||||
|
||||
translate.keys.google = process.env.GOOGLE_KEY || 'fakekey';
|
||||
translate.keys.yandex = process.env.YANDEX_KEY || 'fakekey';
|
||||
|
||||
describe('Main', () => {
|
||||
beforeEach(() => {
|
||||
mock(/googleapis.*target=es/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
|
||||
mock(/googleapis.*target=ja/, { data: { translations: [{ translatedText: 'こんにちは世界'}] } });
|
||||
});
|
||||
|
||||
afterEach(() => mock.end());
|
||||
|
||||
|
||||
it('loads', () => {
|
||||
expect(translate).toBeDefined();
|
||||
});
|
||||
|
||||
it('returns a promise', () => {
|
||||
const ret = translate('Hello world');
|
||||
expect(ret instanceof Promise).toBe(true);
|
||||
});
|
||||
|
||||
it('can translate a simple string', async () => {
|
||||
const es = await translate('Hello world', { from: 'en', to: 'es' });
|
||||
expect(es).toMatch(/Hola mundo/i);
|
||||
const jp = await translate('Hello world', { from: 'en', to: 'ja' });
|
||||
expect(jp).toBe('こんにちは世界');
|
||||
});
|
||||
|
||||
it('accepts full language names', async () => {
|
||||
const es = await translate('Hello world', { from: 'English', to: 'Spanish' });
|
||||
expect(es).toMatch(/Hola mundo/i);
|
||||
const jp = await translate('Hello world', { from: 'English', to: 'Japanese' });
|
||||
expect(jp).toBe('こんにちは世界');
|
||||
});
|
||||
|
||||
it('accepts weird casing for language names', async () => {
|
||||
const es = await translate('Hello world', { from: 'english', to: 'spaNish' });
|
||||
expect(es).toMatch(/Hola mundo/i);
|
||||
const jp = await translate('Hello world', { from: 'ENGLISH', to: 'JapAnesE' });
|
||||
expect(jp).toBe('こんにちは世界');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
let language;
|
||||
describe('language parsing', () => {
|
||||
it('loads', () => {
|
||||
language = translate.language;
|
||||
expect(language).toBeDefined();
|
||||
});
|
||||
|
||||
it('works with a good language name', () => {
|
||||
expect(language('Spanish')).toBe('es');
|
||||
});
|
||||
|
||||
it('works with the plain ISO', () => {
|
||||
expect(language('es')).toBe('es');
|
||||
expect(language('ja')).toBe('ja');
|
||||
expect(language('en')).toBe('en');
|
||||
});
|
||||
|
||||
it('works with the alternative ISO 639-2', () => {
|
||||
expect(language('spa')).toBe('es');
|
||||
expect(language('jpn')).toBe('ja');
|
||||
expect(language('eng')).toBe('en');
|
||||
});
|
||||
|
||||
it('works with diferent casing', () => {
|
||||
expect(language('spanish')).toBe('es');
|
||||
expect(language('SpANisH')).toBe('es');
|
||||
expect(language('SPANISH')).toBe('es');
|
||||
});
|
||||
|
||||
it('throws with an invalid language name type', () => {
|
||||
expect(() => language(20)).toThrow();
|
||||
});
|
||||
|
||||
it('throws with a language name too long', () => {
|
||||
expect(() => language('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')).toThrow();
|
||||
});
|
||||
|
||||
it('throws with a wrong language name', () => {
|
||||
expect(() => language('asdfghjddas')).toThrow();
|
||||
});
|
||||
|
||||
it('works with fuzzy strings', () => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('cache', () => {
|
||||
beforeEach(() => {
|
||||
mock(/googleapis.*target=es/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
|
||||
mock(/googleapis.*target=ja/, { data: { translations: [{ translatedText: 'こんにちは世界'}] } });
|
||||
});
|
||||
|
||||
afterEach(() => mock.end());
|
||||
|
||||
|
||||
const stop = time => new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, time);
|
||||
});
|
||||
|
||||
it('caches', async () => {
|
||||
const before = new Date();
|
||||
await translate('Is this cached?', 'es');
|
||||
const mid = new Date();
|
||||
await translate('Is this cached?', 'es');
|
||||
const after = new Date();
|
||||
expect(mid - before).toBeLessThan(10000);
|
||||
expect(mid - before).toBeGreaterThan(100);
|
||||
expect(after - mid).toBeLessThan(10);
|
||||
expect(after - mid).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
it('removes cache after the time is out', async () => {
|
||||
const before = new Date();
|
||||
await translate('Is this also cached?', { to: 'es', cache: 1000 });
|
||||
const mid = new Date();
|
||||
await stop(1100);
|
||||
await translate('Is this also cached?', { to: 'es' });
|
||||
const after = new Date();
|
||||
expect(mid - before).toBeLessThan(10000);
|
||||
expect(mid - before).toBeGreaterThan(100);
|
||||
expect(after - mid).toBeLessThan(10000);
|
||||
expect(after - mid).toBeGreaterThan(100);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
describe('File size', () => {
|
||||
it('is smaller than 20kb (uncompressed)', () => {
|
||||
const details = fs.statSync(process.cwd() + '/translate.min.js');
|
||||
expect(details.size).toBeLessThan(25000);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Google', () => {
|
||||
beforeEach(() => {
|
||||
mock(/googleapi.*error/, { error: { errors: [{ message: 'Google API Error' }] } });
|
||||
mock(/googleapi.*throw/, { code: 500, message: 'also fails harder' }, true);
|
||||
mock(/googleapi.*&target=ru/, { data: { translations: [{ translatedText: 'Hola mundo' }] } });
|
||||
});
|
||||
|
||||
afterEach(() => mock.end());
|
||||
|
||||
it('works', async () => {
|
||||
const text = await translate('Hello world', { to: 'ru', engine: 'google' });
|
||||
expect(text).toBe('Hola mundo');
|
||||
});
|
||||
|
||||
it('can handle errors from the API', async () => {
|
||||
const prom = translate('error', { to: 'es', engine: 'google' });
|
||||
await expect(prom).rejects.toHaveProperty('message', 'Google API Error');
|
||||
});
|
||||
|
||||
it('can handle errors thrown by fetch()', async () => {
|
||||
const prom = translate('throw', { to: 'es', engine: 'google' });
|
||||
await expect(prom).rejects.toHaveProperty('message', 'also fails harder');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Yandex', () => {
|
||||
beforeEach(() => {
|
||||
mock(/yandex.*error/, { code: 500, message: 'it fails' });
|
||||
mock(/yandex.*throw/, { code: 500, message: 'also fails harder' }, true);
|
||||
mock(/yandex.*&lang=[a-z]*\-es/, { code: 200, text: ['Hola de Yandex'] });
|
||||
});
|
||||
|
||||
afterEach(() => mock.end());
|
||||
|
||||
it('works with a simple request', async () => {
|
||||
const spanish = await translate('Hello from Yandex', { to: 'es', engine: 'yandex' });
|
||||
expect(spanish).toMatch(/Hola de Yandex/i);
|
||||
});
|
||||
|
||||
it('can handle errors from the API', async () => {
|
||||
const prom = translate('error', { to: 'es', engine: 'yandex' });
|
||||
await expect(prom).rejects.toHaveProperty('message', 'it fails');
|
||||
});
|
||||
|
||||
it('can handle errors thrown by fetch()', async () => {
|
||||
const prom = translate('throw', { to: 'es', engine: 'yandex' });
|
||||
await expect(prom).rejects.toHaveProperty('message', 'also fails harder');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
describe('Independent', () => {
|
||||
it('has independent instances', () => {
|
||||
const translate2 = new translate.Translate();
|
||||
translate.keys.madeup = 'a';
|
||||
translate2.keys.madeup = 'b';
|
||||
expect(translate.keys.madeup).toBe('a');
|
||||
expect(translate2.keys.madeup).toBe('b');
|
||||
});
|
||||
|
||||
it('is auto initialized', () => {
|
||||
let inst = translate.Translate();
|
||||
expect(inst.from).toBe('en');
|
||||
inst = new translate.Translate();
|
||||
expect(inst.from).toBe('en');
|
||||
});
|
||||
|
||||
it('fixed the bug #5', async () => {
|
||||
// translate.keys = { google: 'abc' };
|
||||
const options = { to: 'ja', keys: { yandex: 'def' }, engine: 'google' };
|
||||
|
||||
// This will wrongly ignore the key for "google"
|
||||
expect(await translate('Hello world', options)).toBe('こんにちは世界');
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// These cost $ and would need your own keys. Disable otherwise
|
||||
describe.skip('$$$ Real API tests', () => {
|
||||
it('works', async () => {
|
||||
const text = await translate('Hello world', { to: 'fr', engine: 'google' });
|
||||
expect(text).toMatch(/Hola Mundo/i);
|
||||
});
|
||||
});
|
||||
638
node_modules/translate/translate.js
generated
vendored
Normal file
638
node_modules/translate/translate.js
generated
vendored
Normal file
@@ -0,0 +1,638 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.translate = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
var iso = [
|
||||
"aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "ba",
|
||||
"be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce", "ch", "co",
|
||||
"cr", "cs", "cu", "cv", "cy", "da", "de", "dv", "dz", "ee", "el", "en", "eo",
|
||||
"es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr", "fy", "ga", "gd", "gl",
|
||||
"gn", "gu", "gv", "ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz", "ia",
|
||||
"id", "ie", "ig", "ii", "ik", "io", "is", "it", "iu", "ja", "jv", "ka", "kg",
|
||||
"ki", "kj", "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky",
|
||||
"la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk",
|
||||
"ml", "mn", "mr", "ms", "mt", "my", "na", "nb", "nd", "ne", "ng", "nl", "nn",
|
||||
"no", "nr", "nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl", "ps",
|
||||
"pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si",
|
||||
"sk", "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta",
|
||||
"te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty",
|
||||
"ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh", "yi", "yo", "za",
|
||||
"zh", "zu"
|
||||
];
|
||||
|
||||
var iso2 = {
|
||||
"aar": "aa", "abk": "ab", "afr": "af", "aka": "ak", "alb": "sq", "amh": "am",
|
||||
"ara": "ar", "arg": "an", "arm": "hy", "asm": "as", "ava": "av", "ave": "ae",
|
||||
"aym": "ay", "aze": "az", "bak": "ba", "bam": "bm", "baq": "eu", "bel": "be",
|
||||
"ben": "bn", "bih": "bh", "bis": "bi", "bos": "bs", "bre": "br", "bul": "bg",
|
||||
"bur": "my", "cat": "ca", "cha": "ch", "che": "ce", "chi": "zh", "chu": "cu",
|
||||
"chv": "cv", "cor": "kw", "cos": "co", "cre": "cr", "cze": "cs", "dan": "da",
|
||||
"div": "dv", "dut": "nl", "dzo": "dz", "eng": "en", "epo": "eo", "est": "et",
|
||||
"ewe": "ee", "fao": "fo", "fij": "fj", "fin": "fi", "fre": "fr", "fry": "fy",
|
||||
"ful": "ff", "geo": "ka", "ger": "de", "gla": "gd", "gle": "ga", "glg": "gl",
|
||||
"glv": "gv", "gre": "el", "grn": "gn", "guj": "gu", "hat": "ht", "hau": "ha",
|
||||
"heb": "he", "her": "hz", "hin": "hi", "hmo": "ho", "hrv": "hr", "hun": "hu",
|
||||
"ibo": "ig", "ice": "is", "ido": "io", "iii": "ii", "iku": "iu", "ile": "ie",
|
||||
"ina": "ia", "ind": "id", "ipk": "ik", "ita": "it", "jav": "jv", "jpn": "ja",
|
||||
"kal": "kl", "kan": "kn", "kas": "ks", "kau": "kr", "kaz": "kk", "khm": "km",
|
||||
"kik": "ki", "kin": "rw", "kir": "ky", "kom": "kv", "kon": "kg", "kor": "ko",
|
||||
"kua": "kj", "kur": "ku", "lao": "lo", "lat": "la", "lav": "lv", "lim": "li",
|
||||
"lin": "ln", "lit": "lt", "ltz": "lb", "lub": "lu", "lug": "lg", "mac": "mk",
|
||||
"mah": "mh", "mal": "ml", "mao": "mi", "mar": "mr", "may": "ms", "mlg": "mg",
|
||||
"mlt": "mt", "mon": "mn", "nau": "na", "nav": "nv", "nbl": "nr", "nde": "nd",
|
||||
"ndo": "ng", "nep": "ne", "nno": "nn", "nob": "nb", "nor": "no", "nya": "ny",
|
||||
"oci": "oc", "oji": "oj", "ori": "or", "orm": "om", "oss": "os", "pan": "pa",
|
||||
"per": "fa", "pli": "pi", "pol": "pl", "por": "pt", "pus": "ps", "que": "qu",
|
||||
"roh": "rm", "rum": "ro", "run": "rn", "rus": "ru", "sag": "sg", "san": "sa",
|
||||
"sin": "si", "slo": "sk", "slv": "sl", "sme": "se", "smo": "sm", "sna": "sn",
|
||||
"snd": "sd", "som": "so", "sot": "st", "spa": "es", "srd": "sc", "srp": "sr",
|
||||
"ssw": "ss", "sun": "su", "swa": "sw", "swe": "sv", "tah": "ty", "tam": "ta",
|
||||
"tat": "tt", "tel": "te", "tgk": "tg", "tgl": "tl", "tha": "th", "tib": "bo",
|
||||
"tir": "ti", "ton": "to", "tsn": "tn", "tso": "ts", "tuk": "tk", "tur": "tr",
|
||||
"twi": "tw", "uig": "ug", "ukr": "uk", "urd": "ur", "uzb": "uz", "ven": "ve",
|
||||
"vie": "vi", "vol": "vo", "wel": "cy", "wln": "wa", "wol": "wo", "xho": "xh",
|
||||
"yid": "yi", "yor": "yo", "zha": "za", "zul": "zu"
|
||||
};
|
||||
|
||||
var map = {
|
||||
"afar": "aa",
|
||||
"abkhazian": "ab",
|
||||
"afrikaans": "af",
|
||||
"akan": "ak",
|
||||
"albanian": "sq",
|
||||
"amharic": "am",
|
||||
"arabic": "ar",
|
||||
"aragonese": "an",
|
||||
"armenian": "hy",
|
||||
"assamese": "as",
|
||||
"avaric": "av",
|
||||
"avestan": "ae",
|
||||
"aymara": "ay",
|
||||
"azerbaijani": "az",
|
||||
"bashkir": "ba",
|
||||
"bambara": "bm",
|
||||
"basque": "eu",
|
||||
"belarusian": "be",
|
||||
"bengali": "bn",
|
||||
"bihari languages": "bh",
|
||||
"bislama": "bi",
|
||||
"tibetan": "bo",
|
||||
"bosnian": "bs",
|
||||
"breton": "br",
|
||||
"bulgarian": "bg",
|
||||
"burmese": "my",
|
||||
"catalan": "ca",
|
||||
"valencian": "ca",
|
||||
"czech": "cs",
|
||||
"chamorro": "ch",
|
||||
"chechen": "ce",
|
||||
"chinese": "zh",
|
||||
"church slavic": "cu",
|
||||
"old slavonic": "cu",
|
||||
"church slavonic": "cu",
|
||||
"old bulgarian": "cu",
|
||||
"old church slavonic": "cu",
|
||||
"chuvash": "cv",
|
||||
"cornish": "kw",
|
||||
"corsican": "co",
|
||||
"cree": "cr",
|
||||
"welsh": "cy",
|
||||
"danish": "da",
|
||||
"german": "de",
|
||||
"divehi": "dv",
|
||||
"dhivehi": "dv",
|
||||
"maldivian": "dv",
|
||||
"dutch": "nl",
|
||||
"flemish": "nl",
|
||||
"dzongkha": "dz",
|
||||
"greek": "el",
|
||||
"english": "en",
|
||||
"esperanto": "eo",
|
||||
"estonian": "et",
|
||||
"ewe": "ee",
|
||||
"faroese": "fo",
|
||||
"persian": "fa",
|
||||
"fijian": "fj",
|
||||
"finnish": "fi",
|
||||
"french": "fr",
|
||||
"western frisian": "fy",
|
||||
"fulah": "ff",
|
||||
"georgian": "ka",
|
||||
"gaelic": "gd",
|
||||
"scottish gaelic": "gd",
|
||||
"irish": "ga",
|
||||
"galician": "gl",
|
||||
"manx": "gv",
|
||||
"guarani": "gn",
|
||||
"gujarati": "gu",
|
||||
"haitian": "ht",
|
||||
"haitian creole": "ht",
|
||||
"hausa": "ha",
|
||||
"hebrew": "he",
|
||||
"herero": "hz",
|
||||
"hindi": "hi",
|
||||
"hiri motu": "ho",
|
||||
"croatian": "hr",
|
||||
"hungarian": "hu",
|
||||
"igbo": "ig",
|
||||
"icelandic": "is",
|
||||
"ido": "io",
|
||||
"sichuan yi": "ii",
|
||||
"nuosu": "ii",
|
||||
"inuktitut": "iu",
|
||||
"interlingue": "ie",
|
||||
"occidental": "ie",
|
||||
"interlingua": "ia",
|
||||
"indonesian": "id",
|
||||
"inupiaq": "ik",
|
||||
"italian": "it",
|
||||
"javanese": "jv",
|
||||
"japanese": "ja",
|
||||
"kalaallisut": "kl",
|
||||
"greenlandic": "kl",
|
||||
"kannada": "kn",
|
||||
"kashmiri": "ks",
|
||||
"kanuri": "kr",
|
||||
"kazakh": "kk",
|
||||
"central khmer": "km",
|
||||
"kikuyu": "ki",
|
||||
"gikuyu": "ki",
|
||||
"kinyarwanda": "rw",
|
||||
"kirghiz": "ky",
|
||||
"kyrgyz": "ky",
|
||||
"komi": "kv",
|
||||
"kongo": "kg",
|
||||
"korean": "ko",
|
||||
"kuanyama": "kj",
|
||||
"kwanyama": "kj",
|
||||
"kurdish": "ku",
|
||||
"lao": "lo",
|
||||
"latin": "la",
|
||||
"latvian": "lv",
|
||||
"limburgan": "li",
|
||||
"limburger": "li",
|
||||
"limburgish": "li",
|
||||
"lingala": "ln",
|
||||
"lithuanian": "lt",
|
||||
"luxembourgish": "lb",
|
||||
"letzeburgesch": "lb",
|
||||
"luba-katanga": "lu",
|
||||
"ganda": "lg",
|
||||
"macedonian": "mk",
|
||||
"marshallese": "mh",
|
||||
"malayalam": "ml",
|
||||
"maori": "mi",
|
||||
"marathi": "mr",
|
||||
"malay": "ms",
|
||||
"malagasy": "mg",
|
||||
"maltese": "mt",
|
||||
"mongolian": "mn",
|
||||
"nauru": "na",
|
||||
"navajo": "nv",
|
||||
"navaho": "nv",
|
||||
"ndebele, south": "nr",
|
||||
"south ndebele": "nr",
|
||||
"ndebele, north": "nd",
|
||||
"north ndebele": "nd",
|
||||
"ndonga": "ng",
|
||||
"nepali": "ne",
|
||||
"norwegian nynorsk": "nn",
|
||||
"nynorsk, norwegian": "nn",
|
||||
"norwegian bokmål": "nb",
|
||||
"bokmål, norwegian": "nb",
|
||||
"norwegian": "no",
|
||||
"chichewa": "ny",
|
||||
"chewa": "ny",
|
||||
"nyanja": "ny",
|
||||
"occitan": "oc",
|
||||
"ojibwa": "oj",
|
||||
"oriya": "or",
|
||||
"oromo": "om",
|
||||
"ossetian": "os",
|
||||
"ossetic": "os",
|
||||
"panjabi": "pa",
|
||||
"punjabi": "pa",
|
||||
"pali": "pi",
|
||||
"polish": "pl",
|
||||
"portuguese": "pt",
|
||||
"pushto": "ps",
|
||||
"pashto": "ps",
|
||||
"quechua": "qu",
|
||||
"romansh": "rm",
|
||||
"romanian": "ro",
|
||||
"moldavian": "ro",
|
||||
"moldovan": "ro",
|
||||
"rundi": "rn",
|
||||
"russian": "ru",
|
||||
"sango": "sg",
|
||||
"sanskrit": "sa",
|
||||
"sinhala": "si",
|
||||
"sinhalese": "si",
|
||||
"slovak": "sk",
|
||||
"slovenian": "sl",
|
||||
"northern sami": "se",
|
||||
"samoan": "sm",
|
||||
"shona": "sn",
|
||||
"sindhi": "sd",
|
||||
"somali": "so",
|
||||
"sotho, southern": "st",
|
||||
"spanish": "es",
|
||||
"castilian": "es",
|
||||
"sardinian": "sc",
|
||||
"serbian": "sr",
|
||||
"swati": "ss",
|
||||
"sundanese": "su",
|
||||
"swahili": "sw",
|
||||
"swedish": "sv",
|
||||
"tahitian": "ty",
|
||||
"tamil": "ta",
|
||||
"tatar": "tt",
|
||||
"telugu": "te",
|
||||
"tajik": "tg",
|
||||
"tagalog": "tl",
|
||||
"thai": "th",
|
||||
"tigrinya": "ti",
|
||||
"tonga": "to",
|
||||
"tswana": "tn",
|
||||
"tsonga": "ts",
|
||||
"turkmen": "tk",
|
||||
"turkish": "tr",
|
||||
"twi": "tw",
|
||||
"uighur": "ug",
|
||||
"uyghur": "ug",
|
||||
"ukrainian": "uk",
|
||||
"urdu": "ur",
|
||||
"uzbek": "uz",
|
||||
"venda": "ve",
|
||||
"vietnamese": "vi",
|
||||
"volapük": "vo",
|
||||
"walloon": "wa",
|
||||
"wolof": "wo",
|
||||
"xhosa": "xh",
|
||||
"yiddish": "yi",
|
||||
"yoruba": "yo",
|
||||
"zhuang": "za",
|
||||
"chuang": "za",
|
||||
"zulu": "zu"
|
||||
};
|
||||
|
||||
// Relevant ISO: ISO 639-1 & ISO 639-2. Google uses the ISO 639-1.
|
||||
// Valid ISO 639-1 codes
|
||||
// https://www.loc.gov/standards/iso639-2/php/code_list.php
|
||||
// Extract these with this code (after loading https://superdom.site/ )
|
||||
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map((row, i) => `"${row.querySelector('td:nth-child(2)').textContent}", ${i % 12 === 11 ? '\n' : ''}`).join('');
|
||||
// Parsed from here: https://github.com/wooorm/iso-639-2/blob/master/index.json
|
||||
// Extract these with this code (after loading https://superdom.site/ ) + a lot of manual clean up
|
||||
// [...dom.table[1].querySelectorAll('tbody tr')].slice(1).filter(row => !/^\s*$/.test(row.querySelector('td:nth-child(2)').textContent)).map(row =>
|
||||
// ` "${row.querySelector('td:nth-child(3)').textContent.toLowerCase()}": "${row.querySelector('td:nth-child(2)').textContent.toLowerCase()}",`
|
||||
// ).join('\n');
|
||||
// Language parser
|
||||
// @name: a string to be parsed
|
||||
// @output: the normalized language string
|
||||
var language = name => {
|
||||
|
||||
// Validate the name string
|
||||
if (typeof name !== 'string') {
|
||||
throw new Error(`The language must be a string, received ${typeof name}`);
|
||||
}
|
||||
// Possible overflow errors
|
||||
if (name.length > 100) {
|
||||
throw new Error(`The language must be a string under 100 characters, received ${name.length}`);
|
||||
}
|
||||
|
||||
// Let's work with lowercase for everything
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Pass it through several possible maps to try to find the right one
|
||||
name = map[name] || iso2[name] || name;
|
||||
|
||||
// Make sure we have the correct name or throw
|
||||
if (!iso.includes(name)) {
|
||||
throw new Error(`The name "${name}" is not part of the ISO 639-1 and we couldn't automatically parse it :(`);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
// Translation engines
|
||||
// Handle different translations differently to allow for extra flexibility
|
||||
|
||||
|
||||
const google = {
|
||||
needkey: true,
|
||||
fetch: ({ key, from, to, text }) => [
|
||||
`https://translation.googleapis.com/language/translate/v2?key=${key}&format=text&source=${from}&target=${to}&q=${encodeURIComponent(text)}`,
|
||||
{ method: 'POST' }
|
||||
],
|
||||
parse: res => res.json().then(body => {
|
||||
if (body.error) {
|
||||
throw new Error(body.error.errors[0].message);
|
||||
}
|
||||
body = body.data.translations[0];
|
||||
if (!body) {
|
||||
throw new Error('Translation not found');
|
||||
}
|
||||
return body.translatedText;
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
const yandex = {
|
||||
needkey: true,
|
||||
fetch: ({ key, from, to, text }) => [
|
||||
`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${key}&lang=${from}-${to}&text=${encodeURIComponent(text)}`,
|
||||
{ method: 'POST', body: '' }
|
||||
],
|
||||
parse: res => res.json().then(body => {
|
||||
if (body.code !== 200) {
|
||||
throw new Error(body.message);
|
||||
}
|
||||
return body.text[0];
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
var engines = { google, yandex };
|
||||
|
||||
// From https://www.npmjs.com/package/memory-cache (Rollup didn't want to bundle it otherwise)
|
||||
'use strict';
|
||||
|
||||
function Cache () {
|
||||
var _cache = Object.create(null);
|
||||
var _hitCount = 0;
|
||||
var _missCount = 0;
|
||||
var _size = 0;
|
||||
var _debug = false;
|
||||
|
||||
this.put = function(key, value, time, timeoutCallback) {
|
||||
if (_debug) {
|
||||
console.log('caching: %s = %j (@%s)', key, value, time);
|
||||
}
|
||||
|
||||
if (typeof time !== 'undefined' && (typeof time !== 'number' || isNaN(time) || time <= 0)) {
|
||||
throw new Error('Cache timeout must be a positive number');
|
||||
} else if (typeof timeoutCallback !== 'undefined' && typeof timeoutCallback !== 'function') {
|
||||
throw new Error('Cache timeout callback must be a function');
|
||||
}
|
||||
|
||||
var oldRecord = _cache[key];
|
||||
if (oldRecord) {
|
||||
clearTimeout(oldRecord.timeout);
|
||||
} else {
|
||||
_size++;
|
||||
}
|
||||
|
||||
var record = {
|
||||
value: value,
|
||||
expire: time + Date.now()
|
||||
};
|
||||
|
||||
if (!isNaN(record.expire)) {
|
||||
record.timeout = setTimeout(function() {
|
||||
_del(key);
|
||||
if (timeoutCallback) {
|
||||
timeoutCallback(key, value);
|
||||
}
|
||||
}.bind(this), time);
|
||||
}
|
||||
|
||||
_cache[key] = record;
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
this.del = function(key) {
|
||||
var canDelete = true;
|
||||
|
||||
var oldRecord = _cache[key];
|
||||
if (oldRecord) {
|
||||
clearTimeout(oldRecord.timeout);
|
||||
if (!isNaN(oldRecord.expire) && oldRecord.expire < Date.now()) {
|
||||
canDelete = false;
|
||||
}
|
||||
} else {
|
||||
canDelete = false;
|
||||
}
|
||||
|
||||
if (canDelete) {
|
||||
_del(key);
|
||||
}
|
||||
|
||||
return canDelete;
|
||||
};
|
||||
|
||||
function _del(key){
|
||||
_size--;
|
||||
delete _cache[key];
|
||||
}
|
||||
|
||||
this.clear = function() {
|
||||
for (var key in _cache) {
|
||||
clearTimeout(_cache[key].timeout);
|
||||
}
|
||||
_size = 0;
|
||||
_cache = Object.create(null);
|
||||
if (_debug) {
|
||||
_hitCount = 0;
|
||||
_missCount = 0;
|
||||
}
|
||||
};
|
||||
|
||||
this.get = function(key) {
|
||||
var data = _cache[key];
|
||||
if (typeof data != "undefined") {
|
||||
if (isNaN(data.expire) || data.expire >= Date.now()) {
|
||||
if (_debug) _hitCount++;
|
||||
return data.value;
|
||||
} else {
|
||||
// free some space
|
||||
if (_debug) _missCount++;
|
||||
_size--;
|
||||
delete _cache[key];
|
||||
}
|
||||
} else if (_debug) {
|
||||
_missCount++;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.size = function() {
|
||||
return _size;
|
||||
};
|
||||
|
||||
this.memsize = function() {
|
||||
var size = 0,
|
||||
key;
|
||||
for (key in _cache) {
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
};
|
||||
|
||||
this.debug = function(bool) {
|
||||
_debug = bool;
|
||||
};
|
||||
|
||||
this.hits = function() {
|
||||
return _hitCount;
|
||||
};
|
||||
|
||||
this.misses = function() {
|
||||
return _missCount;
|
||||
};
|
||||
|
||||
this.keys = function() {
|
||||
return Object.keys(_cache);
|
||||
};
|
||||
|
||||
this.exportJson = function() {
|
||||
var plainJsCache = {};
|
||||
|
||||
// Discard the `timeout` property.
|
||||
// Note: JSON doesn't support `NaN`, so convert it to `'NaN'`.
|
||||
for (var key in _cache) {
|
||||
var record = _cache[key];
|
||||
plainJsCache[key] = {
|
||||
value: record.value,
|
||||
expire: record.expire || 'NaN',
|
||||
};
|
||||
}
|
||||
|
||||
return JSON.stringify(plainJsCache);
|
||||
};
|
||||
|
||||
this.importJson = function(jsonToImport, options) {
|
||||
var cacheToImport = JSON.parse(jsonToImport);
|
||||
var currTime = Date.now();
|
||||
|
||||
var skipDuplicates = options && options.skipDuplicates;
|
||||
|
||||
for (var key in cacheToImport) {
|
||||
if (cacheToImport.hasOwnProperty(key)) {
|
||||
if (skipDuplicates) {
|
||||
var existingRecord = _cache[key];
|
||||
if (existingRecord) {
|
||||
if (_debug) {
|
||||
console.log('Skipping duplicate imported key \'%s\'', key);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var record = cacheToImport[key];
|
||||
|
||||
// record.expire could be `'NaN'` if no expiry was set.
|
||||
// Try to subtract from it; a string minus a number is `NaN`, which is perfectly fine here.
|
||||
var remainingTime = record.expire - currTime;
|
||||
|
||||
if (remainingTime <= 0) {
|
||||
// Delete any record that might exist with the same key, since this key is expired.
|
||||
this.del(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remaining time must now be either positive or `NaN`,
|
||||
// but `put` will throw an error if we try to give it `NaN`.
|
||||
remainingTime = remainingTime > 0 ? remainingTime : undefined;
|
||||
|
||||
this.put(key, record.value, remainingTime);
|
||||
}
|
||||
}
|
||||
|
||||
return this.size();
|
||||
};
|
||||
}
|
||||
|
||||
const exp$2 = new Cache();
|
||||
exp$2.Cache = Cache;
|
||||
|
||||
// translate.js
|
||||
// Translate text into different languages;
|
||||
|
||||
// Load a language parser to allow for more flexibility in the language choice
|
||||
// Load the default engines for translation
|
||||
// Cache the different translations to avoid resending requests
|
||||
// Main function
|
||||
const Translate = function(options = {}) {
|
||||
if (!(this instanceof Translate)) {
|
||||
return new Translate(options);
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
from: "en",
|
||||
to: "en",
|
||||
cache: undefined,
|
||||
language: language,
|
||||
engines: engines,
|
||||
engine: "google",
|
||||
keys: {}
|
||||
};
|
||||
|
||||
const translate = (text, opts = {}) => {
|
||||
// Load all of the appropriate options (verbose but fast)
|
||||
// Note: not all of those *should* be documented since some are internal only
|
||||
if (typeof opts === "string") opts = { to: opts };
|
||||
opts.text = text;
|
||||
opts.from = language(opts.from || translate.from);
|
||||
opts.to = language(opts.to || translate.to);
|
||||
opts.cache = opts.cache || translate.cache;
|
||||
opts.engines = opts.engines || {};
|
||||
opts.engine = opts.engine || translate.engine;
|
||||
opts.id = opts.id || `${opts.from}:${opts.to}:${opts.engine}:${opts.text}`;
|
||||
opts.keys = opts.keys || translate.keys || {};
|
||||
for (let name in translate.keys) {
|
||||
// The options has stronger preference than the global value
|
||||
opts.keys[name] = opts.keys[name] || translate.keys[name];
|
||||
}
|
||||
opts.key = opts.key || translate.key || opts.keys[opts.engine];
|
||||
|
||||
// TODO: validation for few of those
|
||||
|
||||
// Use the desired engine
|
||||
const engine = opts.engines[opts.engine] || translate.engines[opts.engine];
|
||||
|
||||
// If it is cached return ASAP
|
||||
const cached = exp$2.get(opts.id);
|
||||
if (cached) return Promise.resolve(cached);
|
||||
|
||||
// Target is the same as origin, just return the string
|
||||
if (opts.to === opts.from) {
|
||||
return Promise.resolve(opts.text);
|
||||
}
|
||||
|
||||
// Will load only for Node.js and use the native function on the browser
|
||||
if (typeof fetch === "undefined") {
|
||||
try {
|
||||
global.fetch = require("node-fetch");
|
||||
} catch (error) {
|
||||
console.warn("Please make sure node-fetch is available");
|
||||
}
|
||||
}
|
||||
|
||||
if (engine.needkey && !opts.key) {
|
||||
throw new Error(
|
||||
`The engine "${opts.engine}" needs a key, please provide it`
|
||||
);
|
||||
}
|
||||
|
||||
const fetchOpts = engine.fetch(opts);
|
||||
return fetch(...fetchOpts)
|
||||
.then(engine.parse)
|
||||
.then(translated => exp$2.put(opts.id, translated, opts.cache));
|
||||
};
|
||||
|
||||
for (let key in defaults) {
|
||||
translate[key] =
|
||||
typeof options[key] === "undefined" ? defaults[key] : options[key];
|
||||
}
|
||||
return translate;
|
||||
};
|
||||
|
||||
// Small hack needed for Webpack/Babel: https://github.com/webpack/webpack/issues/706
|
||||
const exp = new Translate();
|
||||
exp.Translate = Translate;
|
||||
|
||||
return exp;
|
||||
|
||||
})));
|
||||
1
node_modules/translate/translate.min.js
generated
vendored
Normal file
1
node_modules/translate/translate.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user