diff --git a/.gitignore b/.gitignore index 901ada8..511e288 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +.scannerwork .coveralls.yml +.eslint _private _config diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4e7915f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + // "eslint.enable": false, + "xo.enable": true, + "xo.format.enable": true, + "xo.options": { + "semicolon": true + } +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 95ec6c9..3ae8230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -# 1.2.1 +# 1.3.0 +- ci(sca): arranged for automated [static code analysis](https://sonarcloud.io/dashboard?id=rondinif%3Aphytojs-js) +- ci(xo): eslinted with xo + +# 1.2.1 - 1.2.3 ## Fixed inconsitent auto-generated references in umd see diff in a1fac62c8757926c579f0882ded17aba3fcd7e45 diff --git a/README.md b/README.md index 66338b2..42174cb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,19 @@ # PhytoJS: @rondinif/phytojs -[![Travis build status](http://img.shields.io/travis/rondinif/phytojs/master.svg?style=flat-square)](https://travis-ci.org/rondinif/phytojs) +[![Travis build status](https://img.shields.io/travis/rondinif/phytojs/master.svg?style=flat-square)](https://travis-ci.org/rondinif/phytojs) [![Coveralls](https://img.shields.io/coveralls/rondinif/phytojs.svg?style=flat-square)](https://coveralls.io/github/rondinif/phytojs) [![NPM version](https://img.shields.io/npm/v/@rondinif/phytojs.svg?style=flat-square)](https://www.npmjs.org/package/@rondinif/phytojs) +[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Twitter Follow](https://img.shields.io/twitter/follow/rondinif.svg?style=social&label=Follow)](https://twitter.com/rondinif) +[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=alert_status)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) +[![Sonarcloud coverage](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=coverage)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) +[![Sonarcloud sqale_index](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=sqale_index)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) + +[![Sonarcloud security_rating](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=security_rating)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) +[![Sonarcloud sqale_rating](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) +[![Sonarcloud reliability_rating](https://sonarcloud.io/api/project_badges/measure?project=rondinif:phytojs-js&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=rondinif:phytojs-js) + A modern javascript library to search about plants on open data - The prefix [phyto-](https://en.wiktionary.org/wiki/phyto-) , comes from Ancient Greek φυτόν (phutón, “plant”), is used when something is **pertaining** to or derived from **plants**. - [js](https://en.wiktionary.org/wiki/js) is the abbreviation of **javascript**. diff --git a/commitlint.config.js b/commitlint.config.js index 461ee41..f26ad5a 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -31,4 +31,4 @@ module.exports = { ] ] } -}; \ No newline at end of file +}; diff --git a/esm/config.js b/esm/config.js index dc630e3..c99ba4d 100644 --- a/esm/config.js +++ b/esm/config.js @@ -1,51 +1,57 @@ import dotenv from 'dotenv-flow'; dotenv.config(); -/* -usage in programs: +/* +Usage in programs: import { config } from './lib/config.mjs'; to check the effective configuration: @see ../config.checher.mjs WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs + - .mjs Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. */ const DEFAULT_IS_UNDER_TEST = false; -const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } +const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } + + case 'false': { + return false; + } + + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } }; const config = { - /* - the test features are enabed + /* + The test features are enabed affected by .env IS_FILESTORE_WRITING_ENABLED */ - isUnderTest: function () { - return process.env.IS_UNDER_TEST ? - castToBoolen(process.env.IS_UNDER_TEST) : - DEFAULT_IS_UNDER_TEST; - } + isUnderTest() { + return process.env.IS_UNDER_TEST ? + castToBoolen(process.env.IS_UNDER_TEST) : + DEFAULT_IS_UNDER_TEST; + } }; export { DEFAULT_IS_UNDER_TEST, config }; diff --git a/esm/log.js b/esm/log.js index 1913ca4..4c3cf9b 100644 --- a/esm/log.js +++ b/esm/log.js @@ -1,74 +1,79 @@ -// import { logFactory } from './log.mjs'; +// Import { logFactory } from './log.mjs'; const logFactory = { - makeTraceFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.trace(...args); - } - }}, - makeDebugFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.debug(...args); - } - }}, - makeInfoFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.info(...args); - } - }}, - makeWarnFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.warn(...args); - } - }}, - makeErrorFunction: (config) => { - return (...args) => { - console.error(...args); - }} - }; + makeTraceFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.trace(...args); + } + }; + }, + makeDebugFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.debug(...args); + } + }; + }, + makeInfoFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.info(...args); + } + }; + }, + makeWarnFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.warn(...args); + } + }; + }, + makeErrorFunction: () => { + return (...args) => { + console.error(...args); + }; + } +}; class Log { - constructor(config) { - if ( config.isLogVerbose() && config.isLogSilent() ) { - throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); - } - this._trace = logFactory.makeTraceFunction(config); - this._debug = logFactory.makeDebugFunction(config); - this._info = logFactory.makeInfoFunction(config); - this._warn = logFactory.makeWarnFunction(config); - this._error = logFactory.makeErrorFunction(config); + constructor(config) { + if (config.isLogVerbose() && config.isLogSilent()) { + throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); + } - this._config = config; - } - - trace(...args) { - return this._trace(...args); - } + this._trace = logFactory.makeTraceFunction(config); + this._debug = logFactory.makeDebugFunction(config); + this._info = logFactory.makeInfoFunction(config); + this._warn = logFactory.makeWarnFunction(config); + this._error = logFactory.makeErrorFunction(config); - debug(...args) { - return this._debug(...args); - } - - info(...args) { - return this._info(...args); - } + this._config = config; + } - warn(...args) { - return this._warn(...args); - } - - error(...args) { - return this._error(...args); - } + trace(...args) { + return this._trace(...args); + } - getLogConfig(...args) { - return this._config; - } + debug(...args) { + return this._debug(...args); + } + info(...args) { + return this._info(...args); + } + + warn(...args) { + return this._warn(...args); + } + + error(...args) { + return this._error(...args); + } + + getLogConfig() { + return this._config; + } } export { Log }; diff --git a/esm/logconfig.js b/esm/logconfig.js index 29df684..75d6fc6 100644 --- a/esm/logconfig.js +++ b/esm/logconfig.js @@ -1,14 +1,14 @@ import dotenv from 'dotenv-flow'; dotenv.config(); -/* -usage in programs: +/* +Usage in programs: import { config } from './lib/config.mjs'; to check the effective configuration: @see ../config.checher.mjs WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs + - .mjs Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. */ @@ -16,46 +16,52 @@ Coding Conventions: before each configuration a comment SHOULD be written; the c const DEFAULT_IS_LOG_VERBOSE = false; const DEFAULT_IS_LOG_SILENT = true; -const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } +const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } + + case 'false': { + return false; + } + + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } }; const logconfig = { - /* - the log is verbose enabed + /* + The log is verbose enabed affected by .env IS_LOG_VERBOSE */ - isLogVerbose: function () { - return process.env.IS_LOG_VERBOSE ? - castToBoolen(process.env.IS_LOG_VERBOSE) : - DEFAULT_IS_LOG_VERBOSE; - }, - /* - the log is verbose enabed + isLogVerbose() { + return process.env.IS_LOG_VERBOSE ? + castToBoolen(process.env.IS_LOG_VERBOSE) : + DEFAULT_IS_LOG_VERBOSE; + }, + /* + The log is verbose enabed affected by .env IS_LOG_VERBOSE */ - isLogSilent: function () { - return process.env.IS_LOG_SILENT ? - castToBoolen(process.env.IS_LOG_SILENT) : - DEFAULT_IS_LOG_SILENT; - } + isLogSilent() { + return process.env.IS_LOG_SILENT ? + castToBoolen(process.env.IS_LOG_SILENT) : + DEFAULT_IS_LOG_SILENT; + } }; export { DEFAULT_IS_LOG_SILENT, DEFAULT_IS_LOG_VERBOSE, logconfig }; diff --git a/esm/phyto.js b/esm/phyto.js index 0db2f37..ce2d1f3 100644 --- a/esm/phyto.js +++ b/esm/phyto.js @@ -1,255 +1,255 @@ import { Log } from '../esm/log'; // DIP: export Higher-order function factories : each of them returns a function as its result. - // Higher-order function: returns a function as its result. function makeGetPromiseOfWikiDataApiResults(fetch, log) { - return (uri, headers) => { - return fetch(encodeURI(uri), { - headers: headers // , - // method: 'GET', ...mode, cache , see - }).then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; + return (uri, headers) => { + return fetch(encodeURI(uri), { + headers + }).then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; } // Higher-order function: returns a function as its result. function makeGetPromiseOfSparqlResults(fetch, log) { - return (serviceUri, sparql, headers) => { - const uri = `${serviceUri}/sparql?query=${sparql}`; - return fetch(encodeURI(uri), { headers }) - .then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; + return (serviceUri, sparql, headers) => { + const uri = `${serviceUri}/sparql?query=${sparql}`; + return fetch(encodeURI(uri), {headers}) + .then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; } const openDataPromisesFactories = { - makeWdSearchByAnyName: (ff, config, log) => name => { - return getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeWdPlantsByAnyName: (ff, config, log) => name => { - return getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { - return getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name); - }, - makeSparqlScientificNameById: (ffSparql, config, log) => id => { - return getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, id); - }, + makeWdSearchByAnyName: (ff, config, log) => name => { + return getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeWdPlantsByAnyName: (ff, config, log) => name => { + return getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { + return getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name); + }, + makeSparqlScientificNameById: (ffSparql, config, log) => id => { + return getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, id); + } }; const openDataEndpointFactories = { - makeWdEndpointUri: (config, log) => () => { - return getWdEndpointUri({ config, log }); - }, - makeSparqlEndpointUri: (config, log) => () => { - return getSparqlEndpointUri({ config, log }); - } + makeWdEndpointUri: (config, log) => () => { + return getWdEndpointUri({config, log}); + }, + makeSparqlEndpointUri: (config, log) => () => { + return getSparqlEndpointUri({config, log}); + } }; -function getSparqlEndpointUri({ config, log }) { - const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; - log.debug(`sparqlEndpointUri: ${serviceUri}`); - return serviceUri; +function getSparqlEndpointUri({config, log}) { + const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; + log.debug(`sparqlEndpointUri: ${serviceUri}`); + return serviceUri; } -function getWdEndpointUri({ config, log }) { - const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; - const serviceUri = `${svc}/w/api.php`; - log.debug(`wdEndpointUri: ${serviceUri}`); - return serviceUri; +function getWdEndpointUri({config, log}) { + const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; + const serviceUri = `${svc}/w/api.php`; + log.debug(`wdEndpointUri: ${serviceUri}`); + return serviceUri; } -/* wdSearchByAnyName: +/* WdSearchByAnyName: dato un nome generico nome di pianta espresso in qualsiasi lingua ritorna una lista di `wikidata entities` [1.0.1 BUG FIX]: added `origin=*` */ -function getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - name = (name === undefined) ? "" : name; - const uri = `${getWdEndpointUri({ config, log })}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; - log.debug(uri); - const headers = { 'Accept': 'application/json' }; - // ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata - // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); - return ff(uri, headers); +function getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + name = (name === undefined) ? '' : name; + const uri = `${getWdEndpointUri({config, log})}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; + log.debug(uri); + const headers = {Accept: 'application/json'}; + // Ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata + // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); + return ff(uri, headers); } -/* wdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName +/* WdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName dato un nome in qualsiasi lingua, usa le API di wikidata.org con action=query e dal risultato estrae solo quegli elementi che potrebbero essere piante quindi restituisce un proprio risultato contenente in nome cercato e le piante */ -async function getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - if (name === undefined) { - return { name: undefined, plants: [] }; - } else if (name === null) { - return { name: null, plants: [] }; - } - const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - try { - log.debug(JSON.stringify(response)); // there is a response we can log it. - if (response.error) { - return { - name: name, - plants: [], - error: { - code: response.error.code, - message: response.error.info - } - } - } - - let plants = response.query.search.filter((item) => { - // species of plant - // variety of plants - return ( - item.snippet.toLowerCase().includes("plant") - || - item.snippet.toLowerCase().includes("cultivar") - ); - }); - // log.debug('============================'); - // log.debug(name); - // log.debug(JSON.stringify(plants)); - return { - "name": name, - "plants": plants - }; - } catch (someError) { - return { - name: name, - plants: [], - error: { - code: "999", - message: `unexpected ${someError.message}` - } - } - } +async function getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + if (name === undefined) { + return {name: undefined, plants: []}; + } + + if (name === null) { + return {name: null, plants: []}; + } + + const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + try { + log.debug(JSON.stringify(response)); // There is a response we can log it. + if (response.error) { + return { + name, + plants: [], + error: { + code: response.error.code, + message: response.error.info + } + }; + } + + const plants = response.query.search.filter(item => { + // Species of plant + // variety of plants + return ( + item.snippet.toLowerCase().includes('plant') || + item.snippet.toLowerCase().includes('cultivar') + ); + }); + // Log.debug('============================'); + // log.debug(name); + // log.debug(JSON.stringify(plants)); + return { + name, + plants + }; + } catch (error) { + return { + name, + plants: [], + error: { + code: '999', + message: `unexpected ${error.message}` + } + }; + } } -/* es: sparqlGetScientificNameByEntityId +/* Es: sparqlGetScientificNameByEntityId data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata */ -function getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); +function getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); } -/* -come sparqlGetScientificNameByEntityId ma con più attribuiti +/* +Come sparqlGetScientificNameByEntityId ma con più attribuiti this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL */ -function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, entityId) { - const sparql = +function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { OPTIONAL { wd:${entityId} wdt:P225 ?scientificname. } OPTIONAL { wd:${entityId} wdt:P105 ?taxonrank.} OPTIONAL { wd:${entityId} wdt:P18 ?image. } SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); } -/* -data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon -ne ricava il relativo articolo wikimedia species +/* +Data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon +ne ricava il relativo articolo wikimedia species */ -function getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); +function getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); } -/* ex: wdPromise +/* Ex: wdPromise get a Promise that the name provided will be used to search plants in the opendata */ -function getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name) { - return new Promise(resolveQuery => { - const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) - .then((value) => { - // log.debug(JSON.stringify(value)); - return value; - }); - asyncPlants.then((responseOfPlantsSearchedByAnyName) => { - let entities = []; - (async function loopWDEntities() { - for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { - // log.debug(i); - const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; - const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; - const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; - // log.debug(`wdEntity: ${wdEntity}`); - const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, wdEntity); - // DEFENSIVE PROGRAMMING BUT UNUSEFUL [ try { - log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); - // } catch(errorLogging) { - // log.error(`sparqlQueryScientificName got no results:${errorLogging.message}`); - // } // DEFENSIVE PROGRAMMING BUT UNUSEFUL ] - - let scientificName; - try { - scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; - } catch (e) { - scientificName = "#ND"; - } - log.info(scientificName); - - let taxonRankId; - let taxonRankLabel; - try { - taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; - taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; - } catch (e) { - taxonRankId = "#ND"; - taxonRankLabel = "#ND"; - } - - let image; - try { - image = sparqlQueryScientificName.results.bindings[0].image.value; - } catch (e) { - log.warn(`image #ND, cautch exception message:[${e.message}]`); - } - - let specieArticle; - try { - const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, wdEntity); - specieArticle = sparqlQueryArticle.results.bindings[0].article.value; - log.info(specieArticle); - } catch (e) { - log.warn(`specieArticle #ND [${e.message}]`); - } - - entities[i] = { - wdEntityId: wdEntity, - wdPageId: wdPageId, - wdSnippet: wdSnippet, - scientificName: scientificName, - taxonRankId: taxonRankId, - taxonRankLabel: taxonRankLabel, - }; - if (specieArticle) { - entities[i]["specieArticle"] = specieArticle; - } - if (image) { - entities[i]["image"] = image; - } - } - resolveQuery({ - name: responseOfPlantsSearchedByAnyName.name, - plants: entities - }); - })(); // .catch(e => log.debug("loopWDEntities Caught Error: " + e)); // UNCOVERED ( intentionally left for DEFENSIVE PROGRAMMING ) - }); // closing res.then - }); +function getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name) { + return new Promise(resolve => { + const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) + .then(value => { + // Log.debug(JSON.stringify(value)); + return value; + }); + asyncPlants.then(responseOfPlantsSearchedByAnyName => { + const entities = []; + (async () => { // #loopWDEntities + for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { + // Log.debug(i); + const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; + const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; + const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; + // Log.debug(`wdEntity: ${wdEntity}`); + const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + + log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); + + let scientificName; + try { + scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; + } catch (error) { + scientificName = '#ND'; + } + + log.info(scientificName); + + let taxonRankId; + let taxonRankLabel; + try { + taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; + taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; + } catch (error) { + taxonRankId = '#ND'; + taxonRankLabel = '#ND'; + } + + let image; + try { + image = sparqlQueryScientificName.results.bindings[0].image.value; + } catch (error) { + log.warn(`image #ND, cautch exception message:[${error.message}]`); + } + + let specieArticle; + try { + const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + specieArticle = sparqlQueryArticle.results.bindings[0].article.value; + log.info(specieArticle); + } catch (error) { + log.warn(`specieArticle #ND [${error.message}]`); + } + + entities[i] = { + wdEntityId: wdEntity, + wdPageId, + wdSnippet, + scientificName, + taxonRankId, + taxonRankLabel + }; + if (specieArticle) { + entities[i].specieArticle = specieArticle; + } + + if (image) { + entities[i].image = image; + } + } + + resolve({ + name: responseOfPlantsSearchedByAnyName.name, + plants: entities + }); + })(); + }); + }); } // https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/ @@ -259,95 +259,93 @@ function getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log } * @classdesc This is a description of the Phyto class. */ class Phyto { - - /** + /** * @constructor - * @param {Function} fetch - * @param {Function} config - * @param {Function} logger + * @param {Function} fetch - a fetch function possibly polymorphic + * @param {object} config - a configuration object isomorph with @rondinif/phytojs/esm/config + * @param {object} log - a logger object isomorph with @rondinif/phytojs/esm/log + * @param {object} logconfig - a configuration object dor the logger, isomorph with @rondinif/phytojs/esm/logconfig */ - constructor(fetch, config, log, logconfig) { - this._effectiveConfig = (typeof config == 'undefined') ? {isUnderTest: () => false } : config; - this._effectiveLog = (typeof log == 'undefined') ? new Log((typeof logconfig == 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true } : logconfig) : log; + constructor(fetch, config, log, logconfig) { + this._effectiveConfig = (typeof config === 'undefined') ? {isUnderTest: () => false} : config; + this._effectiveLog = (typeof log === 'undefined') ? new Log((typeof logconfig === 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true} : logconfig) : log; + const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); + const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); - const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); - const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); - - this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); - this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById( _ffSparql, this._effectiveConfig, this._effectiveLog); + this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); + this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById(_ffSparql, this._effectiveConfig, this._effectiveLog); - this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); - this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); - } + this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); + this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); + } - // SECTION which concerns: `openDataPromisesFactories` + // SECTION which concerns: `openDataPromisesFactories` - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` or any `term` for which the wikidata search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdSearchByAnyName) */ - wdSearchByAnyName(name) { - return this._wdSearchByAnyName(name); - } + wdSearchByAnyName(name) { + return this._wdSearchByAnyName(name); + } - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` of the plant for which the odla search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdPlantsByAnyName) */ - wdPlantsByAnyName(name) { - return this._wdPlantsByAnyName(name); - } + wdPlantsByAnyName(name) { + return this._wdPlantsByAnyName(name); + } - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` of the plant for which the odla re-solver will go to find valid entities uniquely identifiable by means of an `id` and a `scientific-name` + * @return {Promise} - a Promise of results with the list resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/resolvedPlantsByName) */ - resolvedPlantsByName(name) { - return this._resolvedPlantsByName(name); - } + resolvedPlantsByName(name) { + return this._resolvedPlantsByName(name); + } - /** - * @param {string} id - * @return {Promise} + /** + * @param {string} id - the `id` of the entitity for which the odla re-solver will go to find valid `scientific-name` + * @return {Promise} - a Promise of results with the list of `scientific-name` of the resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/sparqlScientificNameById) */ - sparqlScientificNameById(id) { - return this._sparqlScientificNameById(id); - } + sparqlScientificNameById(id) { + return this._sparqlScientificNameById(id); + } - // SECTION which concerns: `openDataEndpointFactories` + // SECTION which concerns: `openDataEndpointFactories` - /** - * @return {string} + /** + * @return {string} - the `SPARQL endpoint` which will be used by the `OpenDataLogicAgent` */ - getSparqlEndpointUri() { - return this._sparqlEndpointUri(); - } + getSparqlEndpointUri() { + return this._sparqlEndpointUri(); + } - /** - * @return {string} + /** + * @return {string} - the `Wikidata API endpoint` which will be used by the `OpenDataLogicAgent` */ - getWikiDataApiEndpointUri() { - return this._wdEndpointUri(); - } + getWikiDataApiEndpointUri() { + return this._wdEndpointUri(); + } - /** - * @return {object} + /** + * @return {object} - the effective `configuration` which will be used by the `OpenDataLogicAgent` */ - config() { - return this._effectiveConfig; - } + config() { + return this._effectiveConfig; + } - /** - * @return {object} + /** + * @return {object} - the effective `logger` which will be used by the `OpenDataLogicAgent` */ - logger() { - console.log(`####:${this._effectiveLog}`); - return this._effectiveLog; - } - + logger() { + // #DEBUG console.log(`####:${this._effectiveLog}`); + return this._effectiveLog; + } } export { Phyto }; diff --git a/package-lock.json b/package-lock.json index 7ab261a..d71149e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@rondinif/phytojs", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -341,6 +341,22 @@ "rimraf": "^2.5.2" } }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, "@roarr/cli": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@roarr/cli/-/cli-1.3.1.tgz", @@ -400,6 +416,29 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@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/nock": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@types/nock/-/nock-9.3.1.tgz", @@ -456,6 +495,12 @@ "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -468,6 +513,42 @@ "uri-js": "^4.2.2" } }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -543,6 +624,30 @@ } } }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -561,6 +666,37 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -588,6 +724,12 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -615,6 +757,12 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, "auto-bind": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.0.tgz", @@ -981,6 +1129,61 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -1008,6 +1211,54 @@ "integrity": "sha512-mDcM3ChboDuhv4glLXEH1us7jMiWXRSs3R13Okoo+kkFOlLIjvF1y88507wTfDf9zsuv0YffSDFUwX95VAT/mg==", "dev": true }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1033,6 +1284,12 @@ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, + "buf-compare": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", + "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -1045,6 +1302,23 @@ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", @@ -1057,6 +1331,12 @@ "write-file-atomic": "^2.4.2" } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -1153,6 +1433,12 @@ "supports-color": "^5.3.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1182,6 +1468,44 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -1228,6 +1552,12 @@ } } }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -1245,6 +1575,16 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1352,12 +1692,64 @@ "dot-prop": "^3.0.0" } }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.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": { + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "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=", + "dev": true + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "conventional-changelog-angular": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", @@ -1507,6 +1899,22 @@ "safe-buffer": "~5.1.1" } }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-assert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", + "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", + "dev": true, + "requires": { + "buf-compare": "^1.0.0", + "is-error": "^2.2.0" + } + }, "core-js": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", @@ -1576,6 +1984,15 @@ "safe-buffer": "^5.0.1" } }, + "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=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -1589,6 +2006,12 @@ "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=", + "dev": true + }, "csstype": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.4.tgz", @@ -1655,6 +2078,12 @@ } } }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -1670,6 +2099,27 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deep-strict-equal": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz", + "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=", + "dev": true, + "requires": { + "core-assert": "^0.2.0" + } + }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -1688,12 +2138,53 @@ "object-keys": "^1.0.12" } }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1715,6 +2206,24 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -1751,6 +2260,12 @@ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1782,59 +2297,644 @@ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { - "once": "^1.4.0" + "once": "^1.4.0" + } + }, + "enhance-visitors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz", + "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=", + "dev": true, + "requires": { + "lodash": "^4.13.1" + } + }, + "env-editor": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.3.1.tgz", + "integrity": "sha1-MNBUDCEBQU8lipTUwKUkwGwT48Y=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "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=", + "dev": true + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "requires": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + } + }, + "eslint-config-prettier": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz", + "integrity": "sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, + "eslint-config-xo": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.26.0.tgz", + "integrity": "sha512-l+93kmBSNr5rMrsqwC6xVWsi8LI4He3z6jSk38e9bAkMNsVsQ8XYO+qzXfJFgFX4i/+hiTswyHtl+nDut9rPaA==", + "dev": true + }, + "eslint-formatter-pretty": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-2.1.1.tgz", + "integrity": "sha512-gWfagucSWBn82WxzwFloBTLAcwYDgnpAfiV5pQfyAV5YpZikuLflRU8nc3Ts9wnNvLhwk4blzb42/C495Yw7BA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.1.0", + "chalk": "^2.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^2.0.0", + "plur": "^3.0.1", + "string-width": "^2.0.0", + "supports-hyperlinks": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "plur": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", + "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", + "dev": true, + "requires": { + "irregular-plurals": "^2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-ava": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-5.1.1.tgz", + "integrity": "sha512-3N7geVdXTabpngQOl+ih1ejMbFOXCUYROnTIP66KAQoMcEAkPSXYc/Jwo/qC4zpRR7PXMuf5afMzTEBpyZmWzQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "deep-strict-equal": "^0.2.0", + "enhance-visitors": "^1.0.0", + "esm": "^3.0.82", + "espree": "^4.0.0", + "espurify": "^1.8.1", + "import-modules": "^1.1.0", + "is-plain-object": "^2.0.4", + "multimatch": "^2.1.0", + "pkg-up": "^2.0.0" + }, + "dependencies": { + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", + "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", + "dev": true, + "requires": { + "eslint-utils": "^1.3.0", + "regexpp": "^2.0.1" + } + }, + "eslint-plugin-eslint-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.1.tgz", + "integrity": "sha512-GZDKhOFqJLKlaABX+kdoLskcTINMrVOWxGca54KcFb1QCPd0CLmqgAMRxkkUfGSmN+5NJUMGh7NGccIMcWPSfQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "dependencies": { + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz", + "integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "resolve": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-no-use-extend-native": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.0.tgz", + "integrity": "sha512-9W2747CwC7aTJknLKY6ftdzj3AZz8DSaa64zONOMIemxH7YRr0+hqrvsNtHK/v9DusPuMxM9y9hBnfHwzKFmww==", + "dev": true, + "requires": { + "is-get-set-prop": "^1.0.0", + "is-js-type": "^2.0.0", + "is-obj-prop": "^1.0.0", + "is-proto-prop": "^2.0.0" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "eslint-plugin-node": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz", + "integrity": "sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w==", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^5.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + } } }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "eslint-plugin-prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz", + "integrity": "sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "prettier-linter-helpers": "^1.0.0" } }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "eslint-plugin-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.1.1.tgz", + "integrity": "sha512-faAHw7uzlNPy7b45J1guyjazw28M+7gJokKUjC5JSFoYfUEyy6Gw/i7YQvmv2Yk00sUjWcmzXQLpU1Ki/C2IZQ==", + "dev": true + }, + "eslint-plugin-unicorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-7.1.0.tgz", + "integrity": "sha512-lW/ZwGR638V0XuZgR160qVQvPtw8tw3laKT5LjJPt+W+tN7kVf2S2V7x+ZrEEwSjEb3OiEzb3cppzaKuYtgYeg==", "dev": true, "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.0.0", + "import-modules": "^1.1.0", + "lodash.camelcase": "^4.1.1", + "lodash.kebabcase": "^4.0.1", + "lodash.snakecase": "^4.0.1", + "lodash.upperfirst": "^4.2.0", + "safe-regex": "^2.0.1" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "eslint-rule-docs": { + "version": "1.1.119", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.119.tgz", + "integrity": "sha512-BjXTSdp4YR9RHoSS+61LynZXJTgr9wdzYPhOCfMTVsVRyvdKpP9FE2/hcWAJe9NpqZfG2/CwmALaXa1YJlIoJQ==", "dev": true }, - "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "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=", + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "esm": { @@ -1843,12 +2943,56 @@ "integrity": "sha512-z8YG7U44L82j1XrdEJcqZOLUnjxco8pO453gKOlaMD1/md1n/5QrscAmYG+oKUspsmDLuBFZrpbxI6aQ67yRxA==", "dev": true }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "espurify": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz", + "integrity": "sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==", + "dev": true, + "requires": { + "core-js": "^2.0.0" + } + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", @@ -1876,12 +3020,159 @@ "strip-eof": "^1.0.0" } }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -1894,12 +3185,61 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + } + } + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -1910,6 +3250,15 @@ "object-assign": "^4.1.0" } }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -1955,6 +3304,23 @@ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1964,6 +3330,12 @@ "is-callable": "^1.1.3" } }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", @@ -2003,6 +3375,15 @@ "mime-types": "^2.1.12" } }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, "fs-exists-cached": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", @@ -2034,6 +3415,12 @@ "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", "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 + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2046,6 +3433,12 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-set-props": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", + "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "dev": true + }, "get-stdin": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", @@ -2061,6 +3454,12 @@ "pump": "^3.0.0" } }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2221,6 +3620,12 @@ "is-glob": "^4.0.1" } }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -2236,6 +3641,57 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "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" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", @@ -2302,24 +3758,82 @@ "ansi-regex": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { + "has-yarn": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz", + "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", "dev": true }, "hasha": { @@ -2367,6 +3881,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "import-fresh": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", @@ -2399,6 +3919,18 @@ } } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "import-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", + "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2459,6 +3991,65 @@ "yoga-layout-prebuilt": "^1.9.3" } }, + "inquirer": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + } + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -2474,6 +4065,32 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, + "irregular-plurals": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", + "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2489,6 +4106,12 @@ "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", @@ -2504,18 +4127,69 @@ "ci-info": "^2.0.0" } }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, + "is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2537,6 +4211,16 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-get-set-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", + "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", + "dev": true, + "requires": { + "get-set-props": "^0.1.0", + "lowercase-keys": "^1.0.0" + } + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -2546,6 +4230,31 @@ "is-extglob": "^2.1.1" } }, + "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=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-js-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", + "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", + "dev": true, + "requires": { + "js-types": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2558,18 +4267,68 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, + "is-obj-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", + "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0", + "obj-props": "^1.0.0" + } + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", "dev": true }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.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=", + "dev": true + }, + "is-proto-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz", + "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0", + "proto-props": "^2.0.0" + } + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -2579,6 +4338,12 @@ "has": "^1.0.1" } }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -2609,6 +4374,18 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2621,6 +4398,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", @@ -2861,6 +4644,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "js-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", + "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", + "dev": true + }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -2901,6 +4690,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2940,6 +4735,21 @@ "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", "dev": true }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -2955,6 +4765,22 @@ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "line-column-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz", + "integrity": "sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU=", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -2997,12 +4823,48 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "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=", + "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.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, "lodash.template": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", @@ -3028,12 +4890,33 @@ "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", "dev": true }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, "log-update": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.2.0.tgz", @@ -3076,6 +4959,12 @@ "signal-exit": "^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 + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -3111,12 +5000,27 @@ "p-defer": "^1.0.0" } }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, "map-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", "dev": true }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", @@ -3253,22 +5157,133 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } } } @@ -3337,6 +5352,27 @@ } } }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -3366,6 +5402,57 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "multimatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", + "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", + "dev": true, + "requires": { + "array-differ": "^2.0.3", + "array-union": "^1.0.2", + "arrify": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "array-differ": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", + "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", + "dev": true + } + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -3504,12 +5591,49 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, + "obj-props": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz", + "integrity": "sha1-YmMT+qRCvv1KROmgLDy2vek3tRE=", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "object-inspect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", @@ -3522,6 +5646,24 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3548,12 +5690,32 @@ } } }, + "open-editor": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/open-editor/-/open-editor-1.2.0.tgz", + "integrity": "sha1-dcoj8LdNSz9V7guKTg9cIyXrd18=", + "dev": true, + "requires": { + "env-editor": "^0.3.1", + "line-column-path": "^1.0.0", + "opn": "^5.0.0" + } + }, "opener": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", "dev": true }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -3572,6 +5734,28 @@ } } }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -3664,6 +5848,18 @@ "release-zalgo": "^1.0.0" } }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3697,6 +5893,18 @@ "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", "dev": true }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -3709,6 +5917,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "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=", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -3755,45 +5969,187 @@ } } }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.6.tgz", + "integrity": "sha512-Btng9qVvFsW6FkXYQQK5nEI5i8xdXFDmlKxC7Q8S2Bu5HGWnbQf7ts2kOoxJIrZn5hmw61RZIayAg2zBuJDtyQ==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "plur": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "picomatch": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.6.tgz", - "integrity": "sha512-Btng9qVvFsW6FkXYQQK5nEI5i8xdXFDmlKxC7Q8S2Bu5HGWnbQf7ts2kOoxJIrZn5hmw61RZIayAg2zBuJDtyQ==", + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "prettier": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.1.tgz", + "integrity": "sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "find-up": "^3.0.0" + "fast-diff": "^1.1.2" } }, - "plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", - "dev": true - }, "pretty-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", @@ -3827,6 +6183,12 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -3844,6 +6206,12 @@ "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", "dev": true }, + "proto-props": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz", + "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==", + "dev": true + }, "proxyquire": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.0.tgz", @@ -3912,6 +6280,18 @@ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", "dev": true }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, "re-emitter": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz", @@ -4014,6 +6394,58 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + } + } + }, + "regexp-tree": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", + "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "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==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -4023,6 +6455,12 @@ "es6-error": "^4.0.1" } }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -4087,6 +6525,23 @@ "path-parse": "^1.0.6" } }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4119,6 +6574,12 @@ } } }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -4138,6 +6599,12 @@ "through": "~2.3.4" } }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -4182,12 +6649,39 @@ "terser": "^3.14.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-regex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.0.2.tgz", + "integrity": "sha512-rRALJT0mh4qVFIJ9HvfjKDN77F9vp7kltOpFFI/8e6oKyHFmmxz4aSkY/YVauRDe7U0RrHdw9Lsxdel3E19s0A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4231,6 +6725,15 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "serialize-javascript": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", @@ -4243,6 +6746,29 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4294,12 +6820,156 @@ "is-fullwidth-code-point": "^2.0.0" } }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, "source-map-support": { "version": "0.5.12", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", @@ -4318,6 +6988,12 @@ } } }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, "spawn-wrap": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", @@ -4373,6 +7049,15 @@ "through": "2" } }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, "split2": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/split2/-/split2-3.1.1.tgz", @@ -4411,6 +7096,27 @@ "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", @@ -4496,6 +7202,12 @@ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", "dev": true }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -4505,6 +7217,49 @@ "has-flag": "^3.0.0" } }, + "supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "dev": true, + "requires": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + } + } + }, + "table": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz", + "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + } + } + }, "tap": { "version": "13.1.8", "resolved": "https://registry.npmjs.org/tap/-/tap-13.1.8.tgz", @@ -4834,6 +7589,49 @@ "integrity": "sha512-fAfA73uFtFGybWGt4+IYT6UPLYVZQ4NfsP+IXEZGY0vh8e2IF7LVKafcQNMRBLqP0wzEA65LM9Tqj+FSmO8GLw==", "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=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "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=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.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": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, "terser": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", @@ -4871,6 +7669,18 @@ "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "the-argv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz", + "integrity": "sha1-AIRwUAVzDdhNt1UlPJMa45jblSI=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -4886,12 +7696,70 @@ "readable-stream": "2 || 3" } }, + "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=", + "dev": true + }, + "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-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + } + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5015,6 +7883,12 @@ "yn": "^3.0.0" } }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -5030,6 +7904,15 @@ "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", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -5101,6 +7984,131 @@ } } }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + } + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -5110,6 +8118,27 @@ "punycode": "^2.1.0" } }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", @@ -5229,6 +8258,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", @@ -5240,6 +8278,216 @@ "signal-exit": "^3.0.2" } }, + "write-json-file": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz", + "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=", + "dev": true, + "requires": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "pify": "^3.0.0", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.0.0" + }, + "dependencies": { + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "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=", + "dev": true + } + } + }, + "write-pkg": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz", + "integrity": "sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==", + "dev": true, + "requires": { + "sort-keys": "^2.0.0", + "write-json-file": "^2.2.0" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xo": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/xo/-/xo-0.24.0.tgz", + "integrity": "sha512-eaXWpNtXHbJ+DSiDkdRnDcMYPeUi/MWFUoUgorBhzAueTCM+v4o9Xv6buYgyoL4r7JuTp5EWXx3lGn9Md4dgWA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "debug": "^4.1.0", + "eslint": "^5.12.0", + "eslint-config-prettier": "^3.3.0", + "eslint-config-xo": "^0.26.0", + "eslint-formatter-pretty": "^2.0.0", + "eslint-plugin-ava": "^5.1.0", + "eslint-plugin-eslint-comments": "^3.0.1", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-no-use-extend-native": "^0.4.0", + "eslint-plugin-node": "^8.0.0", + "eslint-plugin-prettier": "^3.0.0", + "eslint-plugin-promise": "^4.0.0", + "eslint-plugin-unicorn": "^7.0.0", + "find-cache-dir": "^2.0.0", + "get-stdin": "^6.0.0", + "globby": "^9.0.0", + "has-flag": "^3.0.0", + "lodash.isequal": "^4.5.0", + "lodash.mergewith": "^4.6.1", + "meow": "^5.0.0", + "multimatch": "^3.0.0", + "open-editor": "^1.2.0", + "path-exists": "^3.0.0", + "pkg-conf": "^2.1.0", + "prettier": "^1.15.2", + "resolve-cwd": "^2.0.0", + "resolve-from": "^4.0.0", + "semver": "^5.5.0", + "slash": "^2.0.0", + "update-notifier": "^2.3.0", + "xo-init": "^0.7.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "xo-init": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/xo-init/-/xo-init-0.7.0.tgz", + "integrity": "sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "execa": "^0.9.0", + "has-yarn": "^1.0.0", + "minimist": "^1.1.3", + "path-exists": "^3.0.0", + "read-pkg-up": "^3.0.0", + "the-argv": "^1.0.0", + "write-pkg": "^3.1.0" + }, + "dependencies": { + "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=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", + "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.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" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + } + } + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 4a6ad8e..dbde608 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@rondinif/phytojs", - "version": "1.2.1", - "description": "A modern javascript library to search about plants on open data", + "version": "1.3.0", + "description": "A modern javascript toolkit to search about plants on open data", "keywords": [ "botanica", "botanical", @@ -32,8 +32,10 @@ "main": "umd/phyto.js", "module": "esm/phyto.js", "scripts": { - "prepare": "rollup --config", + "remediations": "sed -i.backup 's/\\.\\.\\/esm\\//\\.\\.\\/umd\\//' ./umd/phyto.js", + "prepare": "rollup --config && npm run remediations", "test": "NODE_ENV=test npx tap test/**/*.test.esm.js", + "test:xo": "xo && NODE_ENV=test npx tap test/**/*.test.esm.js", "cover": "NODE_ENV=test npx tap test/**/*.test.esm.js --cov --coverage-report=lcov", "coveralls": "NODE_ENV=test npm run cover && cat ./coverage/lcov.info | coveralls", "test-spec": "NODE_ENV=test npx tap test/**/*.test.esm.js | node_modules/.bin/tap-spec", @@ -45,13 +47,14 @@ "test-odla-stubbed": "NODE_ENV=test node -r esm test/lib/OpenDataLogicAgent.stubbed.test.esm.js | node_modules/.bin/tap-spec", "test-odla-sandboxed": "NODE_ENV=test node -r esm test/lib/OpenDataLogicAgent.sandboxed.test.esm.js | node_modules/.bin/tap-spec", "cover-odla": "NODE_ENV=test npx tap test/lib/*.test.esm.js --cov --coverage-report=lcov", - "sample-umd": "node samples/index.umd.js", + "sample-umd": "node samples/index.umd.js && node samples/index.umd.1.js && node samples/index.umd.2.js && node samples/index.umd.3.js", "sample-umd-esm": "node -r esm ./samples/index.umd.esm.js", "sample-esm": "node -r esm samples/index.esm.js", "clean": "rm -rf .nyc_output/ && rm -rf coverage/", "clean:prepare": "npm run clean && npm run prepare", - "clean:prepare:test": "npm run clean:prepare && npm test", - "clean:prepare:cover": "npm run clean:prepare:test && npm run cover", + "clean:prepare:test:xo": "npm run clean:prepare && npm run test:xo", + "clean:prepare:cover": "npm run clean:prepare:test:xo && npm run cover", + "sonar-scanner": "xo --reporter json > .eslint/report.json && sonar-scanner -X", "start": "http-server docs/mvc" }, "files": [ @@ -77,7 +80,18 @@ "tap": "^13.1.2", "tap-spec": "^5.0.0", "tape": "^4.10.1", - "tape-nock": "^1.6.1" + "tape-nock": "^1.6.1", + "xo": "^0.24.0" }, - "dependencies": {} + "dependencies": {}, + "xo": { + "ignores": [ + "esm", + "umd", + "docs", + "samples", + "script", + "test" + ] + } } diff --git a/rollup.config.js b/rollup.config.js index 73cccb8..acf7538 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,112 +1,107 @@ -// TODO ; leggi https://www.npmjs.com/package/rollup-plugin-terser -// per la gestione dei commenti sulla licenza - -/* -Attenzione il main.js va messo in fondo +/* +Attenzione il main.js va messo in fondo perchè importa gli esm che vanno generati prima -questa scelta è stata fatta per mantenere separati i vari moduli -e garantire una elevata coverage dei test +questa scelta è stata fatta per mantenere separati i vari moduli +e garantire una elevata coverage dei test */ - -import { terser } from 'rollup-plugin-terser'; export default [ - { - input: 'src/config/config.js', - external: [ 'dotenv-flow' ], - // plugins: [terser()], - output: { - file: 'umd/config.js', - format: 'umd', - name: 'config', - esModule: false, - globals: { - 'dotenv-flow': 'dotenv' - } - } - }, - { - input: 'src/config/config.js', - external: [ 'dotenv-flow' ], - output: { - file: 'esm/config.js', - format: 'esm', - globals: { - 'dotenv-flow': 'dotenv' - } - } - }, + { + input: 'src/config/config.js', + external: ['dotenv-flow'], + // Plugins: [terser()], + output: { + file: 'umd/config.js', + format: 'umd', + name: 'config', + esModule: false, + globals: { + 'dotenv-flow': 'dotenv' + } + } + }, + { + input: 'src/config/config.js', + external: ['dotenv-flow'], + output: { + file: 'esm/config.js', + format: 'esm', + globals: { + 'dotenv-flow': 'dotenv' + } + } + }, - { - input: 'src/config/logconfig.js', - external: [ 'dotenv-flow' ], - // plugins: [terser()], - output: { - file: 'umd/logconfig.js', - format: 'umd', - name: 'logconfig', - esModule: false, - globals: { - 'dotenv-flow': 'dotenv' - } - } - }, - { - input: 'src/config/logconfig.js', - external: [ 'dotenv-flow' ], - output: { - file: 'esm/logconfig.js', - format: 'esm', - globals: { - 'dotenv-flow': 'dotenv' - } - } - }, + { + input: 'src/config/logconfig.js', + external: ['dotenv-flow'], + // Plugins: [terser()], + output: { + file: 'umd/logconfig.js', + format: 'umd', + name: 'logconfig', + esModule: false, + globals: { + 'dotenv-flow': 'dotenv' + } + } + }, + { + input: 'src/config/logconfig.js', + external: ['dotenv-flow'], + output: { + file: 'esm/logconfig.js', + format: 'esm', + globals: { + 'dotenv-flow': 'dotenv' + } + } + }, - { - input: 'src/log/log.js', - // plugins: [terser()], - output: { - file: 'umd/log.js', - format: 'umd', - name: 'log', - esModule: false - } - }, - { - input: 'src/log/log.js', - output: { - file: 'esm/log.js', - format: 'esm' - } - }, + { + input: 'src/log/log.js', + // Plugins: [terser()], + output: { + file: 'umd/log.js', + format: 'umd', + name: 'log', + esModule: false + } + }, + { + input: 'src/log/log.js', + output: { + file: 'esm/log.js', + format: 'esm' + } + }, - { - external: [ - 'dotenv-flow', - '../esm/config', - '../esm/logconfig', - '../esm/log' - ], - input: 'src/main.js', - // plugins: [terser()], - output: { - file: 'umd/phyto.js', - format: 'umd', - name: 'phyto', - esModule: false - } - }, - { - external: [ - 'dotenv-flow', - '../esm/config', - '../esm/logconfig', - '../esm/log' - ], - input: 'src/main.js', - output: { - file: 'esm/phyto.js', - format: 'esm' - } - } -]; \ No newline at end of file + { + external: [ + 'dotenv-flow', + '../esm/config', + '../esm/logconfig', + '../esm/log' + ], + input: 'src/main.js', + // Plugins: [terser()], + output: { + file: 'umd/phyto.js', + format: 'umd', + name: 'phyto', + esModule: false + } + }, + { + external: [ + 'dotenv-flow', + '../esm/config', + '../esm/logconfig', + '../esm/log' + ], + input: 'src/main.js', + output: { + file: 'esm/phyto.js', + format: 'esm' + } + } +]; diff --git a/samples/index.umd.2.js b/samples/index.umd.2.js index 631d19c..79bccb7 100644 --- a/samples/index.umd.2.js +++ b/samples/index.umd.2.js @@ -20,8 +20,6 @@ const logconfig = require('../umd/logconfig.js').logconfig; const loglib = require('../umd/log.js'); const log = new loglib.Log(logconfig); -log.error('haha'); - const lib = require('../umd/phyto'); const phyto = new lib.Phyto(fetch, config, log); diff --git a/script/mbstart.sh b/script/mbstart.sh index a1377ed..4189228 100755 --- a/script/mbstart.sh +++ b/script/mbstart.sh @@ -1,4 +1,3 @@ - # TODO - this is a draft # SEE - http://www.mbtest.org/docs/commandLine ( Saving mountebank configuration ) diff --git a/script/remediations.sh b/script/remediations.sh new file mode 100755 index 0000000..e141d01 --- /dev/null +++ b/script/remediations.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# remediation 1: wrong esm path in umd/phyto.js +sed -i.backup 's/\.\.\/esm\//\.\.\/umd\//' ./umd/phyto.js \ No newline at end of file diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..6e2a28a --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,48 @@ + +sonar.projectKey=rondinif:phytojs-js +# must be unique in a given SonarQube instance +# sonar.organization=rondinif-github +# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. +sonar.projectName=PhytoJS is a modern javascript toolkit to search about plants on open data +sonar.projectVersion=1.3.0-SNAPSHOT + +# ===================================================== +# Meta-data for the project +# ===================================================== + +sonar.links.homepage=https://github.com/rondinif/phytojs +sonar.links.ci=https://travis-ci.org/rondinif/phytojs +sonar.links.scm=https://github.com/rondinif/phytojs +sonar.links.issue=https://github.com/rondinif/phytojs/issues + + +# ===================================================== +# Properties that will be shared amongst all modules +# ===================================================== + +# SQ standard properties +# Encoding of the source code. Default is default system encoding +sonar.sourceEncoding=UTF-8 + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +# This property is optional if sonar.modules is set. +sonar.sources=./esm + +# sonar.eslint.eslintconfigpath=eslintrc.json +sonar.tests=test + +# sonar.exclusions=node_modules/**/* , _private/**/*, _config/**/*, test/**/*, samples/**/*, docs/**/*, src/**/*, umd/**/*, script/**/* + +sonar.exclusions=node_modules/**/* , _private/**/*, _config/**/*, samples/**/*, docs/**/*, script/**/* + + +# Properties specific to language plugins: +# - For JavaScript + +# sonar.language=js +sonar.javascript.lcov.reportPaths=./coverage/lcov.info + +sonar.eslint.reportPaths=.eslint/report.json + +# Other proprieties +sonar.cfamily.build-wrapper-output.bypass=true \ No newline at end of file diff --git a/src/config/config.js b/src/config/config.js index bf4debf..6474673 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -1,49 +1,56 @@ -"use strict"; -import dotenv from 'dotenv-flow' -dotenv.config() -/* -usage in programs: +'use strict'; +import dotenv from 'dotenv-flow'; + +dotenv.config(); +/* +Usage in programs: import { config } from './lib/config.mjs'; to check the effective configuration: @see ../config.checher.mjs WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs + - .mjs Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. */ export const DEFAULT_IS_UNDER_TEST = false; -const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } -} +const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } + + case 'false': { + return false; + } + + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } +}; export const config = { - /* - the test features are enabed + /* + The test features are enabed affected by .env IS_FILESTORE_WRITING_ENABLED */ - isUnderTest: function () { - return process.env.IS_UNDER_TEST ? - castToBoolen(process.env.IS_UNDER_TEST) : - DEFAULT_IS_UNDER_TEST; - } -} + isUnderTest() { + return process.env.IS_UNDER_TEST ? + castToBoolen(process.env.IS_UNDER_TEST) : + DEFAULT_IS_UNDER_TEST; + } +}; diff --git a/src/config/logconfig.js b/src/config/logconfig.js index ec840e7..7d94641 100644 --- a/src/config/logconfig.js +++ b/src/config/logconfig.js @@ -1,14 +1,15 @@ -"use strict"; -import dotenv from 'dotenv-flow' -dotenv.config() -/* -usage in programs: +'use strict'; +import dotenv from 'dotenv-flow'; + +dotenv.config(); +/* +Usage in programs: import { config } from './lib/config.mjs'; to check the effective configuration: @see ../config.checher.mjs WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs + - .mjs Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. */ @@ -16,44 +17,50 @@ Coding Conventions: before each configuration a comment SHOULD be written; the c export const DEFAULT_IS_LOG_VERBOSE = false; export const DEFAULT_IS_LOG_SILENT = true; -const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } -} +const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } + + case 'false': { + return false; + } + + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } +}; export const logconfig = { - /* - the log is verbose enabed + /* + The log is verbose enabed affected by .env IS_LOG_VERBOSE */ - isLogVerbose: function () { - return process.env.IS_LOG_VERBOSE ? - castToBoolen(process.env.IS_LOG_VERBOSE) : - DEFAULT_IS_LOG_VERBOSE; - }, - /* - the log is verbose enabed + isLogVerbose() { + return process.env.IS_LOG_VERBOSE ? + castToBoolen(process.env.IS_LOG_VERBOSE) : + DEFAULT_IS_LOG_VERBOSE; + }, + /* + The log is verbose enabed affected by .env IS_LOG_VERBOSE */ - isLogSilent: function () { - return process.env.IS_LOG_SILENT ? - castToBoolen(process.env.IS_LOG_SILENT) : - DEFAULT_IS_LOG_SILENT; - } -} + isLogSilent() { + return process.env.IS_LOG_SILENT ? + castToBoolen(process.env.IS_LOG_SILENT) : + DEFAULT_IS_LOG_SILENT; + } +}; diff --git a/src/lib/OpenDataAsyncFactories.mjs b/src/lib/OpenDataAsyncFactories.mjs deleted file mode 100644 index dfa9281..0000000 --- a/src/lib/OpenDataAsyncFactories.mjs +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; -// DIP: export Higher-order function factories : each of them returns a function as its result. - -// Higher-order function: returns a function as its result. -export function makeGetPromiseOfWikiDataApiResults(fetch, log) { - return (uri, headers) => { - return fetch(encodeURI(uri), { - headers: headers // , - // method: 'GET', ...mode, cache , see - }).then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; -} - -// Higher-order function: returns a function as its result. -export function makeGetPromiseOfSparqlResults(fetch, log) { - return (serviceUri, sparql, headers) => { - const uri = `${serviceUri}/sparql?query=${sparql}`; - return fetch(encodeURI(uri), { headers }) - .then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; -} diff --git a/src/lib/OpenDataLogicAgent.mjs b/src/lib/OpenDataLogicAgent.mjs deleted file mode 100644 index e72cf21..0000000 --- a/src/lib/OpenDataLogicAgent.mjs +++ /dev/null @@ -1,229 +0,0 @@ -"use strict"; -export const openDataPromisesFactories = { - makeWdSearchByAnyName: (ff, config, log) => name => { - return getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeWdPlantsByAnyName: (ff, config, log) => name => { - return getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { - return getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name); - }, - makeSparqlScientificNameById: (ffSparql, config, log) => id => { - return getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, id); - }, -}; - -export const openDataEndpointFactories = { - makeWdEndpointUri: (config, log) => () => { - return getWdEndpointUri({ config, log }); - }, - makeSparqlEndpointUri: (config, log) => () => { - return getSparqlEndpointUri({ config, log }); - } -}; - -function getSparqlEndpointUri({ config, log }) { - const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; - log.debug(`sparqlEndpointUri: ${serviceUri}`); - return serviceUri; -} - -function getWdEndpointUri({ config, log }) { - const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; - const serviceUri = `${svc}/w/api.php`; - log.debug(`wdEndpointUri: ${serviceUri}`); - return serviceUri; -} - -/* wdSearchByAnyName: -dato un nome generico nome di pianta espresso in qualsiasi lingua -ritorna una lista di `wikidata entities` -[1.0.1 BUG FIX]: added `origin=*` -*/ -function getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - name = (name === undefined) ? "" : name; - const uri = `${getWdEndpointUri({ config, log })}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; - log.debug(uri); - const headers = { 'Accept': 'application/json' }; - // ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata - // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); - return ff(uri, headers); -} - -/* wdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName -dato un nome in qualsiasi lingua, -usa le API di wikidata.org con action=query -e dal risultato estrae solo quegli elementi che potrebbero essere piante -quindi restituisce un proprio risultato contenente in nome cercato e le piante -*/ -async function getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - if (name === undefined) { - return { name: undefined, plants: [] }; - } else if (name === null) { - return { name: null, plants: [] }; - } - const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - try { - log.debug(JSON.stringify(response)); // there is a response we can log it. - if (response.error) { - return { - name: name, - plants: [], - error: { - code: response.error.code, - message: response.error.info - } - } - } - - let plants = response.query.search.filter((item) => { - // species of plant - // variety of plants - return ( - item.snippet.toLowerCase().includes("plant") - || - item.snippet.toLowerCase().includes("cultivar") - ); - }); - // log.debug('============================'); - // log.debug(name); - // log.debug(JSON.stringify(plants)); - return { - "name": name, - "plants": plants - }; - } catch (someError) { - return { - name: name, - plants: [], - error: { - code: "999", - message: `unexpected ${someError.message}` - } - } - } -} - -/* es: sparqlGetScientificNameByEntityId -data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon -ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata -*/ -function getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}` - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); -} - -/* -come sparqlGetScientificNameByEntityId ma con più attribuiti -this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL -*/ -function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, entityId) { - const sparql = - `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { - OPTIONAL { wd:${entityId} wdt:P225 ?scientificname. } - OPTIONAL { wd:${entityId} wdt:P105 ?taxonrank.} - OPTIONAL { wd:${entityId} wdt:P18 ?image. } - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } - }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); -} - -/* -data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon -ne ricava il relativo articolo wikimedia species -*/ -function getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); -} - -/* ex: wdPromise -get a Promise that the name provided will be used to search plants in the opendata -*/ -function getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name) { - return new Promise(resolveQuery => { - const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) - .then((value) => { - // log.debug(JSON.stringify(value)); - return value; - }); - asyncPlants.then((responseOfPlantsSearchedByAnyName) => { - let entities = []; - (async function loopWDEntities() { - for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { - // log.debug(i); - const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; - const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; - const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; - // log.debug(`wdEntity: ${wdEntity}`); - const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, wdEntity); - // DEFENSIVE PROGRAMMING BUT UNUSEFUL [ try { - log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); - // } catch(errorLogging) { - // log.error(`sparqlQueryScientificName got no results:${errorLogging.message}`); - // } // DEFENSIVE PROGRAMMING BUT UNUSEFUL ] - - let scientificName; - try { - scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; - } catch (e) { - scientificName = "#ND"; - } - log.info(scientificName); - - let taxonRankId; - let taxonRankLabel; - try { - taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; - taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; - } catch (e) { - taxonRankId = "#ND"; - taxonRankLabel = "#ND"; - } - - let image; - try { - image = sparqlQueryScientificName.results.bindings[0].image.value; - } catch (e) { - log.warn(`image #ND, cautch exception message:[${e.message}]`); - } - - let specieArticle; - try { - const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, wdEntity); - specieArticle = sparqlQueryArticle.results.bindings[0].article.value; - log.info(specieArticle); - } catch (e) { - log.warn(`specieArticle #ND [${e.message}]`); - } - - entities[i] = { - wdEntityId: wdEntity, - wdPageId: wdPageId, - wdSnippet: wdSnippet, - scientificName: scientificName, - taxonRankId: taxonRankId, - taxonRankLabel: taxonRankLabel, - } - if (specieArticle) { - entities[i]["specieArticle"] = specieArticle; - } - if (image) { - entities[i]["image"] = image; - } - } - resolveQuery({ - name: responseOfPlantsSearchedByAnyName.name, - plants: entities - }); - })(); // .catch(e => log.debug("loopWDEntities Caught Error: " + e)); // UNCOVERED ( intentionally left for DEFENSIVE PROGRAMMING ) - }); // closing res.then - }); -} \ No newline at end of file diff --git a/src/lib/open-data-async-factories.js b/src/lib/open-data-async-factories.js new file mode 100644 index 0000000..99867c2 --- /dev/null +++ b/src/lib/open-data-async-factories.js @@ -0,0 +1,21 @@ +'use strict'; +// DIP: export Higher-order function factories : each of them returns a function as its result. +// Higher-order function: returns a function as its result. +export function makeGetPromiseOfWikiDataApiResults(fetch, log) { + return (uri, headers) => { + return fetch(encodeURI(uri), { + headers + }).then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; +} + +// Higher-order function: returns a function as its result. +export function makeGetPromiseOfSparqlResults(fetch, log) { + return (serviceUri, sparql, headers) => { + const uri = `${serviceUri}/sparql?query=${sparql}`; + return fetch(encodeURI(uri), {headers}) + .then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; +} diff --git a/src/lib/open-data-logic-agent.js b/src/lib/open-data-logic-agent.js new file mode 100644 index 0000000..82a9b63 --- /dev/null +++ b/src/lib/open-data-logic-agent.js @@ -0,0 +1,231 @@ +'use strict'; +export const openDataPromisesFactories = { + makeWdSearchByAnyName: (ff, config, log) => name => { + return getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeWdPlantsByAnyName: (ff, config, log) => name => { + return getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { + return getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name); + }, + makeSparqlScientificNameById: (ffSparql, config, log) => id => { + return getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, id); + } +}; + +export const openDataEndpointFactories = { + makeWdEndpointUri: (config, log) => () => { + return getWdEndpointUri({config, log}); + }, + makeSparqlEndpointUri: (config, log) => () => { + return getSparqlEndpointUri({config, log}); + } +}; + +function getSparqlEndpointUri({config, log}) { + const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; + log.debug(`sparqlEndpointUri: ${serviceUri}`); + return serviceUri; +} + +function getWdEndpointUri({config, log}) { + const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; + const serviceUri = `${svc}/w/api.php`; + log.debug(`wdEndpointUri: ${serviceUri}`); + return serviceUri; +} + +/* WdSearchByAnyName: +dato un nome generico nome di pianta espresso in qualsiasi lingua +ritorna una lista di `wikidata entities` +[1.0.1 BUG FIX]: added `origin=*` +*/ +function getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + name = (name === undefined) ? '' : name; + const uri = `${getWdEndpointUri({config, log})}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; + log.debug(uri); + const headers = {Accept: 'application/json'}; + // Ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata + // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); + return ff(uri, headers); +} + +/* WdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName +dato un nome in qualsiasi lingua, +usa le API di wikidata.org con action=query +e dal risultato estrae solo quegli elementi che potrebbero essere piante +quindi restituisce un proprio risultato contenente in nome cercato e le piante +*/ +async function getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + if (name === undefined) { + return {name: undefined, plants: []}; + } + + if (name === null) { + return {name: null, plants: []}; + } + + const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + try { + log.debug(JSON.stringify(response)); // There is a response we can log it. + if (response.error) { + return { + name, + plants: [], + error: { + code: response.error.code, + message: response.error.info + } + }; + } + + const plants = response.query.search.filter(item => { + // Species of plant + // variety of plants + return ( + item.snippet.toLowerCase().includes('plant') || + item.snippet.toLowerCase().includes('cultivar') + ); + }); + // Log.debug('============================'); + // log.debug(name); + // log.debug(JSON.stringify(plants)); + return { + name, + plants + }; + } catch (error) { + return { + name, + plants: [], + error: { + code: '999', + message: `unexpected ${error.message}` + } + }; + } +} + +/* Es: sparqlGetScientificNameByEntityId +data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon +ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata +*/ +function getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); +} + +/* +Come sparqlGetScientificNameByEntityId ma con più attribuiti +this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL +*/ +function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, entityId) { + const sparql = + `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { + OPTIONAL { wd:${entityId} wdt:P225 ?scientificname. } + OPTIONAL { wd:${entityId} wdt:P105 ?taxonrank.} + OPTIONAL { wd:${entityId} wdt:P18 ?image. } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } + }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); +} + +/* +Data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon +ne ricava il relativo articolo wikimedia species +*/ +function getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); +} + +/* Ex: wdPromise +get a Promise that the name provided will be used to search plants in the opendata +*/ +function getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name) { + return new Promise(resolve => { + const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) + .then(value => { + // Log.debug(JSON.stringify(value)); + return value; + }); + asyncPlants.then(responseOfPlantsSearchedByAnyName => { + const entities = []; + (async () => { // #loopWDEntities + for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { + // Log.debug(i); + const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; + const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; + const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; + // Log.debug(`wdEntity: ${wdEntity}`); + const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + + log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); + + let scientificName; + try { + scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; + } catch (error) { + scientificName = '#ND'; + } + + log.info(scientificName); + + let taxonRankId; + let taxonRankLabel; + try { + taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; + taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; + } catch (error) { + taxonRankId = '#ND'; + taxonRankLabel = '#ND'; + } + + let image; + try { + image = sparqlQueryScientificName.results.bindings[0].image.value; + } catch (error) { + log.warn(`image #ND, cautch exception message:[${error.message}]`); + } + + let specieArticle; + try { + const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + specieArticle = sparqlQueryArticle.results.bindings[0].article.value; + log.info(specieArticle); + } catch (error) { + log.warn(`specieArticle #ND [${error.message}]`); + } + + entities[i] = { + wdEntityId: wdEntity, + wdPageId, + wdSnippet, + scientificName, + taxonRankId, + taxonRankLabel + }; + if (specieArticle) { + entities[i].specieArticle = specieArticle; + } + + if (image) { + entities[i].image = image; + } + } + + resolve({ + name: responseOfPlantsSearchedByAnyName.name, + plants: entities + }); + })(); + }); + }); +} diff --git a/src/log/log.js b/src/log/log.js index ea1c55b..654d52a 100644 --- a/src/log/log.js +++ b/src/log/log.js @@ -1,73 +1,78 @@ -"use strict"; -// import { logFactory } from './log.mjs'; +'use strict'; +// Import { logFactory } from './log.mjs'; const logFactory = { - makeTraceFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.trace(...args); - } - }}, - makeDebugFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.debug(...args); - } - }}, - makeInfoFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.info(...args); - } - }}, - makeWarnFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.warn(...args); - } - }}, - makeErrorFunction: (config) => { - return (...args) => { - console.error(...args); - }} - }; + makeTraceFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.trace(...args); + } + }; + }, + makeDebugFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.debug(...args); + } + }; + }, + makeInfoFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.info(...args); + } + }; + }, + makeWarnFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.warn(...args); + } + }; + }, + makeErrorFunction: () => { + return (...args) => { + console.error(...args); + }; + } +}; export class Log { - constructor(config) { - if ( config.isLogVerbose() && config.isLogSilent() ) { - throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); - } - this._trace = logFactory.makeTraceFunction(config); - this._debug = logFactory.makeDebugFunction(config); - this._info = logFactory.makeInfoFunction(config); - this._warn = logFactory.makeWarnFunction(config); - this._error = logFactory.makeErrorFunction(config); + constructor(config) { + if (config.isLogVerbose() && config.isLogSilent()) { + throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); + } - this._config = config; - } - - trace(...args) { - return this._trace(...args); - } + this._trace = logFactory.makeTraceFunction(config); + this._debug = logFactory.makeDebugFunction(config); + this._info = logFactory.makeInfoFunction(config); + this._warn = logFactory.makeWarnFunction(config); + this._error = logFactory.makeErrorFunction(config); - debug(...args) { - return this._debug(...args); - } - - info(...args) { - return this._info(...args); - } + this._config = config; + } - warn(...args) { - return this._warn(...args); - } - - error(...args) { - return this._error(...args); - } + trace(...args) { + return this._trace(...args); + } - getLogConfig(...args) { - return this._config; - } + debug(...args) { + return this._debug(...args); + } + info(...args) { + return this._info(...args); + } + + warn(...args) { + return this._warn(...args); + } + + error(...args) { + return this._error(...args); + } + + getLogConfig() { + return this._config; + } } diff --git a/src/main.js b/src/main.js index 7bec053..6ad0c63 100644 --- a/src/main.js +++ b/src/main.js @@ -1,15 +1,7 @@ -"use strict" -//TODO the boilerplate should be auto-generated avoiding human errors -import {makeGetPromiseOfWikiDataApiResults, makeGetPromiseOfSparqlResults} from './lib/OpenDataAsyncFactories.mjs'; -import { openDataPromisesFactories, openDataEndpointFactories } from './lib/OpenDataLogicAgent.mjs'; - -/* -import { config as defaultConfig } from './config/config'; -import { logconfig } from './config/logconfig'; -import { Log as DefaultLog } from './log/log'; -*/ - -import { Log } from '../esm/log' +'use strict'; +import {Log} from '../esm/log'; +import {makeGetPromiseOfWikiDataApiResults, makeGetPromiseOfSparqlResults} from './lib/open-data-async-factories'; +import {openDataPromisesFactories, openDataEndpointFactories} from './lib/open-data-logic-agent'; // https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/ /** @@ -18,93 +10,91 @@ import { Log } from '../esm/log' * @classdesc This is a description of the Phyto class. */ export class Phyto { - - /** + /** * @constructor - * @param {Function} fetch - * @param {Function} config - * @param {Function} logger + * @param {Function} fetch - a fetch function possibly polymorphic + * @param {object} config - a configuration object isomorph with @rondinif/phytojs/esm/config + * @param {object} log - a logger object isomorph with @rondinif/phytojs/esm/log + * @param {object} logconfig - a configuration object dor the logger, isomorph with @rondinif/phytojs/esm/logconfig */ - constructor(fetch, config, log, logconfig) { - this._effectiveConfig = (typeof config == 'undefined') ? {isUnderTest: () => false } : config; - this._effectiveLog = (typeof log == 'undefined') ? new Log((typeof logconfig == 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true } : logconfig) : log; + constructor(fetch, config, log, logconfig) { + this._effectiveConfig = (typeof config === 'undefined') ? {isUnderTest: () => false} : config; + this._effectiveLog = (typeof log === 'undefined') ? new Log((typeof logconfig === 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true} : logconfig) : log; + const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); + const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); - const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); - const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); - - this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); - this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById( _ffSparql, this._effectiveConfig, this._effectiveLog); + this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); + this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById(_ffSparql, this._effectiveConfig, this._effectiveLog); - this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); - this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); - } + this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); + this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); + } - // SECTION which concerns: `openDataPromisesFactories` + // SECTION which concerns: `openDataPromisesFactories` - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` or any `term` for which the wikidata search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdSearchByAnyName) */ - wdSearchByAnyName(name) { - return this._wdSearchByAnyName(name); - } + wdSearchByAnyName(name) { + return this._wdSearchByAnyName(name); + } - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` of the plant for which the odla search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdPlantsByAnyName) */ - wdPlantsByAnyName(name) { - return this._wdPlantsByAnyName(name); - } + wdPlantsByAnyName(name) { + return this._wdPlantsByAnyName(name); + } - /** - * @param {string} name - * @return {Promise} + /** + * @param {string} name - the `name` of the plant for which the odla re-solver will go to find valid entities uniquely identifiable by means of an `id` and a `scientific-name` + * @return {Promise} - a Promise of results with the list resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/resolvedPlantsByName) */ - resolvedPlantsByName(name) { - return this._resolvedPlantsByName(name); - } + resolvedPlantsByName(name) { + return this._resolvedPlantsByName(name); + } - /** - * @param {string} id - * @return {Promise} + /** + * @param {string} id - the `id` of the entitity for which the odla re-solver will go to find valid `scientific-name` + * @return {Promise} - a Promise of results with the list of `scientific-name` of the resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/sparqlScientificNameById) */ - sparqlScientificNameById(id) { - return this._sparqlScientificNameById(id); - } + sparqlScientificNameById(id) { + return this._sparqlScientificNameById(id); + } - // SECTION which concerns: `openDataEndpointFactories` + // SECTION which concerns: `openDataEndpointFactories` - /** - * @return {string} + /** + * @return {string} - the `SPARQL endpoint` which will be used by the `OpenDataLogicAgent` */ - getSparqlEndpointUri() { - return this._sparqlEndpointUri(); - } + getSparqlEndpointUri() { + return this._sparqlEndpointUri(); + } - /** - * @return {string} + /** + * @return {string} - the `Wikidata API endpoint` which will be used by the `OpenDataLogicAgent` */ - getWikiDataApiEndpointUri() { - return this._wdEndpointUri(); - } + getWikiDataApiEndpointUri() { + return this._wdEndpointUri(); + } - /** - * @return {object} + /** + * @return {object} - the effective `configuration` which will be used by the `OpenDataLogicAgent` */ - config() { - return this._effectiveConfig; - } + config() { + return this._effectiveConfig; + } - /** - * @return {object} + /** + * @return {object} - the effective `logger` which will be used by the `OpenDataLogicAgent` */ - logger() { - console.log(`####:${this._effectiveLog}`); - return this._effectiveLog; - } - + logger() { + // #DEBUG console.log(`####:${this._effectiveLog}`); + return this._effectiveLog; + } } diff --git a/umd/config.js b/umd/config.js index f71779c..32828c9 100644 --- a/umd/config.js +++ b/umd/config.js @@ -1,60 +1,66 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('dotenv-flow')) : - typeof define === 'function' && define.amd ? define(['exports', 'dotenv-flow'], factory) : - (global = global || self, factory(global.config = {}, global.dotenv)); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('dotenv-flow')) : + typeof define === 'function' && define.amd ? define(['exports', 'dotenv-flow'], factory) : + (global = global || self, factory(global.config = {}, global.dotenv)); }(this, function (exports, dotenv) { 'use strict'; - dotenv = dotenv && dotenv.hasOwnProperty('default') ? dotenv['default'] : dotenv; - - dotenv.config(); - /* - usage in programs: - import { config } from './lib/config.mjs'; - to check the effective configuration: - @see ../config.checher.mjs - - WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs - - Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. - */ - - const DEFAULT_IS_UNDER_TEST = false; - - const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } - }; - - const config = { - /* - the test features are enabed - affected by .env IS_FILESTORE_WRITING_ENABLED - */ - isUnderTest: function () { - return process.env.IS_UNDER_TEST ? - castToBoolen(process.env.IS_UNDER_TEST) : - DEFAULT_IS_UNDER_TEST; - } - }; - - exports.DEFAULT_IS_UNDER_TEST = DEFAULT_IS_UNDER_TEST; - exports.config = config; + dotenv = dotenv && dotenv.hasOwnProperty('default') ? dotenv['default'] : dotenv; + + dotenv.config(); + /* + Usage in programs: + import { config } from './lib/config.mjs'; + to check the effective configuration: + @see ../config.checher.mjs + + WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: + - .mjs + + Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. + */ + + const DEFAULT_IS_UNDER_TEST = false; + + const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } + + case 'false': { + return false; + } + + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } + }; + + const config = { + /* + The test features are enabed + affected by .env IS_FILESTORE_WRITING_ENABLED + */ + isUnderTest() { + return process.env.IS_UNDER_TEST ? + castToBoolen(process.env.IS_UNDER_TEST) : + DEFAULT_IS_UNDER_TEST; + } + }; + + exports.DEFAULT_IS_UNDER_TEST = DEFAULT_IS_UNDER_TEST; + exports.config = config; })); diff --git a/umd/log.js b/umd/log.js index a3141d7..3efad21 100644 --- a/umd/log.js +++ b/umd/log.js @@ -1,82 +1,87 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.log = {})); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.log = {})); }(this, function (exports) { 'use strict'; - // import { logFactory } from './log.mjs'; + // Import { logFactory } from './log.mjs'; - const logFactory = { - makeTraceFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.trace(...args); - } - }}, - makeDebugFunction: (config) => { - return (...args) => { - if (config.isLogVerbose()) { - console.debug(...args); - } - }}, - makeInfoFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.info(...args); - } - }}, - makeWarnFunction: (config) => { - return (...args) => { - if (!config.isLogSilent()) { - console.warn(...args); - } - }}, - makeErrorFunction: (config) => { - return (...args) => { - console.error(...args); - }} - }; + const logFactory = { + makeTraceFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.trace(...args); + } + }; + }, + makeDebugFunction: config => { + return (...args) => { + if (config.isLogVerbose()) { + console.debug(...args); + } + }; + }, + makeInfoFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.info(...args); + } + }; + }, + makeWarnFunction: config => { + return (...args) => { + if (!config.isLogSilent()) { + console.warn(...args); + } + }; + }, + makeErrorFunction: () => { + return (...args) => { + console.error(...args); + }; + } + }; - class Log { - constructor(config) { - if ( config.isLogVerbose() && config.isLogSilent() ) { - throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); - } - this._trace = logFactory.makeTraceFunction(config); - this._debug = logFactory.makeDebugFunction(config); - this._info = logFactory.makeInfoFunction(config); - this._warn = logFactory.makeWarnFunction(config); - this._error = logFactory.makeErrorFunction(config); + class Log { + constructor(config) { + if (config.isLogVerbose() && config.isLogSilent()) { + throw new Error(`log misconfiguration : isLogVerbose:${config.isLogVerbose()} && isLogSilent:${config.isLogSilent()}`); + } - this._config = config; - } - - trace(...args) { - return this._trace(...args); - } + this._trace = logFactory.makeTraceFunction(config); + this._debug = logFactory.makeDebugFunction(config); + this._info = logFactory.makeInfoFunction(config); + this._warn = logFactory.makeWarnFunction(config); + this._error = logFactory.makeErrorFunction(config); - debug(...args) { - return this._debug(...args); - } - - info(...args) { - return this._info(...args); - } + this._config = config; + } - warn(...args) { - return this._warn(...args); - } - - error(...args) { - return this._error(...args); - } + trace(...args) { + return this._trace(...args); + } - getLogConfig(...args) { - return this._config; - } + debug(...args) { + return this._debug(...args); + } - } + info(...args) { + return this._info(...args); + } - exports.Log = Log; + warn(...args) { + return this._warn(...args); + } + + error(...args) { + return this._error(...args); + } + + getLogConfig() { + return this._config; + } + } + + exports.Log = Log; })); diff --git a/umd/logconfig.js b/umd/logconfig.js index 97cad6e..c7e697e 100644 --- a/umd/logconfig.js +++ b/umd/logconfig.js @@ -1,71 +1,77 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('dotenv-flow')) : - typeof define === 'function' && define.amd ? define(['exports', 'dotenv-flow'], factory) : - (global = global || self, factory(global.logconfig = {}, global.dotenv)); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('dotenv-flow')) : + typeof define === 'function' && define.amd ? define(['exports', 'dotenv-flow'], factory) : + (global = global || self, factory(global.logconfig = {}, global.dotenv)); }(this, function (exports, dotenv) { 'use strict'; - dotenv = dotenv && dotenv.hasOwnProperty('default') ? dotenv['default'] : dotenv; + dotenv = dotenv && dotenv.hasOwnProperty('default') ? dotenv['default'] : dotenv; - dotenv.config(); - /* - usage in programs: - import { config } from './lib/config.mjs'; - to check the effective configuration: - @see ../config.checher.mjs + dotenv.config(); + /* + Usage in programs: + import { config } from './lib/config.mjs'; + to check the effective configuration: + @see ../config.checher.mjs - WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: - - .mjs + WARNING: to avoid circular reference this module **MUST** not import moduled that consumes configuration, such as: + - .mjs - Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. - */ + Coding Conventions: before each configuration a comment SHOULD be written; the comment also shows the names of the environment variables that can influence the effective configuration value. When present this comment MUST be updated also in the config.checker.mjs program. + */ - const DEFAULT_IS_LOG_VERBOSE = false; - const DEFAULT_IS_LOG_SILENT = true; + const DEFAULT_IS_LOG_VERBOSE = false; + const DEFAULT_IS_LOG_SILENT = true; - const castToBoolen = (anyValue) => { - // console.log(`castToBoolen::anyValue: ${anyValue}`); - // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); - // if (typeof anyValue === "string") { - anyValue = anyValue.trim().toLowerCase(); - // } else { console.log('branch never reached in tests'); } - switch (anyValue) { - case 'true': - return true; - case 'false': - return false; - default: - const value = parseInt(anyValue); - if (isNaN(value)) { - throw new TypeError(`{anyValue} is not acceptable value for boolean configurable options`); - } - console.log(`castToBoolen::value: ${value}`); - return value !== 0 ? true : false; - } - }; + const castToBoolen = anyValue => { + // Console.log(`castToBoolen::anyValue: ${anyValue}`); + // console.log(`castToBoolen::anyValue:typeof: ${typeof anyValue}`); + // if (typeof anyValue === "string") { + anyValue = anyValue.trim().toLowerCase(); + // } else { console.log('branch never reached in tests'); } + switch (anyValue) { + case 'true': { + return true; + } - const logconfig = { - /* - the log is verbose enabed - affected by .env IS_LOG_VERBOSE - */ - isLogVerbose: function () { - return process.env.IS_LOG_VERBOSE ? - castToBoolen(process.env.IS_LOG_VERBOSE) : - DEFAULT_IS_LOG_VERBOSE; - }, - /* - the log is verbose enabed - affected by .env IS_LOG_VERBOSE - */ - isLogSilent: function () { - return process.env.IS_LOG_SILENT ? - castToBoolen(process.env.IS_LOG_SILENT) : - DEFAULT_IS_LOG_SILENT; - } - }; + case 'false': { + return false; + } - exports.DEFAULT_IS_LOG_SILENT = DEFAULT_IS_LOG_SILENT; - exports.DEFAULT_IS_LOG_VERBOSE = DEFAULT_IS_LOG_VERBOSE; - exports.logconfig = logconfig; + default: { + const value = parseInt(anyValue, 10); + if (isNaN(value)) { + throw new TypeError('{anyValue} is not acceptable value for boolean configurable options'); + } + + console.log(`castToBoolen::value: ${value}`); + return value !== 0; + } + } + }; + + const logconfig = { + /* + The log is verbose enabed + affected by .env IS_LOG_VERBOSE + */ + isLogVerbose() { + return process.env.IS_LOG_VERBOSE ? + castToBoolen(process.env.IS_LOG_VERBOSE) : + DEFAULT_IS_LOG_VERBOSE; + }, + /* + The log is verbose enabed + affected by .env IS_LOG_VERBOSE + */ + isLogSilent() { + return process.env.IS_LOG_SILENT ? + castToBoolen(process.env.IS_LOG_SILENT) : + DEFAULT_IS_LOG_SILENT; + } + }; + + exports.DEFAULT_IS_LOG_SILENT = DEFAULT_IS_LOG_SILENT; + exports.DEFAULT_IS_LOG_VERBOSE = DEFAULT_IS_LOG_VERBOSE; + exports.logconfig = logconfig; })); diff --git a/umd/phyto.js b/umd/phyto.js index 06ee82d..6ce952e 100644 --- a/umd/phyto.js +++ b/umd/phyto.js @@ -1,359 +1,357 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../umd/log')) : - typeof define === 'function' && define.amd ? define(['exports', '../umd/log'], factory) : - (global = global || self, factory(global.phyto = {}, global.log)); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../umd/log')) : + typeof define === 'function' && define.amd ? define(['exports', '../umd/log'], factory) : + (global = global || self, factory(global.phyto = {}, global.log)); }(this, function (exports, log) { 'use strict'; - // DIP: export Higher-order function factories : each of them returns a function as its result. - - // Higher-order function: returns a function as its result. - function makeGetPromiseOfWikiDataApiResults(fetch, log) { - return (uri, headers) => { - return fetch(encodeURI(uri), { - headers: headers // , - // method: 'GET', ...mode, cache , see - }).then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; - } - - // Higher-order function: returns a function as its result. - function makeGetPromiseOfSparqlResults(fetch, log) { - return (serviceUri, sparql, headers) => { - const uri = `${serviceUri}/sparql?query=${sparql}`; - return fetch(encodeURI(uri), { headers }) - .then(body => body.json()) - .catch(err => log.error(`ERROR FETCHING DATA: ${err.message}`)); - }; - } - - const openDataPromisesFactories = { - makeWdSearchByAnyName: (ff, config, log) => name => { - return getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeWdPlantsByAnyName: (ff, config, log) => name => { - return getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - }, - makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { - return getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name); - }, - makeSparqlScientificNameById: (ffSparql, config, log) => id => { - return getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, id); - }, - }; - - const openDataEndpointFactories = { - makeWdEndpointUri: (config, log) => () => { - return getWdEndpointUri({ config, log }); - }, - makeSparqlEndpointUri: (config, log) => () => { - return getSparqlEndpointUri({ config, log }); - } - }; - - function getSparqlEndpointUri({ config, log }) { - const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; - log.debug(`sparqlEndpointUri: ${serviceUri}`); - return serviceUri; - } - - function getWdEndpointUri({ config, log }) { - const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; - const serviceUri = `${svc}/w/api.php`; - log.debug(`wdEndpointUri: ${serviceUri}`); - return serviceUri; - } - - /* wdSearchByAnyName: - dato un nome generico nome di pianta espresso in qualsiasi lingua - ritorna una lista di `wikidata entities` - [1.0.1 BUG FIX]: added `origin=*` - */ - function getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - name = (name === undefined) ? "" : name; - const uri = `${getWdEndpointUri({ config, log })}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; - log.debug(uri); - const headers = { 'Accept': 'application/json' }; - // ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata - // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); - return ff(uri, headers); - } - - /* wdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName - dato un nome in qualsiasi lingua, - usa le API di wikidata.org con action=query - e dal risultato estrae solo quegli elementi che potrebbero essere piante - quindi restituisce un proprio risultato contenente in nome cercato e le piante - */ - async function getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) { - if (name === undefined) { - return { name: undefined, plants: [] }; - } else if (name === null) { - return { name: null, plants: [] }; - } - const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ ff, config, log }, name); - try { - log.debug(JSON.stringify(response)); // there is a response we can log it. - if (response.error) { - return { - name: name, - plants: [], - error: { - code: response.error.code, - message: response.error.info - } - } - } - - let plants = response.query.search.filter((item) => { - // species of plant - // variety of plants - return ( - item.snippet.toLowerCase().includes("plant") - || - item.snippet.toLowerCase().includes("cultivar") - ); - }); - // log.debug('============================'); - // log.debug(name); - // log.debug(JSON.stringify(plants)); - return { - "name": name, - "plants": plants - }; - } catch (someError) { - return { - name: name, - plants: [], - error: { - code: "999", - message: `unexpected ${someError.message}` - } - } - } - } - - /* es: sparqlGetScientificNameByEntityId - data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon - ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata - */ - function getPromiseOfSparqlGetScientificNameByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); - } - - /* - come sparqlGetScientificNameByEntityId ma con più attribuiti - this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL - */ - function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, entityId) { - const sparql = - `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { + // DIP: export Higher-order function factories : each of them returns a function as its result. + // Higher-order function: returns a function as its result. + function makeGetPromiseOfWikiDataApiResults(fetch, log) { + return (uri, headers) => { + return fetch(encodeURI(uri), { + headers + }).then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; + } + + // Higher-order function: returns a function as its result. + function makeGetPromiseOfSparqlResults(fetch, log) { + return (serviceUri, sparql, headers) => { + const uri = `${serviceUri}/sparql?query=${sparql}`; + return fetch(encodeURI(uri), {headers}) + .then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; + } + + const openDataPromisesFactories = { + makeWdSearchByAnyName: (ff, config, log) => name => { + return getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeWdPlantsByAnyName: (ff, config, log) => name => { + return getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { + return getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name); + }, + makeSparqlScientificNameById: (ffSparql, config, log) => id => { + return getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, id); + } + }; + + const openDataEndpointFactories = { + makeWdEndpointUri: (config, log) => () => { + return getWdEndpointUri({config, log}); + }, + makeSparqlEndpointUri: (config, log) => () => { + return getSparqlEndpointUri({config, log}); + } + }; + + function getSparqlEndpointUri({config, log}) { + const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; + log.debug(`sparqlEndpointUri: ${serviceUri}`); + return serviceUri; + } + + function getWdEndpointUri({config, log}) { + const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; + const serviceUri = `${svc}/w/api.php`; + log.debug(`wdEndpointUri: ${serviceUri}`); + return serviceUri; + } + + /* WdSearchByAnyName: + dato un nome generico nome di pianta espresso in qualsiasi lingua + ritorna una lista di `wikidata entities` + [1.0.1 BUG FIX]: added `origin=*` + */ + function getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + name = (name === undefined) ? '' : name; + const uri = `${getWdEndpointUri({config, log})}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; + log.debug(uri); + const headers = {Accept: 'application/json'}; + // Ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata + // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); + return ff(uri, headers); + } + + /* WdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName + dato un nome in qualsiasi lingua, + usa le API di wikidata.org con action=query + e dal risultato estrae solo quegli elementi che potrebbero essere piante + quindi restituisce un proprio risultato contenente in nome cercato e le piante + */ + async function getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + if (name === undefined) { + return {name: undefined, plants: []}; + } + + if (name === null) { + return {name: null, plants: []}; + } + + const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + try { + log.debug(JSON.stringify(response)); // There is a response we can log it. + if (response.error) { + return { + name, + plants: [], + error: { + code: response.error.code, + message: response.error.info + } + }; + } + + const plants = response.query.search.filter(item => { + // Species of plant + // variety of plants + return ( + item.snippet.toLowerCase().includes('plant') || + item.snippet.toLowerCase().includes('cultivar') + ); + }); + // Log.debug('============================'); + // log.debug(name); + // log.debug(JSON.stringify(plants)); + return { + name, + plants + }; + } catch (error) { + return { + name, + plants: [], + error: { + code: '999', + message: `unexpected ${error.message}` + } + }; + } + } + + /* Es: sparqlGetScientificNameByEntityId + data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon + ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata + */ + function getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* + Come sparqlGetScientificNameByEntityId ma con più attribuiti + this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL + */ + function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, entityId) { + const sparql = + `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { OPTIONAL { wd:${entityId} wdt:P225 ?scientificname. } OPTIONAL { wd:${entityId} wdt:P105 ?taxonrank.} OPTIONAL { wd:${entityId} wdt:P18 ?image. } SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); - } - - /* - data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon - ne ricava il relativo articolo wikimedia species - */ - function getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, entityId) { - const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; - const headers = { 'Accept': 'application/sparql-results+json' }; - // return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); - return ffSparql(getSparqlEndpointUri({ config, log }), sparql, headers); - } - - /* ex: wdPromise - get a Promise that the name provided will be used to search plants in the opendata - */ - function getPromiseOfPlantResolvedByOpendataByName({ ff, ffSparql, config, log }, name) { - return new Promise(resolveQuery => { - const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ ff, config, log }, name) - .then((value) => { - // log.debug(JSON.stringify(value)); - return value; - }); - asyncPlants.then((responseOfPlantsSearchedByAnyName) => { - let entities = []; - (async function loopWDEntities() { - for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { - // log.debug(i); - const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; - const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; - const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; - // log.debug(`wdEntity: ${wdEntity}`); - const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ ffSparql, config, log }, wdEntity); - // DEFENSIVE PROGRAMMING BUT UNUSEFUL [ try { - log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); - // } catch(errorLogging) { - // log.error(`sparqlQueryScientificName got no results:${errorLogging.message}`); - // } // DEFENSIVE PROGRAMMING BUT UNUSEFUL ] - - let scientificName; - try { - scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; - } catch (e) { - scientificName = "#ND"; - } - log.info(scientificName); - - let taxonRankId; - let taxonRankLabel; - try { - taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; - taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; - } catch (e) { - taxonRankId = "#ND"; - taxonRankLabel = "#ND"; - } - - let image; - try { - image = sparqlQueryScientificName.results.bindings[0].image.value; - } catch (e) { - log.warn(`image #ND, cautch exception message:[${e.message}]`); - } - - let specieArticle; - try { - const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ ffSparql, config, log }, wdEntity); - specieArticle = sparqlQueryArticle.results.bindings[0].article.value; - log.info(specieArticle); - } catch (e) { - log.warn(`specieArticle #ND [${e.message}]`); - } - - entities[i] = { - wdEntityId: wdEntity, - wdPageId: wdPageId, - wdSnippet: wdSnippet, - scientificName: scientificName, - taxonRankId: taxonRankId, - taxonRankLabel: taxonRankLabel, - }; - if (specieArticle) { - entities[i]["specieArticle"] = specieArticle; - } - if (image) { - entities[i]["image"] = image; - } - } - resolveQuery({ - name: responseOfPlantsSearchedByAnyName.name, - plants: entities - }); - })(); // .catch(e => log.debug("loopWDEntities Caught Error: " + e)); // UNCOVERED ( intentionally left for DEFENSIVE PROGRAMMING ) - }); // closing res.then - }); - } - - // https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/ - /** - * This is a description of the Phyto constructor function. - * @class - * @classdesc This is a description of the Phyto class. - */ - class Phyto { - - /** - * @constructor - * @param {Function} fetch - * @param {Function} config - * @param {Function} logger - */ - constructor(fetch, config, log$1, logconfig) { - this._effectiveConfig = (typeof config == 'undefined') ? {isUnderTest: () => false } : config; - this._effectiveLog = (typeof log$1 == 'undefined') ? new log.Log((typeof logconfig == 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true } : logconfig) : log$1; - - - const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); - const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); - - this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); - this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); - this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById( _ffSparql, this._effectiveConfig, this._effectiveLog); - - this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); - this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); - } - - // SECTION which concerns: `openDataPromisesFactories` - - /** - * @param {string} name - * @return {Promise} - */ - wdSearchByAnyName(name) { - return this._wdSearchByAnyName(name); - } - - /** - * @param {string} name - * @return {Promise} - */ - wdPlantsByAnyName(name) { - return this._wdPlantsByAnyName(name); - } - - /** - * @param {string} name - * @return {Promise} - */ - resolvedPlantsByName(name) { - return this._resolvedPlantsByName(name); - } - - /** - * @param {string} id - * @return {Promise} - */ - sparqlScientificNameById(id) { - return this._sparqlScientificNameById(id); - } - - // SECTION which concerns: `openDataEndpointFactories` - - /** - * @return {string} - */ - getSparqlEndpointUri() { - return this._sparqlEndpointUri(); - } - - /** - * @return {string} - */ - getWikiDataApiEndpointUri() { - return this._wdEndpointUri(); - } - - /** - * @return {object} - */ - config() { - return this._effectiveConfig; - } - - /** - * @return {object} - */ - logger() { - console.log(`####:${this._effectiveLog}`); - return this._effectiveLog; - } - - } - - exports.Phyto = Phyto; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* + Data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon + ne ricava il relativo articolo wikimedia species + */ + function getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* Ex: wdPromise + get a Promise that the name provided will be used to search plants in the opendata + */ + function getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name) { + return new Promise(resolve => { + const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) + .then(value => { + // Log.debug(JSON.stringify(value)); + return value; + }); + asyncPlants.then(responseOfPlantsSearchedByAnyName => { + const entities = []; + (async () => { // #loopWDEntities + for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { + // Log.debug(i); + const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; + const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; + const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; + // Log.debug(`wdEntity: ${wdEntity}`); + const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + + log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); + + let scientificName; + try { + scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; + } catch (error) { + scientificName = '#ND'; + } + + log.info(scientificName); + + let taxonRankId; + let taxonRankLabel; + try { + taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; + taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; + } catch (error) { + taxonRankId = '#ND'; + taxonRankLabel = '#ND'; + } + + let image; + try { + image = sparqlQueryScientificName.results.bindings[0].image.value; + } catch (error) { + log.warn(`image #ND, cautch exception message:[${error.message}]`); + } + + let specieArticle; + try { + const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + specieArticle = sparqlQueryArticle.results.bindings[0].article.value; + log.info(specieArticle); + } catch (error) { + log.warn(`specieArticle #ND [${error.message}]`); + } + + entities[i] = { + wdEntityId: wdEntity, + wdPageId, + wdSnippet, + scientificName, + taxonRankId, + taxonRankLabel + }; + if (specieArticle) { + entities[i].specieArticle = specieArticle; + } + + if (image) { + entities[i].image = image; + } + } + + resolve({ + name: responseOfPlantsSearchedByAnyName.name, + plants: entities + }); + })(); + }); + }); + } + + // https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/ + /** + * This is a description of the Phyto constructor function. + * @class + * @classdesc This is a description of the Phyto class. + */ + class Phyto { + /** + * @constructor + * @param {Function} fetch - a fetch function possibly polymorphic + * @param {object} config - a configuration object isomorph with @rondinif/phytojs/esm/config + * @param {object} log - a logger object isomorph with @rondinif/phytojs/esm/log + * @param {object} logconfig - a configuration object dor the logger, isomorph with @rondinif/phytojs/esm/logconfig + */ + constructor(fetch, config, log$1, logconfig) { + this._effectiveConfig = (typeof config === 'undefined') ? {isUnderTest: () => false} : config; + this._effectiveLog = (typeof log$1 === 'undefined') ? new log.Log((typeof logconfig === 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true} : logconfig) : log$1; + + const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); + const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); + + this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); + this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById(_ffSparql, this._effectiveConfig, this._effectiveLog); + + this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); + this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); + } + + // SECTION which concerns: `openDataPromisesFactories` + + /** + * @param {string} name - the `name` or any `term` for which the wikidata search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdSearchByAnyName) + */ + wdSearchByAnyName(name) { + return this._wdSearchByAnyName(name); + } + + /** + * @param {string} name - the `name` of the plant for which the odla search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdPlantsByAnyName) + */ + wdPlantsByAnyName(name) { + return this._wdPlantsByAnyName(name); + } + + /** + * @param {string} name - the `name` of the plant for which the odla re-solver will go to find valid entities uniquely identifiable by means of an `id` and a `scientific-name` + * @return {Promise} - a Promise of results with the list resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/resolvedPlantsByName) + */ + resolvedPlantsByName(name) { + return this._resolvedPlantsByName(name); + } + + /** + * @param {string} id - the `id` of the entitity for which the odla re-solver will go to find valid `scientific-name` + * @return {Promise} - a Promise of results with the list of `scientific-name` of the resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/sparqlScientificNameById) + */ + sparqlScientificNameById(id) { + return this._sparqlScientificNameById(id); + } + + // SECTION which concerns: `openDataEndpointFactories` + + /** + * @return {string} - the `SPARQL endpoint` which will be used by the `OpenDataLogicAgent` + */ + getSparqlEndpointUri() { + return this._sparqlEndpointUri(); + } + + /** + * @return {string} - the `Wikidata API endpoint` which will be used by the `OpenDataLogicAgent` + */ + getWikiDataApiEndpointUri() { + return this._wdEndpointUri(); + } + + /** + * @return {object} - the effective `configuration` which will be used by the `OpenDataLogicAgent` + */ + config() { + return this._effectiveConfig; + } + + /** + * @return {object} - the effective `logger` which will be used by the `OpenDataLogicAgent` + */ + logger() { + // #DEBUG console.log(`####:${this._effectiveLog}`); + return this._effectiveLog; + } + } + + exports.Phyto = Phyto; })); diff --git a/umd/phyto.js.backup b/umd/phyto.js.backup new file mode 100644 index 0000000..d211483 --- /dev/null +++ b/umd/phyto.js.backup @@ -0,0 +1,357 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../esm/log')) : + typeof define === 'function' && define.amd ? define(['exports', '../esm/log'], factory) : + (global = global || self, factory(global.phyto = {}, global.log)); +}(this, function (exports, log) { 'use strict'; + + // DIP: export Higher-order function factories : each of them returns a function as its result. + // Higher-order function: returns a function as its result. + function makeGetPromiseOfWikiDataApiResults(fetch, log) { + return (uri, headers) => { + return fetch(encodeURI(uri), { + headers + }).then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; + } + + // Higher-order function: returns a function as its result. + function makeGetPromiseOfSparqlResults(fetch, log) { + return (serviceUri, sparql, headers) => { + const uri = `${serviceUri}/sparql?query=${sparql}`; + return fetch(encodeURI(uri), {headers}) + .then(body => body.json()) + .catch(error => log.error(`ERROR FETCHING DATA: ${error.message}`)); + }; + } + + const openDataPromisesFactories = { + makeWdSearchByAnyName: (ff, config, log) => name => { + return getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeWdPlantsByAnyName: (ff, config, log) => name => { + return getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name); + }, + makeResolvedPlantsByName: (ff, ffSparql, config, log) => name => { + return getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name); + }, + makeSparqlScientificNameById: (ffSparql, config, log) => id => { + return getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, id); + } + }; + + const openDataEndpointFactories = { + makeWdEndpointUri: (config, log) => () => { + return getWdEndpointUri({config, log}); + }, + makeSparqlEndpointUri: (config, log) => () => { + return getSparqlEndpointUri({config, log}); + } + }; + + function getSparqlEndpointUri({config, log}) { + const serviceUri = config.isUnderTest() ? 'http://127.0.0.1:6569' : 'https://query.wikidata.org'; + log.debug(`sparqlEndpointUri: ${serviceUri}`); + return serviceUri; + } + + function getWdEndpointUri({config, log}) { + const svc = config.isUnderTest() ? 'http://127.0.0.1:6568' : 'https://www.wikidata.org'; + const serviceUri = `${svc}/w/api.php`; + log.debug(`wdEndpointUri: ${serviceUri}`); + return serviceUri; + } + + /* WdSearchByAnyName: + dato un nome generico nome di pianta espresso in qualsiasi lingua + ritorna una lista di `wikidata entities` + [1.0.1 BUG FIX]: added `origin=*` + */ + function getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + name = (name === undefined) ? '' : name; + const uri = `${getWdEndpointUri({config, log})}?action=query&format=json&origin=*&list=search&srsearch=${name}&srlimit=500`; + log.debug(uri); + const headers = {Accept: 'application/json'}; + // Ritorna la promise ottenta dal modulo di gestione delle richieste http asincrone verso opendata + // return OpenDataAsyncRequest.getPromiseOfWikiDataApiResults( uri, headers ); + return ff(uri, headers); + } + + /* WdPlantsByAnyName: // ex: getAsynchronoslyPlantsFromWikiDataApiActionQuerySearchByName + dato un nome in qualsiasi lingua, + usa le API di wikidata.org con action=query + e dal risultato estrae solo quegli elementi che potrebbero essere piante + quindi restituisce un proprio risultato contenente in nome cercato e le piante + */ + async function getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) { + if (name === undefined) { + return {name: undefined, plants: []}; + } + + if (name === null) { + return {name: null, plants: []}; + } + + const response = await getPromiseOfWikiDataApiActionQuerySearchByName({ff, config, log}, name); + try { + log.debug(JSON.stringify(response)); // There is a response we can log it. + if (response.error) { + return { + name, + plants: [], + error: { + code: response.error.code, + message: response.error.info + } + }; + } + + const plants = response.query.search.filter(item => { + // Species of plant + // variety of plants + return ( + item.snippet.toLowerCase().includes('plant') || + item.snippet.toLowerCase().includes('cultivar') + ); + }); + // Log.debug('============================'); + // log.debug(name); + // log.debug(JSON.stringify(plants)); + return { + name, + plants + }; + } catch (error) { + return { + name, + plants: [], + error: { + code: '999', + message: `unexpected ${error.message}` + } + }; + } + } + + /* Es: sparqlGetScientificNameByEntityId + data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon + ne ricava il nome scentifico eseguendo una query spqrql ad un endpoint di wikidata + */ + function getPromiseOfSparqlGetScientificNameByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?scientificname WHERE {wd:${entityId} wdt:P225 ?scientificname.}`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* + Come sparqlGetScientificNameByEntityId ma con più attribuiti + this function use the left-join semantics, which translates to the OPTIONAL keyword in SPARQL + */ + function getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, entityId) { + const sparql = + `SELECT ?scientificname ?taxonrank ?taxonrankLabel ?image WHERE { + OPTIONAL { wd:${entityId} wdt:P225 ?scientificname. } + OPTIONAL { wd:${entityId} wdt:P105 ?taxonrank.} + OPTIONAL { wd:${entityId} wdt:P18 ?image. } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } + }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* + Data una wikidata entity ( es: Q23501) che dovrebbe essere di un taxon + ne ricava il relativo articolo wikimedia species + */ + function getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, entityId) { + const sparql = `SELECT ?article WHERE { ?article schema:about wd:${entityId}; schema:isPartOf . }`; + const headers = {Accept: 'application/sparql-results+json'}; + // Return OpenDataAsyncRequest.getPromiseOfSparqlResults(serviceUri, sparql, headers); + return ffSparql(getSparqlEndpointUri({config, log}), sparql, headers); + } + + /* Ex: wdPromise + get a Promise that the name provided will be used to search plants in the opendata + */ + function getPromiseOfPlantResolvedByOpendataByName({ff, ffSparql, config, log}, name) { + return new Promise(resolve => { + const asyncPlants = getPlantsFromWikiDataApiActionQuerySearchByName({ff, config, log}, name) + .then(value => { + // Log.debug(JSON.stringify(value)); + return value; + }); + asyncPlants.then(responseOfPlantsSearchedByAnyName => { + const entities = []; + (async () => { // #loopWDEntities + for (let i = 0; i < responseOfPlantsSearchedByAnyName.plants.length; i++) { + // Log.debug(i); + const wdEntity = responseOfPlantsSearchedByAnyName.plants[i].title; + const wdPageId = responseOfPlantsSearchedByAnyName.plants[i].pageid; + const wdSnippet = responseOfPlantsSearchedByAnyName.plants[i].snippet; + // Log.debug(`wdEntity: ${wdEntity}`); + const sparqlQueryScientificName = await getPromiseOfSparqlGetScientificNameAndBasicAttributesByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + + log.debug('%s', JSON.stringify(sparqlQueryScientificName.results)); + + let scientificName; + try { + scientificName = sparqlQueryScientificName.results.bindings[0].scientificname.value; + } catch (error) { + scientificName = '#ND'; + } + + log.info(scientificName); + + let taxonRankId; + let taxonRankLabel; + try { + taxonRankId = sparqlQueryScientificName.results.bindings[0].taxonrank.value; + taxonRankLabel = sparqlQueryScientificName.results.bindings[0].taxonrankLabel.value; + } catch (error) { + taxonRankId = '#ND'; + taxonRankLabel = '#ND'; + } + + let image; + try { + image = sparqlQueryScientificName.results.bindings[0].image.value; + } catch (error) { + log.warn(`image #ND, cautch exception message:[${error.message}]`); + } + + let specieArticle; + try { + const sparqlQueryArticle = await getPromiseOfSparqlGetSpecieArticleByEntityId({ffSparql, config, log}, wdEntity); // eslint-disable-line no-await-in-loop + specieArticle = sparqlQueryArticle.results.bindings[0].article.value; + log.info(specieArticle); + } catch (error) { + log.warn(`specieArticle #ND [${error.message}]`); + } + + entities[i] = { + wdEntityId: wdEntity, + wdPageId, + wdSnippet, + scientificName, + taxonRankId, + taxonRankLabel + }; + if (specieArticle) { + entities[i].specieArticle = specieArticle; + } + + if (image) { + entities[i].image = image; + } + } + + resolve({ + name: responseOfPlantsSearchedByAnyName.name, + plants: entities + }); + })(); + }); + }); + } + + // https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/ + /** + * This is a description of the Phyto constructor function. + * @class + * @classdesc This is a description of the Phyto class. + */ + class Phyto { + /** + * @constructor + * @param {Function} fetch - a fetch function possibly polymorphic + * @param {object} config - a configuration object isomorph with @rondinif/phytojs/esm/config + * @param {object} log - a logger object isomorph with @rondinif/phytojs/esm/log + * @param {object} logconfig - a configuration object dor the logger, isomorph with @rondinif/phytojs/esm/logconfig + */ + constructor(fetch, config, log$1, logconfig) { + this._effectiveConfig = (typeof config === 'undefined') ? {isUnderTest: () => false} : config; + this._effectiveLog = (typeof log$1 === 'undefined') ? new log.Log((typeof logconfig === 'undefined') ? {isLogVerbose: () => false, isLogSilent: () => true} : logconfig) : log$1; + + const _ff = makeGetPromiseOfWikiDataApiResults(fetch, this._effectiveLog); + const _ffSparql = makeGetPromiseOfSparqlResults(fetch, this._effectiveLog); + + this._wdSearchByAnyName = openDataPromisesFactories.makeWdSearchByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._wdPlantsByAnyName = openDataPromisesFactories.makeWdPlantsByAnyName(_ff, this._effectiveConfig, this._effectiveLog); + this._resolvedPlantsByName = openDataPromisesFactories.makeResolvedPlantsByName(_ff, _ffSparql, this._effectiveConfig, this._effectiveLog); + this._sparqlScientificNameById = openDataPromisesFactories.makeSparqlScientificNameById(_ffSparql, this._effectiveConfig, this._effectiveLog); + + this._wdEndpointUri = openDataEndpointFactories.makeWdEndpointUri(this._effectiveConfig, this._effectiveLog); + this._sparqlEndpointUri = openDataEndpointFactories.makeSparqlEndpointUri(this._effectiveConfig, this._effectiveLog); + } + + // SECTION which concerns: `openDataPromisesFactories` + + /** + * @param {string} name - the `name` or any `term` for which the wikidata search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdSearchByAnyName) + */ + wdSearchByAnyName(name) { + return this._wdSearchByAnyName(name); + } + + /** + * @param {string} name - the `name` of the plant for which the odla search will be carried out + * @return {Promise} - a Promise of the search results; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/wdPlantsByAnyName) + */ + wdPlantsByAnyName(name) { + return this._wdPlantsByAnyName(name); + } + + /** + * @param {string} name - the `name` of the plant for which the odla re-solver will go to find valid entities uniquely identifiable by means of an `id` and a `scientific-name` + * @return {Promise} - a Promise of results with the list resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/resolvedPlantsByName) + */ + resolvedPlantsByName(name) { + return this._resolvedPlantsByName(name); + } + + /** + * @param {string} id - the `id` of the entitity for which the odla re-solver will go to find valid `scientific-name` + * @return {Promise} - a Promise of results with the list of `scientific-name` of the resolved plants; @see [tests](https://github.com/rondinif/phytojs/blob/master/test/lib/) and [expectations](https://github.com/rondinif/phytojs/tree/master/test/fixture/lib/OpenDataLogicAgent/sparqlScientificNameById) + */ + sparqlScientificNameById(id) { + return this._sparqlScientificNameById(id); + } + + // SECTION which concerns: `openDataEndpointFactories` + + /** + * @return {string} - the `SPARQL endpoint` which will be used by the `OpenDataLogicAgent` + */ + getSparqlEndpointUri() { + return this._sparqlEndpointUri(); + } + + /** + * @return {string} - the `Wikidata API endpoint` which will be used by the `OpenDataLogicAgent` + */ + getWikiDataApiEndpointUri() { + return this._wdEndpointUri(); + } + + /** + * @return {object} - the effective `configuration` which will be used by the `OpenDataLogicAgent` + */ + config() { + return this._effectiveConfig; + } + + /** + * @return {object} - the effective `logger` which will be used by the `OpenDataLogicAgent` + */ + logger() { + // #DEBUG console.log(`####:${this._effectiveLog}`); + return this._effectiveLog; + } + } + + exports.Phyto = Phyto; + +}));