Flags: |
@@ -401,6 +445,8 @@ By using this website and API you are agreeing to
+ Note: Only Unicode characters in the range U+0000 to U+0FFF are allowed (more info)
+
@@ -410,12 +456,14 @@ By using this website and API you are agreeing to
+ ?format=format
This parameter is global - it can be used on every single endpoint of (excluding the documentation and static content).
It is used to change the response format from the default (JSON) to (Loading...), depending on what you need.
If the format parameter is invalid or not specified at all, the default value of JSON will be used.
Available formats are (Loading...)
Example 1 (click to view)
URL: /joke/Any?format=xml
+
<data>
<category>Programming</category>
@@ -428,7 +476,8 @@ By using this website and API you are agreeing to
<racist>false</racist>
<sexist>false</sexist>
</flags>
- <id>12</id>
+ <id>12</id>
+ <lang>en</lang>
</data>
@@ -445,6 +494,7 @@ By using this website and API you are agreeing to
+ ?blacklistFlags=flag1[,flag2,...]
This parameter can only be used on the "joke" endpoint.
If it is used, jokes that match the specified flag(s) will not be served (what is a flag?).
If you want to use multiple flags, separate them with a comma (,) or a plus sign (+).
@@ -461,8 +511,31 @@ By using this website and API you are agreeing to
+
+
+ ?lang=langcode
+ This parameter can be used on every endpoint, but it is possible that no translations or jokes exist yet for your language.
+
+ There are two types of languages; system languages and joke languages. Both are separate from each other.
+ All system messages like errors can have a certain system language, while jokes can only have a joke language.
+ It is possible, that system languages don't yet exist for your language while jokes already do.
+ If no suitable system language is found, will default to English.
+
+ If you are interested in providing translations, please read the Contributing Guide; it will explain it.
+ You can also submit jokes in different languages. Please understand that I will not be able to ensure their proper formatting or legitimacy.
+
+ Currently available system languages: (Loading...)
+ Currently available joke languages: (Loading...)
+
+ Example 1 (click to view)
+ URL: /joke/Any?lang=ru
+ Using the above URL will fetch only jokes that are Russian. If an error gets returned, it will also be in Russian, provided a translation was found.
+
+
+
+ ?type=type
This parameter can only be used on the "joke" endpoint.
If it is set, you will only receive jokes with the specified joke type (what is a joke type?).
If it is not set or set to an invalid value, you will receive jokes of both types.
@@ -483,7 +556,8 @@ By using this website and API you are agreeing to
"racist": false,
"sexist": false
},
- "id": 58
+ "id": 58,
+ "lang": "en"
}
(no jokes with type "single" will be served)
@@ -492,9 +566,10 @@ By using this website and API you are agreeing to
+ ?contains=string
This parameter can only be used on the "joke" endpoint.
If this parameter is specified, only jokes that contain the value of this parameter will be served (case insensitive).
- IMPORTANT: If the value of this parameter contains special characters, it needs to be percent-encoded according to the URI standard (MDN Reference), otherwise you might get an error or a wrong response.
+ IMPORTANT: If the value of this parameter contains special characters, it needs to be percent-encoded according to the URI syntax standard, otherwise you might get an error or a wrong response.
Example (click to view)
URL: /joke/Any?contains=C%23 (%23 = pound character / hashtag / # - so the thing searched for here is "C#")
@@ -511,7 +586,8 @@ By using this website and API you are agreeing to
"racist": false,
"sexist": false
},
- "id": 51
+ "id": 51,
+ "lang": "en"
}
@@ -519,6 +595,7 @@ By using this website and API you are agreeing to
+ ?idRange=number[-number]
This parameter can only be used on the "joke" endpoint.
If it is used, you will only get jokes that are inside the specified range of IDs.
The lower and upper boundary of the ID range needs to be delimited with a minus (-), comma (,) or a plus sign (+).
@@ -536,6 +613,43 @@ By using this website and API you are agreeing to
+
+
+
+ ?amount=number
+ This parameter can only be used on the "joke" endpoint.
+ If it is used, you will get a certain number of jokes in a single request.
+ If has less jokes than demanded, it will not error out but instead send the maximum amount of jokes it can serve.
+ Maximum possible number is and using an invalid value will make default to 1.
+ The joke format will change from the default when you set the amount parameter to 2 or more.
+
+
+ Click to view the format when fetching multiple jokes
+
+{
+ "error": false,
+ "jokes": [
+ {
+ "category": "Miscellaneous",
+ "type": "single",
+ ...
+ },
+ ...
+ ],
+ "amount": 10
+}
+
+
+
+
+
+ Example (click to view)
+ URL: /joke/Any?amount=5
+ Using the above URL will make serve you five jokes at once.
+
+
+
+
In all response data, no matter from which endpoint will have a boolean "error" parameter.
@@ -546,6 +660,7 @@ By using this website and API you are agreeing to
The "message" parameter will contain a short version of the error message and the "timestamp" parameter will contain a 13-character Unix timestamp.
The "causedBy" parameter is an array of possible causes of this error and the "addidionalInfo" parameter contains a more descriptive error message.
+ If possible, will try to translate the error messages but keep in mind there might not exist a translation for your language yet or it is not 100% perfect.
You can view an example of an error, where an invalid category was used, just below this paragraph.
Together with the HTTP status code, which will also be set according to the type of error, these parameters can be used to improve error handling massively from what was the error system in previous versions of .
@@ -558,13 +673,14 @@ By using this website and API you are agreeing to
"causedBy": [
"No jokes were found that match your provided filter(s)"
],
- "additionalInfo": "The specified category is invalid - Got: \"foo\" - Possible categories are: \"Any, Miscellaneous, Programming, Dark\" (case insensitive)",
+ "additionalInfo": "The specified category is invalid - Got: \"foo\" - Possible categories are: \"Any, Miscellaneous, Programming, Dark, Pun\" (case insensitive)",
"timestamp": 1579170794412
}
+
Code |
Name |
@@ -629,6 +745,21 @@ By using this website and API you are agreeing to
+
+
+
+ First, please check if you can access all endpoints with your web browser. If not, your IP address has most likely been acting malicious and was permanently blacklisted.
+ If you keep getting HTTP 403 (Forbidden) response codes in your program but not in your browser and have never shown malicious behavior before, the issue is most likely that Cloudflare is blocking your request.
+ This might be due to inconsistent request data or headers that are often used in malicious requests or cyber attacks (most of the time it's gonna be the fault of the library you are using).
+ A fix to this issue would be to explicitly set a User-Agent header in each of your requests.
+ This is the user agent of your browser which you should be able to use in the fix described above:
+ (Something didn't work, please enter "navigator.userAgent" without quotes in your JavaScript console instead)
+
+
+ You will get 429 errors occasionally if you exceed the maximum of requests per minute.
+ In this case, you will need to wait up to one minute to be able to talk to the API again.
+ If you want to index the API or fetch all jokes, are better off going to the GitHub repository, where you will find everything you need and you don't need to spam .
+
@@ -648,11 +779,11 @@ By using this website and API you are agreeing to
These are all the available categories: (Loading...)
To see how this URL is built with certain parameters set, visit the "Try It" section.
- Example - click to view
+ Full example - click to view
- /joke/Programming,Miscellaneous?format=xml&blacklistFlags=nsfw,sexist&type=single
+ /joke/Programming,Miscellaneous?format=xml&blacklistFlags=nsfw,sexist&type=single&lang=ru&amount=2
- Will give a joke from either the Programming or the Miscellaneous category, with the payload format XML,
+ Will give two Russian joke from either the Programming or the Miscellaneous category, with the payload format XML,
with the joke type "single", while also preventing all jokes that are potentially not safe for work and sexist from being served.
@@ -660,9 +791,11 @@ By using this website and API you are agreeing to
(More info on filtering parameters)
@@ -681,12 +814,14 @@ By using this website and API you are agreeing to
- All the available categories, flags, types and formats
- A 13-character UNIX timestamp
- The URL to a joke submission form
+ - A list of languages (code and name) JokeAPI currently supports
- The minimum and maximum values of an ID range
- A string with some information, like a message of the day
Supported URL parameters:
@@ -703,6 +838,103 @@ By using this website and API you are agreeing to
Supported URL parameters:
+
+
+
+
+
+
+ GET
+ /langcode/[Language]
+
+
+ This endpoint returns the language code of a provided language. It is searched with a fuzzy search, so you just have to provide the approximate language name.
+ This language code is to be used in fetching and submitting jokes in different languages.
+
+
+ Example 1 - click to view
+
+
+ /langcode/german
+
+
+{
+ "error": false,
+ "code": "de"
+}
+
+
+
+
+ Example 2 - click to view
+
+
+ /langcode/sw3d1sh
+
+
+{
+ "error": false,
+ "code": "sv"
+}
+
+
+
+ Supported URL parameters:
+
+
+
+
+
+
+
+ GET
+ /languages
+
+
+ This endpoint returns lists of supported languages in jokes and supported languages in system messages (error messages).
+ Also, it returns a list of possible language values you can use to submit a joke or add a translation.
+
+ Example - click to view
+
+
+ /languages
+
+
+{
+ "defaultLanguage": "en",
+ "jokeLanguages": [
+ "de",
+ "en"
+ ],
+ "systemLanguages": [
+ "de",
+ "en",
+ "ru"
+ ],
+ "possibleLanguages": [
+ {
+ "code": "aa",
+ "name": "Afar"
+ },
+ {
+ ...
+ },
+ ...
+ ],
+ "timestamp": 1590929517702
+}
+
+
+
+ Supported URL parameters:
+
@@ -719,6 +951,7 @@ By using this website and API you are agreeing to
Supported URL parameters:
@@ -735,6 +968,7 @@ By using this website and API you are agreeing to
Supported URL parameters:
@@ -752,6 +986,7 @@ By using this website and API you are agreeing to
Supported URL parameters:
@@ -762,9 +997,12 @@ By using this website and API you are agreeing to
GET
/endpoints
-
- This endpoint returns a list / an array of all available endpoints, their usage (method, url and supported parameters) and a short description each.
-
+
+
+ This endpoint returns a list / an array of all available endpoints, their usage (method, url and supported parameters) and a short description each.
+ Note: the lang parameter will not work here due to JokeAPI's fundamental architecture not allowing it.
+
+
Supported URL parameters:
- ?format
@@ -784,8 +1022,8 @@ By using this website and API you are agreeing to
The payload needs to be sent as JSON. Different formats are not allowed here.
The request payload has to follow the same object structure that the jokes are served in when using the "joke" endpoint.
- Make sure to add a "formatVersion" property, which just contains the current joke format version ().
- This is needed since there were a few changes to the object format since the previous versions and this ensures consistency.
+ Make sure to add a "formatVersion" property, though, which just contains the current joke format version ().
+ This is needed since there were a few changes to the object format since the previous versions and this serves as a kind of acknowledgement.
The joke category has to be any valid category, excluding "Any".
If the joke type is set to "single", the properties "setup" and "delivery" will need to be omitted and the joke is to be put in the "joke" property.
@@ -808,7 +1046,8 @@ By using this website and API you are agreeing to
"political": true,
"racist": false,
"sexist": false
- }
+ },
+ "lang": "en"
}
@@ -833,7 +1072,8 @@ By using this website and API you are agreeing to
"political": true,
"racist": false,
"sexist": false
- }
+ },
+ "lang": "en"
},
"timestamp": 1579685839560
}
@@ -855,6 +1095,7 @@ By using this website and API you are agreeing to
- Joke Type
- Search String
- ID Range
+ - Language
@@ -879,7 +1120,7 @@ By using this website and API you are agreeing to
const https = require("https"); // Native module, no need to explicitly install
const baseURL = "";
-const categories = ["Programming", "Miscellaneous"];
+const categories = ["Programming", "Miscellaneous", "Pun"];
const params = [
"blacklistFlags=nsfw,religious,racist",
"idRange=0-100"
@@ -920,7 +1161,7 @@ By using this website and API you are agreeing to
Web-JavaScript (click to show)
var baseURL = "";
-var categories = ["Programming", "Miscellaneous"];
+var categories = ["Programming", "Miscellaneous", "Pun"];
var params = [
"blacklistFlags=nsfw,religious,racist",
"idRange=0-100"
@@ -968,7 +1209,7 @@ By using this website and API you are agreeing to
private void getJoke()
{
string baseURL = "";
- string[] categories = { "Programming", "Miscellaneous" };
+ string[] categories = { "Programming", "Miscellaneous", "Pun" };
string[] parameters = {
"blacklistFlags=nsfw,religious,racist",
"idRange=0-100"
@@ -986,7 +1227,7 @@ By using this website and API you are agreeing to
// Deserialize the string into an object of the Joke class
JavaScriptSerializer ser = new JavaScriptSerializer();
- Joke randomJoke = ser.Deserialize(responseFromServer);
+ Joke randomJoke = ser.Deserialize<Joke>(responseFromServer);
if (randomJoke.type == "single")
{
@@ -1082,6 +1323,15 @@ By using this website and API you are agreeing to
As there are currently jokes, the ID range can be anywhere in the range of 0 to
+
+
+ This filter allows you to set a certain amount of jokes to receive in a single call to the "Get Joke" endpoint.
+ You can set it using the ?amount URL parameter.
+ Setting the filter to an invalid number will result in the API defaulting to serving a single joke.
+ Setting it to a number larger than will make default to the maximum ().
+ If you request more than jokes, the API will try to serve them encoded with Brotli, Gzip or Deflate, depending on whether or not you set a Accept-Encoding header.
+
+
@@ -1110,7 +1360,7 @@ By using this website and API you are agreeing to
Additionally, I will only be able to provide security updates for a small selection of versions, a list of which you can find here.
I am doing my best to ensure security and stability but there's only so much a single developer can do.
Please report any issue that may arise to the GitHub issue tracker and I will try my best to fix it as soon as possible.
- If you want to contact me, you can join my Discord server (fastest way to contact me) or send me an E-Mail at sven.fehler@web.de
+ If you want to contact me, you can join my Discord server (fastest way to contact me) or send me an E-Mail: (click to show)
@@ -1138,16 +1388,22 @@ By using this website and API you are agreeing to
These are the packages depends on (excluding dependencies of dependencies and devDependencies):
+ - @pm2/io
- dotenv
- farmhash
+ - fs-extra
+ - fuse.js
+ - http-ratelimit
- js2xmlparser
- json-to-pretty-yaml
- - MySQL
+ - mysql
- node-wrap
- promise-all-sequential
- rate-limiter-flexible
- request-ip
- - JSLib
+ - snyk
+ - svjsl
+ - url-parse
- xss
",
+ // baseURL: "",
+ baseURL: "http://127.0.0.1:8076/", // DEBUG
jokeEndpoint: "joke",
anyCategoryName: "Any",
defaultFormat: "json",
- submitUrl: "/submit"
+ // submitUrl: "/submit",
+ submitUrl: "http://127.0.0.1:8076/submit",
+ defaultLang: "en",
+ formatVersion: 3
};
var submission = {};
@@ -182,22 +186,22 @@ function onLoad()
fileFormats.splice(fileFormats.indexOf("JSON"), 1);
}
Array.from(document.getElementsByClassName("insFormatsS")).forEach(function(el) {
- el.innerHTML = fileFormats.join(" and ");
+ el.innerText = fileFormats.join(" and ");
});
var flags = JSON.parse('');
Array.from(document.getElementsByClassName("insFlags")).forEach(function(el) {
- el.innerHTML = flags.join(", ");
+ el.innerText = flags.join(", ");
});
var formats = JSON.parse('');
Array.from(document.getElementsByClassName("insFormats")).forEach(function(el) {
- el.innerHTML = formats.join(", ").toLowerCase();
+ el.innerText = formats.join(", ").toLowerCase();
});
var categories = JSON.parse('');
Array.from(document.getElementsByClassName("insCategories")).forEach(function(el) {
- el.innerHTML = categories.join(", ");
+ el.innerText = categories.join(", ");
});
}
catch(err)
@@ -215,12 +219,13 @@ function onLoad()
"f_flags_racist",
"f_flags_sexist",
"f_setup",
- "f_delivery"
+ "f_delivery",
+ "f_language"
];
for(var ii = 0; ii < inputElems.length; ii++)
{
- var elm = document.getElementById(inputElems[ii]);
+ var elm = gebid(inputElems[ii]);
if(elm.tagName.toLowerCase() != "textarea")
{
@@ -238,11 +243,108 @@ function onLoad()
}
}
- document.getElementById("submitBtn").addEventListener("click", function() {
+ var langXhr = new XMLHttpRequest();
+ var langUrl = settings.baseURL + "/languages";
+ var langSelectElems = document.getElementsByClassName("appendLangOpts");
+
+ var otherOpt = document.createElement("option");
+ otherOpt.innerText = "Other / Custom";
+ otherOpt.value = "other";
+ gebid("f_language").appendChild(otherOpt);
+
+ var sysLangsText = "";
+ var jokeLangsText = "";
+
+ langXhr.open("GET", langUrl);
+ langXhr.onreadystatechange = function() {
+ var xErrElem;
+ if(langXhr.readyState == 4 && langXhr.status < 300)
+ {
+ var respJSON = JSON.parse(langXhr.responseText.toString());
+ var languagesArray = respJSON.jokeLanguages;
+
+ sysLangsText = respJSON.systemLanguages.join(", ");
+ jokeLangsText = respJSON.jokeLanguages.join(", ");
+
+ for(var i = 0; i < languagesArray.length; i++)
+ {
+ for(var j = 0; j < langSelectElems.length; j++)
+ {
+ var langName = "";
+
+ for(var k = 0; k < respJSON.possibleLanguages.length; k++)
+ {
+ if(respJSON.possibleLanguages[k].code == languagesArray[i])
+ {
+ langName = respJSON.possibleLanguages[k].name;
+ }
+ }
+
+ xErrElem = document.createElement("option");
+ xErrElem.value = languagesArray[i];
+ if(languagesArray[i] == settings.defaultLang)
+ {
+ xErrElem.selected = true;
+ }
+ xErrElem.innerText = languagesArray[i] + " - " + langName;
+
+ if(languagesArray[i] == settings.defaultLang)
+ xErrElem.selected = true;
+
+ langSelectElems[j].appendChild(xErrElem);
+ langSelectElems[j].value = settings.defaultLang;
+ }
+ }
+
+ var sysLangsElems = document.getElementsByClassName("insSysLangs");
+ var jokeLangsElems = document.getElementsByClassName("insJokeLangs");
+
+ for(var sI = 0; sI < sysLangsElems.length; sI++)
+ {
+ sysLangsElems[sI].innerText = sysLangsText;
+ }
+
+ for(var jI = 0; jI < sysLangsElems.length; jI++)
+ {
+ jokeLangsElems[jI].innerText = jokeLangsText;
+ }
+ }
+ else if(langXhr.readyState == 4 && langXhr.status >= 300)
+ {
+ for(var ii = 0; ii < langSelectElems.length; ii++)
+ {
+ xErrElem = document.createElement("option");
+ xErrElem.value = "en";
+ xErrElem.innerText = "en - English";
+ xErrElem.selected = true;
+
+ langSelectElems[ii].appendChild(xErrElem);
+ }
+ }
+ };
+ langXhr.send();
+
+ gebid("submitBtn").addEventListener("click", function() {
submitJoke();
});
buildSubmission();
+ setTimeout(function() { buildSubmission() }, 2000);
+
+ gebid("insUserAgent").innerText = navigator.userAgent;
+
+ var abElems = document.getElementsByClassName("antiBotE");
+ for(var l = 0; l < abElems.length; l++)
+ {
+ abElems[l].onclick = function()
+ {
+ if(!this.classList.contains("shown"))
+ {
+ this.innerText = atob(this.dataset.enc);
+ this.classList.add("shown");
+ }
+ }
+ }
}
function addCodeTabs()
@@ -339,14 +441,14 @@ function reRender()
if(el.value == "any")
{
isValid = true;
- ["cat-cb1", "cat-cb2", "cat-cb3"].forEach(function(cat) {
+ ["cat-cb1", "cat-cb2", "cat-cb3", "cat-cb4"].forEach(function(cat) {
gebid(cat).disabled = true;
});
}
else
{
var isChecked = false;
- ["cat-cb1", "cat-cb2", "cat-cb3"].forEach(function(cat) {
+ ["cat-cb1", "cat-cb2", "cat-cb3", "cat-cb4"].forEach(function(cat) {
var cel = gebid(cat);
cel.disabled = false;
@@ -401,6 +503,18 @@ function reRender()
gebid("idRangeWrapper").style.borderColor = "initial";
}
+ var jokesAmount = parseInt(gebid("jokesAmountInput").value);
+
+ if(jokesAmount > parseInt("") || jokesAmount < 1 || isNaN(jokesAmount))
+ {
+ allOk = false;
+ gebid("jokeAmountWrapper").style.borderColor = "red";
+ }
+ else
+ {
+ gebid("jokeAmountWrapper").style.borderColor = "initial";
+ }
+
if(allOk)
{
tryItOk = true;
@@ -435,6 +549,10 @@ function buildURL()
{
selectedCategories.push("Dark");
}
+ if(gebid("cat-cb4").checked)
+ {
+ selectedCategories.push("Pun");
+ }
if(selectedCategories.length == 0)
{
@@ -443,6 +561,12 @@ function buildURL()
}
+ //#SECTION language
+ var langCode = gebid("lcodeSelect").value || settings.defaultLang;
+ if(langCode != settings.defaultLang)
+ queryParams.push("lang=" + langCode);
+
+
//#SECTION flags
var flagElems = [gebid("blf-cb1"), gebid("blf-cb2"), gebid("blf-cb3"), gebid("blf-cb4"), gebid("blf-cb5")];
var flagNames = JSON.parse('');
@@ -511,6 +635,14 @@ function buildURL()
}
+ //#SECTION amount
+ var jokeAmount = parseInt(gebid("jokesAmountInput").value);
+ if(jokeAmount != 1 && !isNaN(jokeAmount) && jokeAmount > 0 && jokeAmount <= parseInt(""))
+ {
+ queryParams.push("amount=" + jokeAmount);
+ }
+
+
tryItURL = settings.baseURL + "/" + settings.jokeEndpoint + "/" + selectedCategories.join(",");
if(queryParams.length > 0)
@@ -518,12 +650,13 @@ function buildURL()
tryItURL += "?" + queryParams.join("&");
}
- gebid("urlBuilderUrl").innerHTML = tryItURL;
+ gebid("urlBuilderUrl").innerText = tryItURL;
}
//#MARKER send request
function sendTryItRequest()
{
+ var sendStartTimestamp = new Date().getTime();
var prpr = gebid("urlBuilderPrettyprint");
var tryItRequestError = function(err) {
if(prpr.classList.contains("prettyprint"))
@@ -601,7 +734,8 @@ function sendTryItRequest()
result = result.replace(/[>]/gm, ">");
}
- gebid("tryItResult").innerHTML = result;
+ gebid("tryItResult").innerText = result;
+ gebid("tryItFormLatency").innerText = "Latency: " + (new Date().getTime() - sendStartTimestamp) + " ms";
PR.prettyPrint(); // eslint-disable-line no-undef
}
@@ -621,7 +755,7 @@ function sendTryItRequest()
//#MARKER interactive elements
function resetTryItForm()
{
- ["cat-cb1", "cat-cb2", "cat-cb3"].forEach(function(cat) {
+ ["cat-cb1", "cat-cb2", "cat-cb3", "cat-cb4"].forEach(function(cat) {
gebid(cat).checked = false;
});
@@ -642,13 +776,15 @@ function resetTryItForm()
gebid("idRangeInputFrom").value = 0;
gebid("idRangeInputTo").value = parseInt("");
+ gebid("jokesAmountInput").value = 1;
+
reRender();
}
//#MARKER submit joke
function submitJoke()
{
- var submitBtn = document.getElementById("submitBtn");
+ var submitBtn = gebid("submitBtn");
if(submitBtn.disabled == true)
{
return;
@@ -670,8 +806,8 @@ function submitJoke()
alert(res.message);
- setTimeout(() => {
- document.getElementById("submitBtn").disabled = false;
+ setTimeout(function() {
+ gebid("submitBtn").disabled = false;
}, 2000);
}
else if(res.error == true)
@@ -700,15 +836,27 @@ function valChanged(element)
{
if(element.value == "single")
{
- document.getElementById("f_setup").placeholder = "Joke";
+ gebid("f_setup").placeholder = "Joke";
- document.getElementById("f_delivery").style.display = "none";
+ gebid("f_delivery").style.display = "none";
}
else if(element.value == "twopart")
{
- document.getElementById("f_setup").placeholder = "Setup";
+ gebid("f_setup").placeholder = "Setup";
+
+ gebid("f_delivery").style.display = "initial";
+ }
+ }
- document.getElementById("f_delivery").style.display = "initial";
+ if(element.id == "f_language")
+ {
+ if(element.value == "other")
+ {
+ gebid("f_langHideContainer").classList.remove("hidden");
+ }
+ else
+ {
+ gebid("f_langHideContainer").classList.add("hidden");
}
}
@@ -717,33 +865,53 @@ function valChanged(element)
function buildSubmission()
{
- var category = document.getElementById("f_category").value;
- var type = document.getElementById("f_type").value;
+ var category = gebid("f_category").value;
+ var type = gebid("f_type").value;
submission = {
- formatVersion: 2,
+ formatVersion: settings.formatVersion,
category: category,
- type: type,
- flags: {
- nsfw: document.getElementById("f_flags_nsfw").checked,
- religious: document.getElementById("f_flags_religious").checked,
- political: document.getElementById("f_flags_political").checked,
- racist: document.getElementById("f_flags_racist").checked,
- sexist: document.getElementById("f_flags_sexist").checked,
- }
+ type: type
}
if(type == "single")
{
- submission.joke = document.getElementById("f_setup").value;
+ submission.joke = gebid("f_setup").value;
}
else if(type == "twopart")
{
- submission.setup = document.getElementById("f_setup").value;
- submission.delivery = document.getElementById("f_delivery").value;
+ submission.setup = gebid("f_setup").value;
+ submission.delivery = gebid("f_delivery").value;
+ }
+
+ var sLang = gebid("f_language").value || settings.defaultLang;
+
+ if(sLang == "other")
+ {
+ var elVal = gebid("f_customLang").value;
+ if(elVal && elVal.length == 2)
+ {
+ sLang = elVal;
+ }
+ else
+ {
+ sLang = "Please enter 2 char language code";
+ }
}
- var subDisp = document.getElementById("submissionDisplay");
+ submission = {
+ ...submission,
+ flags: {
+ nsfw: gebid("f_flags_nsfw").checked,
+ religious: gebid("f_flags_religious").checked,
+ political: gebid("f_flags_political").checked,
+ racist: gebid("f_flags_racist").checked,
+ sexist: gebid("f_flags_sexist").checked,
+ },
+ lang: sLang
+ };
+
+ var subDisp = gebid("submissionDisplay");
var escapedSubmission = JSON.parse(JSON.stringify(submission)); // copy value without reference
if(type == "single")
@@ -755,9 +923,9 @@ function buildSubmission()
escapedSubmission.setup = htmlEscape(submission.setup);
escapedSubmission.delivery = htmlEscape(submission.delivery);
}
- subDisp.innerHTML = JSON.stringify(escapedSubmission, null, 4);
+ subDisp.innerText = JSON.stringify(escapedSubmission, null, 4);
- var subCodeElem = document.getElementById("submissionCodeElement");
+ var subCodeElem = gebid("submissionCodeElement");
if(!subCodeElem.classList.contains("prettyprint"))
{
@@ -875,4 +1043,4 @@ function unused(...args)
});
}
-unused(openNav, closeNav, onLoad, openChangelog, reRender, privPolMoreInfo, hideUsageTerms, sendTryItRequest, submitRestartForm);
\ No newline at end of file
+unused(openNav, closeNav, onLoad, openChangelog, reRender, privPolMoreInfo, hideUsageTerms, sendTryItRequest, submitRestartForm);
diff --git a/endpoints/categories.js b/endpoints/categories.js
index 655a6902..53f8b3f5 100755
--- a/endpoints/categories.js
+++ b/endpoints/categories.js
@@ -15,7 +15,8 @@ const meta = {
"method": "GET",
"url": `${settings.info.docsURL}/categories`,
"supportedParams": [
- "format"
+ "format",
+ "lang"
]
}
};
@@ -34,13 +35,15 @@ const call = (req, res, url, params, format) => {
let responseText = "";
let categories = [settings.jokes.possible.anyCategoryName, ...settings.jokes.possible.categories];
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
if(format != "xml")
{
responseText = convertFileFormat.auto(format, {
"error": false,
"categories": categories,
"timestamp": new Date().getTime()
- });
+ }, lang);
}
else if(format == "xml")
{
@@ -48,10 +51,10 @@ const call = (req, res, url, params, format) => {
"error": false,
"categories": {"category": categories},
"timestamp": new Date().getTime()
- });
+ }, lang);
}
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/endpoints.js b/endpoints/endpoints.js
index b7c20239..0fe7883f 100755
--- a/endpoints/endpoints.js
+++ b/endpoints/endpoints.js
@@ -2,8 +2,9 @@ const http = require("http");
const convertFileFormat = require("../src/fileFormatConverter");
const httpServer = require("../src/httpServer");
const parseURL = require("../src/parseURL");
+const languages = require("../src/languages");
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
const settings = require("../settings");
jsl.unused(http);
@@ -34,6 +35,8 @@ const call = (req, res, url, params, format) => {
let endpointList = [];
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
try
{
fs.readdir(settings.endpoints.dirPath, (err, files) => {
@@ -97,14 +100,19 @@ const call = (req, res, url, params, format) => {
}
catch(err)
{
- return epError(res, format, err);
+ return epError(res, format, err, lang);
}
};
-const epError = (res, format, err) => {
- let errFromRegistry = require("." + settings.errors.errorRegistryIncludePath)["100"];
-
+const epError = (res, format, err, lang) => {
let errObj = {};
+ let errFromRegistry = require("../data/errorMessages")["100"];
+
+ if(errFromRegistry == undefined)
+ throw new Error(`Couldn't find errorMessages module or Node is using an outdated, cached version`);
+
+ if(!lang || !languages.isValidLang(lang))
+ lang = settings.languages.defaultLanguage;
if(format != "xml")
{
@@ -112,8 +120,8 @@ const epError = (res, format, err) => {
"error": true,
"internalError": true,
"code": 100,
- "message": errFromRegistry.errorMessage,
- "causedBy": errFromRegistry.causedBy,
+ "message": errFromRegistry.errorMessage[lang] || errFromRegistry.errorMessage[settings.languages.defaultLanguage],
+ "causedBy": errFromRegistry.causedBy[lang] || errFromRegistry.causedBy[settings.languages.defaultLanguage],
"additionalInfo": err,
"timestamp": new Date().getTime()
}
@@ -124,14 +132,14 @@ const epError = (res, format, err) => {
"error": true,
"internalError": true,
"code": 100,
- "message": errFromRegistry.errorMessage,
- "causedBy": {"cause": errFromRegistry.causedBy},
+ "message": errFromRegistry.errorMessage[lang] || errFromRegistry.errorMessage[settings.languages.defaultLanguage],
+ "causedBy": { "cause": (errFromRegistry.causedBy[lang] || errFromRegistry.causedBy[settings.languages.defaultLanguage]) },
"additionalInfo": err,
"timestamp": new Date().getTime()
}
}
- httpServer.pipeString(res, convertFileFormat.auto(format, errObj), parseURL.getMimeTypeFromFileFormatString(format));
+ httpServer.pipeString(res, convertFileFormat.auto(format, errObj), parseURL.getMimeTypeFromFileFormatString(format), lang);
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/flags.js b/endpoints/flags.js
index 304a23fb..4f204337 100755
--- a/endpoints/flags.js
+++ b/endpoints/flags.js
@@ -15,7 +15,8 @@ const meta = {
"method": "GET",
"url": `${settings.info.docsURL}/flags`,
"supportedParams": [
- "format"
+ "format",
+ "lang"
]
}
};
@@ -33,13 +34,15 @@ const call = (req, res, url, params, format) => {
let responseText = "";
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
if(format != "xml")
{
responseText = convertFileFormat.auto(format, {
"error": false,
"flags": settings.jokes.possible.flags,
"timestamp": new Date().getTime()
- });
+ }, lang);
}
else if(format == "xml")
{
@@ -47,10 +50,10 @@ const call = (req, res, url, params, format) => {
"error": false,
"flags": {"flag": settings.jokes.possible.flags},
"timestamp": new Date().getTime()
- });
+ }, lang);
}
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/formats.js b/endpoints/formats.js
index cc91db92..dedbeab3 100755
--- a/endpoints/formats.js
+++ b/endpoints/formats.js
@@ -15,7 +15,8 @@ const meta = {
"method": "GET",
"url": `${settings.info.docsURL}/formats`,
"supportedParams": [
- "format"
+ "format",
+ "lang"
]
}
};
@@ -33,13 +34,15 @@ const call = (req, res, url, params, format) => {
let responseText = "";
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
if(format != "xml")
{
responseText = convertFileFormat.auto(format, {
"error": false,
"formats": settings.jokes.possible.formats,
"timestamp": new Date().getTime()
- });
+ }, lang);
}
else if(format == "xml")
{
@@ -47,10 +50,10 @@ const call = (req, res, url, params, format) => {
"error": false,
"formats": {"format": settings.jokes.possible.formats},
"timestamp": new Date().getTime()
- });
+ }, lang);
}
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/info.js b/endpoints/info.js
index 18b550ed..78f82e4d 100755
--- a/endpoints/info.js
+++ b/endpoints/info.js
@@ -4,7 +4,9 @@ const httpServer = require("../src/httpServer");
const parseURL = require("../src/parseURL");
const jsl = require("svjsl");
const parseJokes = require("../src/parseJokes");
+const languages = require("../src/languages");
const settings = require("../settings");
+const translate = require("../src/translate");
jsl.unused(http);
@@ -16,7 +18,8 @@ const meta = {
"method": "GET",
"url": `${settings.info.docsURL}/info`,
"supportedParams": [
- "format"
+ "format",
+ "lang"
]
}
};
@@ -32,7 +35,9 @@ const meta = {
const call = (req, res, url, params, format) => {
jsl.unused([req, url, params]);
- let errFromRegistry = require("." + settings.errors.errorRegistryIncludePath)["100"];
+ let supportedLangsLength = languages.jokeLangs().length;
+
+ let errFromRegistry = require("." + settings.errors.errorMessagesPath)["100"];
let responseText = {};
if(format != "xml")
{
@@ -58,6 +63,22 @@ const call = (req, res, url, params, format) => {
}
let totalJokesCount = (!jsl.isEmpty(parseJokes.jokeCount) ? parseJokes.jokeCount : 0);
+
+ let idRangePerLang = {};
+ let idRangePerLangXml = [];
+ Object.keys(parseJokes.jokeCountPerLang).forEach(lc => {
+ let to = (parseJokes.jokeCountPerLang[lc] - 1);
+ idRangePerLang[lc] = [ 0, to ];
+ idRangePerLangXml.push({
+ langCode: lc,
+ from: 0,
+ to: to
+ });
+ });
+
+ let systemLanguagesLength = translate.systemLangs().length;
+
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
if(format != "xml")
{
@@ -71,12 +92,14 @@ const call = (req, res, url, params, format) => {
"flags": settings.jokes.possible.flags,
"types": settings.jokes.possible.types,
"submissionURL": settings.jokes.jokeSubmissionURL,
- "idRange": [ 0, --totalJokesCount ]
+ "idRange": idRangePerLang
},
"formats": settings.jokes.possible.formats,
- "info": settings.info.infoMsg,
+ "jokeLanguages": supportedLangsLength,
+ "systemLanguages": systemLanguagesLength,
+ "info": translate(lang, "messageOfTheDay", settings.info.name),
"timestamp": new Date().getTime()
- });
+ }, lang);
}
else if(format == "xml")
{
@@ -90,12 +113,14 @@ const call = (req, res, url, params, format) => {
"flags": {"flag": settings.jokes.possible.flags},
"types": {"type": settings.jokes.possible.types},
"submissionURL": settings.jokes.jokeSubmissionURL,
- "idRange": [ 0, --totalJokesCount ]
+ "idRanges": { "idRange": idRangePerLangXml }
},
"formats": {"format": settings.jokes.possible.formats},
- "info": settings.info.infoMsg,
+ "jokeLanguages": supportedLangsLength,
+ "systemLanguages": systemLanguagesLength,
+ "info": translate(lang, "messageOfTheDay", settings.info.name),
"timestamp": new Date().getTime()
- });
+ }, lang);
}
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
diff --git a/endpoints/joke.js b/endpoints/joke.js
index a607af8f..18415d05 100755
--- a/endpoints/joke.js
+++ b/endpoints/joke.js
@@ -3,6 +3,8 @@ const convertFileFormat = require("../src/fileFormatConverter");
const httpServer = require("../src/httpServer");
const parseURL = require("../src/parseURL");
const parseJokes = require("../src/parseJokes");
+const languages = require("../src/languages");
+const tr = require("../src/translate");
const FilteredJoke = require("../src/classes/FilteredJoke");
const jsl = require("svjsl");
const settings = require("../settings");
@@ -21,7 +23,9 @@ const meta = {
"blacklistFlags",
"type",
"contains",
- "idRange"
+ "idRange",
+ "lang",
+ "amount"
]
}
};
@@ -58,7 +62,7 @@ const call = (req, res, url, params, format) => {
if(category.toLowerCase() == cat.toLowerCase())
categoryValid = true;
}
- else if(typeof category == "object")
+ else if(Array.isArray(category))
{
if(category.map(c => c.toLowerCase()).includes(cat.toLowerCase()))
categoryValid = true;
@@ -70,23 +74,50 @@ const call = (req, res, url, params, format) => {
fCat = filterJoke.setAllowedCategories([category]);
else fCat = filterJoke.setAllowedCategories(category);
+ let langCode = settings.languages.defaultLanguage;
+
+ //#SECTION language
+ if(params && !jsl.isEmpty(params["lang"]))
+ {
+ try
+ {
+ langCode = params["lang"].toString();
+
+ if(languages.isValidLang(langCode))
+ filterJoke.setLanguage(langCode);
+ else
+ return isErrored(res, format, tr(langCode, "invalidLangCode", langCode), langCode);
+ }
+ catch(err)
+ {
+ return isErrored(res, format, tr(langCode, "invalidLangCodeNoArg"), langCode);
+ }
+ }
+
if(!fCat || !categoryValid)
- return isErrored(res, format, `The specified categor${category.length == undefined || typeof category != "object" || category.length == 1 ? "y is" : "ies are"} invalid - Got: "${category.length == undefined || typeof category != "object" ? category : category.join(", ")}" - Possible categories are: "${[settings.jokes.possible.anyCategoryName, ...settings.jokes.possible.categories].join(", ")}" (case insensitive)`);
+ {
+ let avlCats = [settings.jokes.possible.anyCategoryName, ...settings.jokes.possible.categories].join(", ");
+ let catName = category.length == undefined || typeof category != "object" ? category : category.join(", ");
+
+ return isErrored(res, format, tr(langCode, "invalidCategory", catName, avlCats), langCode);
+ }
+ let jokeAmount = 1;
+
if(!jsl.isEmpty(params))
{
//#SECTION type
if(!jsl.isEmpty(params["type"]) && settings.jokes.possible.types.map(t => t.toLowerCase()).includes(params["type"].toLowerCase()))
{
if(!filterJoke.setAllowedType(params["type"].toLowerCase()))
- return isErrored(res, format, `The specified type is invalid - Got: "${params["type"]}" - Possible types are: "${settings.jokes.possible.types}"`);
+ return isErrored(res, format, tr(langCode, "invalidType", params["type"], settings.jokes.possible.types.join(", ")), langCode);
}
//#SECTION contains
if(!jsl.isEmpty(params["contains"]))
{
if(!filterJoke.setSearchString(params["contains"].toLowerCase()))
- return isErrored(res, format, `The specified type is invalid - Got: "${params["type"]}" - Possible types are: "${settings.jokes.possible.types.join(", ")}"`);
+ return isErrored(res, format, tr(langCode, "invalidType", params["type"], settings.jokes.possible.types.join(", ")), langCode);
}
//#SECTION idRange
@@ -98,19 +129,25 @@ const call = (req, res, url, params, format) => {
{
let splitParams = params["idRange"].split(settings.jokes.splitCharRegex);
+ if(!splitParams[0] && splitParams[1])
+ splitParams[0] = splitParams[1];
+
+ if(!splitParams[1] && splitParams[0])
+ splitParams[1] = splitParams[0];
+
if(!filterJoke.setIdRange(parseInt(splitParams[0]), parseInt(splitParams[1])))
- return isErrored(res, format, `The specified ID range is invalid - Got: "${splitParams[0]} to ${splitParams[1]}" - ID range is: "0-${(parseJokes.jokeCount - 1)}"`);
+ return isErrored(res, format, tr(langCode, "idRangeInvalid", splitParams[0], splitParams[1], (parseJokes.jokeCountPerLang[langCode] - 1)), langCode);
}
else
{
let id = parseInt(params["idRange"]);
- if(!filterJoke.setIdRange(id, id))
- return isErrored(res, format, `The specified ID range is invalid - Got: "${params["idRange"]}" - ID range is: "0-${(parseJokes.jokeCount - 1)}"`);
+ if(!filterJoke.setIdRange(id, id, langCode))
+ return isErrored(res, format, tr(langCode, "idRangeInvalidSingle", params["idRange"], (parseJokes.jokeCountPerLang[langCode] - 1)), langCode);
}
}
catch(err)
{
- return isErrored(res, format, `The values in the "idRange" parameter are invalid or are not numbers - ${err}`);
+ return isErrored(res, format, tr(langCode, "idRangeInvalidGeneric", err), langCode);
}
}
@@ -125,22 +162,74 @@ const call = (req, res, url, params, format) => {
});
if(erroredFlags.length > 0)
- return isErrored(res, format, `The specified flags are invalid - Got: "${flags.join(", ")}" - Possible flags are: "${settings.jokes.possible.flags.join(", ")}"`);
+ return isErrored(res, format, tr(langCode, "invalidFlags", flags.join(", "), settings.jokes.possible.flags.join(", ")), langCode);
+ tr(langCode, "invalidFlags", flags.join(", "), settings.jokes.possible.flags.join(", "))
let fFlg = filterJoke.setBlacklistFlags(flags);
if(!fFlg)
- return isErrored(res, format, `The specified flags are invalid - Got: "${flags.join(", ")}" - Possible flags are: "${settings.jokes.possible.flags.join(", ")}"`);
+ return isErrored(res, format, tr(langCode, "invalidFlags", flags.join(", "), settings.jokes.possible.flags.join(", ")), langCode);
+ }
+
+ //#SECTION amount
+ if(!jsl.isEmpty(params["amount"]))
+ {
+ jokeAmount = parseInt(params["amount"]);
+
+ if(isNaN(jokeAmount) || jokeAmount < 1)
+ jokeAmount = 1;
+
+ if(jokeAmount > settings.jokes.maxAmount)
+ jokeAmount = settings.jokes.maxAmount;
+
+ let fAmt = filterJoke.setAmount(jokeAmount);
+ if(!fAmt)
+ return isErrored(res, format, tr(langCode, "amountInternalError", fAmt), langCode);
}
}
- filterJoke.getJoke().then(joke => {
- if(!joke["error"])
- joke["error"] = false;
- let responseText = convertFileFormat.auto(format, joke);
- httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
+ filterJoke.getJokes(filterJoke.getAmount()).then(jokesArray => {
+ let responseText = "";
+
+ if(jokeAmount == 1)
+ {
+ let singleObj = {
+ error: false,
+ ...jokesArray[0]
+ };
+
+ responseText = convertFileFormat.auto(format, singleObj, langCode);
+ }
+ else
+ {
+ let multiObj = {};
+
+ if(format != "xml")
+ {
+ multiObj = {
+ error: false,
+ jokes: jokesArray,
+ amount: jokesArray.length || 1
+ };
+ }
+ else
+ {
+ multiObj = {
+ error: false,
+ jokes: { "joke": jokesArray },
+ amount: jokesArray.length || 1
+ };
+ }
+
+ responseText = convertFileFormat.auto(format, multiObj, langCode);
+ }
+
+ if(jokeAmount > settings.jokes.encodeAmount)
+ httpServer.tryServeEncoded(req, res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
+ else
+ httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
}).catch(err => {
- return isErrored(res, format, `Error while finalizing joke filtering: ${Array.isArray(err) ? err.join("; ") : err}`);
+ return isErrored(res, format, tr(langCode, "errorWhileFinalizing", Array.isArray(err) ? err.join("; ") : err), langCode);
});
};
@@ -149,18 +238,36 @@ const call = (req, res, url, params, format) => {
* @param {http.ServerResponse} res
* @param {String} format
* @param {String} msg
+ * @param {String} lang 2-char lang code
+ * @param {...any} args Arguments to replace numbered %-placeholders with. Only use objects that are strings or convertable to them with `.toString()`!
*/
-const isErrored = (res, format, msg) => {
- let errFromRegistry = require("." + settings.errors.errorRegistryIncludePath)["106"];
- let errorObj = {}
+const isErrored = (res, format, msg, lang, ...args) => {
+ let errFromRegistry = require("." + settings.errors.errorMessagesPath)["106"];
+ let errorObj = {};
+
+ let insArgs = (texts, insertions) => {
+ if(!Array.isArray(insertions) || insertions.length <= 0)
+ return texts;
+
+ insertions.forEach((ins, i) => {
+
+ if(Array.isArray(texts))
+ texts = texts.map(tx => tx.replace(`%${i + 1}`, ins));
+ else if(typeof texts == "string")
+ texts = texts.replace(`%${i + 1}`, ins);
+ });
+
+ return texts;
+ };
+
if(format != "xml")
{
errorObj = {
error: true,
internalError: false,
code: 106,
- message: errFromRegistry.errorMessage,
- causedBy: errFromRegistry.causedBy,
+ message: insArgs(errFromRegistry.errorMessage[lang], args) || insArgs(errFromRegistry.errorMessage[settings.languages.defaultLanguage], args),
+ causedBy: insArgs(errFromRegistry.causedBy[lang], args) || insArgs(errFromRegistry.causedBy[settings.languages.defaultLanguage], args),
additionalInfo: msg,
timestamp: new Date().getTime()
};
@@ -171,15 +278,15 @@ const isErrored = (res, format, msg) => {
error: true,
internalError: false,
code: 106,
- message: errFromRegistry.errorMessage,
- causedBy: {"cause": errFromRegistry.causedBy},
+ message: insArgs(errFromRegistry.errorMessage[lang], args) || insArgs(errFromRegistry.errorMessage[settings.languages.defaultLanguage], args),
+ causedBy: {"cause": insArgs(errFromRegistry.causedBy[lang], args) || insArgs(errFromRegistry.causedBy[settings.languages.defaultLanguage], args)},
additionalInfo: msg,
timestamp: new Date().getTime()
};
}
- let responseText = convertFileFormat.auto(format, errorObj);
+ let responseText = convertFileFormat.auto(format, errorObj, lang);
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/langcode.js b/endpoints/langcode.js
new file mode 100644
index 00000000..84865119
--- /dev/null
+++ b/endpoints/langcode.js
@@ -0,0 +1,81 @@
+const http = require("http");
+const convertFileFormat = require("../src/fileFormatConverter");
+const httpServer = require("../src/httpServer");
+const parseURL = require("../src/parseURL");
+const languages = require("../src/languages");
+const jsl = require("svjsl");
+const settings = require("../settings");
+const translate = require("../src/translate");
+
+jsl.unused(http);
+
+
+const meta = {
+ "name": "LangCodes",
+ "desc": "Returns the language code of the specified language",
+ "usage": {
+ "method": "GET",
+ "url": `${settings.info.docsURL}/langcode/{LANGUAGE}`,
+ "supportedParams": [
+ "format",
+ "lang"
+ ]
+ }
+};
+
+/**
+ * Calls this endpoint
+ * @param {http.IncomingMessage} req The HTTP server request
+ * @param {http.ServerResponse} res The HTTP server response
+ * @param {Array} url URL path array gotten from the URL parser module
+ * @param {Object} params URL query params gotten from the URL parser module
+ * @param {String} format The file format to respond with
+ */
+const call = (req, res, url, params, format) => {
+ jsl.unused([req, params]);
+
+ let statusCode = 200;
+
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
+ if(url[1] == undefined)
+ {
+ statusCode = 400;
+ return httpServer.pipeString(res, convertFileFormat.auto(format, {
+ "error": true,
+ "message": translate(lang, "noLangCodeSpecified")
+ }, lang), parseURL.getMimeTypeFromFileFormatString(format), statusCode);
+ }
+
+ let defaultValDisabled = (params && params.noDefault && params.noDefault == true);
+
+ let responseText = "";
+ let langCode = null;
+ // if(!defaultValDisabled)
+ // langCode = settings.languages.defaultLanguage;
+ let language = url[1].toString().toLowerCase();
+
+ let ltc = languages.languageToCode(language);
+ langCode = (ltc === false ? (defaultValDisabled ? null : settings.languages.defaultLanguage) : ltc);
+
+ if(langCode == null || ltc === false)
+ {
+ // error
+ statusCode = 400;
+ responseText = convertFileFormat.auto(format, {
+ "error": true,
+ "message": `The provided language "${decodeURIComponent(language)}" could not be resolved.`
+ }, lang);
+ }
+ else
+ {
+ responseText = convertFileFormat.auto(format, {
+ "error": false,
+ "code": langCode
+ }, lang);
+ }
+
+ httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format), statusCode);
+};
+
+module.exports = { meta, call };
diff --git a/endpoints/languages.js b/endpoints/languages.js
new file mode 100644
index 00000000..1fe92e2a
--- /dev/null
+++ b/endpoints/languages.js
@@ -0,0 +1,77 @@
+const http = require("http");
+const convertFileFormat = require("../src/fileFormatConverter");
+const httpServer = require("../src/httpServer");
+const parseURL = require("../src/parseURL");
+const jsl = require("svjsl");
+const languages = require("../src/languages");
+const settings = require("../settings");
+
+jsl.unused(http);
+
+
+const meta = {
+ "name": "Languages",
+ "desc": `Returns a list of supported and partially supported languages`,
+ "usage": {
+ "method": "GET",
+ "url": `${settings.info.docsURL}/languages`,
+ "supportedParams": [
+ "format",
+ "lang"
+ ]
+ }
+};
+
+/**
+ * Calls this endpoint
+ * @param {http.IncomingMessage} req The HTTP server request
+ * @param {http.ServerResponse} res The HTTP server response
+ * @param {Array} url URL path array gotten from the URL parser module
+ * @param {Object} params URL query params gotten from the URL parser module
+ * @param {String} format The file format to respond with
+ */
+const call = (req, res, url, params, format) => {
+ jsl.unused([req, url, params]);
+
+ let jokeLangs = languages.jokeLangs().map(jl => jl.code).sort();
+ let sysLangs = languages.systemLangs().sort();
+
+ let responseText = "";
+
+ let langArray = [];
+ let pl = languages.getPossibleLanguages();
+
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
+ Object.keys(pl).forEach(lc => {
+ langArray.push({
+ "code": lc,
+ "name": pl[lc]
+ });
+ });
+
+ if(format == "xml")
+ {
+ responseText = convertFileFormat.auto(format, {
+ "defaultLanguage": settings.languages.defaultLanguage,
+ "jokeLanguages": { "code": jokeLangs },
+ "systemLanguages": { "code": sysLangs },
+ "possibleLanguages": { "language": langArray },
+ "timestamp": new Date().getTime()
+ }, lang);
+ }
+ else
+ {
+ responseText = convertFileFormat.auto(format, {
+ "defaultLanguage": settings.languages.defaultLanguage,
+ "jokeLanguages": jokeLangs,
+ "systemLanguages": sysLangs,
+ "possibleLanguages": langArray,
+ "timestamp": new Date().getTime()
+ }, lang);
+ }
+
+ return httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
+};
+
+module.exports = { meta, call };
diff --git a/endpoints/ping.js b/endpoints/ping.js
index cbdc94d7..fd5ad629 100755
--- a/endpoints/ping.js
+++ b/endpoints/ping.js
@@ -2,6 +2,7 @@ const http = require("http");
const convertFileFormat = require("../src/fileFormatConverter");
const httpServer = require("../src/httpServer");
const parseURL = require("../src/parseURL");
+const tr = require("../src/translate");
const jsl = require("svjsl");
const settings = require("../settings");
@@ -15,7 +16,8 @@ const meta = {
"method": "GET",
"url": `${settings.info.docsURL}/ping`,
"supportedParams": [
- "format"
+ "format",
+ "lang"
]
}
};
@@ -31,13 +33,15 @@ const meta = {
const call = (req, res, url, params, format) => {
jsl.unused([req, url, params]);
+ let lang = (params && params["lang"]) ? params["lang"] : settings.languages.defaultLanguage;
+
let responseText = convertFileFormat.auto(format, {
"error": false,
- "ping": "Pong!",
+ "ping": tr(lang, "pingPong"),
"timestamp": new Date().getTime()
- });
+ }, lang);
httpServer.pipeString(res, responseText, parseURL.getMimeTypeFromFileFormatString(format));
};
-module.exports = { meta, call };
\ No newline at end of file
+module.exports = { meta, call };
diff --git a/endpoints/static.js b/endpoints/static.js
index 409d3881..b1a90d07 100755
--- a/endpoints/static.js
+++ b/endpoints/static.js
@@ -2,7 +2,7 @@ const http = require("http");
const httpServer = require("../src/httpServer");
const jsl = require("svjsl");
const settings = require("../settings");
-const fs = require("fs");
+const fs = require("fs-extra");
const debug = require("../src/verboseLogging");
jsl.unused(http);
@@ -95,6 +95,7 @@ const call = (req, res, url, params, format) => {
debug("Static", `Serving static content "${requestedFile}" with encoding "${selectedEncoding}"`);
res.setHeader("Content-Encoding", selectedEncoding);
+ res.setHeader("Cache-Control", "max-age=86400");
return httpServer.pipeFile(res, filePath, mimeType, statusCode);
}
@@ -106,4 +107,4 @@ const call = (req, res, url, params, format) => {
});
};
-module.exports = { call, meta };
\ No newline at end of file
+module.exports = { call, meta };
diff --git a/package-lock.json b/package-lock.json
index b9e84ead..f094e0ca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,9 +1,18 @@
{
"name": "@sv443/jokeapi",
- "version": "2.1.5",
+ "version": "2.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@arcanis/slice-ansi": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@arcanis/slice-ansi/-/slice-ansi-1.0.2.tgz",
+ "integrity": "sha512-lDL63z0W/L/WTgqrwVOuNyMAsTv+pvjybd21z9SWdStmQoXT59E/iVWwat3gYjcdTNBf6oHAMoyFm8dtjpXEYw==",
+ "dev": true,
+ "requires": {
+ "grapheme-splitter": "^1.0.4"
+ }
+ },
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -36,52 +45,216 @@
"integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
"dev": true
},
+ "@nodelib/fs.scandir": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+ "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.3",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+ "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+ "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.3",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@opencensus/core": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz",
+ "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==",
+ "requires": {
+ "continuation-local-storage": "^3.2.1",
+ "log-driver": "^1.2.7",
+ "semver": "^5.5.0",
+ "shimmer": "^1.2.0",
+ "uuid": "^3.2.1"
+ }
+ },
+ "@opencensus/propagation-b3": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz",
+ "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==",
+ "requires": {
+ "@opencensus/core": "^0.0.8",
+ "uuid": "^3.2.1"
+ },
+ "dependencies": {
+ "@opencensus/core": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz",
+ "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==",
+ "requires": {
+ "continuation-local-storage": "^3.2.1",
+ "log-driver": "^1.2.7",
+ "semver": "^5.5.0",
+ "shimmer": "^1.2.0",
+ "uuid": "^3.2.1"
+ }
+ }
+ }
+ },
+ "@pm2/agent-node": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/@pm2/agent-node/-/agent-node-1.1.10.tgz",
+ "integrity": "sha512-xRcrk7OEwhS3d/227/kKGvxgmbIi6Yyp27FzGlFNermEKhgddmFaRnmd7GRLIsBM/KB28NrwflBZulzk/mma6g==",
+ "requires": {
+ "debug": "^3.1.0",
+ "eventemitter2": "^5.0.1",
+ "proxy-agent": "^3.0.3",
+ "ws": "^6.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "eventemitter2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+ "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI="
+ }
+ }
+ },
+ "@pm2/io": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/@pm2/io/-/io-4.3.5.tgz",
+ "integrity": "sha512-CY/a6Nw72vrlp/FPx38l4jfEHp4gNEbo8i+WlSJ2cnWO6VE6CKmnC1zb4yQLvdP8f3EuzzoOBZVq6aGN20M82Q==",
+ "requires": {
+ "@opencensus/core": "0.0.9",
+ "@opencensus/propagation-b3": "0.0.8",
+ "@pm2/agent-node": "^1.1.10",
+ "async": "~2.6.1",
+ "debug": "4.1.1",
+ "eventemitter2": "^6.3.1",
+ "require-in-the-middle": "^5.0.0",
+ "semver": "6.3.0",
+ "shimmer": "^1.2.0",
+ "signal-exit": "^3.0.3",
+ "tslib": "1.9.3"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
+ },
+ "tslib": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
+ }
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.0.0.tgz",
+ "integrity": "sha512-kqA5I6Yun7PBHk8WN9BBP1c7FfN2SrD05GuVSEYPqDb4nerv7HqYfgBfMIKmT/EuejURkJKLZuLyGKGs6WEG9w==",
+ "dev": true
+ },
"@snyk/cli-interface": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.6.0.tgz",
- "integrity": "sha512-jtk0gf80v4mFyDqaQNokD8GOPMTXpIUL35ewg6jtmuZw41xt56WF9kqCjiiViSRRRYA0RK+RuiVfmJA5pxvMUQ==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.0.tgz",
+ "integrity": "sha512-St/G39iJG1zQK15L24kcVYM2gmFc/ylBCcBqU2DMZKJKwOPccKLUO6s+dWIUXMccQ+DFS6TuHPvuAKQNi9C4Yg==",
+ "dev": true,
"requires": {
+ "@snyk/dep-graph": "1.19.0",
"@snyk/graphlib": "2.1.9-patch",
"tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "@snyk/dep-graph": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.19.0.tgz",
+ "integrity": "sha512-/0phOICMk4hkX2KtZgi+4KNd5G9oYDIlxQDQk+ui2xl4gonPvK6Q5MFzHP7Xet1YY/XoU33ox41i+IO48qZ+zQ==",
+ "dev": true,
+ "requires": {
+ "@snyk/graphlib": "2.1.9-patch",
+ "lodash.isequal": "^4.5.0",
+ "object-hash": "^2.0.3",
+ "semver": "^6.0.0",
+ "source-map-support": "^0.5.19",
+ "tslib": "^2.0.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz",
+ "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==",
+ "dev": true
+ }
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
}
},
"@snyk/cocoapods-lockfile-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.2.0.tgz",
- "integrity": "sha512-DyFqZudOlGXHBOVneLnQnyQ97xZLq+PTF9PhWOmrEzH/tKcLyXhdW/WmDPVNJVyNvogyRZ4cXIj487xy/EeZEw==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.4.0.tgz",
+ "integrity": "sha512-mAWgKIHFv0QEGpRvocVMxLAdJx7BmXtVOyQN/VtsGBoGFKqhO0jbtKUUVJC4b0jyKfVmEF2puo94i+1Uqz5q6A==",
+ "dev": true,
"requires": {
- "@snyk/dep-graph": "1.18.2",
+ "@snyk/dep-graph": "1.18.4",
"@snyk/ruby-semver": "^2.0.4",
"@types/js-yaml": "^3.12.1",
- "core-js": "^3.2.0",
"js-yaml": "^3.13.1",
"source-map-support": "^0.5.7",
"tslib": "^1.10.0"
},
"dependencies": {
"@snyk/dep-graph": {
- "version": "1.18.2",
- "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.2.tgz",
- "integrity": "sha512-v7tIiCH4LmYOSc0xGHKSxSZ2PEDv8zDlYU7ZKSH+1Hk8Qvj3YYEFvtV1iFBHUEQFUen4kQA6lWxlwF8chsNw+w==",
+ "version": "1.18.4",
+ "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.4.tgz",
+ "integrity": "sha512-SePWsDyD7qrLxFifIieEl4GqyOODfOnP0hmUweTG5YcMroAV5nARGAUcjxREGzbXMcUpPfZhAaqFjYgzUDH8dQ==",
+ "dev": true,
"requires": {
"@snyk/graphlib": "2.1.9-patch",
"@snyk/lodash": "4.17.15-patch",
- "object-hash": "^1.3.1",
- "prettier": "^1.19.1",
- "semver": "^6.0.0",
- "source-map-support": "^0.5.11",
- "tslib": "^1.10.0"
+ "object-hash": "^2.0.3",
+ "semver": "^7.3.2",
+ "source-map-support": "^0.5.19",
+ "tslib": "^1.11.1"
}
},
- "object-hash": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
- "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA=="
- },
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
}
}
},
@@ -89,42 +262,16 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@snyk/composer-lockfile-parser/-/composer-lockfile-parser-1.4.0.tgz",
"integrity": "sha512-ga4YTRjJUuP0Ufr+t1IucwVjEFAv66JSBB/zVHP2zy/jmfA3l3ZjlGQSjsRC6Me9P2Z0esQ83AYNZvmIf9pq2w==",
+ "dev": true,
"requires": {
"@snyk/lodash": "^4.17.15-patch"
}
},
- "@snyk/configstore": {
- "version": "3.2.0-rc1",
- "resolved": "https://registry.npmjs.org/@snyk/configstore/-/configstore-3.2.0-rc1.tgz",
- "integrity": "sha512-CV3QggFY8BY3u8PdSSlUGLibqbqCG1zJRmGM2DhnhcxQDRRPTGTP//l7vJphOVsUP1Oe23+UQsj7KRWpRUZiqg==",
- "requires": {
- "dot-prop": "^5.2.0",
- "graceful-fs": "^4.1.2",
- "make-dir": "^1.0.0",
- "unique-string": "^1.0.0",
- "write-file-atomic": "^2.0.0",
- "xdg-basedir": "^3.0.0"
- },
- "dependencies": {
- "make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
- }
- }
- },
"@snyk/dep-graph": {
"version": "1.18.3",
"resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.3.tgz",
"integrity": "sha512-7qWRTIJdZuc5VzDjdV2+03AHElyAZmhq7eV9BRu+jqrYjo9ohWBGEZgYslrTdvfqfJ8rkdrG3j0/0Aa25IxJcg==",
+ "dev": true,
"requires": {
"@snyk/graphlib": "2.1.9-patch",
"@snyk/lodash": "4.17.15-patch",
@@ -137,19 +284,33 @@
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
- "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
}
}
},
+ "@snyk/docker-registry-v2-client": {
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/@snyk/docker-registry-v2-client/-/docker-registry-v2-client-1.13.5.tgz",
+ "integrity": "sha512-lgJiC071abCpFVLp47OnykU8MMrhdQe386Wt6QaDmjI0s2DQn/S58NfdLrPU7s6l4zoGT7UwRW9+7paozRgFTA==",
+ "dev": true,
+ "requires": {
+ "needle": "^2.5.0",
+ "parse-link-header": "^1.0.1",
+ "tslib": "^1.10.0"
+ }
+ },
"@snyk/gemfile": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@snyk/gemfile/-/gemfile-1.2.0.tgz",
- "integrity": "sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA=="
+ "integrity": "sha512-nI7ELxukf7pT4/VraL4iabtNNMz8mUo7EXlqCFld8O5z6mIMLX9llps24iPpaIZOwArkY3FWA+4t+ixyvtTSIA==",
+ "dev": true
},
"@snyk/graphlib": {
"version": "2.1.9-patch",
"resolved": "https://registry.npmjs.org/@snyk/graphlib/-/graphlib-2.1.9-patch.tgz",
"integrity": "sha512-uFO/pNMm3pN15QB+hVMU7uaQXhsBNwEA8lOET/VDcdOzLptODhXzkJqSHqt0tZlpdAz6/6Uaj8jY00UvPFgFMA==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch"
}
@@ -158,6 +319,7 @@
"version": "6.2.2-patch",
"resolved": "https://registry.npmjs.org/@snyk/inquirer/-/inquirer-6.2.2-patch.tgz",
"integrity": "sha512-IUq5bHRL0vtVKtfvd4GOccAIaLYHbcertug2UVZzk5+yY6R/CxfYsnFUTho1h4BdkfNdin2tPjE/5jRF4SKSrw==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch",
"ansi-escapes": "^3.2.0",
@@ -174,46 +336,38 @@
"through": "^2.3.6"
},
"dependencies": {
- "ansi-escapes": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
- "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ=="
- },
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
},
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
"requires": {
"restore-cursor": "^2.0.0"
}
},
- "figures": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
- "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
- "requires": {
- "escape-string-regexp": "^1.0.5"
- }
- },
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
},
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
- "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
},
"onetime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
"requires": {
"mimic-fn": "^1.0.0"
}
@@ -222,6 +376,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
"requires": {
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
@@ -231,6 +386,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
@@ -238,12 +394,12 @@
}
},
"@snyk/java-call-graph-builder": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.8.1.tgz",
- "integrity": "sha512-2G96dChYYXV73G8y9U0fi45dH6ybOjUSRBTJrMnmNkHJoOp1bzz8L4p5rkRypHQqr4SBS1EdCQeRw1eWRLm+Lg==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.10.0.tgz",
+ "integrity": "sha512-x3vKElHJRsPjlMBRACeD6kHtki54ffahYeAm4ny5epVpxm16/OT6f6AjNjPuX8DbxcauaD7wqirtc62OPH3YqA==",
+ "dev": true,
"requires": {
"@snyk/graphlib": "2.1.9-patch",
- "@snyk/lodash": "4.17.15-patch",
"ci-info": "^2.0.0",
"debug": "^4.1.1",
"glob": "^7.1.6",
@@ -254,82 +410,123 @@
"source-map-support": "^0.5.7",
"temp-dir": "^2.0.0",
"tslib": "^1.9.3"
- },
- "dependencies": {
- "ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
- }
}
},
"@snyk/lodash": {
"version": "4.17.15-patch",
"resolved": "https://registry.npmjs.org/@snyk/lodash/-/lodash-4.17.15-patch.tgz",
- "integrity": "sha512-e4+t34bGyjjRnwXwI14hqye9J/nRbG9iwaqTgXWHskm5qC+iK0UrjgYdWXiHJCf3Plbpr+1rpW+4LPzZnCGMhQ=="
+ "integrity": "sha512-e4+t34bGyjjRnwXwI14hqye9J/nRbG9iwaqTgXWHskm5qC+iK0UrjgYdWXiHJCf3Plbpr+1rpW+4LPzZnCGMhQ==",
+ "dev": true
},
"@snyk/rpm-parser": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@snyk/rpm-parser/-/rpm-parser-1.1.0.tgz",
- "integrity": "sha512-+DyCagvnpyBjwYTxaPMQGLW4rkpKAw1Jrh8YbZCg7Ix172InBxdve/0zud18Lu2H6xWtDDdMvRDdfl82wlTBvA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@snyk/rpm-parser/-/rpm-parser-2.0.0.tgz",
+ "integrity": "sha512-bWjQY5Xk3TcfVpeo8M5BhhSUEdPr2P19AWW13CHPu6sFZkckLWEcjQycnBsVD6RBmxGXecJ1YNui8dq6soHoYQ==",
+ "dev": true,
"requires": {
- "event-loop-spinner": "1.1.0",
- "typescript": "3.8.3"
+ "event-loop-spinner": "^2.0.0"
+ },
+ "dependencies": {
+ "event-loop-spinner": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz",
+ "integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.10.0"
+ }
+ }
}
},
"@snyk/ruby-semver": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@snyk/ruby-semver/-/ruby-semver-2.2.0.tgz",
"integrity": "sha512-FqUayoVjcyCsQFYPm3DcaCKdFR4xmapUkCGY+bcNBs3jqCUw687PoP9CPQ1Jvtaw5YpfBNl/62jyntsWCeciuA==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch"
}
},
"@snyk/snyk-cocoapods-plugin": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.2.0.tgz",
- "integrity": "sha512-Ux7hXKawbk30niGBToGkKqHyKzhT3E7sCl0FNkPkHaaGZwPwhFCDyNFxBd4uGgWiQ+kT+RjtH5ahna+bSP69Yg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.3.0.tgz",
+ "integrity": "sha512-4V1xJMqsK6J3jHu9UufKySorzA8O1vNLRIK1JgJf5KcXQCP44SJI5dk9Xr9iFGXXtGo8iI9gmokQcHlGpkPSJg==",
+ "dev": true,
"requires": {
"@snyk/cli-interface": "1.5.0",
- "@snyk/cocoapods-lockfile-parser": "3.2.0",
+ "@snyk/cocoapods-lockfile-parser": "3.4.0",
"@snyk/dep-graph": "^1.18.2",
"source-map-support": "^0.5.7",
- "tslib": "^1.10.0"
+ "tslib": "^2.0.0"
},
"dependencies": {
"@snyk/cli-interface": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-1.5.0.tgz",
"integrity": "sha512-+Qo+IO3YOXWgazlo+CKxOuWFLQQdaNCJ9cSfhFQd687/FuesaIxWdInaAdfpsLScq0c6M1ieZslXgiZELSzxbg==",
+ "dev": true,
"requires": {
"tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
}
+ },
+ "tslib": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz",
+ "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==",
+ "dev": true
}
}
},
- "@snyk/update-notifier": {
- "version": "2.5.1-rc2",
- "resolved": "https://registry.npmjs.org/@snyk/update-notifier/-/update-notifier-2.5.1-rc2.tgz",
- "integrity": "sha512-dlled3mfpnAt3cQb5hxkFiqfPCj4Yk0xV8Yl5P8PeVv1pUmO7vI4Ka4Mjs4r6CYM5f9kZhviFPQQcWOIDlMRcw==",
+ "@snyk/snyk-docker-pull": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@snyk/snyk-docker-pull/-/snyk-docker-pull-3.2.0.tgz",
+ "integrity": "sha512-uWKtjh29I/d0mfmfBN7w6RwwNBQxQVKrauF5ND/gqb0PVsKV22GIpkI+viWjI7KNKso6/B0tMmsv7TX2tsNcLQ==",
+ "dev": true,
"requires": {
- "@snyk/configstore": "3.2.0-rc1",
- "boxen": "^1.3.0",
- "chalk": "^2.3.2",
- "import-lazy": "^2.1.0",
- "is-ci": "^1.0.10",
- "is-installed-globally": "^0.1.0",
- "is-npm": "^1.0.0",
- "latest-version": "^3.1.0",
- "semver-diff": "^2.0.0",
- "xdg-basedir": "^3.0.0"
+ "@snyk/docker-registry-v2-client": "^1.13.5",
+ "child-process": "^1.0.2",
+ "tar-stream": "^2.1.2",
+ "tmp": "^0.1.0"
+ },
+ "dependencies": {
+ "tmp": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
+ "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^2.6.3"
+ }
+ }
}
},
- "@types/agent-base": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/@types/agent-base/-/agent-base-4.2.1.tgz",
- "integrity": "sha512-GRmnDTq6ajyRyT8Ybg4IVVOyYqqFIAR4Zo9L+fdMAP+IJxd0nlTV99/IelJCBF629WOj6MpE9ohLHYCmkeJqRA==",
+ "@szmarczak/http-timer": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
+ "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
+ "dev": true,
"requires": {
- "@types/node": "*"
+ "defer-to-connect": "^2.0.0"
+ }
+ },
+ "@types/cacheable-request": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
+ "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
+ "dev": true,
+ "requires": {
+ "@types/http-cache-semantics": "*",
+ "@types/keyv": "*",
+ "@types/node": "*",
+ "@types/responselike": "*"
}
},
"@types/color-name": {
@@ -341,71 +538,409 @@
"@types/debug": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
- "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ=="
+ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==",
+ "dev": true
+ },
+ "@types/emscripten": {
+ "version": "1.39.4",
+ "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz",
+ "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
},
"@types/hosted-git-info": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/@types/hosted-git-info/-/hosted-git-info-2.7.0.tgz",
- "integrity": "sha512-OW/D8GqCyQtH8F7xDdDxzPJTBgknZeZhlCakUcBCya2rYPRN53F+0YJVwSPyiyAhrknnjkl3P9qVk0oBI4S1qw=="
+ "integrity": "sha512-OW/D8GqCyQtH8F7xDdDxzPJTBgknZeZhlCakUcBCya2rYPRN53F+0YJVwSPyiyAhrknnjkl3P9qVk0oBI4S1qw==",
+ "dev": true
+ },
+ "@types/http-cache-semantics": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
+ "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==",
+ "dev": true
},
"@types/js-yaml": {
- "version": "3.12.3",
- "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.3.tgz",
- "integrity": "sha512-otRe77JNNWzoVGLKw8TCspKswRoQToys4tuL6XYVBFxjgeM0RUrx7m3jkaTdxILxeGry3zM8mGYkGXMeQ02guA=="
+ "version": "3.12.5",
+ "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz",
+ "integrity": "sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==",
+ "dev": true
+ },
+ "@types/keyv": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
+ "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
},
"@types/node": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz",
- "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA=="
+ "version": "13.13.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.14.tgz",
+ "integrity": "sha512-Az3QsOt1U/K1pbCQ0TXGELTuTkPLOiFIQf3ILzbOyo0FqgV9SxRnxbxM5QlAveERZMHpZY+7u3Jz2tKyl+yg6g==",
+ "dev": true
+ },
+ "@types/responselike": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
+ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
},
"@types/semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ=="
+ "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==",
+ "dev": true
},
"@types/xml2js": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.5.tgz",
"integrity": "sha512-yohU3zMn0fkhlape1nxXG2bLEGZRc1FeqF80RoHaYXJN7uibaauXfhzhOJr1Xh36sn+/tx21QAOf07b/xYVk1w==",
+ "dev": true,
"requires": {
"@types/node": "*"
}
},
- "@typescript-eslint/typescript-estree": {
- "version": "2.31.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz",
- "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==",
+ "@yarnpkg/core": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.1.1.tgz",
+ "integrity": "sha512-qeBxz8nHjKAbGTP2ZcXBnXGfM7+cN0A73mIai/24uru1ayvCIgfjWL1uIj/MM+m+K5lJX0Dcn94ZBHWits9JWQ==",
"dev": true,
"requires": {
- "debug": "^4.1.1",
- "eslint-visitor-keys": "^1.1.0",
- "glob": "^7.1.6",
- "is-glob": "^4.0.1",
- "lodash": "^4.17.15",
- "semver": "^6.3.0",
- "tsutils": "^3.17.1"
+ "@arcanis/slice-ansi": "^1.0.2",
+ "@yarnpkg/fslib": "^2.1.0",
+ "@yarnpkg/json-proxy": "^2.1.0",
+ "@yarnpkg/libzip": "^2.1.0",
+ "@yarnpkg/parsers": "^2.1.0",
+ "@yarnpkg/pnp": "^2.1.0",
+ "@yarnpkg/shell": "^2.1.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "ci-info": "^2.0.0",
+ "clipanion": "^2.4.2",
+ "cross-spawn": "7.0.3",
+ "diff": "^4.0.1",
+ "globby": "^10.0.1",
+ "got": "^11.1.3",
+ "json-file-plus": "^3.3.1",
+ "logic-solver": "^2.0.1",
+ "micromatch": "^4.0.2",
+ "mkdirp": "^0.5.1",
+ "p-limit": "^2.2.0",
+ "pluralize": "^7.0.0",
+ "pretty-bytes": "^5.1.0",
+ "semver": "^7.1.2",
+ "stream-to-promise": "^2.2.0",
+ "tar": "^4.4.6",
+ "tslib": "^1.13.0",
+ "tunnel": "^0.0.6"
},
"dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
- }
- }
- },
- "@yarnpkg/lockfile": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
- "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
- },
- "abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
- },
- "acorn": {
- "version": "7.3.1",
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "pluralize": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@yarnpkg/fslib": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.1.0.tgz",
+ "integrity": "sha512-E+f8w5yQZnTf1soyTWy7qdf+GmHsY+A0yEN4Di44/Txk6XRIMruyc1ShDi93mOI6ilnXxD87rNms18zJ8WnspA==",
+ "dev": true,
+ "requires": {
+ "@yarnpkg/libzip": "^2.1.0",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
+ }
+ },
+ "@yarnpkg/json-proxy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/json-proxy/-/json-proxy-2.1.0.tgz",
+ "integrity": "sha512-rOgCg2DkyviLgr80mUMTt9vzdf5RGOujQB26yPiXjlz4WNePLBshKlTNG9rKSoKQSOYEQcw6cUmosfOKDatrCw==",
+ "dev": true,
+ "requires": {
+ "@yarnpkg/fslib": "^2.1.0",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
+ }
+ },
+ "@yarnpkg/libzip": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.1.0.tgz",
+ "integrity": "sha512-39c7KuSWcYUqVxlBLZwfqdD/D6lS+jplNVWd6uAnk8EpnacaYGJRegvkqWyfw5c8KHukNMeEGF5JHrXPZYBM0w==",
+ "dev": true,
+ "requires": {
+ "@types/emscripten": "^1.38.0",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
+ }
+ },
+ "@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+ "dev": true
+ },
+ "@yarnpkg/parsers": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.1.0.tgz",
+ "integrity": "sha512-75OYQ6PMs1C3zm+W+T1xhLyVDX78zXQGEVHpWd4o/QwpAbhneB3/5FXVGRzI3gjPPWWSb/pKOPB1S6p0xmQD2Q==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "^3.10.0",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
+ }
+ },
+ "@yarnpkg/pnp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.1.0.tgz",
+ "integrity": "sha512-b8NlB71EFifv1jDX47nFaRXrykROxHcS7YuGb2dQ+Gp9gqJ0thIaZ3yB9+qWF8acdWtNcMpjCug4xkfAAR5Odw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "^13.7.0",
+ "@yarnpkg/fslib": "^2.1.0",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ }
+ }
+ },
+ "@yarnpkg/shell": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.1.0.tgz",
+ "integrity": "sha512-9i9ZWqeKHGV0DOfdxTVq5zl73Li8Fg947v57uLBEaytNF+HywkDfouNkg/6HfgBrpI0WH8OJ9Pz/uDaE5cpctw==",
+ "dev": true,
+ "requires": {
+ "@yarnpkg/fslib": "^2.1.0",
+ "@yarnpkg/parsers": "^2.1.0",
+ "clipanion": "^2.4.2",
+ "cross-spawn": "7.0.3",
+ "fast-glob": "^3.2.2",
+ "stream-buffers": "^3.0.2",
+ "tslib": "^1.13.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "7.3.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
"integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
"dev": true
@@ -437,11 +972,46 @@
}
},
"ansi-align": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
- "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
"requires": {
- "string-width": "^2.0.0"
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
}
},
"ansi-colors": {
@@ -450,6 +1020,12 @@
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
@@ -459,6 +1035,7 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -466,7 +1043,14 @@
"ansicolors": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
- "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk="
+ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=",
+ "dev": true
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+ "dev": true
},
"app-module-path": {
"version": "2.2.0",
@@ -482,7 +1066,8 @@
"archy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
- "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA="
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
},
"are-we-there-yet": {
"version": "1.1.5",
@@ -497,14 +1082,31 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
},
"ast-module-types": {
"version": "2.6.0",
@@ -526,18 +1128,48 @@
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+ },
+ "async-listener": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz",
+ "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==",
+ "requires": {
+ "semver": "^5.3.0",
+ "shimmer": "^1.1.0"
+ }
+ },
+ "at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
"bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
@@ -566,28 +1198,130 @@
}
},
"boxen": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
- "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+ "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+ "dev": true,
"requires": {
- "ansi-align": "^2.0.0",
- "camelcase": "^4.0.0",
- "chalk": "^2.0.1",
- "cli-boxes": "^1.0.0",
- "string-width": "^2.0.0",
- "term-size": "^1.2.0",
- "widest-line": "^2.0.0"
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^4.1.0",
+ "term-size": "^2.1.0",
+ "type-fest": "^0.8.1",
+ "widest-line": "^3.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+ "dev": true,
+ "requires": {
+ "pako": "~0.2.0"
+ }
+ },
"buffer": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
@@ -600,13 +1334,46 @@
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
+ "cacheable-lookup": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz",
+ "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==",
+ "dev": true
+ },
+ "cacheable-request": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz",
+ "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^4.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^2.0.0"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+ "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ }
+ }
+ },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -614,19 +1381,16 @@
"dev": true
},
"camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
- },
- "capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -636,7 +1400,14 @@
"chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
- "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "child-process": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/child-process/-/child-process-1.0.2.tgz",
+ "integrity": "sha1-mJdNx+0e5MYin44wX6cxOmiFp/I=",
+ "dev": true
},
"chownr": {
"version": "1.1.4",
@@ -644,14 +1415,16 @@
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
},
"ci-info": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
- "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
},
"cli-boxes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
- "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
+ "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==",
+ "dev": true
},
"cli-cursor": {
"version": "3.1.0",
@@ -665,7 +1438,8 @@
"cli-spinner": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/cli-spinner/-/cli-spinner-0.2.10.tgz",
- "integrity": "sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q=="
+ "integrity": "sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==",
+ "dev": true
},
"cli-spinners": {
"version": "2.3.0",
@@ -674,14 +1448,22 @@
"dev": true
},
"cli-width": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
- "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+ "dev": true
+ },
+ "clipanion": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.4.2.tgz",
+ "integrity": "sha512-kBCYtQKI4/R/zjierdwoDAsNUSvoh4pX2tseYxgLYQcKIpdPsHZrFWiQOfbe2Scd/btsqJEc4q6g55q0p5DZAw==",
+ "dev": true
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
@@ -692,6 +1474,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -702,6 +1485,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -710,6 +1494,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
@@ -723,6 +1508,23 @@
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ },
+ "dependencies": {
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ }
+ }
+ },
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -737,6 +1539,7 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
"requires": {
"color-name": "1.1.3"
}
@@ -744,7 +1547,8 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
},
"commander": {
"version": "5.1.0",
@@ -761,45 +1565,77 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "configstore": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+ "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^3.0.0",
+ "unique-string": "^2.0.0",
+ "write-file-atomic": "^3.0.0",
+ "xdg-basedir": "^4.0.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
- "core-js": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
- "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ "continuation-local-storage": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz",
+ "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==",
+ "requires": {
+ "async-listener": "^0.6.0",
+ "emitter-listener": "^1.1.1"
+ }
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "requires": {
- "capture-stack-trace": "^1.0.0"
- }
- },
"cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
"requires": {
- "lru-cache": "^4.0.1",
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"crypto-random-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
- "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true
},
"cssfilter": {
"version": "0.0.10",
@@ -822,7 +1658,8 @@
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
},
"decomment": {
"version": "0.9.2",
@@ -860,6 +1697,21 @@
"clone": "^1.0.2"
}
},
+ "defer-to-connect": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
+ "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
"degenerator": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz",
@@ -1005,17 +1857,76 @@
"ast-module-types": "^2.6.0",
"node-source-walk": "^4.2.0",
"typescript": "^3.8.3"
+ },
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": {
+ "version": "2.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
+ "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "eslint-visitor-keys": "^1.1.0",
+ "glob": "^7.1.6",
+ "is-glob": "^4.0.1",
+ "lodash": "^4.17.15",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ }
+ },
+ "semver": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+ "dev": true
+ }
}
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "docker-modem": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-2.1.3.tgz",
+ "integrity": "sha512-cwaRptBmYZwu/FyhGcqBm2MzXA77W2/E6eVkpOZVDk6PkI9Bjj84xPrXiHMA+OWjzNy+DFjgKh8Q+1hMR7/OHg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "readable-stream": "^3.5.0",
+ "split-ca": "^1.0.1",
+ "ssh2": "^0.8.7"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
},
"dockerfile-ast": {
"version": "0.0.19",
"resolved": "https://registry.npmjs.org/dockerfile-ast/-/dockerfile-ast-0.0.19.tgz",
"integrity": "sha512-iDRNFeAB2j4rh/Ecc2gh3fjciVifCMsszfCfHlYF5Wv8yybjZLiRDZUBt/pS3xrAz8uWT8fCHLq4pOQMmwCDwA==",
+ "dev": true,
"requires": {
"vscode-languageserver-types": "^3.5.0"
}
@@ -1033,6 +1944,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
"integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==",
+ "dev": true,
"requires": {
"is-obj": "^2.0.0"
},
@@ -1040,7 +1952,8 @@
"is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
- "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true
}
}
},
@@ -1053,6 +1966,7 @@
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/dotnet-deps-parser/-/dotnet-deps-parser-4.10.0.tgz",
"integrity": "sha512-dEO1oTvreaDCtcvhRdOmmAMubyC+MWqVr1c/1Wvasi+NW4NZeB67qGh1taqowUFh+aCXtPw3SP2eExn6aNkhwA==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch",
"@types/xml2js": "0.4.5",
@@ -1064,12 +1978,34 @@
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
},
"email-validator": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz",
- "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ=="
+ "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==",
+ "dev": true
+ },
+ "emitter-listener": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz",
+ "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==",
+ "requires": {
+ "shimmer": "^1.2.0"
+ }
},
"emoji-regex": {
"version": "7.0.3",
@@ -1127,10 +2063,17 @@
"es6-promise": "^4.0.3"
}
},
+ "escape-goat": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
+ "dev": true
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
},
"escodegen": {
"version": "1.14.1",
@@ -1427,17 +2370,24 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz",
"integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==",
+ "dev": true,
"requires": {
"tslib": "^1.10.0"
}
},
+ "eventemitter2": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz",
+ "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ=="
+ },
"execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
"requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
@@ -1459,6 +2409,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
"requires": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
@@ -1480,6 +2431,20 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
+ "fast-glob": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
+ "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.0",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.2",
+ "picomatch": "^2.2.1"
+ }
+ },
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -1491,6 +2456,24 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
+ "fastq": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
+ "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
"file-entry-cache": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
@@ -1540,6 +2523,15 @@
}
}
},
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
"find": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz",
@@ -1577,10 +2569,31 @@
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
+ "fs-extra": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
+ "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^1.0.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
},
"ftp": {
"version": "0.3.10",
@@ -1614,12 +2627,23 @@
}
}
},
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
+ "fuse.js": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-5.2.3.tgz",
+ "integrity": "sha512-ld3AEgKtKnnXCtJavtygAb+aLlD5aVvLwTocXXBSStLA6JGFI6oMxTvumwh46N2/3gs3A7JNDu1px5F1/cq84g=="
+ },
"gauge": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -1672,9 +2696,13 @@
"dev": true
},
"get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
},
"get-uri": {
"version": "2.0.4",
@@ -1704,23 +2732,6 @@
}
}
},
- "git-up": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz",
- "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==",
- "requires": {
- "is-ssh": "^1.3.0",
- "parse-url": "^5.0.0"
- }
- },
- "git-url-parse": {
- "version": "11.1.2",
- "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.1.2.tgz",
- "integrity": "sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==",
- "requires": {
- "git-up": "^4.0.0"
- }
- },
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -1730,6 +2741,7 @@
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -1749,11 +2761,12 @@
}
},
"global-dirs": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
- "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
+ "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+ "dev": true,
"requires": {
- "ini": "^1.3.4"
+ "ini": "^1.3.5"
}
},
"globals": {
@@ -1765,6 +2778,30 @@
"type-fest": "^0.8.1"
}
},
+ "globby": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ }
+ }
+ },
"gonzales-pe": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
@@ -1775,21 +2812,39 @@
}
},
"got": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
- "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
- "requires": {
- "create-error-class": "^3.0.0",
- "duplexer3": "^0.1.4",
- "get-stream": "^3.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "safe-buffer": "^5.0.1",
- "timed-out": "^4.0.0",
- "unzip-response": "^2.0.1",
- "url-parse-lax": "^1.0.0"
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-11.5.0.tgz",
+ "integrity": "sha512-vOZEcEaK0b6x11uniY0HcblZObKPRO75Jvz53VKuqGSaKCM/zEt0sj2LGYVdqDYJzO3wYdG+FPQQ1hsgoXy7vQ==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^3.0.0",
+ "@szmarczak/http-timer": "^4.0.5",
+ "@types/cacheable-request": "^6.0.1",
+ "@types/responselike": "^1.0.0",
+ "cacheable-lookup": "^5.0.3",
+ "cacheable-request": "^7.0.1",
+ "decompress-response": "^6.0.0",
+ "http2-wrapper": "^1.0.0-beta.4.8",
+ "lowercase-keys": "^2.0.0",
+ "p-cancelable": "^2.0.0",
+ "responselike": "^2.0.0"
+ },
+ "dependencies": {
+ "decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^3.1.0"
+ }
+ },
+ "mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true
+ }
}
},
"graceful-fs": {
@@ -1797,6 +2852,12 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
},
+ "grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
+ },
"graphviz": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz",
@@ -1806,20 +2867,66 @@
"temp": "~0.4.0"
}
},
+ "gunzip-maybe": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz",
+ "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==",
+ "dev": true,
+ "requires": {
+ "browserify-zlib": "^0.1.4",
+ "is-deflate": "^1.0.0",
+ "is-gzip": "^1.0.0",
+ "peek-stream": "^1.1.0",
+ "pumpify": "^1.3.3",
+ "through2": "^2.0.3"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true
},
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
+ "has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true
+ },
"hosted-git-info": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
- "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz",
+ "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
},
"http-errors": {
"version": "1.7.3",
@@ -1862,6 +2969,16 @@
"resolved": "https://registry.npmjs.org/http-ratelimit/-/http-ratelimit-0.2.3.tgz",
"integrity": "sha512-bp9qBHmsuvlF2eagibxWn9kKxqTVkf89K678hquVq/7LOvAeEGe65Z6tpO4YTHkCCyse/7i+uo9HaAJto1QLcg=="
},
+ "http2-wrapper": {
+ "version": "1.0.0-beta.5.2",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
+ "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
+ "dev": true,
+ "requires": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.0.0"
+ }
+ },
"https-proxy-agent": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz",
@@ -1903,7 +3020,8 @@
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
- "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
+ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
+ "dev": true
},
"import-fresh": {
"version": "3.2.1",
@@ -1918,12 +3036,14 @@
"import-lazy": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
- "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
},
"indexes-of": {
"version": "1.0.1",
@@ -1935,6 +3055,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@@ -1953,25 +3074,46 @@
"invert-kv": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
+ "is": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
+ "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
+ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
+ "dev": true
+ },
"is-ci": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
- "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
"requires": {
- "ci-info": "^1.5.0"
+ "ci-info": "^2.0.0"
}
},
+ "is-deflate": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz",
+ "integrity": "sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=",
+ "dev": true
+ },
"is-docker": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
- "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ=="
+ "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==",
+ "dev": true
},
"is-extglob": {
"version": "2.1.1",
@@ -1996,13 +3138,20 @@
"is-extglob": "^2.1.1"
}
},
+ "is-gzip": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz",
+ "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=",
+ "dev": true
+ },
"is-installed-globally": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
- "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
"requires": {
- "global-dirs": "^0.1.0",
- "is-path-inside": "^1.0.0"
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
}
},
"is-interactive": {
@@ -2012,33 +3161,28 @@
"dev": true
},
"is-npm": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
- "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "dev": true
},
- "is-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
- "is-path-inside": {
+ "is-obj": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
- "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
- "requires": {
- "path-is-inside": "^1.0.1"
- }
- },
- "is-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
- "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
},
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
+ "is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true
},
"is-regexp": {
"version": "1.0.0",
@@ -2052,23 +3196,17 @@
"integrity": "sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=",
"dev": true
},
- "is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
- },
- "is-ssh": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz",
- "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==",
- "requires": {
- "protocols": "^1.1.0"
- }
- },
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
},
"is-url": {
"version": "1.2.4",
@@ -2080,10 +3218,17 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
"requires": {
"is-docker": "^2.0.0"
}
},
+ "is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
"is_js": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
@@ -2097,7 +3242,8 @@
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
},
"js-tokens": {
"version": "4.0.0",
@@ -2109,6 +3255,7 @@
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -2129,6 +3276,25 @@
}
}
},
+ "json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "json-file-plus": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/json-file-plus/-/json-file-plus-3.3.1.tgz",
+ "integrity": "sha512-wo0q1UuiV5NsDPQDup1Km8IwEeqe+olr8tkWxeJq9Bjtcp7DZ0l+yrg28fSC3DEtrE311mhTZ54QGS6oiqnZEA==",
+ "dev": true,
+ "requires": {
+ "is": "^3.2.1",
+ "node.extend": "^2.0.0",
+ "object.assign": "^4.1.0",
+ "promiseback": "^2.0.2",
+ "safer-buffer": "^2.0.2"
+ }
+ },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2150,29 +3316,58 @@
"remove-trailing-spaces": "^1.0.6"
}
},
+ "jsonfile": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
+ "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^1.0.0"
+ }
+ },
"jszip": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz",
- "integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==",
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz",
+ "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==",
+ "dev": true,
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"set-immediate-shim": "~1.0.1"
+ },
+ "dependencies": {
+ "pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true
+ }
+ }
+ },
+ "keyv": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz",
+ "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.1"
}
},
"latest-version": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
- "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
"requires": {
- "package-json": "^4.0.0"
+ "package-json": "^6.3.0"
}
},
"lcid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
"requires": {
"invert-kv": "^1.0.0"
}
@@ -2190,6 +3385,7 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "dev": true,
"requires": {
"immediate": "~3.0.5"
}
@@ -2197,43 +3393,78 @@
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
- "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
- "dev": true
+ "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
},
"lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
- "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+ "dev": true
},
"lodash.assignin": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
- "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI="
+ "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=",
+ "dev": true
},
"lodash.clone": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
- "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y="
+ "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=",
+ "dev": true
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "lodash.flatmap": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz",
+ "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=",
+ "dev": true
},
"lodash.flatten": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
- "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
+ "dev": true
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "dev": true
+ },
+ "lodash.isempty": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
+ "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=",
+ "dev": true
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+ "dev": true
},
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
- "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+ "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=",
+ "dev": true
+ },
+ "lodash.topairs": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz",
+ "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=",
+ "dev": true
+ },
+ "log-driver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
+ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg=="
},
"log-symbols": {
"version": "3.0.0",
@@ -2244,24 +3475,35 @@
"chalk": "^2.4.2"
}
},
+ "logic-solver": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/logic-solver/-/logic-solver-2.0.1.tgz",
+ "integrity": "sha1-6fpHAC612M2nYW1BY5uXVS62dL4=",
+ "dev": true,
+ "requires": {
+ "underscore": "^1.7.0"
+ }
+ },
"lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
},
"lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
"requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
+ "yallist": "^4.0.0"
}
},
"macos-release": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
- "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA=="
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.0.tgz",
+ "integrity": "sha512-ko6deozZYiAkqa/0gmcsz+p4jSy3gY7/ZsCEokPaYd8k+6/aXGkiTgr61+Owup7Sf+xjqW8u2ElhoM9SEcEfuA==",
+ "dev": true
},
"madge": {
"version": "3.9.0",
@@ -2372,6 +3614,22 @@
"readable-stream": "^2.0.1"
}
},
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -2387,6 +3645,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -2396,6 +3655,33 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ },
+ "dependencies": {
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "minizlib": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "dev": true,
+ "requires": {
+ "minipass": "^2.9.0"
+ }
+ },
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
@@ -2419,6 +3705,11 @@
"node-source-walk": "^4.0.0"
}
},
+ "module-details-from-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
+ "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is="
+ },
"module-lookup-amd": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-6.2.0.tgz",
@@ -2494,6 +3785,7 @@
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.10.0.tgz",
"integrity": "sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q==",
+ "dev": true,
"requires": {
"async": "^1.4.0",
"ini": "^1.3.0",
@@ -2502,9 +3794,10 @@
}
},
"needle": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz",
- "integrity": "sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz",
+ "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==",
+ "dev": true,
"requires": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
@@ -2515,6 +3808,7 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
"requires": {
"ms": "^2.1.1"
}
@@ -2529,7 +3823,8 @@
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
},
"node-abi": {
"version": "2.16.0",
@@ -2558,20 +3853,32 @@
"resolved": "https://registry.npmjs.org/node-wrap/-/node-wrap-0.2.0.tgz",
"integrity": "sha512-q5nI3nfk1fHEYRNkDiqP04s9GrvhmQ+RxH+a/wE21GXbl+hcphlDaxrtO7duiXM41ilxaw4MtcXoV4pzDWdXnQ=="
},
+ "node.extend": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.2.tgz",
+ "integrity": "sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3",
+ "is": "^3.2.1"
+ }
+ },
"noop-logger": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
},
"normalize-url": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
- "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+ "dev": true
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
"requires": {
"path-key": "^2.0.0"
}
@@ -2600,7 +3907,26 @@
"object-hash": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz",
- "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg=="
+ "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
},
"once": {
"version": "1.4.0",
@@ -2620,9 +3946,10 @@
}
},
"open": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/open/-/open-7.0.3.tgz",
- "integrity": "sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.0.4.tgz",
+ "integrity": "sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ==",
+ "dev": true,
"requires": {
"is-docker": "^2.0.0",
"is-wsl": "^2.1.1"
@@ -2713,6 +4040,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
"requires": {
"lcid": "^1.0.0"
}
@@ -2721,6 +4049,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz",
"integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==",
+ "dev": true,
"requires": {
"macos-release": "^2.2.0",
"windows-release": "^3.1.0"
@@ -2729,17 +4058,41 @@
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-cancelable": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
+ "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==",
+ "dev": true
},
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
},
"p-map": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
- "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
},
"pac-proxy-agent": {
"version": "3.0.1",
@@ -2769,20 +4122,153 @@
}
},
"package-json": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
- "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
"requires": {
- "got": "^6.7.1",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.0"
+ },
+ "dependencies": {
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+ "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ }
+ }
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ }
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
}
},
"pako": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
- "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+ "dev": true
},
"parent-module": {
"version": "1.0.1",
@@ -2793,51 +4279,59 @@
"callsites": "^3.0.0"
}
},
+ "parse-link-header": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz",
+ "integrity": "sha1-vt/g0hGK64S+deewJUGeyKYRQKc=",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.1"
+ }
+ },
"parse-ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz",
"integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==",
"dev": true
},
- "parse-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz",
- "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==",
- "requires": {
- "is-ssh": "^1.3.0",
- "protocols": "^1.4.0"
- }
- },
- "parse-url": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz",
- "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==",
- "requires": {
- "is-ssh": "^1.3.0",
- "normalize-url": "^3.3.0",
- "parse-path": "^4.0.0",
- "protocols": "^1.4.0"
- }
- },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "peek-stream": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz",
+ "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "duplexify": "^3.5.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
"pify": {
@@ -2942,14 +4436,16 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"prepend-http": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
- "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true
},
- "prettier": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
- "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew=="
+ "pretty-bytes": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
+ "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==",
+ "dev": true
},
"pretty-ms": {
"version": "7.0.0",
@@ -2968,12 +4464,14 @@
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dev": true,
"requires": {
"asap": "~2.0.3"
}
@@ -2983,10 +4481,24 @@
"resolved": "https://registry.npmjs.org/promise-all-sequential/-/promise-all-sequential-1.0.0.tgz",
"integrity": "sha512-XQPGPgQZERb1mYEpqSR5tIsC2E5amQZgnqVUPK6gsDtcOv/Yjxmz99cOA1MxLWcuWXz1lZZiD3hERA+rFVdP2w=="
},
- "protocols": {
- "version": "1.4.7",
- "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz",
- "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg=="
+ "promise-deferred": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/promise-deferred/-/promise-deferred-2.0.3.tgz",
+ "integrity": "sha512-n10XaoznCzLfyPFOlEE8iurezHpxrYzyjgq/1eW9Wk1gJwur/N7BdBmjJYJpqMeMcXK4wEbzo2EvZQcqjYcKUQ==",
+ "dev": true,
+ "requires": {
+ "promise": "^7.3.1"
+ }
+ },
+ "promiseback": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/promiseback/-/promiseback-2.0.3.tgz",
+ "integrity": "sha512-VZXdCwS0ppVNTIRfNsCvVwJAaP2b+pxQF7lM8DMWfmpNWyTxB6O5YNbzs+8z0ki/KIBHKHk308NTIl4kJUem3w==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.5",
+ "promise-deferred": "^2.0.3"
+ }
},
"proxy-agent": {
"version": "3.1.1",
@@ -3032,7 +4544,8 @@
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
},
"pump": {
"version": "3.0.0",
@@ -3043,12 +4556,55 @@
"once": "^1.3.1"
}
},
+ "pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "dev": true,
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
+ "pupa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz",
+ "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==",
+ "dev": true,
+ "requires": {
+ "escape-goat": "^2.0.0"
+ }
+ },
+ "querystringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
+ },
+ "quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true
+ },
"rate-limiter-flexible": {
"version": "2.1.9",
"resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.1.9.tgz",
@@ -3104,20 +4660,21 @@
"dev": true
},
"registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz",
+ "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==",
+ "dev": true,
"requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
+ "rc": "^1.2.8"
}
},
"registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
"requires": {
- "rc": "^1.0.1"
+ "rc": "^1.2.8"
}
},
"remedial": {
@@ -3138,6 +4695,16 @@
"is_js": "^0.9.0"
}
},
+ "require-in-the-middle": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.0.3.tgz",
+ "integrity": "sha512-p/ICV8uMlqC4tjOYabLMxAWCIKa0YUQgZZ6KDM0xgXJNgdGQ1WmL2A07TwmrZw+wi6ITUFKzH5v3n+ENEyXVkA==",
+ "requires": {
+ "debug": "^4.1.1",
+ "module-details-from-path": "^1.0.3",
+ "resolve": "^1.12.0"
+ }
+ },
"requirejs": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
@@ -3155,15 +4722,25 @@
"stringify-object": "^3.2.1"
}
},
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
+ },
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
- "dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
+ "resolve-alpn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
+ "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==",
+ "dev": true
+ },
"resolve-dependency-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz",
@@ -3176,6 +4753,15 @@
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
+ "responselike": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
+ "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^2.0.0"
+ }
+ },
"restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@@ -3186,26 +4772,38 @@
"signal-exit": "^3.0.2"
}
},
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"run-async": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz",
- "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==",
- "requires": {
- "is-promise": "^2.1.0"
- }
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "run-parallel": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+ "dev": true
},
"rxjs": {
- "version": "6.5.5",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
- "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz",
+ "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==",
+ "dev": true,
"requires": {
"tslib": "^1.9.0"
}
@@ -3240,12 +4838,14 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
- "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
},
"secure-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/secure-keys/-/secure-keys-1.0.0.tgz",
- "integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o="
+ "integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=",
+ "dev": true
},
"semver": {
"version": "5.7.1",
@@ -3253,11 +4853,20 @@
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"semver-diff": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
- "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+ "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+ "dev": true,
"requires": {
- "semver": "^5.0.3"
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
}
},
"set-blocking": {
@@ -3268,7 +4877,8 @@
"set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
- "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
},
"setprototypeof": {
"version": "1.1.1",
@@ -3279,6 +4889,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
"requires": {
"shebang-regex": "^1.0.0"
}
@@ -3286,7 +4897,13 @@
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shimmer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
+ "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
},
"signal-exit": {
"version": "3.0.2",
@@ -3308,6 +4925,12 @@
"simple-concat": "^1.0.0"
}
},
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
"slice-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
@@ -3333,42 +4956,40 @@
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
},
"snyk": {
- "version": "1.321.0",
- "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.321.0.tgz",
- "integrity": "sha512-0uczPo7A/XD5g8HZwfmO3kwp4QUtuuHelg97O9JcnfLT7Hh6RoyJuuBdEmIECgdCIFZXVV9kAfMAAs6hpgOXsA==",
+ "version": "1.361.3",
+ "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.361.3.tgz",
+ "integrity": "sha512-93SxV9WD+pN/9bGRizfoiYwfKHy5mDyTCdOYtWcVbTFMi7Gf+I4Q5YprunHBTeJLLh0+qsD6l77QBo9GiYyiaA==",
+ "dev": true,
"requires": {
- "@snyk/cli-interface": "2.6.0",
- "@snyk/configstore": "^3.2.0-rc1",
+ "@snyk/cli-interface": "2.8.0",
"@snyk/dep-graph": "1.18.3",
"@snyk/gemfile": "1.2.0",
"@snyk/graphlib": "2.1.9-patch",
"@snyk/inquirer": "6.2.2-patch",
"@snyk/lodash": "^4.17.15-patch",
"@snyk/ruby-semver": "2.2.0",
- "@snyk/snyk-cocoapods-plugin": "2.2.0",
- "@snyk/update-notifier": "^2.5.1-rc2",
- "@types/agent-base": "^4.2.0",
+ "@snyk/snyk-cocoapods-plugin": "2.3.0",
"abbrev": "^1.1.1",
"ansi-escapes": "3.2.0",
"chalk": "^2.4.2",
"cli-spinner": "0.2.10",
- "debug": "^3.1.0",
+ "configstore": "^5.0.1",
+ "debug": "^4.1.1",
"diff": "^4.0.1",
- "git-url-parse": "11.1.2",
"glob": "^7.1.3",
- "needle": "^2.2.4",
+ "needle": "^2.5.0",
"open": "^7.0.3",
"os-name": "^3.0.0",
"proxy-agent": "^3.1.1",
"proxy-from-env": "^1.0.0",
"semver": "^6.0.0",
"snyk-config": "3.1.0",
- "snyk-docker-plugin": "3.2.0",
- "snyk-go-plugin": "1.14.0",
- "snyk-gradle-plugin": "3.2.7",
- "snyk-module": "1.9.1",
- "snyk-mvn-plugin": "2.15.2",
- "snyk-nodejs-lockfile-parser": "1.22.0",
+ "snyk-docker-plugin": "3.13.1",
+ "snyk-go-plugin": "1.14.2",
+ "snyk-gradle-plugin": "3.5.1",
+ "snyk-module": "3.1.0",
+ "snyk-mvn-plugin": "2.17.1",
+ "snyk-nodejs-lockfile-parser": "1.26.3",
"snyk-nuget-plugin": "1.18.1",
"snyk-php-plugin": "1.9.0",
"snyk-policy": "1.14.1",
@@ -3381,38 +5002,28 @@
"source-map-support": "^0.5.11",
"strip-ansi": "^5.2.0",
"tempfile": "^2.0.0",
- "then-fs": "^2.0.0",
+ "update-notifier": "^4.1.0",
"uuid": "^3.3.2",
"wrap-ansi": "^5.1.0"
},
"dependencies": {
- "ansi-escapes": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
- "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ=="
- },
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
- },
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "requires": {
- "ms": "^2.1.1"
- }
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
@@ -3423,6 +5034,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/snyk-config/-/snyk-config-3.1.0.tgz",
"integrity": "sha512-3UlyogA67/9WOssJ7s4d7gqWQRWyO/LbgdBBNMhhmFDKa7eTUSW+A782CVHgyDSJZ2kNANcMWwMiOL+h3p6zQg==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch",
"debug": "^4.1.1",
@@ -3430,44 +5042,87 @@
}
},
"snyk-docker-plugin": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.2.0.tgz",
- "integrity": "sha512-LKsvGcRVBYzyTNT/Z5kImm6uHMX3wAs7gvR4dO8zqBVzCsn3zfi//kmRHWh7zhgvIb6reuhUqY1hMXaz0q/mBw==",
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.13.1.tgz",
+ "integrity": "sha512-4GEZ8Rx+1K33i0SuMRO03T+n8jAosLae4iuo1TZu9ugkxdQzbBStzVFz2N6x1s0GI/psWQNOWSLKfzFJYMOctw==",
+ "dev": true,
"requires": {
- "@snyk/rpm-parser": "^1.1.0",
+ "@snyk/rpm-parser": "^2.0.0",
+ "@snyk/snyk-docker-pull": "^3.1.3",
"debug": "^4.1.1",
+ "docker-modem": "2.1.3",
"dockerfile-ast": "0.0.19",
"event-loop-spinner": "^1.1.0",
+ "gunzip-maybe": "^1.4.2",
"semver": "^6.1.0",
"snyk-nodejs-lockfile-parser": "1.22.0",
"tar-stream": "^2.1.0",
+ "tmp": "^0.2.1",
"tslib": "^1"
},
"dependencies": {
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "snyk-nodejs-lockfile-parser": {
+ "version": "1.22.0",
+ "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.22.0.tgz",
+ "integrity": "sha512-l6jLoJxqcIIkQopSdQuAstXdMw5AIgLu+uGc5CYpHyw8fYqOwna8rawwofNeGuwJAAv4nEiNiexeYaR88OCq6Q==",
+ "dev": true,
+ "requires": {
+ "@snyk/graphlib": "2.1.9-patch",
+ "@snyk/lodash": "^4.17.15-patch",
+ "@yarnpkg/lockfile": "^1.0.2",
+ "event-loop-spinner": "^1.1.0",
+ "p-map": "2.1.0",
+ "snyk-config": "^3.0.0",
+ "source-map-support": "^0.5.7",
+ "tslib": "^1.9.3",
+ "uuid": "^3.3.2"
+ }
+ },
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
+ }
}
}
},
"snyk-go-parser": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/snyk-go-parser/-/snyk-go-parser-1.4.0.tgz",
- "integrity": "sha512-zcLA8u/WreycCjFKBblYfxszg7Fmnemuu9Ug/CE/jqF0yBXsI5DCWMteUvFkoa8DRntfGTlgf98TRl2aTSc2MQ==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/snyk-go-parser/-/snyk-go-parser-1.4.1.tgz",
+ "integrity": "sha512-StU3uHB85VMEkcgXta63M0Fgd+9cs5sMCjQXTBoYTdE4dxarPn7U67yCuwkRRdZdny1ZXtzfY8LKns9i0+dy9w==",
+ "dev": true,
"requires": {
"toml": "^3.0.0",
"tslib": "^1.10.0"
}
},
"snyk-go-plugin": {
- "version": "1.14.0",
- "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.14.0.tgz",
- "integrity": "sha512-9L+76De8F6yXWb+O3DA8QUi7+eDF2mOzCOveEPUJGkqWIDmurIiFcVxHJoj0EStjcxb3dX367KKlDlfFx+HiyA==",
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.14.2.tgz",
+ "integrity": "sha512-r/uaM3gk/RF7m/VGYswxlnA6I+kMgK3eVPsPyf7400BhqF8noh8K7v10CEg67mHA4JM0l7dZASqejr/5kKw9ZQ==",
+ "dev": true,
"requires": {
"@snyk/graphlib": "2.1.9-patch",
"debug": "^4.1.1",
- "snyk-go-parser": "1.4.0",
+ "snyk-go-parser": "1.4.1",
"tmp": "0.1.0",
"tslib": "^1.10.0"
},
@@ -3476,6 +5131,7 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
"integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+ "dev": true,
"requires": {
"rimraf": "^2.6.3"
}
@@ -3483,56 +5139,116 @@
}
},
"snyk-gradle-plugin": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/snyk-gradle-plugin/-/snyk-gradle-plugin-3.2.7.tgz",
- "integrity": "sha512-fBgQpRwfuHGuPvYGEjgNBtuwnkNAV9sv17lG+eWdQO3ntkAKnt1RyzQydAdffK2e8339XM6Mg/1EPYuIGIY3TA==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/snyk-gradle-plugin/-/snyk-gradle-plugin-3.5.1.tgz",
+ "integrity": "sha512-8tZwQCqRbjp1azvc+bBRXSbn2AjbUpFAM6qoSpM/IZpfGl1RaOtz4/JTkGFxj+iBhTFoAkGxEunT66eO0pHZZw==",
+ "dev": true,
"requires": {
- "@snyk/cli-interface": "2.3.2",
+ "@snyk/cli-interface": "2.8.0",
+ "@snyk/dep-graph": "^1.17.0",
"@types/debug": "^4.1.4",
- "chalk": "^2.4.2",
+ "chalk": "^3.0.0",
"debug": "^4.1.1",
- "tmp": "0.0.33",
- "tslib": "^1.9.3"
+ "tmp": "0.2.1",
+ "tslib": "^2.0.0"
},
"dependencies": {
- "@snyk/cli-interface": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.3.2.tgz",
- "integrity": "sha512-jmZyxVHqzYU1GfdnWCGdd68WY/lAzpPVyqalHazPj4tFJehrSfEFc82RMTYAMgXEJuvFRFIwhsvXh3sWUhIQmg==",
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
"requires": {
- "tslib": "^1.9.3"
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "requires": {
+ "rimraf": "^3.0.0"
}
+ },
+ "tslib": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz",
+ "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==",
+ "dev": true
}
}
},
"snyk-module": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-1.9.1.tgz",
- "integrity": "sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-3.1.0.tgz",
+ "integrity": "sha512-HHuOYEAACpUpkFgU8HT57mmxmonaJ4O3YADoSkVhnhkmJ+AowqZyJOau703dYHNrq2DvQ7qYw81H7yyxS1Nfjw==",
+ "dev": true,
"requires": {
- "debug": "^3.1.0",
- "hosted-git-info": "^2.7.1"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "requires": {
- "ms": "^2.1.1"
- }
- }
+ "debug": "^4.1.1",
+ "hosted-git-info": "^3.0.4"
}
},
"snyk-mvn-plugin": {
- "version": "2.15.2",
- "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.15.2.tgz",
- "integrity": "sha512-2TTRizQxfUrA9w0pjxxsvGE+FgFSgog2wwpm378jNiKAZazGgV0txVMM4CoZJMz/tbUmzaJSS8DMQe1C7wlBFQ==",
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.17.1.tgz",
+ "integrity": "sha512-U7ZKrKVnUW2gcyYIzvc0w9nRYh4NXv+wShTIcs++ARCAJOG9A4nxh+ZRmINQ7Sy7EB2qLIRwN4Ssr17+y2mhuA==",
+ "dev": true,
"requires": {
"@snyk/cli-interface": "2.5.0",
- "@snyk/java-call-graph-builder": "1.8.1",
+ "@snyk/java-call-graph-builder": "1.10.0",
"debug": "^4.1.1",
- "needle": "^2.4.0",
+ "needle": "^2.5.0",
"tmp": "^0.1.0",
"tslib": "1.11.1"
},
@@ -3541,6 +5257,7 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.5.0.tgz",
"integrity": "sha512-XMc2SCFH4RBSncZgoPb+BBlNq0NYpEpCzptKi69qyMpBy0VsRqIQqddedaazMCU1xEpXTytq6KMYpzUafZzp5Q==",
+ "dev": true,
"requires": {
"tslib": "^1.9.3"
}
@@ -3549,6 +5266,7 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
"integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+ "dev": true,
"requires": {
"rimraf": "^2.6.3"
}
@@ -3556,25 +5274,44 @@
}
},
"snyk-nodejs-lockfile-parser": {
- "version": "1.22.0",
- "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.22.0.tgz",
- "integrity": "sha512-l6jLoJxqcIIkQopSdQuAstXdMw5AIgLu+uGc5CYpHyw8fYqOwna8rawwofNeGuwJAAv4nEiNiexeYaR88OCq6Q==",
+ "version": "1.26.3",
+ "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.26.3.tgz",
+ "integrity": "sha512-mBQ6vhnXAeyMxlnl9amjJWpA+/3qqXwM8Sj/P+9uH2TByOFLxdGzMNQFcl3q/H2yUdcs/epVdXJp09A2dK2glA==",
+ "dev": true,
"requires": {
"@snyk/graphlib": "2.1.9-patch",
- "@snyk/lodash": "^4.17.15-patch",
- "@yarnpkg/lockfile": "^1.0.2",
- "event-loop-spinner": "^1.1.0",
+ "@yarnpkg/core": "^2.0.0-rc.29",
+ "@yarnpkg/lockfile": "^1.1.0",
+ "event-loop-spinner": "^2.0.0",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.flatmap": "^4.5.0",
+ "lodash.isempty": "^4.4.0",
+ "lodash.set": "^4.3.2",
+ "lodash.topairs": "^4.3.0",
"p-map": "2.1.0",
"snyk-config": "^3.0.0",
"source-map-support": "^0.5.7",
"tslib": "^1.9.3",
- "uuid": "^3.3.2"
+ "uuid": "^3.3.2",
+ "yaml": "^1.9.2"
+ },
+ "dependencies": {
+ "event-loop-spinner": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz",
+ "integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.10.0"
+ }
+ }
}
},
"snyk-nuget-plugin": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/snyk-nuget-plugin/-/snyk-nuget-plugin-1.18.1.tgz",
"integrity": "sha512-Bq+IzbyewxIrUhgdFaDKS5wCNixERC7QBitKsZGM3uCOr9fJM8rr5qg5SS9UIU7eyeKvzuVO/V1yDzjo1cKvUw==",
+ "dev": true,
"requires": {
"@snyk/lodash": "4.17.15-patch",
"debug": "^4.1.1",
@@ -3589,6 +5326,7 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.3.0.tgz",
"integrity": "sha512-EJ9k766htB1ZWnsV5ZMDkKLgA+201r/ouFF8R2OigVjVdcm2rurcBrrdXaeqBJbqnUVMko512PYmlncBKE1Huw==",
+ "dev": true,
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
@@ -3596,10 +5334,17 @@
"set-immediate-shim": "~1.0.1"
}
},
+ "pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true
+ },
"tslib": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
- "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
}
}
},
@@ -3607,6 +5352,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/snyk-paket-parser/-/snyk-paket-parser-1.6.0.tgz",
"integrity": "sha512-6htFynjBe/nakclEHUZ1A3j5Eu32/0pNve5Qm4MFn3YQmJgj7UcAO8hdyK3QfzEY29/kAv/rkJQg+SKshn+N9Q==",
+ "dev": true,
"requires": {
"tslib": "^1.9.3"
}
@@ -3615,6 +5361,7 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/snyk-php-plugin/-/snyk-php-plugin-1.9.0.tgz",
"integrity": "sha512-uORrEoC47dw0ITZYu5vKqQtmXnbbQs+ZkWeo5bRHGdf10W8e4rNr1S1R4bReiLrSbSisYhVHeFMkdOAiLIPJVQ==",
+ "dev": true,
"requires": {
"@snyk/cli-interface": "2.3.2",
"@snyk/composer-lockfile-parser": "1.4.0",
@@ -3625,6 +5372,7 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.3.2.tgz",
"integrity": "sha512-jmZyxVHqzYU1GfdnWCGdd68WY/lAzpPVyqalHazPj4tFJehrSfEFc82RMTYAMgXEJuvFRFIwhsvXh3sWUhIQmg==",
+ "dev": true,
"requires": {
"tslib": "^1.9.3"
}
@@ -3635,6 +5383,7 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/snyk-policy/-/snyk-policy-1.14.1.tgz",
"integrity": "sha512-C5vSkoBYxPnaqb218sm4m6N5s1BhIXlldpIX5xRNnZ0QkDwVj3dy/PfgwxRgVQh7QFGa1ajbvKmsGmm4RRsN8g==",
+ "dev": true,
"requires": {
"debug": "^4.1.1",
"email-validator": "^2.0.4",
@@ -3650,17 +5399,26 @@
"@types/node": {
"version": "6.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz",
- "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA=="
+ "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA==",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+ "dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
},
"snyk-module": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-2.1.0.tgz",
"integrity": "sha512-K5xeA39vLbm23Y/29wFEhKGvo7FwV4x9XhCP5gB22dBPyYiCCNiDERX4ofHQvtM6q96cL0hIroMdlbctv/0nPw==",
+ "dev": true,
"requires": {
"@types/hosted-git-info": "^2.7.0",
"@types/node": "^6.14.7",
@@ -3672,6 +5430,7 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
"requires": {
"ms": "^2.1.1"
}
@@ -3684,6 +5443,7 @@
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/snyk-python-plugin/-/snyk-python-plugin-1.17.1.tgz",
"integrity": "sha512-KKklat9Hfbj4hw2y63LRhgmziYzmyRt+cSuzN5KDmBSAGYck0EAoPDtNpJXjrIs1kPNz28EXnE6NDnadXnOjiQ==",
+ "dev": true,
"requires": {
"@snyk/cli-interface": "^2.0.3",
"tmp": "0.0.33"
@@ -3693,6 +5453,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/snyk-resolve/-/snyk-resolve-1.0.1.tgz",
"integrity": "sha512-7+i+LLhtBo1Pkth01xv+RYJU8a67zmJ8WFFPvSxyCjdlKIcsps4hPQFebhz+0gC5rMemlaeIV6cqwqUf9PEDpw==",
+ "dev": true,
"requires": {
"debug": "^3.1.0",
"then-fs": "^2.0.0"
@@ -3702,6 +5463,7 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
"requires": {
"ms": "^2.1.1"
}
@@ -3712,6 +5474,7 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/snyk-resolve-deps/-/snyk-resolve-deps-4.4.0.tgz",
"integrity": "sha512-aFPtN8WLqIk4E1ulMyzvV5reY1Iksz+3oPnUVib1jKdyTHymmOIYF7z8QZ4UUr52UsgmrD9EA/dq7jpytwFoOQ==",
+ "dev": true,
"requires": {
"@types/node": "^6.14.4",
"@types/semver": "^5.5.0",
@@ -3735,15 +5498,49 @@
"@types/node": {
"version": "6.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.10.tgz",
- "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA=="
+ "integrity": "sha512-pF4HjZGSog75kGq7B1InK/wt/N08BuPATo+7HRfv7gZUzccebwv/fmWVGs/j6LvSiLWpCuGGhql51M/wcQsNzA==",
+ "dev": true
},
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
"requires": {
"ms": "^2.1.1"
}
+ },
+ "hosted-git-info": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "snyk-module": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-1.9.1.tgz",
+ "integrity": "sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "hosted-git-info": "^2.7.1"
+ }
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
}
}
},
@@ -3751,6 +5548,7 @@
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/snyk-sbt-plugin/-/snyk-sbt-plugin-2.11.0.tgz",
"integrity": "sha512-wUqHLAa3MzV6sVO+05MnV+lwc+T6o87FZZaY+43tQPytBI2Wq23O3j4POREM4fa2iFfiQJoEYD6c7xmhiEUsSA==",
+ "dev": true,
"requires": {
"debug": "^4.1.1",
"semver": "^6.1.2",
@@ -3762,12 +5560,14 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
},
"tmp": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
"integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
+ "dev": true,
"requires": {
"rimraf": "^2.6.3"
}
@@ -3778,6 +5578,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/snyk-tree/-/snyk-tree-1.0.0.tgz",
"integrity": "sha1-D7cxdtvzLngvGRAClBYESPkRHMg=",
+ "dev": true,
"requires": {
"archy": "^1.0.0"
}
@@ -3786,6 +5587,7 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/snyk-try-require/-/snyk-try-require-1.3.1.tgz",
"integrity": "sha1-bgJvkuZK9/zM6h7lPVJIQeQYohI=",
+ "dev": true,
"requires": {
"debug": "^3.1.0",
"lodash.clonedeep": "^4.3.0",
@@ -3797,9 +5599,26 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
"requires": {
"ms": "^2.1.1"
}
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
}
}
},
@@ -3840,26 +5659,112 @@
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
+ "split-ca": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
+ "integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=",
+ "dev": true
+ },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
},
"sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
},
+ "ssh2": {
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.8.9.tgz",
+ "integrity": "sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==",
+ "dev": true,
+ "requires": {
+ "ssh2-streams": "~0.4.10"
+ }
+ },
+ "ssh2-streams": {
+ "version": "0.4.10",
+ "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz",
+ "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.0",
+ "bcrypt-pbkdf": "^1.0.2",
+ "streamsearch": "~0.1.2"
+ }
+ },
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
+ "stream-buffers": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
+ "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==",
+ "dev": true
+ },
+ "stream-shift": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+ "dev": true
+ },
+ "stream-to-array": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz",
+ "integrity": "sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=",
+ "dev": true,
+ "requires": {
+ "any-promise": "^1.1.0"
+ }
+ },
+ "stream-to-promise": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-2.2.0.tgz",
+ "integrity": "sha1-se2y4cjLESidG1A8CNPyrvUeZQ8=",
+ "dev": true,
+ "requires": {
+ "any-promise": "~1.3.0",
+ "end-of-stream": "~1.1.0",
+ "stream-to-array": "~2.3.0"
+ },
+ "dependencies": {
+ "end-of-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz",
+ "integrity": "sha1-6TUyWLqpEIll78QcsO+K3i88+wc=",
+ "dev": true,
+ "requires": {
+ "once": "~1.3.0"
+ }
+ },
+ "once": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ }
+ }
+ },
+ "streamsearch": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+ "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=",
+ "dev": true
+ },
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -3928,7 +5833,8 @@
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
},
"strip-json-comments": {
"version": "2.0.1",
@@ -3957,6 +5863,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@@ -4018,6 +5925,29 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
"dev": true
},
+ "tar": {
+ "version": "4.4.13",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+ "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ },
+ "dependencies": {
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
"tar-fs": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
@@ -4062,12 +5992,14 @@
"temp-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
- "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg=="
+ "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
+ "dev": true
},
"tempfile": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
"integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=",
+ "dev": true,
"requires": {
"temp-dir": "^1.0.0",
"uuid": "^3.0.1"
@@ -4076,17 +6008,16 @@
"temp-dir": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
- "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
+ "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
+ "dev": true
}
}
},
"term-size": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
- "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
- "requires": {
- "execa": "^0.7.0"
- }
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
+ "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==",
+ "dev": true
},
"text-table": {
"version": "0.2.0",
@@ -4098,6 +6029,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/then-fs/-/then-fs-2.0.0.tgz",
"integrity": "sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI=",
+ "dev": true,
"requires": {
"promise": ">=3.2 <8"
}
@@ -4105,26 +6037,48 @@
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
},
"thunkify": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz",
"integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0="
},
- "timed-out": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
- },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
"requires": {
"os-tmpdir": "~1.0.2"
}
},
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -4133,7 +6087,8 @@
"toml": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
- "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
+ "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==",
+ "dev": true
},
"traverse-chain": {
"version": "0.1.0",
@@ -4144,12 +6099,14 @@
"tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
- "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true
},
"tslib": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
- "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA=="
+ "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
+ "dev": true
},
"tsutils": {
"version": "3.17.1",
@@ -4160,6 +6117,12 @@
"tslib": "^1.8.1"
}
},
+ "tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true
+ },
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -4168,6 +6131,12 @@
"safe-buffer": "^5.0.1"
}
},
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -4182,10 +6151,26 @@
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
"typescript": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
- "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w=="
+ "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
+ "dev": true
+ },
+ "underscore": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
+ "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==",
+ "dev": true
},
"uniq": {
"version": "1.0.1",
@@ -4194,22 +6179,96 @@
"dev": true
},
"unique-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
- "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
"requires": {
- "crypto-random-string": "^1.0.0"
+ "crypto-random-string": "^2.0.0"
}
},
+ "universalify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+ "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
+ },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
- "unzip-response": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
- "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
+ "update-notifier": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz",
+ "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==",
+ "dev": true,
+ "requires": {
+ "boxen": "^4.2.0",
+ "chalk": "^3.0.0",
+ "configstore": "^5.0.1",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.1",
+ "is-npm": "^4.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "pupa": "^2.0.1",
+ "semver-diff": "^3.1.1",
+ "xdg-basedir": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
},
"uri-js": {
"version": "4.2.2",
@@ -4220,12 +6279,22 @@
"punycode": "^2.1.0"
}
},
+ "url-parse": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
+ "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
"url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
"requires": {
- "prepend-http": "^1.0.1"
+ "prepend-http": "^2.0.0"
}
},
"util-deprecate": {
@@ -4247,7 +6316,8 @@
"vscode-languageserver-types": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
- "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
+ "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==",
+ "dev": true
},
"walkdir": {
"version": "0.4.1",
@@ -4268,6 +6338,7 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
"requires": {
"isexe": "^2.0.0"
}
@@ -4286,60 +6357,52 @@
}
},
"widest-line": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
- "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "dev": true,
"requires": {
- "string-width": "^2.1.1"
+ "string-width": "^4.0.0"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ }
}
},
"window-size": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
- "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
+ "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
+ "dev": true
},
"windows-release": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz",
- "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz",
+ "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==",
+ "dev": true,
"requires": {
"execa": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "requires": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
- "requires": {
- "cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- }
- },
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "requires": {
- "pump": "^3.0.0"
- }
- }
}
},
"word-wrap": {
@@ -4351,6 +6414,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
@@ -4360,22 +6424,20 @@
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
- },
- "emoji-regex": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
- "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
@@ -4386,6 +6448,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
@@ -4407,24 +6470,36 @@
}
},
"write-file-atomic": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
- "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
"requires": {
- "graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.2"
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "ws": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "requires": {
+ "async-limiter": "~1.0.0"
}
},
"xdg-basedir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
- "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+ "dev": true
},
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "dev": true,
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
@@ -4433,7 +6508,8 @@
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "dev": true
},
"xregexp": {
"version": "2.0.0",
@@ -4456,20 +6532,35 @@
}
}
},
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
},
"yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yaml": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+ "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+ "dev": true
},
"yargs": {
"version": "3.32.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+ "dev": true,
"requires": {
"camelcase": "^2.0.1",
"cliui": "^3.0.3",
@@ -4480,15 +6571,11 @@
"y18n": "^3.2.0"
},
"dependencies": {
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
- },
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -4499,6 +6586,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
diff --git a/package.json b/package.json
index 98d66ba4..6a9ea55a 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
"name": "@sv443/jokeapi",
- "version": "2.1.5",
+ "version": "2.2.0",
"description": "A RESTful API that serves jokes from many categories while also offering a lot of filtering methods",
"main": "JokeAPI.js",
"homepage": "https://sv443.net/jokeapi/v2",
"scripts": {
"start": "node . && exit $?",
- "test": "echo \"No test script specified\" && exit 0",
+ "test": "snyk test && node tools/test",
"reformat": "node tools/reformat",
"reassign-ids": "node tools/reassign-ids",
"validate-jokes": "node tools/validate-jokes",
@@ -33,7 +33,7 @@
],
"author": {
"name": "Sv443",
- "email": "sven.fehler@web.de",
+ "email": "contact@sv443.net",
"url": "https://sv443.net/"
},
"contributors": [
@@ -50,11 +50,14 @@
"license": "MIT",
"bugs": {
"url": "https://github.com/Sv443/JokeAPI/issues/new/choose",
- "email": "sven.fehler@web.de"
+ "email": "contact@sv443.net"
},
"dependencies": {
+ "@pm2/io": "^4.3.5",
"dotenv": "^8.2.0",
"farmhash": "^3.1.0",
+ "fs-extra": "^9.0.1",
+ "fuse.js": "^5.2.3",
"http-ratelimit": "^0.2.3",
"js2xmlparser": "^4.0.1",
"json-to-pretty-yaml": "^1.2.2",
@@ -63,13 +66,16 @@
"promise-all-sequential": "^1.0.0",
"rate-limiter-flexible": "^2.1.9",
"request-ip": "^2.1.3",
- "snyk": "^1.321.0",
"svjsl": "^1.9.4",
+ "url-parse": "^1.4.7",
"xss": "^1.0.8"
},
"devDependencies": {
"eslint": "^7.5.0",
- "madge": "^3.9.0"
+ "lodash": "^4.17.15",
+ "madge": "^3.9.0",
+ "snyk": "^1.361.3",
+ "table": "^5.4.6"
},
"snyk": true
}
diff --git a/settings.js b/settings.js
old mode 100755
new mode 100644
index f3239129..5d996a03
--- a/settings.js
+++ b/settings.js
@@ -5,7 +5,7 @@ const bgc = jsl.colors.bg;
const settings = {
debug: {
- verboseLogging: false, // set to true to enable extra debug output
+ verboseLogging: true, // set to true to enable extra debug output
progressBarDisabled: true, // set to true to disable the progress bar - greatly improves readability of verbose debug output
onlyLogErrors: true, // set to true to disable sending any console logs but error messages
},
@@ -22,7 +22,6 @@ const settings = {
website: packageJSON.author.url, // author website
github: `https://github.com/${packageJSON.author.name}`, // author github page
},
- infoMsg: "If you want to be updated on the status and future updates of JokeAPI or need some help, please consider joining my Discord server: https://sv443.net/discord",
privacyPolicyUrl: "https://sv443.net/privacypolicy/en"
},
wrapper: {
@@ -42,6 +41,7 @@ const settings = {
"./data/logs",
"./data/submissions",
"./docs/compiled",
+ "./data/lists"
],
exitSignals: [ // all signals that should cause a soft exit
"SIGINT",
@@ -55,16 +55,23 @@ const settings = {
blacklistLoggingEnabled: true, // whether or not to log the character when an IP is on the blacklist
},
jokes: {
- jokesFormatVersion: 2, // current joke format version
- jokesFilePath: "./data/jokes.json", // path to the jokes file
+ jokesFormatVersion: 3, // current joke format version
+ jokesFolderPath: "./data/jokes/", // path to the jokes folder - needs trailing slash
jokeSubmissionURL: `${packageJSON.homepage}#submit`, // joke submission url
jokeSubmissionPath: "./data/submissions/", // path to a directory where joke submissions should be saved to - needs trailing slash
+ submissions: {
+ timeFrame: 60, // time frame of submission rate limiter (in seconds)
+ rateLimiting: 3, // how many requests per timeframe should be allowed
+ invalidCharRegex: /(?![\u0000-\u0fff])./gm, // eslint-disable-line no-control-regex
+ },
+ jokesTemplateFile: "template.json", // relative to "jokes.jokesFolderPath"
possible: {
anyCategoryName: "Any", // the name of the "Any" category
categories: [ // all categories (excluding "Any") - case insensitive
"Miscellaneous",
"Programming",
- "Dark"
+ "Dark",
+ "Pun"
],
flags: [ // all flags - HAS TO BE LOWER CASE!
"nsfw",
@@ -89,16 +96,18 @@ const settings = {
fileFormat: "json", // the default file format string
mimeType: "application/json", // the default file format mime type
},
- lastIDsMaxLength: 10, // the maximum amount of joke IDs that get saved to the blacklist-array
- jokeRandomizationAttempts: 20, // after how many attempts of selecting a random joke to stop trying
+ lastIDsMaxLength: 15, // the maximum amount of joke IDs that get saved to the blacklist-array
+ jokeRandomizationAttempts: 25, // after how many attempts of selecting a random joke to stop trying
splitChars: [",", "+", "-"], // which characters should separate the values of parameters with support for multiple values
splitCharRegex: /[,+-]/gm, // which characters should separate the values of parameters with support for multiple values
+ maxAmount: 10, // the maximum amount of jokes that can be fetched with a single call to the get jokes endpoint
+ encodeAmount: 5, // if more than this number of jokes is requested, encode them
},
httpServer: {
port: 8076, // http server port
allowCORS: true, // whether or not to allow Cross Origin Resource Sharing
rateLimiting: 60, // amount of allowed requests per below defined timeframe
- timeFrame: 60, // timeframe in seconds - also supports floating point numbers
+ timeFrame: 60, // timeframe in seconds
urlPathOffset: 0, // example: "/jokeapi/info" with an offset of 1 will only start parsing the path beginning at "info" - an Apache reverse proxy will do this automatically though
maxPayloadSize: 5120, // max size (in bytes) that will be accepted in a PUT request - if payload exceeds this size, it will abort with status 413
maxUrlLength: 250, // max amount of characters of the URL - if the URL is longer than this, the request will abort with status 414
@@ -124,8 +133,8 @@ const settings = {
],
},
errors: {
- errorRegistryIncludePath: "./data/errorRegistry", // path to the error registry
- errorLogDir: "./data/logs/", // path to the error log directory - needs trailing slash
+ errorLogDir: "./data/logs/", // path to the error log directory - needs trailing slash
+ errorMessagesPath: "./data/errorMessages", // path to error messages file
},
lists: {
blacklistPath: "./data/lists/ipBlacklist.json", // path to the IP blacklist
@@ -159,12 +168,12 @@ const settings = {
success: col.green, // when request was successful
error: col.red, // when request was errored
ratelimit: col.magenta, // when request was rate limited
- docs: col.yellow, // when docs were requested
- blacklisted: bgc.red + col.yellow, // when a request IP is blacklisted
+ docs: col.yellow, // when docs were requested
+ blacklisted: bgc.red + col.yellow, // when a request IP is blacklisted
docsrecompiled: bgc.yellow + col.blue, // when the docs were recompiled
},
analytics: {
- enabled: true, // whether or not the analytics module should be enabled
+ enabled: false, // whether or not the analytics module should be enabled
dirPath: "./data/analytics/", // path to the analytics directory - needs trailing slash
sqlTableName: "analytics", // name of the SQL table
},
@@ -175,8 +184,17 @@ const settings = {
},
auth: {
tokenListFile: "./data/tokens.json", // path to the token list file
- tokenHeaderName: "authorization", // the name of the token header (in lower case)
+ tokenHeaderName: "authorization", // the name of the token header (lower case)
tokenValidHeader: "Token-Valid", // the name of the token validity response header (normal case, not lower case)
+ daemonInterval: 20, // after how many seconds the auth tokens should be refreshed
+ },
+ languages: {
+ langFilePath: "./data/languages.json", // file containing all language codes and corresponding language information
+ defaultLanguage: "en", // default language (two character code, lowercase)
+ translationsFile: "./data/translations.json", // translations file
+ },
+ tests: { // unit tests
+ location: "./tests/", // folder where unit tests are located - requires trailing slash
}
}
diff --git a/src/analytics.js b/src/analytics.js
index 5b648597..925ca2b4 100755
--- a/src/analytics.js
+++ b/src/analytics.js
@@ -1,7 +1,7 @@
const http = require("http");
const jsl = require("svjsl");
const sql = require("mysql");
-const fs = require("fs");
+const fs = require("fs-extra");
const logger = require("./logger");
const settings = require("../settings");
const debug = require("./verboseLogging");
diff --git a/src/auth.js b/src/auth.js
index 9ca10c9d..2de2424f 100755
--- a/src/auth.js
+++ b/src/auth.js
@@ -1,35 +1,65 @@
const http = require("http");
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
+const crypto = require("crypto");
const settings = require("../settings");
jsl.unused([http]);
+var previousDaemonHash;
+var tokenList;
-
+/**
+ * Initializes the auth module
+ */
const init = () => {
return new Promise(resolve => {
fs.exists(settings.auth.tokenListFile, exists => {
if(!exists)
fs.writeFileSync(settings.auth.tokenListFile, JSON.stringify([], null, 4));
- try
- {
- let tokens = JSON.parse(fs.readFileSync(settings.auth.tokenListFile).toString());
- process._tokenList = tokens;
- return resolve();
- }
- catch(err)
- {
- process._tokenList = [];
- fs.writeFileSync(settings.auth.tokenListFile, JSON.stringify([], null, 4));
- return resolve();
- }
+ refreshTokens();
+ setInterval(() => daemonInterval(), settings.auth.daemonInterval);
+ return resolve();
});
});
};
+/**
+ * To be called on interval to check if the tokens should be refreshed
+ */
+function daemonInterval()
+{
+ let tokenFileRaw = fs.readFileSync(settings.auth.tokenListFile).toString();
+ let tokenHash = crypto.createHash("md5").update(tokenFileRaw).digest("hex");
+
+ if(previousDaemonHash == undefined)
+ return;
+ else if(previousDaemonHash != tokenHash)
+ {
+ previousDaemonHash = tokenHash;
+ refreshTokens();
+ }
+}
+
+/**
+ * Refreshes the auth tokens in memory
+ */
+function refreshTokens()
+{
+ try
+ {
+ let tokens = JSON.parse(fs.readFileSync(settings.auth.tokenListFile).toString());
+ tokenList = tokens;
+ }
+ catch(err)
+ {
+ tokenList = [];
+ fs.writeFileSync(settings.auth.tokenListFile, JSON.stringify([], null, 4));
+ }
+}
+
/**
* @typedef {Object} Authorization
* @prop {Boolean} isAuthorized
@@ -48,9 +78,9 @@ const authByHeader = (req, res) => {
if(req.headers && req.headers[settings.auth.tokenHeaderName])
{
- if(Array.isArray(process._tokenList) && process._tokenList.length > 0)
+ if(Array.isArray(tokenList) && tokenList.length > 0)
{
- process._tokenList.forEach(tokenObj => {
+ tokenList.forEach(tokenObj => {
if(tokenObj.token == req.headers[settings.auth.tokenHeaderName].toString())
{
requestersToken = req.headers[settings.auth.tokenHeaderName].toString();
diff --git a/src/classes/AllJokes.js b/src/classes/AllJokes.js
index 25a15fac..6e16a806 100755
--- a/src/classes/AllJokes.js
+++ b/src/classes/AllJokes.js
@@ -1,74 +1,118 @@
-/**
- * @typedef {Object} SingleJoke A joke of type single
- * @prop {String} category The category of the joke
- * @prop {("single")} type The type of the joke
- * @prop {String} joke The joke itself
- * @prop {Object} flags
- * @prop {Boolean} flags.nsfw Whether the joke is NSFW or not
- * @prop {Boolean} flags.racist Whether the joke is racist or not
- * @prop {Boolean} flags.sexist Whether the joke is sexist or not
- * @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
- * @prop {Boolean} flags.political Whether the joke is politically offensive or not
- * @prop {Number} id The ID of the joke
- */
+const jsl = require("svjsl");
+
+const parseJokes = require("../parseJokes");
+const languages = require("../languages");
+
+const settings = require("../../settings");
-/**
- * @typedef {Object} TwopartJoke A joke of type twopart
- * @prop {String} category The category of the joke
- * @prop {("twopart")} type The type of the joke
- * @prop {String} setup The setup of the joke
- * @prop {String} delivery The delivery of the joke
- * @prop {Object} flags
- * @prop {Boolean} flags.nsfw Whether the joke is NSFW or not
- * @prop {Boolean} flags.racist Whether the joke is racist or not
- * @prop {Boolean} flags.sexist Whether the joke is sexist or not
- * @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
- * @prop {Boolean} flags.political Whether the joke is politically offensive or not
- * @prop {Number} id The ID of the joke
- */
+
+jsl.unused(parseJokes); // only used for typedefs
+
+// expected format:
+/*
+{
+ "en": {
+ info: {
+ formatVersion: 2
+ },
+ jokes: [
+ {
+ (joke)
+ },
+ ...
+ ]
+ },
+ ...
+}
+*/
/**
- * @typedef {Object} JokeArray
- * @prop {Object} info
- * @prop {Number} info.formatVersion
- * @prop {Array} jokes
+ * @typedef {Object} CountPerLangObj
+ * @prop {Number} [en]
+ * @prop {Number} [de]
*/
class AllJokes
{
/**
* Constructs a new AllJokes object. This object contains all methods to get certain jokes
- * @param {JokeArray} jokeArray
+ * @param {Object} jokeArray
*/
constructor(jokeArray)
{
- if(typeof jokeArray != "object" || Array.isArray(jokeArray) || !Array.isArray(jokeArray.jokes))
+ this.jokes = {};
+ let jokeCount = 0;
+ let formatVersions = [];
+ let jokeCountPerLang = {};
+
+ //#SECTION check validity, get joke count and get format versions
+ Object.keys(jokeArray).forEach(key => {
+ if(!languages.isValidLang(key))
+ throw new Error(`Error: invalid language code in construction of an AllJokes object. Expected valid two character language code - got "${key}"`);
+
+ if(!jokeCountPerLang[key])
+ jokeCountPerLang[key] = 0;
+
+ jokeCount += jokeArray[key].jokes.length;
+ jokeCountPerLang[key] += jokeArray[key].jokes.length;
+
+ let fv = jokeArray[key].info.formatVersion;
+
+ jokeArray[key].jokes.forEach((j, i) => {
+ jsl.unused(j);
+
+ jokeArray[key].jokes[i].lang = key;
+ });
+
+ if(fv != settings.jokes.jokesFormatVersion)
+ throw new Error(`Error: Jokes file with language ${key} has the wrong format version. Expected ${settings.jokes.jokesFormatVersion} but got ${fv}`);
+
+ formatVersions.push(fv);
+ });
+
+ formatVersions.push(settings.jokes.jokesFormatVersion);
+
+ if(!jsl.allEqual(formatVersions))
+ throw new Error(`Error: One or more of the jokes-xy.json files contain(s) a wrong formatVersion parameter`);
+
+ if(typeof jokeArray != "object" || Array.isArray(jokeArray))
throw new Error(`Error while constructing a new AllJokes object: parameter "jokeArray" is invalid`);
- this.info = jokeArray["info"];
- this.jokes = jokeArray["jokes"];
- this._jokeCount = jokeArray["jokes"].length;
- this._formatVersion = this.info.formatVersion;
+ this.jokes = jokeArray;
+ this._jokeCount = jokeCount;
+ this._jokeCountPerLang = jokeCountPerLang;
+ this._formatVersions = formatVersions;
+
+ return this;
}
/**
- * Returns an array of all jokes
- * @returns {Array}
+ * Returns an array of all jokes of the specified language
+ * @param {String} [langCode="en"] Two character language code
+ * @returns {Array}
*/
- getJokeArray()
+ getJokeArray(langCode)
{
- return this.jokes;
+ if(!languages.isValidLang(langCode))
+ langCode = settings.languages.defaultLanguage;
+
+ return (typeof this.jokes[langCode] == "object" ? this.jokes[langCode].jokes : []);
}
/**
* Returns the joke format version
- * @returns {(Number|undefined)} Returns a number, if the format version was set, returns undefined, if not
+ * @param {String} [langCode="en"] Two character language code
+ * @returns {Number|undefined} Returns a number if the format version was set, returns undefined, if not
*/
- getFormatVersion()
+ getFormatVersion(langCode)
{
- if(this.info == undefined)
+ if(!languages.isValidLang(langCode))
+ langCode = settings.languages.defaultLanguage;
+
+ if(typeof this.jokes[langCode] != "object")
return undefined;
- return this.info.formatVersion;
+
+ return this.jokes[langCode].info ? this.jokes[langCode].info.formatVersion : undefined;
}
/**
@@ -81,13 +125,13 @@ class AllJokes
}
/**
- * Returns the joke format version
- * @returns {Number}
+ * Returns an object containing joke counts for every lang code
+ * @returns {CountPerLangObj}
*/
- getJokeFormatVersion()
+ getJokeCountPerLang()
{
- return this._formatVersion;
+ return this._jokeCountPerLang;
}
}
-module.exports = AllJokes;
\ No newline at end of file
+module.exports = AllJokes;
diff --git a/src/classes/FilteredJoke.js b/src/classes/FilteredJoke.js
index f6a0fd99..f5854d6a 100755
--- a/src/classes/FilteredJoke.js
+++ b/src/classes/FilteredJoke.js
@@ -2,41 +2,18 @@
// filters can be applied with setter methods
// final getter method returns one or multiple jokes that match all filters
-/**
- * @typedef {Object} SingleJoke A joke of type single
- * @prop {String} category The category of the joke
- * @prop {("single")} type The type of the joke
- * @prop {String} joke The joke itself
- * @prop {Object} flags
- * @prop {Boolean} flags.nsfw Whether the joke is NSFW or not
- * @prop {Boolean} flags.racist Whether the joke is racist or not
- * @prop {Boolean} flags.sexist Whether the joke is sexist or not
- * @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
- * @prop {Boolean} flags.political Whether the joke is politically offensive or not
- * @prop {Number} id The ID of the joke
- */
-
-/**
- * @typedef {Object} TwopartJoke A joke of type twopart
- * @prop {String} category The category of the joke
- * @prop {("twopart")} type The type of the joke
- * @prop {String} setup The setup of the joke
- * @prop {String} delivery The delivery of the joke
- * @prop {Object} flags
- * @prop {Boolean} flags.nsfw Whether the joke is NSFW or not
- * @prop {Boolean} flags.racist Whether the joke is racist or not
- * @prop {Boolean} flags.sexist Whether the joke is sexist or not
- * @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
- * @prop {Boolean} flags.political Whether the joke is politically offensive or not
- * @prop {Number} id The ID of the joke
- */
-
const AllJokes = require("./AllJokes");
const parseJokes = require("../parseJokes");
+const languages = require("../languages");
+const tr = require("../translate");
const jsl = require("svjsl");
const settings = require("../../settings");
-jsl.unused([AllJokes]);
+
+jsl.unused(AllJokes);
+
+var _lastIDs = [];
+var _selectionAttempts = 0;
class FilteredJoke
{
@@ -53,18 +30,29 @@ class FilteredJoke
this._allJokes = allJokes;
this._filteredJokes = null;
+ let idRangePerLang = {};
+
+ Object.keys(parseJokes.jokeCountPerLang).forEach(lc => {
+ idRangePerLang[lc] = [ 0, (parseJokes.jokeCountPerLang[lc] - 1) ];
+ });
+
this._allowedCategories = [
settings.jokes.possible.anyCategoryName.toLowerCase(),
...settings.jokes.possible.categories.map(c => c.toLowerCase())
];
this._allowedTypes = [...settings.jokes.possible.types];
this._searchString = null;
- this._idRange = [0, (parseJokes.jokeCount - 1)];
+ this._idRange = [0, (parseJokes.jokeCountPerLang[settings.languages.defaultLanguage] - 1)];
+ this._idRangePerLang = idRangePerLang;
this._flags = [];
this._errors = [];
+ this._lang = settings.languages.defaultLanguage;
+ this._amount = 1;
+
+ if(!_lastIDs || !Array.isArray(_lastIDs))
+ _lastIDs = [];
- if(!global._lastIDs || !Array.isArray(global._lastIDs))
- global._lastIDs = [];
+ return this;
}
//#MARKER categories
@@ -182,12 +170,16 @@ class FilteredJoke
* The IDs a joke can be of
* @param {Number} start
* @param {Number} [end] If this is not set, it will default to the same value the param `start` has
+ * @param {String} [lang] Lang code
* @returns {Boolean} Returns false if the parameter(s) is/are not of type `number`, else returns true
*/
- setIdRange(start, end = null)
+ setIdRange(start, end = null, lang = null)
{
if(jsl.isEmpty(end))
end = start;
+
+ if(jsl.isEmpty(lang))
+ lang = this.getLanguage() || settings.languages.defaultLanguage;
if(isNaN(parseInt(start)) || isNaN(parseInt(end)) || typeof start != "number" || typeof end != "number" || jsl.isEmpty(start) || jsl.isEmpty(end))
{
@@ -195,7 +187,7 @@ class FilteredJoke
return false;
}
- if(start < 0 || end > (parseJokes.jokeCount - 1))
+ if(start < 0 || end > this._idRangePerLang[lang][1])
{
this._errors.push("The \"idRange\" parameter values are out of range");
return false;
@@ -247,23 +239,81 @@ class FilteredJoke
return this._flags;
}
+ //#MARKER language
+ /**
+ * Sets the language
+ * @param {String} code
+ * @returns {Boolean} Returns true if the language was set, false if it is invalid
+ */
+ setLanguage(code)
+ {
+ if(languages.isValidLang(code) === true)
+ {
+ this._lang = code;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the set language code
+ * @returns {String}
+ */
+ getLanguage()
+ {
+ return this._lang || settings.languages.defaultLanguage;
+ }
+
+ //#MARKER amount
+ /**
+ * Sets the amount of jokes
+ * @param {Number} num
+ * @returns {Boolean|String} Returns true if the amount was set, string containing error if it is invalid
+ */
+ setAmount(num)
+ {
+ num = parseInt(num);
+
+ if(isNaN(num) || num < 1 || num > settings.jokes.maxAmount)
+ return `"num" parameter in FilteredJoke.setAmount() couldn't be resolved to an integer or it is less than 0 or greater than ${settings.jokes.maxAmount}`;
+
+ this._amount = num;
+ return true;
+ }
+
+ /**
+ * Returns the set joke amount or `1` if not yet set
+ * @returns {Number}
+ */
+ getAmount()
+ {
+ return this._amount || 1;
+ }
+
//#MARKER apply filters
/**
* Applies the previously set filters and modifies the `this._filteredJokes` property with the applied filters
* @private
+ * @param {String} lang
* @returns {Promise}
*/
- _applyFilters()
+ _applyFilters(lang)
{
return new Promise((resolve, reject) => {
try
{
this._filteredJokes = [];
- this._allJokes.getJokeArray().forEach(joke => { // iterate over each joke, reading all set filters and thereby checking if it suits the request
+ if(!lang)
+ lang = settings.languages.defaultLanguage;
+
+ this._allJokes.getJokeArray(lang).forEach(joke => {
+ // iterate over each joke, reading all set filters and thereby checking if it suits the request
+ // to deny a joke from being served, just return from this callback function
//#SECTION id range
- let idRange = this.getIdRange();
+ let idRange = this.getIdRange(lang);
if(joke.id < idRange[0] || joke.id > idRange[1]) // if the joke is
return;
@@ -298,109 +348,156 @@ class FilteredJoke
let searchMatches = false;
if(!jsl.isEmpty(this.getSearchString()))
{
- if(joke.type == "single"
- && joke.joke.toLowerCase().includes(this.getSearchString()))
+ if(joke.type == "single" && joke.joke.toLowerCase().includes(this.getSearchString()))
searchMatches = true;
- else if (joke.type == "twopart"
- && (joke.setup + joke.delivery).toLowerCase().includes(this.getSearchString()))
+ else if (joke.type == "twopart" && (joke.setup + joke.delivery).toLowerCase().includes(this.getSearchString()))
searchMatches = true;
}
else searchMatches = true;
if(!searchMatches) // if the provided search string doesn't match the joke, the joke is invalid
return;
+
+ //#SECTION language
+ let langCode = this.getLanguage();
+ if(!languages.isValidLang(langCode))
+ return; // invalid lang code
+ if(joke.lang.toLowerCase() != langCode.toLowerCase())
+ return; // lang code doesn't match
+
+ // amount param is used in getJokes()
//#SECTION done
this._filteredJokes.push(joke); // joke is valid, push it to the array that gets passed in the resolve()
});
- resolve(this._filteredJokes);
+
+ return resolve(this._filteredJokes);
}
catch(err)
{
- reject(err);
+ return reject(err);
}
});
}
- //#MARKER get joke(s)
+ //#MARKER get joke
/**
* Applies all filters and returns the final joke
- * @returns {Promise} Returns a promise containing a single, randomly selected joke that matches the previously set filters. If the filters didn't match, rejects promise.
+ * @param {Number} [amount=1] The amount of jokes to return
+ * @returns {Promise>} Returns a promise containing an array, which in turn contains a single or multiple randomly selected joke/s that match/es the previously set filters. If the filters didn't match, rejects promise.
*/
- getJoke()
+ getJokes(amount = 1)
{
+ amount = parseInt(amount);
+ if(isNaN(amount) || jsl.isEmpty(amount))
+ amount = 1;
+
return new Promise((resolve, reject) => {
- this._applyFilters().then(filteredJokes => {
+ let retJokes = [];
+ let multiSelectLastIDs = [];
+
+ this._applyFilters(this._lang || settings.languages.defaultLanguage).then(filteredJokes => {
if(filteredJokes.length == 0 || typeof filteredJokes != "object")
{
- if(this._errors)
+ if(this._errors && this._errors.length > 0)
return reject(this._errors);
else
- return reject("No jokes were found that match your provided filter(s)");
+ return reject(tr(this.getLanguage(), "foundNoMatchingJokes"));
}
- if(!global._lastIDs || !Array.isArray(global._lastIDs))
- global._lastIDs = [];
+ if(!_lastIDs || !Array.isArray(_lastIDs))
+ _lastIDs = [];
- if(typeof global._selectionAttempts != "number")
- global._selectionAttempts = 0;
+ if(typeof _selectionAttempts != "number")
+ _selectionAttempts = 0;
/**
- * @param {Array} jokes
+ * @param {Array} jokes
*/
let selectRandomJoke = jokes => {
- let selectedJoke = filteredJokes[jsl.randRange(0, (filteredJokes.length - 1))];
+ let idx = jsl.randRange(0, (jokes.length - 1));
+ let selectedJoke = jokes[idx];
- if(jokes.length > settings.jokes.lastIDsMaxLength && global._lastIDs.includes(selectedJoke.id))
+ if(jokes.length > settings.jokes.lastIDsMaxLength && _lastIDs.includes(selectedJoke.id))
{
- if(global._selectionAttempts > settings.jokes.jokeRandomizationAttempts)
+ if(_selectionAttempts > settings.jokes.jokeRandomizationAttempts)
return reject();
- global._selectionAttempts++;
- let reducedJokeArray = [];
+ _selectionAttempts++;
- jokes.forEach(j => {
- if(!global._lastIDs.includes(j.id))
- reducedJokeArray.push(j);
- });
-
- return selectRandomJoke(reducedJokeArray);
+ jokes.splice(idx, 1); // remove joke that is already contained in _lastIDs
+
+ return selectRandomJoke(jokes);
}
else
{
- global._lastIDs.push(selectedJoke.id);
+ _lastIDs.push(selectedJoke.id);
+
+ if(_lastIDs.length > settings.jokes.lastIDsMaxLength)
+ _lastIDs.shift();
+
+ _selectionAttempts = 0;
+
+ if(!multiSelectLastIDs.includes(selectedJoke.id))
+ {
+ multiSelectLastIDs.push(selectedJoke.id);
+ return selectedJoke;
+ }
+ else
+ {
+ if(_selectionAttempts > settings.jokes.jokeRandomizationAttempts)
+ return reject();
- if(global._lastIDs.length > settings.jokes.lastIDsMaxLength)
- global._lastIDs.shift();
+ _selectionAttempts++;
- global._selectionAttempts = 0;
+ jokes.splice(idx, 1); // remove joke that is already contained in _lastIDs
- return selectedJoke;
+ return selectRandomJoke(jokes);
+ }
}
};
- let randJoke = selectRandomJoke(filteredJokes);
- return resolve(randJoke);
+ if(amount < filteredJokes.length)
+ {
+ for(let i = 0; i < amount; i++)
+ {
+ let rJoke = selectRandomJoke(filteredJokes);
+ if(rJoke != null)
+ retJokes.push(rJoke);
+ }
+ }
+ else retJokes = filteredJokes;
+
+ // Sort jokes by ID
+ // retJokes.sort((a, b) => {
+ // if(b.id > a.id)
+ // return -1;
+ // else
+ // return 1;
+ // });
+
+ return resolve(retJokes);
}).catch(err => {
return reject(err);
});
});
}
+ //#MARKER get all jokes
/**
* Applies all filters and returns an array of all jokes that are viable
- * @returns {Promise>} Returns a promise containing a single, randomly selected joke that matches the previously set filters. If the filters didn't match, rejects promise.
+ * @returns {Promise>} Returns a promise containing a single, randomly selected joke that matches the previously set filters. If the filters didn't match, rejects promise.
*/
getAllJokes()
{
return new Promise((resolve, reject) => {
- this._applyFilters().then(filteredJokes => {
- resolve(filteredJokes);
+ this._applyFilters(this._lang || settings.languages.defaultLanguage).then(filteredJokes => {
+ return resolve(filteredJokes);
}).catch(err => {
- reject(err);
+ return reject(err);
});
});
}
}
-module.exports = FilteredJoke;
\ No newline at end of file
+module.exports = FilteredJoke;
diff --git a/src/docs.js b/src/docs.js
index 47524acf..45984ca7 100755
--- a/src/docs.js
+++ b/src/docs.js
@@ -2,7 +2,7 @@
const jsl = require("svjsl");
const farmhash = require("farmhash");
-const fs = require("fs");
+const fs = require("fs-extra");
const settings = require("../settings");
const debug = require("./verboseLogging");
const packageJSON = require("../package.json");
@@ -12,6 +12,7 @@ const zlib = require("zlib");
const xss = require("xss");
const semver = require("semver");
const analytics = require("./analytics");
+const languages = require("./languages");
/**
@@ -109,17 +110,21 @@ const recompileDocs = () => {
process.brCompErrOnce = false;
if(settings.httpServer.encodings.gzip)
- saveEncoded("gzip", injectedFileNames[i], injected).catch(err => void(err));
+ saveEncoded("gzip", injectedFileNames[i], injected).catch(err => jsl.unused(err));
if(settings.httpServer.encodings.deflate)
- saveEncoded("deflate", injectedFileNames[i], injected).catch(err => void(err));
+ saveEncoded("deflate", injectedFileNames[i], injected).catch(err => jsl.unused(err));
if(settings.httpServer.encodings.brotli)
- saveEncoded("brotli", injectedFileNames[i], injected).catch(() => {
+ {
+ saveEncoded("brotli", injectedFileNames[i], injected).catch(err => {
+ jsl.unused(err);
+
if(!process.brCompErrOnce)
{
process.brCompErrOnce = true;
injectError(`Brotli compression is only supported since Node.js version 11.7.0 - current Node.js version is ${semver.clean(process.version)}`, false);
}
});
+ }
fs.writeFile(injectedFileNames[i], injected, err => {
if(err)
@@ -127,7 +132,7 @@ const recompileDocs = () => {
return resolve();
});
- })
+ });
}));
});
@@ -262,6 +267,10 @@ const inject = filePath => {
"": settings.jokes.jokesFormatVersion.toString(),
"": settings.httpServer.maxPayloadSize.toString(),
"": settings.httpServer.maxUrlLength.toString(),
+ "": languages.jokeLangs().length.toString(),
+ "": languages.systemLangs().length.toString(),
+ "": settings.jokes.maxAmount.toString(),
+ "": settings.jokes.encodeAmount.toString()
};
let allMatches = 0;
@@ -303,4 +312,4 @@ const sanitize = str => {
const minify = input => input.toString().replace(/(\n|\r\n|\t)/gm, "");
-module.exports = { init, recompileDocs, minify, sanitize };
\ No newline at end of file
+module.exports = { init, recompileDocs, minify, sanitize };
diff --git a/src/fileFormatConverter.js b/src/fileFormatConverter.js
index 84314301..5f745b0c 100755
--- a/src/fileFormatConverter.js
+++ b/src/fileFormatConverter.js
@@ -4,14 +4,20 @@ const jsl = require("svjsl");
const jsonToYaml = require("json-to-pretty-yaml");
const jsonToXml = require("js2xmlparser");
+const languages = require("./languages");
+const tr = require("./translate");
+const systemLangs = tr.systemLangs;
+
+const settings = require("../settings");
/**
* Converts a JSON object to a string representation of a XML, YAML, plain text or JSON (as fallback) object - based on a passed format string
* @param {("xml"|"yaml"|"json"|"txt")} format Can be "xml", "yaml" or "txt", everything else will default to JSON
- * @param {Object} jsonInput
+ * @param {Object} jsonInput
+ * @param {String} [lang] Needed for converting to "txt" - TODO: implement everywhere
* @returns {String} String representation of the converted object
*/
-const auto = (format, jsonInput) => {
+const auto = (format, jsonInput, lang) => {
format = format.toLowerCase();
switch(format)
{
@@ -20,7 +26,7 @@ const auto = (format, jsonInput) => {
case "xml":
return toXML(jsonInput);
case "txt":
- return toTXT(jsonInput);
+ return toTXT(jsonInput, lang);
case "json":
default:
return JSON.stringify(jsonInput, null, 4);
@@ -39,16 +45,26 @@ const toXML = jsonInput => {
return jsonToXml.parse("data", jsonInput);
};
-const toTXT = jsonInput => {
- let returnText = `Internal Error - no conversion mapping for data with keys "${Object.keys(jsonInput).join(", ")}" - ERR_NO_CONV_MAPPING @ FF_CONV`;
+/**
+ * Converts a JSON object to plain text, according to the set conversion mapping
+ * @param {Object} jsonInput
+ * @param {String} lang
+ */
+const toTXT = (jsonInput, lang) => {
+ let returnText = tr(lang, "noConversionMapping", Object.keys(jsonInput).join(", "), "ERR_NO_CONV_MAPPING @ FFCONV");
if(!jsonInput)
- returnText = "Internal Error - could not convert data to plain text - ERR_NO_JSON_INPUT @ FF_CONV"
+ returnText = tr(lang, "cantConvertToPlainText", "ERR_NO_JSON_INPUT @ FFCONV");
if(jsonInput)
{
if(jsonInput.error === true)
- returnText = `${jsonInput.internalError === true ? "Internal " : ""}Error ${jsonInput.code || 100} - ${jsonInput.message}\nThis error is caused by:\n- ${jsonInput.causedBy.join("\n- ")}${jsonInput.additionalInfo ? `\n\nAdditional Information: ${jsonInput.additionalInfo}` : ""}`;
+ {
+ if(jsonInput.internalError)
+ returnText = tr(lang, "conversionInternalError", (jsonInput.code || 100), jsonInput.message, jsonInput.causedBy.join("\n- "), (jsonInput.additionalInfo ? jsonInput.additionalInfo : "X"));
+ else
+ returnText = tr(lang, "conversionGeneralError", (jsonInput.code || 100), jsonInput.message, jsonInput.causedBy.join("\n- "), (jsonInput.additionalInfo ? jsonInput.additionalInfo : "X"));
+ }
else
{
if(jsonInput.joke || (jsonInput.setup && jsonInput.delivery)) // endpoint: /joke
@@ -58,27 +74,67 @@ const toTXT = jsonInput => {
else if(jsonInput.type == "twopart")
returnText = `${jsonInput.setup}\n\n${jsonInput.delivery}`;
}
-
- else if(jsonInput.formats) // endpoint: /formats
- returnText = `Available formats are: "${jsonInput.formats.join('", "')}"`;
else if(jsonInput.categories) // endpoint: /categories
- returnText = `Available categories are: "${jsonInput.categories.join('", "')}"`;
+ returnText = tr(lang, "availableCategories", jsonInput.categories.join('", "'));
else if(jsonInput.flags) // endpoint: /flags
- returnText = `Available flags are: "${jsonInput.flags.join('", "')}"`;
+ returnText = tr(lang, "availableFlags", jsonInput.flags.join('", "'));
else if(jsonInput.ping) // endpoint: /ping
- returnText = `${jsonInput.ping}\nTimestamp: ${jsonInput.timestamp}`;
+ returnText = `${jsonInput.ping}\n${tr(lang, "timestamp", jsonInput.timestamp)}`;
+
+ else if(jsonInput.code) // endpoint: /langcode
+ returnText = `${jsonInput.error ? tr(lang, "genericError", jsonInput.message) : tr(lang, "languageCode", jsonInput.code)}`;
+
+ else if(jsonInput.defaultLanguage) // endpoint: /languages
+ {
+ let suppLangs = [];
+ languages.jokeLangs().forEach(lang => {
+ suppLangs.push(`${lang.name} [${lang.code}]`);
+ });
+
+ let sysLangs = systemLangs().map(lc => `${languages.codeToLanguage(lc)} [${lc}]`);
+
+ let possLangs = [];
+
+ jsonInput.possibleLanguages.forEach(pl => {
+ possLangs.push(`${pl.name} [${pl.code}]`);
+ });
+
+ returnText = tr(lang, "languagesEndpoint", languages.codeToLanguage(jsonInput.defaultLanguage), jsonInput.defaultLanguage, languages.jokeLangs().length, suppLangs.sort().join(", "), sysLangs.length, sysLangs.sort().join(", "), possLangs.sort().join("\n"));
+ }
else if(jsonInput.version) // endpoint: /info
- returnText = `Version: ${jsonInput.version}\nJoke Count: ${jsonInput.jokes.totalCount}\nCategories: "${jsonInput.jokes.categories.join('", "')}"\nFlags: "${jsonInput.jokes.flags.join('", "')}"\nSubmission URL: ${jsonInput.jokes.submissionURL}\n\n${jsonInput.info}`;
+ {
+ let suppLangs = [];
+ languages.jokeLangs().forEach(lang => {
+ suppLangs.push(`${lang.name} [${lang.code}]`);
+ });
+
+ let sysLangs = systemLangs().map(lc => `${languages.codeToLanguage(lc)} [${lc}]`);
+
+ let idRanges = [];
+ Object.keys(jsonInput.jokes.idRange).forEach(lc => {
+ let lcIr = jsonInput.jokes.idRange[lc];
+ idRanges.push(`${languages.codeToLanguage(lc)} [${lc}]: ${lcIr[0]}-${lcIr[1]}`);
+ });
+
+ returnText = tr(lang, "infoEndpoint",
+ settings.info.name, jsonInput.version, jsonInput.jokes.totalCount, jsonInput.jokes.categories.join(`", "`), jsonInput.jokes.flags.join('", "'),
+ jsonInput.formats.join('", "'), jsonInput.jokes.types.join('", "'), jsonInput.jokes.submissionURL, idRanges.join("\n"), languages.jokeLangs().length,
+ suppLangs.sort().join(", "), sysLangs.length, sysLangs.sort().join(", "), jsonInput.info
+ );
+ }
+
+ else if(jsonInput.formats) // endpoint: /formats
+ returnText = tr(lang, "availableFormats", jsonInput.formats.join('", "'));
else if(Array.isArray(jsonInput) && jsonInput[0].usage && jsonInput[0].usage.method) // endpoint: /endpoints
{
- returnText = "Endpoints:\n\n\n";
+ returnText = `${tr(lang, "endpointsWord")}:\n\n\n`;
jsonInput.forEach(ep => {
- returnText += `${ep.name} - ${ep.description}\n Usage: ${ep.usage.method} ${ep.usage.url}\n Supported parameters: ${ep.usage.supportedParams.length > 0 ? `"${ep.usage.supportedParams.join('", "')}"` : "none"}\n\n\n`
+ returnText += `${tr(lang, "endpointDetails", ep.name, ep.description, ep.usage.method, ep.usage.url, (ep.usage.supportedParams.length > 0 ? `"${ep.usage.supportedParams.join('", "')}"` : "X"))}\n\n`;
});
}
}
diff --git a/src/httpServer.js b/src/httpServer.js
old mode 100755
new mode 100644
index 5d04a143..c2b9aabe
--- a/src/httpServer.js
+++ b/src/httpServer.js
@@ -2,9 +2,10 @@
const jsl = require("svjsl");
const http = require("http");
-const { RateLimiterMemory, RateLimiterRes } = require("rate-limiter-flexible");
const Readable = require("stream").Readable;
-const fs = require("fs");
+const fs = require("fs-extra");
+const zlib = require("zlib");
+const semver = require("semver");
const settings = require("../settings");
const debug = require("./verboseLogging");
@@ -17,6 +18,10 @@ const lists = require("./lists");
const analytics = require("./analytics");
const jokeSubmission = require("./jokeSubmission");
const auth = require("./auth");
+const meter = require("./meter");
+const languages = require("./languages");
+const { RateLimiterMemory, RateLimiterRes } = require("rate-limiter-flexible");
+const tr = require("./translate");
jsl.unused(RateLimiterRes); // typedef only
@@ -30,12 +35,17 @@ const init = () => {
* Initializes the HTTP server - should only be called once
*/
let initHttpServer = () => {
- //#SECTION set up rate limiter
+ //#SECTION set up rate limiters
let rl = new RateLimiterMemory({
points: settings.httpServer.rateLimiting,
duration: settings.httpServer.timeFrame
});
+ let rlSubm = new RateLimiterMemory({
+ points: settings.jokes.submissions.rateLimiting,
+ duration: settings.jokes.submissions.timeFrame
+ });
+
//#SECTION create HTTP server
let httpServer = http.createServer(async (req, res) => {
let parsedURL = parseURL(req.url);
@@ -45,17 +55,21 @@ const init = () => {
let analyticsObject = {
ipAddress: ip,
urlPath: parsedURL.pathArray,
- urlParameters: parsedURL.queryParams
+ urlParameters: parsedURL.queryParams
};
+ let lang = parsedURL.queryParams ? parsedURL.queryParams.lang : "invalid-lang-code";
+
+ if(languages.isValidLang(lang) !== true)
+ lang = settings.languages.defaultLanguage;
- debug("HTTP", `Incoming ${req.method} request from "${ip.substring(0, 8)}${localhostIP ? `..." ${jsl.colors.fg.blue}(local)${jsl.colors.rst}` : "...\""}`);
+ debug("HTTP", `Incoming ${req.method} request from "${lang}-${ip.substring(0, 8)}${localhostIP ? `..." ${jsl.colors.fg.blue}(local)${jsl.colors.rst}` : "...\""} to ${req.url}`);
let fileFormat = settings.jokes.defaultFileFormat.fileFormat;
if(!jsl.isEmpty(parsedURL.queryParams) && !jsl.isEmpty(parsedURL.queryParams.format))
fileFormat = parseURL.getFileFormatFromQString(parsedURL.queryParams);
if(req.url.length > settings.httpServer.maxUrlLength)
- return respondWithError(res, 108, 414, fileFormat, `The length of the URL (${req.url.length} characters) exceeds the maximum accepted length of ${settings.httpServer.maxUrlLength} characters`);
+ return respondWithError(res, 108, 414, fileFormat, tr(lang, "uriTooLong", req.url.length, settings.httpServer.maxUrlLength), lang, req.url.length);
//#SECTION check lists
try
@@ -63,7 +77,7 @@ const init = () => {
if(lists.isBlacklisted(ip))
{
logRequest("blacklisted", null, analyticsObject);
- return respondWithError(res, 103, 403, fileFormat);
+ return respondWithError(res, 103, 403, fileFormat, tr(lang, "ipBlacklisted", settings.info.author.website), lang);
}
debug("HTTP", `Requested URL: ${parsedURL.initialURL}`);
@@ -106,9 +120,13 @@ const init = () => {
urlPath: parsedURL.pathArray
}
});
- return respondWithError(res, 500, 100, fileFormat, err);
+ return respondWithError(res, 500, 100, fileFormat, tr(lang, "errSetupHttpResponse", err), lang);
}
+ meter.update("reqtotal", 1);
+ meter.update("req1min", 1);
+ meter.update("req10min", 1);
+
//#SECTION GET
if(req.method === "GET")
{
@@ -120,7 +138,7 @@ const init = () => {
let lowerCaseEndpoints = [];
endpoints.forEach(ep => lowerCaseEndpoints.push(ep.name.toLowerCase()));
- if(!jsl.isEmpty(urlPath))
+ if(!jsl.isArrayEmpty(urlPath))
requestedEndpoint = urlPath[0];
else
{
@@ -133,7 +151,7 @@ const init = () => {
setRateLimitedHeaders(res, rlRes);
analytics.rateLimited(ip);
logRequest("ratelimited", `IP: ${ip}`, analyticsObject);
- return respondWithError(res, 101, 429, fileFormat);
+ return respondWithError(res, 101, 429, fileFormat, tr(lang, "rateLimited", settings.httpServer.rateLimiting, settings.httpServer.timeFrame), lang);
}
else
return serveDocumentation(req, res);
@@ -143,7 +161,7 @@ const init = () => {
// setRateLimitedHeaders(res, rlRes);
analytics.rateLimited(ip);
logRequest("ratelimited", `IP: ${ip}`, analyticsObject);
- return respondWithError(res, 101, 429, fileFormat);
+ return respondWithError(res, 101, 429, fileFormat, tr(lang, "rateLimited", settings.httpServer.rateLimiting, settings.httpServer.timeFrame), lang);
}
}
@@ -211,7 +229,7 @@ const init = () => {
}
catch(err)
{
- return respondWithError(res, 104, 500, fileFormat);
+ return respondWithError(res, 104, 500, fileFormat, tr(lang, "endpointInternalError", err), lang);
}
}
else
@@ -220,12 +238,12 @@ const init = () => {
{
let rlRes = await rl.get(ip);
- if((rlRes &&rlRes._remainingPoints < 0) && !lists.isWhitelisted(ip) && !isAuthorized)
+ if((rlRes && rlRes._remainingPoints < 0) && !lists.isWhitelisted(ip) && !isAuthorized)
{
setRateLimitedHeaders(res, rlRes);
logRequest("ratelimited", `IP: ${ip}`, analyticsObject);
analytics.rateLimited(ip);
- return respondWithError(res, 101, 429, fileFormat);
+ return respondWithError(res, 101, 429, fileFormat, tr(lang, "rateLimited", settings.httpServer.rateLimiting, settings.httpServer.timeFrame), lang);
}
else
{
@@ -243,7 +261,7 @@ const init = () => {
// setRateLimitedHeaders(res, rlRes);
logRequest("ratelimited", `IP: ${ip}`, analyticsObject);
analytics.rateLimited(ip);
- return respondWithError(res, 101, 429, fileFormat);
+ return respondWithError(res, 100, 500, fileFormat, tr(lang, "generalInternalError", err), lang);
}
}
}
@@ -253,9 +271,9 @@ const init = () => {
if(!foundEndpoint)
{
if(!jsl.isEmpty(fileFormat) && req.url.toLowerCase().includes("format"))
- return respondWithError(res, 102, 404, fileFormat, `Endpoint "${!jsl.isEmpty(requestedEndpoint) ? requestedEndpoint : "/"}" not found - Please read the documentation at ${settings.info.docsURL}#endpoints to see all available endpoints`);
+ return respondWithError(res, 102, 404, fileFormat, tr(lang, "endpointNotFound", (!jsl.isEmpty(requestedEndpoint) ? requestedEndpoint : "/")), lang);
else
- return respondWithErrorPage(res, 404, `Endpoint "${!jsl.isEmpty(requestedEndpoint) ? requestedEndpoint : "/"}" not found - Please read the documentation at ${settings.info.docsURL}#endpoints to see all available endpoints`);
+ return respondWithErrorPage(res, 404, tr(lang, "endpointNotFound", (!jsl.isEmpty(requestedEndpoint) ? requestedEndpoint : "/")));
}
}, 5000);
}
@@ -264,8 +282,12 @@ const init = () => {
else if(req.method === "PUT")
{
//#MARKER Joke submission
- if(!jsl.isEmpty(parsedURL.pathArray) && parsedURL.pathArray[0] == "submit")
+ let submissionsRateLimited = await rlSubm.get(ip);
+
+ if(!jsl.isEmpty(parsedURL.pathArray) && parsedURL.pathArray[0] == "submit" && !(submissionsRateLimited && submissionsRateLimited._remainingPoints <= 0 && !headerAuth.isAuthorized))
{
+ rlSubm.consume(ip, 1);
+
let data = "";
let dataGotten = false;
req.on("data", chunk => {
@@ -273,8 +295,8 @@ const init = () => {
let payloadLength = byteLength(data);
if(payloadLength > settings.httpServer.maxPayloadSize)
- return respondWithError(res, 107, 413, fileFormat, `The provided payload data is too large (${payloadLength} bytes of ${settings.httpServer.maxPayloadSize})`);
-
+ return respondWithError(res, 107, 413, fileFormat, tr(lang, "payloadTooLarge", payloadLength, settings.httpServer.maxPayloadSize), lang);
+
if(!jsl.isEmpty(data))
dataGotten = true;
@@ -285,13 +307,17 @@ const init = () => {
if(!dataGotten)
{
debug("HTTP", "PUT request timed out");
- return respondWithError(res, 105, 400, fileFormat, "Request body is empty");
+ return respondWithError(res, 105, 400, fileFormat, tr(lang, "requestEmptyOrTimedOut"), lang);
}
}, 3000);
}
else
{
//#MARKER Restart / invalid PUT
+
+ if(submissionsRateLimited && submissionsRateLimited._remainingPoints <= 0 && !headerAuth.isAuthorized)
+ return respondWithError(res, 110, 429, fileFormat, tr(lang, "rateLimitedShort"), lang);
+
let data = "";
let dataGotten = false;
req.on("data", chunk => {
@@ -307,18 +333,18 @@ const init = () => {
"error": false,
"message": `Restarting ${settings.info.name}`,
"timestamp": new Date().getTime()
- }));
+ }, lang));
console.log(`\n\n[${logger.getTimestamp(" | ")}] ${jsl.colors.fg.red}IP ${jsl.colors.fg.yellow}${ip.substr(0, 8)}[...]${jsl.colors.fg.red} sent a restart command\n\n\n${jsl.colors.rst}`);
process.exit(2); // if the process is exited with status 2, the package node-wrap will restart the process
}
- else return respondWithErrorPage(res, 400, `Request body is invalid or was sent to the wrong endpoint "${parsedURL.pathArray != null ? parsedURL.pathArray[0] : "/"}", please refer to the documentation at ${settings.info.docsURL}#submit-joke to see how to correctly structure a joke submission.`);
+ else return respondWithErrorPage(res, 400, tr(lang, "invalidSubmissionOrWrongEndpoint", (parsedURL.pathArray != null ? parsedURL.pathArray[0] : "/")));
});
setTimeout(() => {
if(!dataGotten)
{
debug("HTTP", "PUT request timed out");
- return respondWithErrorPage(res, 400, "Request body is empty");
+ return respondWithErrorPage(res, 400, tr(lang, "requestBodyIsInvalid"));
}
}, 3000);
}
@@ -335,7 +361,7 @@ const init = () => {
"internalError": false,
"message": `Wrong method "${req.method}" used. Expected "GET", "OPTIONS" or "HEAD"`,
"timestamp": new Date().getTime()
- }));
+ }, lang));
}
});
@@ -412,21 +438,45 @@ function setRateLimitedHeaders(res, rlRes)
* @param {Number} responseCode The HTTP response code to end the request with
* @param {String} fileFormat The file format to respond with - automatically gets converted to MIME type
* @param {String} errorMessage Additional error info
+ * @param {String} lang Language code of the request
+ * @param {...any} args Arguments to replace numbered %-placeholders with. Only use objects that are strings or convertable to them with `.toString()`!
*/
-const respondWithError = (res, errorCode, responseCode, fileFormat, errorMessage) => {
+const respondWithError = (res, errorCode, responseCode, fileFormat, errorMessage, lang, ...args) => {
try
{
- let errFromRegistry = require(`.${settings.errors.errorRegistryIncludePath}`)[errorCode.toString()];
+ errorCode = errorCode.toString();
+ let errFromRegistry = require("../data/errorMessages")[errorCode];
let errObj = {};
+ if(errFromRegistry == undefined)
+ throw new Error(`Couldn't find errorMessages module or Node is using an outdated, cached version`);
+
+ if(!lang || !languages.isValidLang(lang))
+ lang = settings.languages.defaultLanguage;
+
+ let insArgs = (texts, insertions) => {
+ if(!Array.isArray(insertions) || insertions.length <= 0)
+ return texts;
+
+ insertions.forEach((ins, i) => {
+
+ if(Array.isArray(texts))
+ texts = texts.map(tx => tx.replace(`%${i + 1}`, ins));
+ else if(typeof texts == "string")
+ texts = texts.replace(`%${i + 1}`, ins);
+ });
+
+ return texts;
+ };
+
if(fileFormat != "xml")
{
errObj = {
"error": true,
"internalError": errFromRegistry.errorInternal,
"code": errorCode,
- "message": errFromRegistry.errorMessage,
- "causedBy": errFromRegistry.causedBy,
+ "message": insArgs(errFromRegistry.errorMessage[lang], args) || insArgs(errFromRegistry.errorMessage[settings.languages.defaultLanguage], args),
+ "causedBy": insArgs(errFromRegistry.causedBy[lang], args) || insArgs(errFromRegistry.causedBy[settings.languages.defaultLanguage], args),
"timestamp": new Date().getTime()
}
}
@@ -436,8 +486,8 @@ const respondWithError = (res, errorCode, responseCode, fileFormat, errorMessage
"error": true,
"internalError": errFromRegistry.errorInternal,
"code": errorCode,
- "message": errFromRegistry.errorMessage,
- "causedBy": {"cause": errFromRegistry.causedBy},
+ "message": insArgs(errFromRegistry.errorMessage[lang], args) || insArgs(errFromRegistry.errorMessage[settings.languages.defaultLanguage], args),
+ "causedBy": {"cause": insArgs(errFromRegistry.causedBy[lang], args) || insArgs(errFromRegistry.causedBy[settings.languages.defaultLanguage], args)},
"timestamp": new Date().getTime()
}
}
@@ -445,7 +495,9 @@ const respondWithError = (res, errorCode, responseCode, fileFormat, errorMessage
if(!jsl.isEmpty(errorMessage))
errObj.additionalInfo = errorMessage;
- return pipeString(res, convertFileFormat.auto(fileFormat, errObj), parseURL.getMimeTypeFromFileFormatString(fileFormat), responseCode);
+ let converted = convertFileFormat.auto(fileFormat, errObj, lang).toString();
+
+ return pipeString(res, converted, parseURL.getMimeTypeFromFileFormatString(fileFormat), responseCode);
}
catch(err)
{
@@ -492,7 +544,8 @@ const pipeString = (res, text, mimeType, statusCode = 200) => {
try
{
statusCode = parseInt(statusCode);
- if(isNaN(statusCode)) throw new Error("");
+ if(isNaN(statusCode))
+ throw new Error("Invalid status code");
}
catch(err)
{
@@ -506,16 +559,18 @@ const pipeString = (res, text, mimeType, statusCode = 200) => {
s.push(text);
s.push(null);
- if(!res.headersSent)
- {
- res.writeHead(statusCode, {
- "Content-Type": `${mimeType}; charset=UTF-8`,
- "Content-Length": text.length
- });
- }
-
if(!res.writableEnded)
+ {
s.pipe(res);
+
+ if(!res.headersSent)
+ {
+ res.writeHead(statusCode, {
+ "Content-Type": `${mimeType}; charset=UTF-8`,
+ "Content-Length": byteLength(text) // Content-Length needs the byte length, not the char length
+ });
+ }
+ }
}
/**
@@ -538,14 +593,17 @@ const pipeFile = (res, filePath, mimeType, statusCode = 200) => {
}
if(!fs.existsSync(filePath))
- return respondWithErrorPage(res, 404, `File at "${filePath}" not found.`);
+ return respondWithErrorPage(res, 404, `Internal error: file at "${filePath}" not found.`);
try
{
- res.writeHead(statusCode, {
- "Content-Type": `${mimeType}; charset=UTF-8`,
- "Content-Length": fs.statSync(filePath).size
- });
+ if(!res.headersSent)
+ {
+ res.writeHead(statusCode, {
+ "Content-Type": `${mimeType}; charset=UTF-8`,
+ "Content-Length": fs.statSync(filePath).size
+ });
+ }
let readStream = fs.createReadStream(filePath);
readStream.pipe(res);
@@ -605,7 +663,7 @@ const serveDocumentation = (req, res) => {
/**
* Returns the name of the client's accepted encoding with the highest priority
* @param {http.IncomingMessage} req The HTTP req object
- * @returns {null|"gzip"|"deflate"|"brotli"} Returns null if no encodings are supported, else returns the encoding name
+ * @returns {null|"gzip"|"deflate"|"br"} Returns null if no encodings are supported, else returns the encoding name
*/
const getAcceptedEncoding = req => {
let selectedEncoding = null;
@@ -632,24 +690,15 @@ const getAcceptedEncoding = req => {
}
/**
- * Returns the length of a string in bytes - [Source of code](https://gist.github.com/lovasoa/11357947)
+ * Returns the length of a string in bytes
* @param {String} str
* @returns {Number}
*/
-const byteLength = str => {
- let s = str.length;
- for (let i = str.length - 1; i >= 0; i--)
- {
- let code = str.charCodeAt(i);
-
- if (code > 0x7f && code <= 0x7ff)
- s++;
- else if (code > 0x7ff && code <= 0xffff)
- s+=2;
- if (code >= 0xDC00 && code <= 0xDFFF)
- i--;
- }
- return s;
+function byteLength(str)
+{
+ if(!str)
+ return 0;
+ return Buffer.byteLength(str, "utf8");
}
/**
@@ -665,10 +714,71 @@ const getFileExtensionFromEncoding = encoding => {
case "deflate":
return "zz";
case "br":
+ case "brotli":
return "br";
default:
return "";
}
}
-module.exports = { init, respondWithError, respondWithErrorPage, pipeString, pipeFile, serveDocumentation, getAcceptedEncoding, getFileExtensionFromEncoding };
+/**
+ * Tries to serve data with an encoding supported by the client, else just serves the raw data
+ * @param {http.IncomingMessage} req The HTTP req object
+ * @param {http.ServerResponse} res The HTTP res object
+ * @param {String} data The data to send to the client
+ * @param {String} mimeType The MIME type to respond with
+ */
+function tryServeEncoded(req, res, data, mimeType)
+{
+ let selectedEncoding = getAcceptedEncoding(req);
+
+ debug("HTTP", `Trying to serve with encoding ${selectedEncoding}`);
+
+ if(selectedEncoding)
+ res.setHeader("Content-Encoding", selectedEncoding);
+ else
+ res.setHeader("Content-Encoding", "identity");
+
+ switch(selectedEncoding)
+ {
+ case "br":
+ if(!semver.lt(process.version, "v11.7.0")) // Brotli was added in Node v11.7.0
+ {
+ zlib.brotliCompress(data, (err, encRes) => {
+ if(!err)
+ return pipeString(res, encRes, mimeType);
+ else
+ return pipeString(res, `Internal error while encoding text into ${selectedEncoding}: ${err}`, mimeType);
+ });
+ }
+ else
+ {
+ res.setHeader("Content-Encoding", "identity");
+
+ return pipeString(res, data, mimeType);
+ }
+ break;
+ case "gzip":
+ zlib.gzip(data, (err, encRes) => {
+ if(!err)
+ return pipeString(res, encRes, mimeType);
+ else
+ return pipeString(res, `Internal error while encoding text into ${selectedEncoding}: ${err}`, mimeType);
+ });
+ break;
+ case "deflate":
+ zlib.deflate(data, (err, encRes) => {
+ if(!err)
+ return pipeString(res, encRes, mimeType);
+ else
+ return pipeString(res, `Internal error while encoding text into ${selectedEncoding}: ${err}`, mimeType);
+ });
+ break;
+ default:
+ res.setHeader("Content-Encoding", "identity");
+
+ return pipeString(res, data, mimeType);
+ }
+}
+
+module.exports = { init, respondWithError, respondWithErrorPage, pipeString, pipeFile, serveDocumentation, getAcceptedEncoding, getFileExtensionFromEncoding, tryServeEncoded };
diff --git a/src/jokeSubmission.js b/src/jokeSubmission.js
index 20797d4e..aa2dde8d 100755
--- a/src/jokeSubmission.js
+++ b/src/jokeSubmission.js
@@ -1,5 +1,5 @@
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
const http = require("http");
var httpServer = require("./httpServer"); // module loading order is a bit fucked, so this module has to be loaded multiple times
@@ -8,9 +8,12 @@ const logRequest = require("./logRequest");
const convertFileFormat = require("./fileFormatConverter");
const analytics = require("./analytics");
const parseURL = require("./parseURL");
+const meter = require("./meter");
+const tr = require("./translate");
+
const settings = require("../settings");
-jsl.unused([http, analytics]);
+jsl.unused(http, analytics, tr);
/**
@@ -26,10 +29,18 @@ const jokeSubmission = (res, data, fileFormat, ip, analyticsObject) => {
{
if(typeof httpServer == "object" && Object.keys(httpServer).length <= 0)
httpServer = require("./httpServer");
-
+
let submittedJoke = JSON.parse(data);
+
+ let langCode = submittedJoke.lang || settings.languages.defaultLanguage;
+
if(jsl.isEmpty(submittedJoke))
- return httpServer.respondWithError(res, 105, 400, fileFormat, "Request body is empty");
+ return httpServer.respondWithError(res, 105, 400, fileFormat, tr(langCode, "requestBodyIsInvalid"), langCode);
+
+ let invalidChars = data.match(settings.jokes.submissions.invalidCharRegex);
+ let invalidCharsStr = invalidChars ? invalidChars.map(ch => `0x${ch.charCodeAt(0).toString(16)}`).join(", ") : null;
+ if(invalidCharsStr && invalidChars.length > 0)
+ return httpServer.respondWithError(res, 109, 400, fileFormat, tr(langCode, "invalidChars", invalidCharsStr), langCode);
if(submittedJoke.formatVersion == parseJokes.jokeFormatVersion && submittedJoke.formatVersion == settings.jokes.jokesFormatVersion)
{
@@ -37,14 +48,14 @@ const jokeSubmission = (res, data, fileFormat, ip, analyticsObject) => {
let validationResult = parseJokes.validateSingle(submittedJoke);
if(typeof validationResult === "object")
- return httpServer.respondWithError(res, 105, 400, fileFormat, `Submitted joke format is incorrect - encountered error${validationResult.length == 1 ? ": " : "s:\n"}${validationResult.join("\n")}`);
+ return httpServer.respondWithError(res, 105, 400, fileFormat, tr(langCode, "submittedJokeFormatInvalid", validationResult.join("\n")), langCode);
else if(validationResult === true)
{
// joke is valid, find file name and then write to file
let sanitizedIP = ip.replace(settings.httpServer.ipSanitization.regex, settings.httpServer.ipSanitization.replaceChar).substring(0, 8);
let curUnix = new Date().getTime();
- let fileName = `${settings.jokes.jokeSubmissionPath}submission_${sanitizedIP}_0_${curUnix}.json`;
+ let fileName = `${settings.jokes.jokeSubmissionPath}${langCode}/submission_${sanitizedIP}_0_${curUnix}.json`;
let iter = 0;
let findNextNum = currentNum => {
@@ -52,7 +63,7 @@ const jokeSubmission = (res, data, fileFormat, ip, analyticsObject) => {
if(iter >= settings.httpServer.rateLimiting)
{
logRequest("ratelimited", `IP: ${ip}`, analyticsObject);
- return httpServer.respondWithError(res, 101, 429, fileFormat);
+ return httpServer.respondWithError(res, 101, 429, fileFormat, tr(langCode, "rateLimited", settings.httpServer.rateLimiting, settings.httpServer.timeFrame));
}
if(fs.existsSync(`${settings.jokes.jokeSubmissionPath}submission_${sanitizedIP}_${currentNum}_${curUnix}.json`))
@@ -60,28 +71,30 @@ const jokeSubmission = (res, data, fileFormat, ip, analyticsObject) => {
else return currentNum;
};
+ fs.ensureDirSync(`${settings.jokes.jokeSubmissionPath}${langCode}`);
+
if(fs.existsSync(`${settings.jokes.jokeSubmissionPath}${fileName}`))
- fileName = `${settings.jokes.jokeSubmissionPath}submission_${sanitizedIP}_${findNextNum()}_${curUnix}.json`;
+ fileName = `${settings.jokes.jokeSubmissionPath}${langCode}/submission_${sanitizedIP}_${findNextNum()}_${curUnix}.json`;
try
{
// file name was found, write to file now:
- return writeJokeToFile(res, fileName, submittedJoke, fileFormat, ip, analyticsObject);
+ return writeJokeToFile(res, fileName, submittedJoke, fileFormat, ip, analyticsObject, langCode);
}
catch(err)
{
- return httpServer.respondWithError(res, 100, 500, fileFormat, `Internal error while saving joke: ${err}`);
+ return httpServer.respondWithError(res, 100, 500, fileFormat, tr(langCode, "errWhileSavingSubmission", err), langCode);
}
}
}
else
{
- return httpServer.respondWithError(res, 105, 400, fileFormat, `Joke format version is incorrect - expected "${parseJokes.jokeFormatVersion}" - got "${submittedJoke.formatVersion}"`);
+ return httpServer.respondWithError(res, 105, 400, fileFormat, tr(langCode, "wrongFormatVersion", parseJokes.jokeFormatVersion, submittedJoke.formatVersion), langCode);
}
}
catch(err)
{
- return httpServer.respondWithError(res, 105, 400, fileFormat, `Request body contains invalid JSON: ${err}`);
+ return httpServer.respondWithError(res, 105, 400, fileFormat, tr(settings.languages.defaultLanguage, "invalidJSON", err), settings.languages.defaultLanguage);
}
}
@@ -93,31 +106,82 @@ const jokeSubmission = (res, data, fileFormat, ip, analyticsObject) => {
* @param {String} fileFormat
* @param {String} ip
* @param {(analytics.AnalyticsDocsRequest|analytics.AnalyticsSuccessfulRequest|analytics.AnalyticsRateLimited|analytics.AnalyticsError|analytics.AnalyticsSubmission)} analyticsObject
+ * @param {String} [langCode]
*/
-const writeJokeToFile = (res, filePath, submittedJoke, fileFormat, ip, analyticsObject) => {
+const writeJokeToFile = (res, filePath, submittedJoke, fileFormat, ip, analyticsObject, langCode) => {
if(typeof httpServer == "object" && Object.keys(httpServer).length <= 0)
httpServer = require("./httpServer");
- fs.writeFile(filePath, JSON.stringify(submittedJoke, null, 4), err => {
+ let reformattedJoke = reformatJoke(submittedJoke);
+
+ fs.writeFile(filePath, JSON.stringify(reformattedJoke, null, 4), err => {
if(!err)
{
// successfully wrote to file
let responseObj = {
"error": false,
- "message": "Joke submission was successfully saved. It will soon be checked out by the author.",
- "submission": submittedJoke,
+ "message": tr(langCode, "submissionSaved"),
+ "submission": reformattedJoke,
"timestamp": new Date().getTime()
};
+ meter.update("submission", 1);
+
let submissionObject = analyticsObject;
- submissionObject.submission = submittedJoke;
+ submissionObject.submission = reformattedJoke;
logRequest("submission", ip, submissionObject);
- return httpServer.pipeString(res, convertFileFormat.auto(fileFormat, responseObj), parseURL.getMimeTypeFromFileFormatString(fileFormat), 201);
+ return httpServer.pipeString(res, convertFileFormat.auto(fileFormat, responseObj, langCode), parseURL.getMimeTypeFromFileFormatString(fileFormat), 201);
}
// error while writing to file
- else return httpServer.respondWithError(res, 100, 500, fileFormat, `Internal error while saving joke: ${err}`);
+ else return httpServer.respondWithError(res, 100, 500, fileFormat, tr(langCode, "errWhileSavingSubmission", err), langCode);
});
}
-module.exports = jokeSubmission;
\ No newline at end of file
+/**
+ * Ensures that a joke is formatted as expected
+ * @param {parseJokes.SingleJoke|parseJokes.TwopartJoke} joke
+ * @returns {parseJokes.SingleJoke|parseJokes.TwopartJoke}
+ */
+function reformatJoke(joke)
+{
+ let retJoke = {};
+
+ if(joke.formatVersion)
+ retJoke.formatVersion = joke.formatVersion;
+
+ retJoke = {
+ ...retJoke,
+ category: joke.category,
+ type: joke.type
+ };
+
+ if(joke.type == "single")
+ {
+ retJoke.joke = joke.joke;
+ }
+ else if(joke.type == "twopart")
+ {
+ retJoke.setup = joke.setup;
+ retJoke.delivery = joke.delivery;
+ }
+
+ retJoke.flags = {
+ nsfw: joke.flags.nsfw,
+ religious: joke.flags.religious,
+ political: joke.flags.political,
+ racist: joke.flags.racist,
+ sexist: joke.flags.sexist,
+ };
+
+ if(joke.lang)
+ retJoke.lang = joke.lang;
+
+ if(joke.id)
+ retJoke.id = joke.id;
+
+ return retJoke;
+}
+
+module.exports = jokeSubmission;
+module.exports.reformatJoke = reformatJoke;
diff --git a/src/languages.js b/src/languages.js
new file mode 100644
index 00000000..0fd5b399
--- /dev/null
+++ b/src/languages.js
@@ -0,0 +1,175 @@
+const fs = require("fs-extra");
+const jsl = require("svjsl");
+const Fuse = require("fuse.js");
+
+const debug = require("./verboseLogging");
+const tr = require("./translate");
+
+const settings = require("../settings");
+
+var langs;
+
+/**
+ * Initializes the language module
+ */
+function init()
+{
+ debug("Languages", `Initializing - loading languages from "${settings.languages.langFilePath}"`);
+ return new Promise((resolve, reject) => {
+ fs.readFile(settings.languages.langFilePath, (err, data) => {
+ if(err)
+ return reject(err);
+ else
+ {
+ let languages = JSON.parse(data.toString());
+ debug("Languages", `Found ${languages.length} languages`);
+ langs = languages;
+ return resolve(languages);
+ }
+ });
+ });
+}
+
+/**
+ * Checks whether or not a provided language code is ISO 639-1 or ISO 639-2 compatible
+ * @param {String} langCode Two-character language code
+ * @returns {Boolean|String} Returns `true` if code exists, string with error message if not
+ */
+function isValidLang(langCode)
+{
+ if(langs == undefined)
+ return "INTERNAL_ERROR: Language module was not correctly initialized (yet)";
+
+ if(typeof langCode !== "string" || langCode.length !== 2)
+ return "Language code is not a string or not two characters in length";
+
+ let requested = langs[langCode.toLowerCase()];
+
+ if(typeof requested === "string")
+ return true;
+ else
+ return "Language code doesn't exist";
+}
+
+/**
+ * Converts a language name (fuzzy) into an ISO 639-1 or ISO 639-2 compatible lang code
+ * @param {String} language
+ * @returns {Boolean|String} Returns `false` if no matching language code was found, else returns string with language code
+ */
+function languageToCode(language)
+{
+ if(langs == undefined)
+ throw new Error("INTERNAL_ERROR: Language module was not correctly initialized (yet)");
+
+ if(typeof language !== "string" || language.length < 1)
+ throw new TypeError("Language is not a string or not two characters in length");
+
+ let searchObj = [];
+
+ Object.keys(langs).forEach(key => {
+ searchObj.push({
+ code: key,
+ lang: langs[key].toLowerCase()
+ });
+ });
+
+ let fuzzy = new Fuse(searchObj, {
+ includeScore: true,
+ keys: ["code", "lang"],
+ threshold: 0.4
+ });
+
+ let result = fuzzy.search(language)[0];
+
+ if(result)
+ return result.item.code;
+ else
+ return false;
+}
+
+/**
+ * Converts an ISO 639-1 or ISO 639-2 compatible lang code into a language name
+ * @param {String} code
+ * @returns {Boolean|String} Returns `false` if no matching language was found, else returns string with language name
+ */
+function codeToLanguage(code)
+{
+ try
+ {
+ let jsonObj = JSON.parse(fs.readFileSync(settings.languages.langFilePath).toString());
+
+ return jsonObj[code] || false;
+ }
+ catch(err)
+ {
+ jsl.unused(err);
+ return false;
+ }
+}
+
+/**
+ * @typedef {Object} SupLangObj
+ * @prop {String} code
+ * @prop {String} name
+ */
+
+/**
+ * Returns a list of languages that jokes are available from
+ * @returns {Array}
+ */
+function jokeLangs()
+{
+ let retLangs = [];
+
+ fs.readdirSync(settings.jokes.jokesFolderPath).forEach(f => {
+ if(f == settings.jokes.jokesTemplateFile)
+ return;
+
+ let langCode = f.split("-")[1].substr(0, 2);
+
+ retLangs.push({
+ code: langCode,
+ name: codeToLanguage(langCode)
+ });
+ });
+
+ return retLangs;
+}
+
+/**
+ * Returns a list of languages that error messages and maybe other stuff are available as
+ * @returns {Array}
+ */
+function systemLangs()
+{
+ return tr.systemLangs();
+}
+
+/**
+ * Returns all possible language codes
+ * @returns {Array}
+ */
+function getPossibleCodes()
+{
+ return Object.keys(langs);
+}
+
+/**
+ * Returns all possible languages, mapped as an object where keys are codes and values are language names
+ * @returns {Object}
+ */
+function getPossibleLanguages()
+{
+ return langs;
+}
+
+module.exports = {
+ init,
+ isValidLang,
+ languageToCode,
+ codeToLanguage,
+ jokeLangs,
+ systemLangs,
+ getPossibleCodes,
+ getPossibleLanguages
+};
diff --git a/src/lists.js b/src/lists.js
index 81a3ed66..e53845bc 100755
--- a/src/lists.js
+++ b/src/lists.js
@@ -1,7 +1,7 @@
// this module initializes the blacklist, whitelist and console blacklist
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
const settings = require("../settings");
const debug = require("./verboseLogging");
const logger = require("./logger");
@@ -12,7 +12,8 @@ const resolveIP = require("./resolveIP");
* Initializes all lists (blacklist, whitelist and console blacklist)
* @returns {Promise}
*/
-const init = () => {
+function init()
+{
return new Promise((resolve, reject) => {
//#SECTION read list files
debug("Lists", "Reading blacklist...");
@@ -21,7 +22,8 @@ const init = () => {
return reject(err1);
else if(!jsl.isEmpty(err1) && err1.toString().includes("ENOENT"))
{
- debug("Lists", `${jsl.colors.fg.red}No blacklist file found! Defaulting to empty list.${jsl.colors.rst}`);
+ fs.writeFileSync(settings.lists.blacklistPath, "[\n\t\n]");
+ debug("Lists", `${jsl.colors.fg.red}No blacklist file found! Created empty list.${jsl.colors.rst}`);
blacklist = "[\n\t\n]";
}
@@ -71,14 +73,15 @@ const init = () => {
});
});
});
-};
+}
/**
* Checks whether a provided IP address is in the blacklist
* @param {String} ip
* @returns {Bool} true if blacklisted, false if not
*/
-const isBlacklisted = ip => {
+function isBlacklisted(ip)
+{
if(jsl.isEmpty(process.jokeapi) || jsl.isEmpty(process.jokeapi.lists) || !(process.jokeapi.lists.blacklist instanceof Array))
{
logger("fatal", `Blacklist was not initialized when calling lists.isBlacklisted()`, true);
@@ -107,7 +110,8 @@ const isBlacklisted = ip => {
* @returns {Bool} Returns true if whitelisted, false if not
* @throws Throws an error if the lists module was not previously initialized
*/
-const isWhitelisted = ip => {
+function isWhitelisted(ip)
+{
let whitelisted = false;
if(jsl.isEmpty(process.jokeapi) || jsl.isEmpty(process.jokeapi.lists) || !(process.jokeapi.lists.whitelist instanceof Array))
@@ -131,7 +135,8 @@ const isWhitelisted = ip => {
* @param {String} ip
* @returns {Bool} true if console blacklisted, false if not
*/
-const isConsoleBlacklisted = ip => {
+function isConsoleBlacklisted(ip)
+{
if(jsl.isEmpty(process.jokeapi) || jsl.isEmpty(process.jokeapi.lists) || !(process.jokeapi.lists.consoleBlacklist instanceof Array))
{
logger("fatal", `Console blacklist was not initialized when calling lists.isConsoleBlacklisted()`, true);
diff --git a/src/logRequest.js b/src/logRequest.js
old mode 100755
new mode 100644
index db987318..aa28a078
--- a/src/logRequest.js
+++ b/src/logRequest.js
@@ -124,15 +124,18 @@ const logRequest = (type, additionalInfo, analyticsData) => {
if(!settings.logging.blacklistLoggingEnabled)
logDisabled = true;
- // analytics({
- // type: "Error",
- // data: {
- // ipAddress: analyticsData.ipAddress,
- // urlPath: analyticsData.urlPath,
- // urlParameters: analyticsData.urlParameters,
- // errorMessage: `Blacklisted - ${additionalInfo}`
- // }
- // });
+ if(!jsl.isEmpty(analyticsData))
+ {
+ analytics({
+ type: "Blacklisted",
+ data: {
+ ipAddress: analyticsData.ipAddress,
+ urlPath: analyticsData.urlPath,
+ urlParameters: analyticsData.urlParameters,
+ submission: analyticsData.submission
+ }
+ });
+ }
break;
}
@@ -154,13 +157,12 @@ const logRequest = (type, additionalInfo, analyticsData) => {
* @param {Number} initTimestamp The timestamp of when JokeAPI was initialized
*/
const initMsg = (initTimestamp) => {
- console.log("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- console.log(`${jsl.colors.fg.blue}[${logger.getTimestamp(" | ")}] ${jsl.colors.fg.green}Started ${settings.info.name} v${settings.info.version}${jsl.colors.rst}`);
+ console.log(` \n \n${jsl.colors.fg.blue}[${logger.getTimestamp(" | ")}] ${jsl.colors.fg.green}Started ${settings.info.name} v${settings.info.version}${jsl.colors.rst}`);
console.log(` ├─ Registered and validated ${jsl.colors.fg.green}${parseJokes.jokeCount}${jsl.colors.rst} jokes`);
if(analytics.connectionInfo && analytics.connectionInfo.connected)
console.log(` ├─ Connected to analytics database at ${jsl.colors.fg.green}${analytics.connectionInfo.info}${jsl.colors.rst}`);
else
- console.log(` ├─ Analytics database ${jsl.colors.fg.red}not connected${jsl.colors.rst}`);
+ console.log(` ├─ Analytics database ${settings.analytics.enabled ? jsl.colors.fg.red : jsl.colors.fg.yellow}not connected${settings.analytics.enabled ? "" : " (disabled)"}${jsl.colors.rst}`);
console.log(` ├─ ${settings.info.name} is listening at ${jsl.colors.fg.green}0.0.0.0:${settings.httpServer.port}${jsl.colors.rst}`);
console.log(` └─ Initialization took ${jsl.colors.fg.green}${(new Date().getTime() - initTimestamp).toFixed(0)}ms${jsl.colors.rst}`);
process.stdout.write("\n");
diff --git a/src/logger.js b/src/logger.js
index e361b744..fe1f6e07 100755
--- a/src/logger.js
+++ b/src/logger.js
@@ -1,4 +1,4 @@
-const fs = require("fs");
+const fs = require("fs-extra");
const jsl = require("svjsl");
const settings = require("../settings");
@@ -76,4 +76,4 @@ const getTimestamp = (separator) => {
}
module.exports = logger;
-module.exports.getTimestamp = getTimestamp;
\ No newline at end of file
+module.exports.getTimestamp = getTimestamp;
diff --git a/src/main.js b/src/main.js
old mode 100755
new mode 100644
index 66790377..942728d1
--- a/src/main.js
+++ b/src/main.js
@@ -5,7 +5,7 @@
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
require("dotenv").config();
const settings = require("../settings");
@@ -17,6 +17,9 @@ const docs = require("./docs");
const analytics = require("./analytics");
const logRequest = require("./logRequest");
const auth = require("./auth");
+const languages = require("./languages");
+const translate = require("./translate");
+const meter = require("./meter");
const promiseAllSequential = require("promise-all-sequential");
const col = jsl.colors.fg;
@@ -31,12 +34,20 @@ settings.init.exitSignals.forEach(sig => {
const initAll = () => {
let initTimestamp = new Date().getTime();
debug("Init", "Initializing all modules - calling joke parser...");
-
+
process.jokeapi = {};
initializeDirs();
let initPromises = [];
let initStages = [
+ {
+ name: "Initializing languages",
+ fn: languages.init
+ },
+ {
+ name: "Initializing translations",
+ fn: translate.init
+ },
{
name: "Initializing joke parser",
fn: parseJokes.init
@@ -60,6 +71,10 @@ const initAll = () => {
{
name: "Initializing analytics module",
fn: analytics.init
+ },
+ {
+ name: "Initializing pm2 meter",
+ fn: meter.init
}
];
diff --git a/src/meter.js b/src/meter.js
new file mode 100644
index 00000000..0b554a82
--- /dev/null
+++ b/src/meter.js
@@ -0,0 +1,130 @@
+// handles custom metering / monitoring values in pm2
+
+const io = require("@pm2/io");
+const fs = require("fs-extra");
+
+const debug = require("./verboseLogging");
+const settings = require("../settings");
+
+var req1mMeter = null;
+var req10mMeter = null;
+var req1hMeter = null;
+var reqtotalMeter = null;
+var submissionMeter = null;
+var m1 = 0;
+var m10 = 0;
+var h1 = 0;
+var tot = 0;
+var subms = 0;
+
+/**
+ * Initializes the meter module
+ * @returns {Promise}
+ */
+function init()
+{
+ return new Promise((resolve, reject) => {
+ try
+ {
+ req1mMeter = io.metric({
+ name: "Reqs / 1m",
+ unit: "req"
+ });
+ req1mMeter.set(-1);
+ setInterval(() => {
+ req1mMeter.set(m1);
+ m1 = 0;
+ }, 1000 * 60);
+
+
+ req10mMeter = io.metric({
+ name: "Reqs / 10m",
+ unit: "req"
+ });
+ req10mMeter.set(-1);
+ setInterval(() => {
+ req10mMeter.set(m10);
+ m10 = 0;
+ }, 1000 * 60 * 10);
+
+
+ req1hMeter = io.metric({
+ name: "Reqs / 1h",
+ unit: "req"
+ });
+ req1hMeter.set(-1);
+ setInterval(() => {
+ req1hMeter.set(h1);
+ h1 = 0;
+ }, 1000 * 60 * 60);
+
+
+ reqtotalMeter = io.metric({
+ name: "Total Reqs",
+ unit: "req"
+ });
+ reqtotalMeter.set(-1);
+
+
+ submissionMeter = io.metric({
+ name: "Submissions",
+ unit: "sub"
+ });
+ subms = fs.readdirSync(settings.jokes.jokeSubmissionPath).length;
+ submissionMeter.set(subms);
+ setInterval(() => {
+ subms = fs.readdirSync(settings.jokes.jokeSubmissionPath).length;
+ submissionMeter.set(subms);
+ }, 1000 * 60 * 10);
+ }
+ catch(err)
+ {
+ return reject(err);
+ }
+
+ return resolve();
+ });
+}
+
+/**
+ * Adds a number to a meter
+ * @param {"req1min"|"req10mins"|"req1hour"|"reqtotal"|"submission"} meterName
+ * @param {Number|undefined} addValue
+ */
+function update(meterName, addValue)
+{
+ if(typeof addValue == "undefined")
+ addValue = 1;
+
+ debug("Meter", `Updating meter ${meterName} - adding value ${addValue}`);
+
+ if(typeof addValue != "number")
+ throw new TypeError(`meter.update(): "addValue" has wrong type "${typeof addValue}" - expected "number"`);
+
+ switch(meterName)
+ {
+ case "req1min":
+ m1 += addValue;
+ break;
+ case "req10min":
+ m10 += addValue;
+ break;
+ case "req1hour":
+ h1 += addValue;
+ break;
+ case "reqtotal":
+ tot += addValue;
+ reqtotalMeter.set(tot);
+ break;
+ case "submission":
+ subms += addValue;
+ submissionMeter.set(subms);
+ break;
+ default:
+ throw new Error(`meter.update(): "meterName" has incorrect value`);
+ }
+
+ return;
+}
+
+module.exports = { init, update };
diff --git a/src/parseJokes.js b/src/parseJokes.js
index 16241fc3..4bb8c3d0 100755
--- a/src/parseJokes.js
+++ b/src/parseJokes.js
@@ -1,10 +1,11 @@
// this module parses all the jokes to verify that they are valid and that their structure is not messed up
-const fs = require("fs");
+const fs = require("fs-extra");
const jsl = require("svjsl");
const settings = require("../settings");
const debug = require("./verboseLogging");
+const languages = require("./languages");
const AllJokes = require("./classes/AllJokes");
/**
@@ -13,77 +14,118 @@ const AllJokes = require("./classes/AllJokes");
*/
const init = () => {
return new Promise((resolve, reject) => {
- fs.readFile(settings.jokes.jokesFilePath, (err, jokesFile) => {
- if(err)
- return reject(err);
-
- let result = [];
-
- try
- {
- jokesFile = JSON.parse(jokesFile.toString());
- }
- catch(err)
- {
- return reject(`Error while parsing file "${settings.jokes.jokesFilePath}" as JSON: ${err}`);
- }
-
- //#MARKER format version
- if(jokesFile.info.formatVersion == settings.jokes.jokesFormatVersion)
- result.push(true);
- else result.push(`Joke file format version is set to "${jokesFile.info.formatVersion}" - Expected: "${settings.jokes.jokesFormatVersion}"`);
-
- jokesFile.jokes.forEach((joke, i) => {
- //#MARKER joke ID
- if(!jsl.isEmpty(joke.id) && !isNaN(parseInt(joke.id)))
- result.push(true);
- else result.push(`Joke with index/ID ${i} doesn't have an "id" property or it is invalid`);
-
- //#MARKER type and actual joke
- if(joke.type == "single")
- {
- if(!jsl.isEmpty(joke.joke))
- result.push(true);
- else result.push(`Joke with index/ID ${i} doesn't have a "joke" property`);
- }
- else if(joke.type == "twopart")
- {
- if(!jsl.isEmpty(joke.setup))
- result.push(true);
- else result.push(`Joke with index/ID ${i} doesn't have a "setup" property`);
-
- if(!jsl.isEmpty(joke.delivery))
- result.push(true);
- else result.push(`Joke with index/ID ${i} doesn't have a "delivery" property`);
- }
- else result.push(`Joke with index/ID ${i} doesn't have a "type" property or it is invalid`);
-
- //#MARKER flags
- if(!jsl.isEmpty(joke.flags))
- {
- if(!jsl.isEmpty(joke.flags.nsfw) || (joke.flags.nsfw !== false && joke.flags.nsfw !== true))
- result.push(true);
- else result.push(`Joke with index/ID ${i} has an invalid "NSFW" flag`);
-
- if(!jsl.isEmpty(joke.flags.racist) || (joke.flags.racist !== false && joke.flags.racist !== true))
- result.push(true);
- else result.push(`Joke with index/ID ${i} has an invalid "racist" flag`);
-
- if(!jsl.isEmpty(joke.flags.sexist) || (joke.flags.sexist !== false && joke.flags.sexist !== true))
- result.push(true);
- else result.push(`Joke with index/ID ${i} has an invalid "sexist" flag`);
-
- if(!jsl.isEmpty(joke.flags.political) || (joke.flags.political !== false && joke.flags.political !== true))
- result.push(true);
- else result.push(`Joke with index/ID ${i} has an invalid "political" flag`);
-
- if(!jsl.isEmpty(joke.flags.religious) || (joke.flags.religious !== false && joke.flags.religious !== true))
+ let jokesFiles = fs.readdirSync(settings.jokes.jokesFolderPath);
+ let result = [];
+ let allJokesFilesObj = {};
+
+ let outerPromises = [];
+
+ jokesFiles.forEach(jf => {
+ if(jf == settings.jokes.jokesTemplateFile)
+ return;
+
+ outerPromises.push(new Promise((resolveOuter, rejectOuter) => {
+ jsl.unused(rejectOuter);
+
+ let fileNameValid = (fileName) => {
+ if(!fileName.endsWith(".json"))
+ return false;
+ let spl1 = fileName.split(".json")[0];
+ if(spl1.includes("-") && languages.isValidLang(spl1.split("-")[1]) && spl1.split("-")[0] == "jokes")
+ return true;
+ return false;
+ };
+
+ let getLangCode = (fileName) => {
+ if(!fileName.endsWith(".json"))
+ return false;
+ let spl1 = fileName.split(".json")[0];
+ if(spl1.includes("-") && languages.isValidLang(spl1.split("-")[1]))
+ return spl1.split("-")[1].toLowerCase();
+ };
+
+ let langCode = getLangCode(jf);
+
+ if(!jf.endsWith(".json") || !fileNameValid(jf))
+ result.push(`${jsl.colors.fg.red}Error: Invalid file "${settings.jokes.jokesFolderPath}${jf}" found. It has to follow this pattern: "jokes-xy.json"`);
+
+
+ fs.readFile(`${settings.jokes.jokesFolderPath}${jf}`, (err, jokesFile) => {
+ if(err)
+ return reject(err);
+
+ try
+ {
+ jokesFile = JSON.parse(jokesFile.toString());
+ }
+ catch(err)
+ {
+ return reject(`Error while parsing file "${settings.jokes.jokesFilePath}" as JSON: ${err}`);
+ }
+
+ //#MARKER format version
+ if(jokesFile.info.formatVersion == settings.jokes.jokesFormatVersion)
result.push(true);
- else result.push(`Joke with index/ID ${i} has an invalid "religious" flag`);
- }
- else result.push(`Joke with index/ID ${i} doesn't have a "flags" object or it is invalid`);
- });
+ else result.push(`Joke file format version is set to "${jokesFile.info.formatVersion}" - Expected: "${settings.jokes.jokesFormatVersion}"`);
+
+ jokesFile.jokes.forEach((joke, i) => {
+ //#MARKER joke ID
+ if(!jsl.isEmpty(joke.id) && !isNaN(parseInt(joke.id)))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} doesn't have an "id" property or it is invalid`);
+
+ //#MARKER type and actual joke
+ if(joke.type == "single")
+ {
+ if(!jsl.isEmpty(joke.joke))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} doesn't have a "joke" property`);
+ }
+ else if(joke.type == "twopart")
+ {
+ if(!jsl.isEmpty(joke.setup))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} doesn't have a "setup" property`);
+
+ if(!jsl.isEmpty(joke.delivery))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} doesn't have a "delivery" property`);
+ }
+ else result.push(`Joke with index/ID ${i} doesn't have a "type" property or it is invalid`);
+
+ //#MARKER flags
+ if(!jsl.isEmpty(joke.flags))
+ {
+ if(!jsl.isEmpty(joke.flags.nsfw) || (joke.flags.nsfw !== false && joke.flags.nsfw !== true))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} has an invalid "NSFW" flag`);
+
+ if(!jsl.isEmpty(joke.flags.racist) || (joke.flags.racist !== false && joke.flags.racist !== true))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} has an invalid "racist" flag`);
+
+ if(!jsl.isEmpty(joke.flags.sexist) || (joke.flags.sexist !== false && joke.flags.sexist !== true))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} has an invalid "sexist" flag`);
+
+ if(!jsl.isEmpty(joke.flags.political) || (joke.flags.political !== false && joke.flags.political !== true))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} has an invalid "political" flag`);
+
+ if(!jsl.isEmpty(joke.flags.religious) || (joke.flags.religious !== false && joke.flags.religious !== true))
+ result.push(true);
+ else result.push(`Joke with index/ID ${i} has an invalid "religious" flag`);
+ }
+ else result.push(`Joke with index/ID ${i} doesn't have a "flags" object or it is invalid`);
+ });
+
+ allJokesFilesObj[langCode] = jokesFile;
+ return resolveOuter();
+ });
+ }));
+ });
+ Promise.all(outerPromises).then(() => {
let errors = [];
result.forEach(res => {
@@ -91,11 +133,22 @@ const init = () => {
errors.push(res);
});
- let allJokesObj = new AllJokes(jokesFile);
+ let allJokesObj = new AllJokes(allJokesFilesObj);
+
+ let formatVersions = [settings.jokes.jokesFormatVersion];
+ languages.jokeLangs().map(jl => jl.code).sort().forEach(lang => {
+ formatVersions.push(allJokesObj.getFormatVersion(lang));
+ });
+
+ if(!jsl.allEqual(formatVersions))
+ errors.push(`One or more of the jokes files has an invalid format version`);
+
module.exports.allJokes = allJokesObj;
module.exports.jokeCount = allJokesObj.getJokeCount();
- module.exports.jokeFormatVersion = allJokesObj.getFormatVersion();
- this.jokeFormatVersion = allJokesObj.getFormatVersion();
+ module.exports.jokeCountPerLang = allJokesObj.getJokeCountPerLang();
+ let fmtVer = allJokesObj.getFormatVersion("en");
+ module.exports.jokeFormatVersion = fmtVer;
+ this.jokeFormatVersion = fmtVer;
debug("JokeParser", `Done parsing jokes. Errors: ${errors.length === 0 ? jsl.colors.fg.green : jsl.colors.fg.red}${errors.length}${jsl.colors.rst}`);
@@ -104,6 +157,8 @@ const init = () => {
return resolve();
return reject(`Errors:\n- ${errors.join("\n- ")}`);
+ }).catch(err => {
+ return reject(err);
});
});
}
@@ -119,6 +174,7 @@ const init = () => {
* @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
* @prop {Boolean} flags.political Whether the joke is politically offensive or not
* @prop {Number} id The ID of the joke
+ * @prop {String} lang The language of the joke
*/
/**
@@ -133,6 +189,7 @@ const init = () => {
* @prop {Boolean} flags.religious Whether the joke is religiously offensive or not
* @prop {Boolean} flags.political Whether the joke is politically offensive or not
* @prop {Number} id The ID of the joke
+ * @prop {String} lang The language of the joke
*/
/**
@@ -208,6 +265,16 @@ const validateSingle = joke => {
jokeErrors.push(`Joke doesn't have the "religious" flag or it is invalid`);
}
else jokeErrors.push(`Joke doesn't have a "flags" object or it is invalid`);
+
+ //#MARKER lang
+ if(jsl.isEmpty(joke.lang))
+ jokeErrors.push(`Joke doesn't have a "lang" property or it is empty or of the wrong type`);
+
+ let langV = languages.isValidLang(joke.lang);
+ if(typeof langV === "string")
+ jokeErrors.push(`"lang" parameter: ${langV}`);
+ else if(langV !== true)
+ jokeErrors.push(`Joke doesn't have a "lang" property or it is empty or of the wrong type`);
}
catch(err)
{
@@ -219,4 +286,4 @@ const validateSingle = joke => {
else return jokeErrors;
}
-module.exports = { init, validateSingle }
\ No newline at end of file
+module.exports = { init, validateSingle }
diff --git a/src/parseURL.js b/src/parseURL.js
index 1a68e142..7192fd47 100755
--- a/src/parseURL.js
+++ b/src/parseURL.js
@@ -1,7 +1,8 @@
// this module parses the passed URL, returning an object that is uniform and easy to use
+const urlParse = require("url-parse");
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
const settings = require("../settings");
@@ -24,47 +25,25 @@ const settings = require("../settings");
* @param {String} url
* @returns {(ParsedUrl|ErroredParsedUrl)}
*/
-const parseURL = url => {
- let error = null;
-
- let pathArr = [];
- let qstrObj = {};
-
+function parseURL(url)
+{
try
{
- let rawPath = url.split("?")[0];
- let rawQstr = url.split("?")[1];
-
-
- if(rawPath.includes("/"))
- pathArr = rawPath.split("/");
- else pathArr = [rawQstr];
-
- if(pathArr.includes("v2"))
- {
- pathArr.forEach((itm, i) => {
- if(itm == "v2")
- pathArr.splice(i, 1);
- });
- }
+ let trimFirstSlash = u2 => {
+ if(u2[0] == "")
+ u2.shift();
+ return u2;
+ };
- pathArr.forEach((pathSection, i) => {
- if(jsl.isEmpty(pathSection))
- pathArr.splice(i, 1);
- });
+ let parsed = urlParse(url);
- // if a URL path offset was set in the settings, remove the first n elements from the path array
- if(settings.httpServer.urlPathOffset > 0)
- {
- for(let i = 0; i < settings.httpServer.urlPathOffset; i++)
- {
- if(pathArr.length > 0)
- pathArr.shift();
- }
- }
+ let qstrObj = {};
+ let qstrArr = [];
+ let rawQstr = (parsed.query == "" ? null : parsed.query);
+ if(rawQstr && rawQstr.startsWith("?"))
+ rawQstr = rawQstr.substr(1);
- let qstrArr = [];
if(!jsl.isEmpty(rawQstr) && rawQstr.includes("&"))
qstrArr = rawQstr.split("&");
else if(!jsl.isEmpty(rawQstr))
@@ -72,6 +51,7 @@ const parseURL = url => {
if(qstrArr.length > 0)
+ {
qstrArr.forEach(qstrEntry => {
if(qstrEntry.includes("="))
{
@@ -79,30 +59,109 @@ const parseURL = url => {
qstrObj[decodeURIComponent(splitEntry[0])] = decodeURIComponent(splitEntry[1].toLowerCase());
}
});
- else qstrObj = null;
- }
- catch(err)
- {
- error = err;
- }
-
- if(jsl.isArrayEmpty(pathArr))
- pathArr = null;
+ }
+ else
+ qstrObj = null;
- if(!error)
- return {
+ let retObj = {
error: null,
initialURL: url,
- pathArray: pathArr,
+ pathArray: trimFirstSlash(parsed.pathname.split("/")),
queryParams: qstrObj
- }
- else
+ };
+
+ return retObj;
+ }
+ catch(err)
+ {
return {
- error: error,
+ error: err.toString(),
initialURL: url
- }
+ };
+ }
}
+// *** *** *** Still leaving legacy code in, in case something goes wrong and I need to quickly switch back *** *** ***
+
+// const parseURL = url => {
+// let error = null;
+
+// let pathArr = [];
+// let qstrObj = {};
+
+// try
+// {
+// let rawPath = url.split("?")[0];
+// let rawQstr = url.split("?")[1];
+
+
+// if(rawPath.includes("/"))
+// pathArr = rawPath.split("/");
+// else pathArr = [rawQstr];
+
+// if(pathArr.includes("v2"))
+// {
+// pathArr.forEach((itm, i) => {
+// if(itm == "v2")
+// pathArr.splice(i, 1);
+// });
+// }
+
+// pathArr.forEach((pathSection, i) => {
+// if(jsl.isEmpty(pathSection))
+// pathArr.splice(i, 1);
+// });
+
+// // if a URL path offset was set in the settings, remove the first n elements from the path array
+// if(settings.httpServer.urlPathOffset > 0)
+// {
+// for(let i = 0; i < settings.httpServer.urlPathOffset; i++)
+// {
+// if(pathArr.length > 0)
+// pathArr.shift();
+// }
+// }
+
+
+// let qstrArr = [];
+// if(!jsl.isEmpty(rawQstr) && rawQstr.includes("&"))
+// qstrArr = rawQstr.split("&");
+// else if(!jsl.isEmpty(rawQstr))
+// qstrArr = [rawQstr];
+
+
+// if(qstrArr.length > 0)
+// qstrArr.forEach(qstrEntry => {
+// if(qstrEntry.includes("="))
+// {
+// let splitEntry = qstrEntry.split("=");
+// qstrObj[decodeURIComponent(splitEntry[0])] = decodeURIComponent(splitEntry[1].toLowerCase());
+// }
+// });
+// else qstrObj = null;
+// }
+// catch(err)
+// {
+// error = err;
+// }
+
+// if(jsl.isArrayEmpty(pathArr))
+// pathArr = null;
+
+// if(!error)
+// return {
+// error: null,
+// initialURL: url,
+// pathArray: pathArr,
+// queryParams: qstrObj
+// }
+// else
+// return {
+// error: error,
+// initialURL: url
+// }
+// }
+
const getFileFormatFromQString = qstrObj => {
if(!jsl.isEmpty(qstrObj.format))
{
@@ -130,4 +189,4 @@ const getMimeTypeFromFileFormatString = fileFormatString => {
module.exports = parseURL;
module.exports.getFileFormatFromQString = getFileFormatFromQString;
-module.exports.getMimeTypeFromFileFormatString = getMimeTypeFromFileFormatString;
\ No newline at end of file
+module.exports.getMimeTypeFromFileFormatString = getMimeTypeFromFileFormatString;
diff --git a/src/translate.js b/src/translate.js
new file mode 100644
index 00000000..2c032d01
--- /dev/null
+++ b/src/translate.js
@@ -0,0 +1,85 @@
+const fs = require("fs-extra");
+const jsl = require("svjsl");
+
+const debug = require("./verboseLogging")
+const settings = require("../settings");
+
+
+var trFile = {};
+
+/**
+ * Initializes the translation module by caching the translations so they only need to be read from disk once
+ * @returns {Promise}
+ */
+function init()
+{
+ debug("Translate", `Initializing - loading translations from "${settings.languages.translationsFile}"`);
+ return new Promise((resolve, reject) => {
+ fs.readFile(settings.languages.translationsFile, (err, res) => {
+ if(err)
+ return reject(`Error while reading translations file: ${err}`);
+ else
+ {
+ trFile = JSON.parse(res.toString());
+ debug("Translate", `Found ${Object.keys(trFile.tr).length} translations`);
+ return resolve();
+ }
+ });
+ });
+}
+
+/**
+ * Returns the translation of a sentence of a specified language.
+ * @param {String} lang Language code
+ * @param {String} id The name of the translation node
+ * @param {...any} args Arguments to replace numbered %-placeholders with. Only use objects that are strings or convertable to them with `.toString()`!
+ * @returns {String|null} Returns `null` if no translation is available. Else returns a string
+ */
+function translate(lang, id, ...args)
+{
+ if(!lang)
+ lang = settings.languages.defaultLanguage;
+
+ let langTr = trFile.tr[id];
+ if(!langTr)
+ return null;
+
+ let translation = langTr[lang.toString().toLowerCase()].toString();
+ if(!translation)
+ return null;
+
+ if(Array.isArray(args) && translation.includes("%"))
+ {
+ args.forEach((arg, i) => {
+ let rex = new RegExp(`%${i + 1}`);
+ if(translation.match(rex))
+ {
+ try
+ {
+ translation = translation.replace(rex, arg.toString());
+ }
+ catch(err)
+ {
+ jsl.unused(err);
+ }
+ }
+ });
+ }
+
+ debug("Translate", `Translating ${id} into ${lang} - result: ${translation}`);
+
+ return translation;
+}
+
+/**
+ * Returns a list of system languages (2 char code)
+ * @returns {Array}
+ */
+function systemLangs()
+{
+ return trFile.languages;
+}
+
+module.exports = translate;
+module.exports.init = init;
+module.exports.systemLangs = systemLangs;
diff --git a/src/verboseLogging.js b/src/verboseLogging.js
index 50f16b39..3cb823b1 100755
--- a/src/verboseLogging.js
+++ b/src/verboseLogging.js
@@ -10,11 +10,12 @@ const col = jsl.colors;
* @param {String} section
* @param {String} message
*/
-const verboseLogging = (section, message) => {
- if(jsl.isEmpty(settings.debug.verboseLogging) || settings.debug.verboseLogging === false)
+function verboseLogging(section, message)
+{
+ if(settings.debug.verboseLogging !== true)
return;
console.log(`${col.fg.yellow}[DBG/${col.rst}${col.fg.blue}${section}${col.rst}${col.fg.yellow}]${col.rst} - ${message}`);
}
-module.exports = verboseLogging;
\ No newline at end of file
+module.exports = verboseLogging;
diff --git a/tests/joke-endpoint.js b/tests/joke-endpoint.js
new file mode 100644
index 00000000..61f91ceb
--- /dev/null
+++ b/tests/joke-endpoint.js
@@ -0,0 +1,28 @@
+/* eslint-disable */
+
+const settings = require("../settings");
+
+const meta = {
+ name: "Joke",
+ category: "Endpoints",
+ endpointURL: "/joke"
+};
+
+/**
+ * @typedef {Object} UnitTestResult
+ * @prop {String} name
+ * @prop {Boolean} success
+ */
+
+/**
+ * Runs this unit test
+ * @returns {Promise, String>}
+ */
+function run()
+{
+ return new Promise((resolve, reject) => {
+
+ });
+}
+
+module.exports = { meta, run };
diff --git a/tools/add-joke.js b/tools/add-joke.js
index 9efd751d..7a5dcc9c 100755
--- a/tools/add-joke.js
+++ b/tools/add-joke.js
@@ -1,121 +1,137 @@
const jsl = require("svjsl");
const readline = require("readline");
const settings = require("../settings");
-const fs = require("fs");
+const fs = require("fs-extra");
+const { join } = require("path");
+const jokeSubmission = require("../src/jokeSubmission");
+const languages = require("../src/languages");
-const init = () => {
+const init = async () => {
let joke = {};
+ if(!process.stdin.isTTY)
+ {
+ console.log(`${jsl.colors.fg.red}Error: process doesn't have a stdin to read from${jsl.colors.rst}`);
+ process.exit(1);
+ }
+
process.stdin.setRawMode(true);
- getJokeCategory().then(cat => {
- joke["category"] = cat;
- getJokeType().then(type => {
- joke["type"] = type;
+ await languages.init();
- let rl = readline.createInterface(process.stdin, process.stdout);
- rl.pause();
+ joke["category"] = await getJokeCategory();
+ joke["type"] = await getJokeType();
+ let jokeLang = await getJokeLang();
- let contFlags = () => {
- process.stdout.write("\n");
-
- joke["flags"] = {};
- let allFlags = settings.jokes.possible.flags;
-
- let flagIteration = idx => {
- if(idx >= allFlags.length)
- return flagIterFinished();
- else
- {
- jsl.pause(`Is this joke ${allFlags[idx]}? (y/N):`).then(key => {
- if(key.toLowerCase() == "y")
- joke["flags"][allFlags[idx]] = true;
- else joke["flags"][allFlags[idx]] = false;
-
- return flagIteration(++idx);
- }).catch(err => {
- console.error(`Error: ${err}`);
- return process.exit(1);
- });
- }
- };
-
- let flagIterFinished = () => {
-
- fs.readFile(settings.jokes.jokesFilePath, (err, res) => {
- if(!err)
- {
- let jokeFile = JSON.parse(res.toString());
+ let rl = readline.createInterface(process.stdin, process.stdout);
+ rl.pause();
- joke["id"] = jokeFile.jokes.length;
+ let contFlags = () => {
+ process.stdout.write("\n");
- jokeFile.jokes.push(joke);
+ joke["flags"] = {};
+ let allFlags = settings.jokes.possible.flags;
- fs.writeFile(settings.jokes.jokesFilePath, JSON.stringify(jokeFile, null, 4), (err) => {
- if(err)
- {
- console.log(`${jsl.colors.fg.red}\n${err}${jsl.colors.rst}\n\n`);
- process.exit(1);
- }
- else
+ let flagIteration = idx => {
+ if(idx >= allFlags.length)
+ return flagIterFinished();
+ else
+ {
+ jsl.pause(`Is this joke ${allFlags[idx]}? (y/N):`).then(key => {
+ if(key.toLowerCase() == "y")
+ joke["flags"][allFlags[idx]] = true;
+ else joke["flags"][allFlags[idx]] = false;
+
+ return flagIteration(++idx);
+ }).catch(err => {
+ console.error(`Error: ${err}`);
+ return process.exit(1);
+ });
+ }
+ };
+
+ let jokesFileName = `jokes-${jokeLang}.json`;
+
+ let flagIterFinished = () => {
+ let fPath = join(settings.jokes.jokesFolderPath, jokesFileName);
+
+ if(!fs.existsSync(fPath))
+ fs.copySync(join(settings.jokes.jokesFolderPath, settings.jokes.jokesTemplateFile), fPath);
+
+ fs.readFile(fPath, (err, res) => {
+ if(!err)
+ {
+ let jokeFile = JSON.parse(res.toString());
+
+ joke = jokeSubmission.reformatJoke(joke);
+
+ joke["id"] = jokeFile.jokes.length || 0;
+
+ jokeFile.jokes.push(joke);
+
+ fs.writeFile(fPath, JSON.stringify(jokeFile, null, 4), (err) => {
+ if(err)
+ {
+ console.log(`${jsl.colors.fg.red}\n${err}${jsl.colors.rst}\n\n`);
+ process.exit(1);
+ }
+ else
+ {
+ console.clear();
+ console.log(`${jsl.colors.fg.green}\nJoke was successfully added to file "${jokesFileName}":${jsl.colors.rst}\n\n${JSON.stringify(joke, null, 4)}\n\n\n`);
+
+ jsl.pause("Add another joke? (y/N): ").then(key => {
+ if(key.toLowerCase() === "y")
{
console.clear();
- console.log(`${jsl.colors.fg.green}\nJoke was successfully added:${jsl.colors.rst}\n\n${JSON.stringify(joke, null, 4)}\n\n\n`);
-
- jsl.pause("Add another joke? (y/N): ").then(key => {
- if(key.toLowerCase() === "y")
- {
- console.clear();
- return init();
- }
- else return process.exit(0);
- }).catch(err => {
- console.error(`Error: ${err}`);
- return process.exit(1);
- });
+ return init();
}
+ else return process.exit(0);
+ }).catch(err => {
+ console.error(`Error: ${err}`);
+ return process.exit(1);
});
}
- else
- {
- console.log(`${jsl.colors.fg.red}\n${err}${jsl.colors.rst}\n\n`);
- process.exit(1);
- }
});
}
+ else
+ {
+ console.log(`${jsl.colors.fg.red}\n${err}${jsl.colors.rst}\n\n`);
+ process.exit(1);
+ }
+ });
+ }
- return flagIteration(0);
- };
+ return flagIteration(0);
+ };
- console.log(`Use "\\n" for a line break. Special characters like double quotes do not need to be escaped.\n`);
+ console.log(`Use "\\n" for a line break. Special characters like double quotes do not need to be escaped.\n`);
- if(type != "twopart")
- {
- rl.resume();
- rl.question("Enter Joke: ", jokeText => {
- rl.pause();
- joke["joke"] = jokeText.replace(/\\n/gm, "\n");
+ if(joke["type"] != "twopart")
+ {
+ rl.resume();
+ rl.question("Enter Joke: ", jokeText => {
+ rl.pause();
+ joke["joke"] = jokeText.replace(/\\n/gm, "\n");
- return contFlags();
- });
- }
- else
- {
- rl.resume();
- rl.question("Enter Joke Setup: ", jokeSetup => {
- rl.question("Enter Joke Delivery: ", jokeDelivery => {
- rl.pause();
- joke["setup"] = jokeSetup.replace(/\\n/gm, "\n");
- joke["delivery"] = jokeDelivery.replace(/\\n/gm, "\n");
-
- return contFlags();
- });
- });
- }
+ return contFlags();
});
- });
+ }
+ else
+ {
+ rl.resume();
+ rl.question("Enter Joke Setup: ", jokeSetup => {
+ rl.question("Enter Joke Delivery: ", jokeDelivery => {
+ rl.pause();
+ joke["setup"] = jokeSetup.replace(/\\n/gm, "\n");
+ joke["delivery"] = jokeDelivery.replace(/\\n/gm, "\n");
+
+ return contFlags();
+ });
+ });
+ }
};
const getJokeCategory = () => {
@@ -166,4 +182,34 @@ const getJokeType = () => {
});
};
-init();
\ No newline at end of file
+function getJokeLang()
+{
+ return new Promise(resolve => {
+ let langRL = readline.createInterface(process.stdin, process.stdout);
+
+ let tryGetLang = () => {
+ langRL.resume();
+ langRL.question("Enter two-character language code (en): ", ans => {
+ langRL.pause();
+
+ if(!ans)
+ ans = settings.languages.defaultLanguage;
+
+ ans = ans.toString().toLowerCase();
+
+ if(languages.isValidLang(ans) === true)
+ return resolve(ans);
+ else
+ {
+ console.clear();
+ console.log(`\n${jsl.colors.fg.red}Invalid lang code!${jsl.colors.rst}\n\n`);
+ return tryGetLang();
+ }
+ });
+ }
+
+ return tryGetLang();
+ });
+}
+
+init();
diff --git a/tools/add-token.js b/tools/add-token.js
index a78c06a0..d049dc84 100755
--- a/tools/add-token.js
+++ b/tools/add-token.js
@@ -1,5 +1,5 @@
const jsl = require("svjsl");
-const fs = require("fs");
+const fs = require("fs-extra");
const settings = require("../settings");
try
diff --git a/tools/reassign-ids.js b/tools/reassign-ids.js
index b5b96885..80058dfd 100755
--- a/tools/reassign-ids.js
+++ b/tools/reassign-ids.js
@@ -1,40 +1,54 @@
// this reassigns all jokes' IDs. Always run this after something changes in the joke's order
// run this with the command "npm run reassign-ids"
+const { resolve, join } = require("path");
+const fs = require("fs-extra");
+const settings = require("../settings");
+
try
{
- const fs = require("fs");
- const settings = require("../settings");
+ console.log(`\nReassigning joke IDs in files in path "${settings.jokes.jokesFolderPath}"...`);
- console.log(`\nReassigning joke IDs in file "${settings.jokes.jokesFilePath}"...`);
+ let totalReassignedFiles = 0;
+ let totalReassignedIDs = 0;
- let initialJokes = JSON.parse(fs.readFileSync(settings.jokes.jokesFilePath).toString()).jokes;
- let initialInfo = JSON.parse(fs.readFileSync(settings.jokes.jokesFilePath).toString()).info;
+ fs.readdirSync(settings.jokes.jokesFolderPath).forEach(fName => {
+ if(fName.startsWith("template"))
+ return;
- let reassignedJokes = [];
+ totalReassignedFiles++;
- if(initialInfo.formatVersion != 2)
- initialInfo.formatVersion = 2;
+ let fPath = resolve(join(settings.jokes.jokesFolderPath, fName));
+ let jokeFileObj = JSON.parse(fs.readFileSync(fPath).toString());
- initialJokes.forEach((joke, i) => {
- let rJoke = joke;
- rJoke.id = i;
- reassignedJokes.push(rJoke);
- });
+ let initialJokes = jokeFileObj.jokes;
+ let initialInfo = jokeFileObj.info;
+
+ let reassignedJokes = [];
- let doneFile = {
- info: initialInfo,
- jokes: reassignedJokes
- };
+ if(initialInfo.formatVersion != settings.jokes.jokesFormatVersion)
+ initialInfo.formatVersion = settings.jokes.jokesFormatVersion;
- fs.writeFileSync(settings.jokes.jokesFilePath, JSON.stringify(doneFile, null, 4));
+ initialJokes.forEach((joke, i) => {
+ let rJoke = joke;
+ rJoke.id = i;
+ reassignedJokes.push(rJoke);
+ totalReassignedIDs++;
+ });
+ let doneFile = {
+ info: initialInfo,
+ jokes: reassignedJokes
+ };
- console.log(`\x1b[32m\x1b[1mDone reassigning IDs of all ${reassignedJokes.length} jokes.\n\x1b[0m`);
+ fs.writeFileSync(fPath, JSON.stringify(doneFile, null, 4));
+ });
+
+ console.log(`\x1b[32m\x1b[1mDone reassigning IDs of all ${totalReassignedFiles} files (${totalReassignedIDs} reassigned joke IDs).\n\x1b[0m`);
process.exit(0);
}
catch(err)
{
console.log(`\n\n\x1b[31m\x1b[1m>> Error while reassigning joke IDs:\n${err}\n\n\x1b[0m`);
process.exit(1);
-}
\ No newline at end of file
+}
diff --git a/tools/reformat.js b/tools/reformat.js
index 7e7f4905..d98f3460 100755
--- a/tools/reformat.js
+++ b/tools/reformat.js
@@ -1,12 +1,11 @@
// this reformats jokes from the old <1.1.3 format to the new 2.0.0 format
// run this with the command "npm run reformat"
+const fs = require("fs-extra");
+const isEmpty = require("svjsl").isEmpty;
+
try
{
- const fs = require("fs");
- const isEmpty = require("svjsl").isEmpty;
-
-
console.log(`\nReformatting jokes from file "./data/jokes.json" to new format and putting it in file "./data/jokes_new.json"...`);
let initialJokes = JSON.parse(fs.readFileSync("./data/jokes.json").toString());
@@ -62,4 +61,4 @@ catch(err)
{
console.log(`\n\n\x1b[31m\x1b[1m>> Error while reformatting jokes:\n${err}\n\n\x1b[0m`);
process.exit(1);
-}
\ No newline at end of file
+}
diff --git a/tools/submissions.js b/tools/submissions.js
index 718560c4..d19db9e6 100755
--- a/tools/submissions.js
+++ b/tools/submissions.js
@@ -1,10 +1,14 @@
const settings = require("../settings");
-const fs = require("fs");
-const path = require("path");
+const fs = require("fs-extra");
+const { resolve, join } = require("path");
const jsl = require("svjsl");
+const parseJokes = require("../src/parseJokes");
+const jokeSubmission = require("../src/jokeSubmission");
+jsl.unused(parseJokes);
let addedCount = 0;
-let jokesFile = getAllJokes();
+let jokesFiles = getAllJokes();
+
const run = () => {
let submissions = getSubmissions();
@@ -26,17 +30,15 @@ const run = () => {
let goThroughSubmission = (idx) => {
if(!submissions[idx])
- {
- finishAdding();
- console.log(`${jsl.colors.fg.green}Successfully added ${jsl.colors.fg.yellow}${addedCount}${jsl.colors.fg.green} joke${addedCount != 1 ? "s" : ""}${jsl.colors.rst}.\nExiting.\n\n`);
- return process.exit(0);
- }
+ return finishAdding();
let submission = submissions[idx];
if(submission.formatVersion != settings.jokes.jokesFormatVersion)
console.error(`${jsl.colors.fg.red}Error: Format version is incorrect${jsl.colors.rst}`);
+ console.log(`${jsl.colors.fg.yellow}Language:${jsl.colors.rst} ${submission.lang}`);
+
if(submission.type == "single")
{
console.log(`${jsl.colors.fg.yellow}Joke:${jsl.colors.rst} ${submission.joke}`);
@@ -73,12 +75,31 @@ const run = () => {
};
/**
- * Reads the jokes file and returns it as an object
- * @returns {Object}
+ * @typedef {Object} AllJokesObj
+ * @prop {Object} [en]
+ * @prop {Object} en.info
+ * @prop {String} en.info.formatVersion
+ * @prop {Array|Array} en.jokes
+ */
+
+/**
+ * Reads the jokes files and returns it as an object
+ * @returns {AllJokesObj}
*/
function getAllJokes()
{
- return JSON.parse(fs.readFileSync(settings.jokes.jokesFilePath).toString());
+ let retObj = {};
+ fs.readdirSync(settings.jokes.jokesFolderPath).forEach(jokesFile => {
+ if(jokesFile.startsWith("template"))
+ return;
+
+ let langCode = jokesFile.split("-")[1].substr(0, 2);
+ let filePath = resolve(join(settings.jokes.jokesFolderPath, jokesFile));
+
+ retObj[langCode] = JSON.parse(fs.readFileSync(filePath).toString());
+ });
+
+ return retObj;
}
/**
@@ -86,22 +107,42 @@ function getAllJokes()
* @param {Object} joke
*/
const addJoke = joke => {
- let fJoke = new Object(joke);
+ let fJoke = JSON.parse(JSON.stringify(joke)); // reserialize because call by reference :(
delete fJoke.formatVersion;
+ delete fJoke.lang;
- jokesFile.jokes.push(fJoke);
- addedCount++;
+ // jokesFile.jokes.push(fJoke);
+ if(!jokesFiles[joke.lang])
+ jokesFiles[joke.lang] = JSON.parse(fs.readFileSync(resolve(join(settings.jokes.jokesFolderPath, settings.jokes.jokesTemplateFile))).toString());
+
+ Object.keys(jokesFiles).forEach(langCode => {
+ if(joke.lang == langCode)
+ {
+ jokesFiles[langCode].jokes.push(jokeSubmission.reformatJoke(fJoke));
+ addedCount++;
+ }
+ });
};
/**
- * Writes the `jokesFile` object to the jokes file
+ * Writes the `jokesFiles` object to the jokes file
*/
const finishAdding = () => {
- fs.writeFileSync(settings.jokes.jokesFilePath, JSON.stringify(jokesFile, null, 4));
+ Object.keys(jokesFiles).forEach(langCode => {
+ fs.writeFileSync(resolve(join(settings.jokes.jokesFolderPath, `jokes-${langCode}.json`)), JSON.stringify(jokesFiles[langCode], null, 4));
+ });
- fs.readdirSync(settings.jokes.jokeSubmissionPath).forEach(file => {
- fs.unlinkSync(path.join(settings.jokes.jokeSubmissionPath, file));
+ jsl.pause(`Delete all submissions? (Y/n):`).then(val => {
+ if(val.toLowerCase() != "n")
+ {
+ fs.readdirSync(settings.jokes.jokeSubmissionPath).forEach(folder => {
+ fs.removeSync(join(settings.jokes.jokeSubmissionPath, folder));
+ });
+ }
+
+ console.log(`${jsl.colors.fg.green}Successfully added ${jsl.colors.fg.yellow}${addedCount}${jsl.colors.fg.green} joke${addedCount != 1 ? "s" : ""}${jsl.colors.rst}.\nExiting.\n\n`);
+ return process.exit(0);
});
};
@@ -130,10 +171,17 @@ const getFlags = joke => {
*/
const getSubmissions = () => {
let submissions = [];
- fs.readdirSync(settings.jokes.jokeSubmissionPath).forEach(file => {
- submissions.push(JSON.parse(fs.readFileSync(path.resolve(`${settings.jokes.jokeSubmissionPath}/${file}`)).toString()));
+ fs.readdirSync(settings.jokes.jokeSubmissionPath).forEach(lang => {
+ fs.readdirSync(resolve(join(settings.jokes.jokeSubmissionPath, lang))).forEach(file => {
+ submissions.push(JSON.parse(fs.readFileSync(resolve(`${settings.jokes.jokeSubmissionPath}/${lang}/${file}`)).toString()));
+ });
});
return submissions;
};
-run();
\ No newline at end of file
+if(!process.stdin.isTTY)
+{
+ console.log(`${jsl.colors.fg.red}Error: process doesn't have a stdin to read from${jsl.colors.rst}`);
+ process.exit(1);
+}
+else run();
diff --git a/tools/test.js b/tools/test.js
new file mode 100644
index 00000000..adadfd59
--- /dev/null
+++ b/tools/test.js
@@ -0,0 +1,16 @@
+/* eslint-disable */
+
+const settings = require("../settings");
+
+
+function getAllTests()
+{
+
+}
+
+function runAllTests()
+{
+ let tests = getAllTests();
+}
+
+runAllTests();
diff --git a/tools/validate-ids.js b/tools/validate-ids.js
index 9920ecd2..9e18ef91 100755
--- a/tools/validate-ids.js
+++ b/tools/validate-ids.js
@@ -1,6 +1,10 @@
// this validates all jokes' IDs. This will be run through the CI to make sure the IDs are correct
// run this with the command "npm run reassign-ids"
+const { resolve, join } = require("path");
+const fs = require("fs-extra");
+const settings = require("../settings");
+
const exitWithError = (msg, err) => {
console.log(`\n\n\x1b[31m\x1b[1m>> ${msg}:\n${err}\n\n\x1b[0m`);
process.exit(1);
@@ -8,46 +12,63 @@ const exitWithError = (msg, err) => {
try
{
- const fs = require("fs");
- const settings = require("../settings");
+ console.log(`\nValidating joke IDs in files in "${settings.jokes.jokesFolderPath}"...`);
+
+ let validatedFiles = 0;
+ let notOk = 0;
+
+ fs.readdirSync(settings.jokes.jokesFolderPath).forEach(fName => {
+ if(fName.startsWith("template"))
+ return;
+
+ let langCode = fName.split("-")[1].substr(0, 2);
- console.log(`\nValidating joke IDs in file "${settings.jokes.jokesFilePath}"...`);
+ let filePath = resolve(join(settings.jokes.jokesFolderPath, fName));
- let initialJokes = JSON.parse(fs.readFileSync(settings.jokes.jokesFilePath).toString()).jokes;
- let initialInfo = JSON.parse(fs.readFileSync(settings.jokes.jokesFilePath).toString()).info;
+ let jokeFileObj = JSON.parse(fs.readFileSync(filePath).toString());
+ let initialJokes = jokeFileObj.jokes;
+ let initialInfo = jokeFileObj.info;
+
+ if(initialInfo.formatVersion != settings.jokes.jokesFormatVersion)
+ return exitWithError("Error while checking format version", `Format version in file "${filePath}" (version ${initialInfo.formatVersion}) is different from the one being currently used in JokeAPI (${settings.jokes.jokesFormatVersion})`);
+
+ let erroredJokes = [];
+
+ initialJokes.forEach((joke, i) => {
+ if(joke.id != i)
+ erroredJokes.push({joke: joke, idx: i});
+ });
- if(initialInfo.formatVersion != settings.jokes.jokesFormatVersion)
- return exitWithError("Error while checking format version", `Format version in file "${settings.jokes.jokesFilePath}" (version ${initialInfo.formatVersion}) is different from the one being currently used in JokeAPI (${settings.jokes.jokesFormatVersion})`);
+ validatedFiles++;
- let erroredJokes = [];
+ if(erroredJokes.length != 0)
+ {
+ console.log(`\n\n\x1b[31m\x1b[1mInvalid joke ID${erroredJokes.length > 1 ? "s" : ""} found:\x1b[0m\n`);
+ erroredJokes.forEach(errjoke => {
+ let jokeContent = "";
+ if(errjoke.joke.type == "single")
+ jokeContent = errjoke.joke.joke.replace(/\n/gm, "\\n");
+ else if(errjoke.joke.type == "twopart")
+ jokeContent = `${errjoke.joke.setup.replace(/\n/gm, "\\n")} - ${errjoke.joke.delivery.replace(/\n/gm, "\\n")}`;
- initialJokes.forEach((joke, i) => {
- if(joke.id != i)
- erroredJokes.push({joke: joke, idx: i});
+ console.log(`#${errjoke.joke.id} | ${langCode} | ${errjoke.joke.category} | ${jokeContent} (Expected ID #${errjoke.idx} - joke instead has #${errjoke.joke.id})`);
+ notOk++;
+ });
+ }
});
- if(erroredJokes.length == 0)
+ if(notOk > 0)
{
- console.log(`\x1b[32m\x1b[1mDone validating IDs of all ${initialJokes.length} jokes.\n\x1b[0m`);
- process.exit(0);
+ console.log(`\n\x1b[33m\x1b[1mYou can run the command "npm run reassign-ids" to correct all joke IDs\n\x1b[0m`);
+ process.exit(1);
}
else
{
- console.log(`\n\n\x1b[31m\x1b[1mInvalid joke ID${erroredJokes.length > 1 ? "s" : ""} found:\x1b[0m\n`);
- erroredJokes.forEach(errjoke => {
- let jokeContent = "";
- if(errjoke.joke.type == "single")
- jokeContent = errjoke.joke.joke.replace(/\n/gm, "\\n");
- else if(errjoke.joke.type == "twopart")
- jokeContent = `${errjoke.joke.setup.replace(/\n/gm, "\\n")} - ${errjoke.joke.delivery.replace(/\n/gm, "\\n")}`;
-
- console.log(`> #${errjoke.joke.id} | ${errjoke.joke.category} | ${jokeContent} (Expected ID #${errjoke.idx} - joke instead has #${errjoke.joke.id})`);
- });
- console.log(`\n\x1b[33m\x1b[1mYou can run the command "npm run reassign-ids" to correct all joke IDs\n\x1b[0m`);
- process.exit(1);
+ console.log(`\x1b[32m\x1b[1mDone validating IDs of all ${validatedFiles} files.\n\x1b[0m`);
+ process.exit(0);
}
}
catch(err)
{
return exitWithError("General error while validating joke IDs", err);
-}
\ No newline at end of file
+}
diff --git a/tools/validate-jokes.js b/tools/validate-jokes.js
index d2f3c591..876be881 100755
--- a/tools/validate-jokes.js
+++ b/tools/validate-jokes.js
@@ -1,12 +1,16 @@
const jsl = require("svjsl");
const settings = require("../settings");
-console.log(`\nValidating jokes in "${settings.jokes.jokesFilePath}"...\n`);
-
-require("../src/parseJokes").init().then(() => {
- console.log(`\n${jsl.colors.fg.green}All jokes are valid.${jsl.colors.rst}\n`);
- process.exit(0);
-}).catch(err => {
- console.log(`\n${jsl.colors.fg.red}${err}${jsl.colors.rst}\n`);
- process.exit(1);
-});
\ No newline at end of file
+
+
+console.log(`\nValidating jokes-xy.json files in "${settings.jokes.jokesFolderPath}"...\n`);
+
+require("../src/translate").init().then(() => {
+ require("../src/parseJokes").init().then(() => {
+ console.log(`${jsl.colors.fg.green}All jokes are valid.${jsl.colors.rst}\n`);
+ process.exit(0);
+ }).catch(err => {
+ console.log(`${jsl.colors.fg.red}${err}${jsl.colors.rst}\n`);
+ process.exit(1);
+ });
+});
|