workshopper-adventure
Advanced tools
Comparing version 3.4.2 to 3.4.3
314
adventure.js
@@ -7,2 +7,3 @@ const minimist = require('minimist') | ||
, chalk = require('chalk') | ||
, commandico = require('commandico') | ||
, inherits = require('util').inherits | ||
@@ -12,6 +13,8 @@ , EventEmitter = require('events').EventEmitter | ||
/* jshint -W079 */ | ||
const createMenu = require('simple-terminal-menu') | ||
, print = require('./print-text') | ||
, util = require('./util') | ||
, i18n = require('./i18n') | ||
const createMenu = require('simple-terminal-menu') | ||
, print = require('./lib/print') | ||
, util = require('./util') | ||
, i18n = require('./i18n') | ||
, storage = require('./lib/storage') | ||
, error = print.error | ||
/* jshint +W079 */ | ||
@@ -21,2 +24,10 @@ | ||
function legacyCommands(item) { | ||
if (!item.aliases) | ||
item.aliases = [] | ||
if (item && item.name) | ||
item.aliases.unshift(item.name) | ||
return item | ||
} | ||
function Adventure (options) { | ||
@@ -32,6 +43,6 @@ if (!(this instanceof Adventure)) | ||
if (typeof options !== 'object') | ||
throw new TypeError('need to provide an options object') | ||
return error('You need to provide an options object') | ||
if (typeof options.name !== 'string') | ||
throw new TypeError('need to provide a `name` String option') | ||
return error('You need to provide a `name` String option') | ||
@@ -46,4 +57,7 @@ this.name = options.name | ||
this.globalDataDir = util.userDir('.config', 'workshopper') | ||
this.dataDir = util.userDir('.config', this.appName) | ||
this.global = storage(storage.userDir, '.config', 'workshopper') | ||
this.local = storage(storage.userDir, '.config', this.appName) | ||
this.globalDataDir = this.global.dir | ||
this.dataDir = this.local.dir | ||
@@ -94,39 +108,5 @@ // Backwards compatibility with adventure | ||
this.commands = Array.isArray(options.commands) ? options.commands : [] | ||
this.options = options | ||
} | ||
inherits(Adventure, EventEmitter) | ||
Adventure.prototype.execute = function (args) { | ||
var mode = args[0] | ||
, handled = false | ||
, argv = minimist(args, { | ||
alias: { | ||
h: 'help', | ||
l: 'lang', | ||
v: 'version', | ||
select: 'print', | ||
selected: 'current' | ||
} | ||
}) | ||
try { | ||
this.lang = i18n.chooseLang( | ||
this.globalDataDir | ||
, this.dataDir | ||
, argv.lang | ||
, this.defaultLang | ||
, this.options.languages | ||
) | ||
} catch (e) { | ||
if (e instanceof TypeError) // In case the language couldn't be selected | ||
console.log(e.message) | ||
else | ||
console.error(e.stack) | ||
process.exit(1) | ||
} | ||
this.i18n = i18n.init(this.options, this.exercises, this.lang, this.globalDataDir) | ||
this.i18n = i18n.init(this.options, this.exercises, this.global, this.local, this.defaultLang) | ||
this.__ = this.i18n.__ | ||
@@ -139,2 +119,3 @@ this.__n = this.i18n.__n | ||
this.__defineGetter__('subtitle', this.__.bind(this, 'subtitle')) | ||
this.__defineGetter__('lang', this.i18n.lang.bind(this.i18n, 'lang')) | ||
this.__defineGetter__('width', function () { | ||
@@ -144,89 +125,16 @@ return this.menuOptions.width | ||
this.current = this.getData('current') | ||
this.current = this.local.get('current') | ||
if (this.commands) | ||
this.commands.forEach(function (item) { | ||
if (mode == item.name | ||
|| argv[item.name] | ||
|| (item.short && argv[item.short])) { | ||
handled = true | ||
return item.handler(this) | ||
} | ||
}.bind(this)) | ||
this.app = commandico(this, 'menu') | ||
.loadCommands(path.join(__dirname, 'lib/commands')) | ||
.loadModifiers(path.join(__dirname, 'lib/modifiers')) | ||
.addCommands((options.commands || []).map(legacyCommands)) | ||
.addModifiers((options.modifiers || []).map(legacyCommands)) | ||
} | ||
inherits(Adventure, EventEmitter) | ||
if (argv.version || mode == 'version') | ||
return console.log( | ||
this.appName | ||
+ '@' | ||
+ require(path.join(this.appDir, 'package.json')).version | ||
) | ||
if (handled) | ||
return | ||
if (argv.help || mode == 'help') | ||
return this._printHelp() | ||
if (mode == 'list') { | ||
return this.exercises.forEach(function (name) { | ||
console.log(this.__('exercise.' + name)) | ||
}.bind(this)) | ||
} | ||
if (mode == 'current') | ||
return console.log(this.__('exercise.' + this.current)) | ||
if (mode == 'print') { | ||
var selected = argv._.length > 1 ? argv._.slice(1).join(' ') : this.current | ||
if (/[0-9]+/.test(selected)) { | ||
selected = this.exercises[parseInt(selected-1, 10)] || selected | ||
} else { | ||
selected = this.exercises.filter(function (exercise) { | ||
return selected === this.__('exercise.' + exercise) | ||
}.bind(this))[0] || selected; | ||
} | ||
onselect.call(this, selected) | ||
return | ||
} | ||
if (mode == 'verify' || mode == 'run') { | ||
if (!this.current) | ||
return error(this.__('error.exercise.none_active')) | ||
exercise = this.loadExercise(this.current) | ||
if (!exercise) | ||
return error(this.__('error.exercise.missing', {name: name})) | ||
if (exercise.requireSubmission !== false && argv._.length == 1) | ||
return error(this.__('ui.usage', {appName: this.appName, mode: mode})) | ||
return this.runExercise(exercise, mode, argv._.slice(1)) | ||
} | ||
if (mode == 'next') { | ||
var remainingAfterCurrent = this.exercises.slice(this.exercises.indexOf(this.current)) | ||
var completed = this.getData('completed') | ||
if (!completed) | ||
return error(this.__('error.exercise.none_active') + '\n') | ||
var incompleteAfterCurrent = remainingAfterCurrent.filter(function (elem) { | ||
return completed.indexOf(elem) < 0 | ||
}) | ||
if (incompleteAfterCurrent.length === 0) | ||
return console.log(this.__('error.no_uncomplete_left') + '\n') | ||
return onselect.call(this, incompleteAfterCurrent[0]) | ||
} | ||
if (mode == 'reset') { | ||
this.reset() | ||
return console.log(this.__('progress.reset', {title: this.__('title')})) | ||
} | ||
this.printMenu() | ||
Adventure.prototype.execute = function (args) { | ||
return this.app.execute(args) | ||
} | ||
@@ -243,3 +151,3 @@ | ||
? fn_or_object | ||
: { name: name_or_object } | ||
: {} | ||
@@ -256,3 +164,3 @@ if (typeof name_or_object === 'string') | ||
if (!meta.dir) | ||
meta.dir = this.dirFromName(meta.name) | ||
meta.dir = util.dirFromName(this.exerciseDir, meta.name) | ||
@@ -305,3 +213,2 @@ if (meta.dir && !meta.exerciseFile) | ||
// overall exercise fail | ||
@@ -323,14 +230,10 @@ Adventure.prototype.exerciseFail = function (mode, exercise) { | ||
var done = function done () { | ||
var completed = this.getData('completed') || [] | ||
var completed = this.local.get('completed') || [] | ||
, remaining | ||
this.updateData('completed', function (xs) { | ||
if (!xs) | ||
xs = [] | ||
if (completed.indexOf(exercise.meta.name) === -1) | ||
completed.push(exercise.meta.name) | ||
return xs.indexOf(exercise.meta.name) >= 0 ? xs : xs.concat(exercise.meta.name) | ||
}) | ||
this.local.save('completed', completed) | ||
completed = this.getData('completed') || [] | ||
remaining = this.exercises.length - completed.length | ||
@@ -344,4 +247,4 @@ | ||
} | ||
if (exercise.solution) | ||
if (typeof exercise.getSolutionFiles !== 'function' && exercise.solution) | ||
print.text(this.appName, this.appDir, exercise.solutionType || 'txt', exercise.solution) | ||
@@ -363,2 +266,3 @@ | ||
if (!exercise.hideSolutions && typeof exercise.getSolutionFiles === 'function') { | ||
@@ -412,3 +316,2 @@ exercise.getSolutionFiles(function (err, files) { | ||
// single 'pass' event for a validation | ||
@@ -425,3 +328,2 @@ function onpass (msg) { | ||
Adventure.prototype.runExercise = function (exercise, mode, args) { | ||
@@ -476,40 +378,6 @@ // individual validation events | ||
Adventure.prototype.selectLanguage = function (lang) { | ||
this.i18n.change(this.globalDataDir, this.dataDir, lang, this.defaultLang, this.i18n.languages) | ||
this.lang = lang | ||
this.printMenu() | ||
} | ||
Adventure.prototype.printLanguageMenu = function () { | ||
var __ = this.i18n.__ | ||
, menu = createMenu(this.menuOptions) | ||
, completed = this.getData('completed') || [] | ||
menu.writeLine(chalk.bold(__('title'))) | ||
if (this.i18n.has('subtitle')) | ||
menu.writeLine(chalk.italic(__('subtitle'))) | ||
menu.writeSeparator() | ||
this.i18n.languages.forEach(function (language) { | ||
var label = chalk.bold('»') + ' ' + __('language.' + language) | ||
, marker = (this.lang === language) ? '[' + __('language._current') + ']' : '' | ||
menu.add(label, marker, this.selectLanguage.bind(this, language)) | ||
}.bind(this)) | ||
menu.writeSeparator() | ||
menu.add(chalk.bold(__('menu.cancel')), this.printMenu.bind(this)) | ||
menu.add(chalk.bold(__('menu.exit')), this._exit.bind(this)) | ||
} | ||
Adventure.prototype._exit = function () { | ||
process.exit(0) | ||
} | ||
Adventure.prototype.printMenu = function () { | ||
var __ = this.i18n.__ | ||
, menu = createMenu(this.menuOptions) | ||
, completed = this.getData('completed') || [] | ||
, completed = this.local.get('completed') || [] | ||
@@ -526,3 +394,3 @@ menu.writeLine(chalk.bold(__('title'))) | ||
, marker = (completed.indexOf(exercise) >= 0) ? '[' + __('menu.completed') + ']' : '' | ||
menu.add(label, marker, onselect.bind(this, exercise)) | ||
menu.add(label, marker, this.printExercise.bind(this, exercise)) | ||
}.bind(this)) | ||
@@ -532,76 +400,13 @@ | ||
menu.add(chalk.bold(__('menu.help')), this._printHelp.bind(this)) | ||
if (this.i18n.languages && this.i18n.languages.length > 1) | ||
menu.add(chalk.bold(__('menu.language')), this.printLanguageMenu.bind(this)) | ||
this.commands.filter(function (extra) { | ||
this.app.commands.reverse().filter(function (extra) { | ||
return extra.menu !== false | ||
}).forEach(function (extra) { | ||
}.bind(this)).forEach(function (extra) { | ||
menu.add(chalk.bold(__('menu.' + extra.name)), extra.handler.bind(extra, this)) | ||
}.bind(this)) | ||
menu.add(chalk.bold(__('menu.exit')), this._exit.bind(this)) | ||
menu.add(chalk.bold(__('menu.exit')), process.exit.bind(process, 0)) | ||
} | ||
Adventure.prototype.getData = function (name) { | ||
var file = path.resolve(this.dataDir, name + '.json') | ||
try { | ||
return JSON.parse(fs.readFileSync(file, 'utf8')) | ||
} catch (e) {} | ||
return null | ||
} | ||
Adventure.prototype.updateData = function (id, fn) { | ||
var json = {} | ||
, file | ||
try { | ||
json = this.getData(id) | ||
} catch (e) {} | ||
file = path.resolve(this.dataDir, id + '.json') | ||
fs.writeFileSync(file, JSON.stringify(fn(json))) | ||
} | ||
Adventure.prototype.reset = function () { | ||
fs.unlink(path.resolve(this.dataDir, 'completed.json'), function () {}) | ||
fs.unlink(path.resolve(this.dataDir, 'current.json'), function () {}) | ||
} | ||
Adventure.prototype.dirFromName = function (name) { | ||
return util.dirFromName(this.exerciseDir, name) | ||
} | ||
Adventure.prototype._printHelp = function () { | ||
var part | ||
, stream = require("combined-stream").create() | ||
if (this.helpFile) | ||
part = print.localisedFileStream(this.appName, this.appDir, this.helpFile, this.lang) | ||
if (part) | ||
stream.append(part) | ||
part = print.localisedFirstFileStream(this.appName, this.appDir, [ | ||
path.join(__dirname, './i18n/usage/{lang}.txt'), | ||
path.join(__dirname, './i18n/usage/en.txt') | ||
], this.lang) | ||
if (part) | ||
stream.append(part) | ||
stream.pipe(process.stdout) | ||
} | ||
Adventure.prototype.getExerciseMeta = function (name) { | ||
return this._meta[util.idFromName(name)] | ||
} | ||
Adventure.prototype.loadExercise = function (name) { | ||
var meta = this.getExerciseMeta(name) | ||
var meta = this._meta[util.idFromName(name)] | ||
@@ -621,9 +426,3 @@ if (!meta) | ||
function error () { | ||
var pr = chalk.bold.red | ||
console.log(pr.apply(pr, arguments)) | ||
process.exit(-1) | ||
} | ||
function onselect (name) { | ||
Adventure.prototype.printExercise = function printExercise (name) { | ||
var exercise = this.loadExercise(name) | ||
@@ -646,5 +445,3 @@ , afterPrepare | ||
this.updateData('current', function () { | ||
return exercise.meta.name | ||
}) | ||
this.local.save('current', exercise.meta.name) | ||
@@ -661,3 +458,3 @@ afterPreparation = function (err) { | ||
else { | ||
part = print.localisedFileStream(this.appName, this.appDir, path.resolve(__dirname, 'i18n/missing_problem/{lang}.md'), this.lang) | ||
part = print.localisedFileStream(this.appName, this.appDir, path.resolve(__dirname, 'i18n/missing_problem/{lang}.md'), this.lang) | ||
if (part) | ||
@@ -699,7 +496,2 @@ stream.append(part) | ||
Adventure.prototype.error = error | ||
Adventure.prototype.print = print | ||
module.exports = Adventure | ||
module.exports = Adventure |
54
i18n.js
@@ -5,2 +5,3 @@ const i18n = require('i18n-core') | ||
, path = require('path') | ||
, error = require('./lib/print').error | ||
, fs = require('fs') | ||
@@ -59,24 +60,5 @@ | ||
function chooseLang (globalDataDir, appDataDir, lang, defaultLang, availableLangs) { | ||
var globalPath = path.resolve(globalDataDir, 'lang.json') | ||
, appPath = path.resolve(appDataDir, 'lang.json') | ||
, data | ||
try { | ||
// Lets see if we find some stored language in the app's config | ||
data = require(appPath) | ||
} catch (e) { | ||
// Without a file an error will occur here, but thats okay | ||
} | ||
if (!data) { | ||
// Lets see if some other workshopper stored language settings | ||
try { | ||
data = require(globalPath) | ||
} catch (e) { | ||
data = {} | ||
// Without a file an error will occur here, but thats okay | ||
} | ||
} | ||
function chooseLang (globalData, appData, defaultLang, availableLangs, lang) { | ||
if (!!lang && typeof lang != 'string') | ||
throw new TypeError('Please supply a language. Available languages are: ' + availableLangs.join(', ')) | ||
return error('Please supply a language. Available languages are: ' + availableLangs.join(', ')) | ||
@@ -87,7 +69,9 @@ if (lang) | ||
if (availableLangs.indexOf(defaultLang) === -1) | ||
throw new TypeError('The default language "' + defaultLang + ' is not one of the available languages?! Available languages are: ' + availableLangs.join(', ')) | ||
return error('The default language "' + defaultLang + ' is not one of the available languages?! Available languages are: ' + availableLangs.join(', ')) | ||
if (lang && availableLangs.indexOf(lang) === -1) | ||
throw new TypeError('The language "' + lang + '" is not available.\nAvailable languages are ' + availableLangs.join(', ') + '.\n\nNote: the language is not case-sensitive ("en", "EN", "eN", "En" will become "en") and you can use "_" instead of "-" for seperators.') | ||
return error('The language "' + lang + '" is not available.\nAvailable languages are ' + availableLangs.join(', ') + '.\n\nNote: the language is not case-sensitive ("en", "EN", "eN", "En" will become "en") and you can use "_" instead of "-" for seperators.') | ||
var data = (appData.get('lang') || globalData.get('lang') || {}) | ||
if (availableLangs.indexOf(data.selected) === -1) | ||
@@ -99,8 +83,5 @@ // The stored data is not available so lets use one of the other languages | ||
try { | ||
fs.writeFileSync(globalPath, JSON.stringify(data)) | ||
fs.writeFileSync(appPath, JSON.stringify(data)) | ||
} catch(e) { | ||
// It is not good if an error occurs but it shouldn't really matter | ||
} | ||
globalData.save('lang', data) | ||
appData.save('lang', data) | ||
return data.selected | ||
@@ -110,4 +91,3 @@ } | ||
module.exports = { | ||
chooseLang: chooseLang, | ||
init: function(options, exercises, lang) { | ||
init: function(options, exercises, globalData, appData, defaultLang) { | ||
var generalTranslator = i18nChain( | ||
@@ -122,2 +102,5 @@ i18nFs(path.resolve(__dirname, './i18n')) | ||
) | ||
, languages = options.languages || ['en'] | ||
, choose = chooseLang.bind(null, globalData, appData, defaultLang, languages) | ||
, lang = choose(null) | ||
, result = translator.lang(lang, true) | ||
@@ -130,9 +113,12 @@ translator.fallback = function (key) { | ||
} | ||
result.languages = options.languages || ['en'] | ||
result.change = function (globalDataDir, appDataDir, lang, defaultLang, availableLangs) { | ||
result.languages = languages | ||
result.change = function (lang) { | ||
lang = choose(lang) | ||
result.changeLang(lang) | ||
chooseLang(globalDataDir, appDataDir, lang, defaultLang, availableLangs) | ||
} | ||
result.lang = function () { | ||
return lang | ||
} | ||
return result | ||
} | ||
} |
{ | ||
"name": "workshopper-adventure", | ||
"version": "3.4.2", | ||
"version": "3.4.3", | ||
"description": "A terminal workshop runner framework (adventure compatible)", | ||
"main": "./index.js", | ||
"author": "Rod Vagg <rod@vagg.org> (https://github.com/rvagg)", | ||
"author": "Martin Heidegger <martin.heidegger@gmail.com> (https://github.com/martinheidegger)", | ||
"repository": { | ||
@@ -16,2 +16,3 @@ "type": "git", | ||
"combined-stream": "0.0.7", | ||
"commandico": "^1.0.0", | ||
"i18n-core": "^1.3.2", | ||
@@ -29,5 +30,5 @@ "map-async": "~0.1.1", | ||
"bugs": { | ||
"url": "https://github.com/rvagg/workshopper/issues" | ||
"url": "https://github.com/workshopper/workshopper-adventure/issues" | ||
}, | ||
"homepage": "https://github.com/rvagg/workshopper", | ||
"homepage": "https://github.com/workshopper/workshopper-adventure", | ||
"directories": { | ||
@@ -34,0 +35,0 @@ "example": "examples" |
@@ -1,22 +0,23 @@ | ||
# Workshopper | ||
# Workshopper-Adventure | ||
**A terminal workshop runner framework** | ||
**A flexible terminal workshop runner framework** | ||
[![NPM](https://nodei.co/npm/workshopper.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/workshopper/) [![NPM](https://nodei.co/npm-dl/workshopper.png?months=3&height=3)](https://nodei.co/npm/workshopper/) | ||
[![NPM](https://nodei.co/npm/workshopper-adventure.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/workshopper-adventure/) [![NPM](https://nodei.co/npm-dl/workshopper-adventure.png?months=3&height=3)](https://nodei.co/npm/workshopper-adventure/) | ||
![Learn You The Node.js For Much Win!](https://raw.github.com/rvagg/learnyounode/master/learnyounode.png) | ||
**Workshopper** is used by **[learnyounode](https://github.com/rvagg/learnyounode)**, and other Node.js command-line workshop applications. | ||
**Workshopper** was used by **[learnyounode](https://github.com/rvagg/learnyounode)**, and other Node.js command-line workshop applications. | ||
*Documentation is being written for the v1 rewrite right now! Ping @rvagg if you need anything. **learnyounode** is now using this new version, for now you can use it to see how this works. | ||
**Adventure** was used by **[javascripting](hhttps://github.com/sethvincent/javascripting), and other Node.js command-line workshop applications. | ||
For now, [@linclark](https://github.com/linclark) has written a good introduction on creating your own workshop, available [here](http://lin-clark.com/blog/2014/07/01/authoring-nodejs-workshopper-lessons/). | ||
**Workshopper-Adventure** allows you to create a workshop written | ||
like either of those frameworks! | ||
[@linclark](https://github.com/linclark) has written a good introduction on creating your own workshop, available [here](http://lin-clark.com/blog/2014/07/01/authoring-nodejs-workshopper-lessons/). | ||
## High-level overview | ||
Workshopper is essentially a *test-runner* with a fancy terminal UI. The Workshopper package itself is largely concerned with the menu system and some of the basic command-line parsing. Much of the work for executing the exercise validation is handled by [workshopper-exercise](http://github.com/rvagg/workshopper-exercise). | ||
Workshopper-Adventure is essentially a *test-runner* with a fancy terminal UI. The Workshopper package itself is largely concerned with the menu system and some of the basic command-line parsing. Much of the work for executing the exercise validation is handled by [workshopper-exercise](http://github.com/rvagg/workshopper-exercise). | ||
### Contributors | ||
@@ -45,2 +46,3 @@ | ||
* [@martinheidegger](https://github.com/martinheidegger) | ||
* [@rvagg](https://github.com/rvagg) | ||
@@ -57,4 +59,8 @@ * [@substack](https://github.com/substack) | ||
**Workshopper-Adventure** is Copyright (c) 2015 Martin Heidegger [@martinheidegger](https://github.com/martinheidegger) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. | ||
it is originally a fork of **Workshopper** | ||
**Workshopper** is Copyright (c) 2013-2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. | ||
**Workshopper** builds on the excellent work by [@substack](https://github.com/substack) and [@maxogden](https://github.com/maxogden) who created **[stream-adventure](https://github.com/substack/stream-adventure)** which serves as the original foundation for **Workshopper** and **learnyounode**. Portions of **Workshopper** may also be Copyright (c) 2013 [@substack](https://github.com/substack) and [@maxogden](https://github.com/maxogden) given that it builds on their original code. | ||
**Workshopper-Adventure** builds on the excellent work by [@substack](https://github.com/substack) and [@maxogden](https://github.com/maxogden) who created **[stream-adventure](https://github.com/substack/stream-adventure)** which serves as the original foundation for **Workshopper** and **learnyounode**. Portions of **Workshopper** may also be Copyright (c) 2013 [@substack](https://github.com/substack) and [@maxogden](https://github.com/maxogden) given that it builds on their original code. |
const path = require('path') | ||
, fs = require('fs') | ||
, mkdirp = require('mkdirp') | ||
, vw = require('visualwidth') | ||
@@ -26,9 +25,2 @@ | ||
function userDir () { | ||
var folders = [process.env.HOME || process.env.USERPROFILE].concat(Array.prototype.slice.apply(arguments)) | ||
var dir = path.join.apply(path, folders) | ||
mkdirp.sync(dir) | ||
return dir | ||
} | ||
function getFsObject(type, file, base) { | ||
@@ -57,3 +49,2 @@ var stat | ||
, getFile: getFsObject.bind(null, 'file') | ||
, userDir: userDir | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
75775
75
65
12
14
1454
+ Addedcommandico@^1.0.0
+ Added@hapi/address@2.1.4(transitive)
+ Added@hapi/bourne@1.3.2(transitive)
+ Added@hapi/hoek@8.5.1(transitive)
+ Added@hapi/joi@15.1.1(transitive)
+ Added@hapi/topo@3.1.6(transitive)
+ Addedamdefine@1.0.1(transitive)
+ Addedansi-regex@1.1.1(transitive)
+ Addedargparse@1.0.10(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbossy@1.0.3(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbuffer-from@1.1.2(transitive)
+ Addedcircular-json@0.3.3(transitive)
+ Addedcli-width@1.1.1(transitive)
+ Addedcommandico@1.1.2(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconcat-stream@1.6.2(transitive)
+ Addedd@1.0.2(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddeep-is@0.1.4(transitive)
+ Addeddiff@2.2.3(transitive)
+ Addeddoctrine@0.6.40.7.2(transitive)
+ Addedes5-ext@0.10.64(transitive)
+ Addedes6-iterator@2.0.3(transitive)
+ Addedes6-map@0.1.5(transitive)
+ Addedes6-set@0.1.6(transitive)
+ Addedes6-symbol@3.1.4(transitive)
+ Addedes6-weak-map@2.0.3(transitive)
+ Addedescope@3.6.0(transitive)
+ Addedeslint@0.24.11.5.1(transitive)
+ Addedeslint-config-hapi@2.0.1(transitive)
+ Addedeslint-plugin-hapi@1.2.2(transitive)
+ Addedesniff@2.0.1(transitive)
+ Addedespree@2.2.5(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedesrecurse@4.3.0(transitive)
+ Addedestraverse@4.3.05.3.0(transitive)
+ Addedestraverse-fb@1.3.2(transitive)
+ Addedesutils@1.1.6(transitive)
+ Addedevent-emitter@0.3.5(transitive)
+ Addedexit@0.1.2(transitive)
+ Addedexplicit@0.1.3(transitive)
+ Addedext@1.7.0(transitive)
+ Addedfast-levenshtein@1.0.7(transitive)
+ Addedfigures@1.7.0(transitive)
+ Addedfile-entry-cache@1.3.1(transitive)
+ Addedflat-cache@1.3.4(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedgenerate-function@2.3.1(transitive)
+ Addedgenerate-object-property@1.2.0(transitive)
+ Addedget-stdin@3.0.2(transitive)
+ Addedglob@4.5.35.0.157.2.3(transitive)
+ Addedglobals@8.18.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhandlebars@4.7.8(transitive)
+ Addedhapi-capitalize-modules@1.1.6(transitive)
+ Addedhapi-scope-start@1.1.4(transitive)
+ Addedhoek@2.16.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinquirer@0.8.50.9.0(transitive)
+ Addedis-my-ip-valid@1.0.1(transitive)
+ Addedis-my-json-valid@2.20.6(transitive)
+ Addedis-property@1.0.2(transitive)
+ Addedis-resolvable@1.1.0(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisemail@1.2.0(transitive)
+ Addeditems@1.1.1(transitive)
+ Addedjoi@6.8.1(transitive)
+ Addedjs-yaml@3.14.1(transitive)
+ Addedjslint@0.9.8(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsonpointer@5.0.1(transitive)
+ Addedlab@5.18.1(transitive)
+ Addedlevn@0.2.5(transitive)
+ Addedlodash@3.10.1(transitive)
+ Addedlodash._arraycopy@3.0.0(transitive)
+ Addedlodash._arrayeach@3.0.0(transitive)
+ Addedlodash._arraymap@3.0.0(transitive)
+ Addedlodash._baseassign@3.2.0(transitive)
+ Addedlodash._baseclone@3.3.0(transitive)
+ Addedlodash._basecopy@3.0.1(transitive)
+ Addedlodash._basedifference@3.0.3(transitive)
+ Addedlodash._baseflatten@3.1.4(transitive)
+ Addedlodash._basefor@3.0.3(transitive)
+ Addedlodash._baseindexof@3.1.0(transitive)
+ Addedlodash._bindcallback@3.0.1(transitive)
+ Addedlodash._cacheindexof@3.0.2(transitive)
+ Addedlodash._createassigner@3.1.1(transitive)
+ Addedlodash._createcache@3.1.2(transitive)
+ Addedlodash._getnative@3.9.1(transitive)
+ Addedlodash._isiterateecall@3.0.9(transitive)
+ Addedlodash._pickbyarray@3.0.2(transitive)
+ Addedlodash._pickbycallback@3.0.0(transitive)
+ Addedlodash.clonedeep@3.0.2(transitive)
+ Addedlodash.isarguments@3.1.0(transitive)
+ Addedlodash.isarray@3.0.4(transitive)
+ Addedlodash.isplainobject@3.2.0(transitive)
+ Addedlodash.istypedarray@3.0.6(transitive)
+ Addedlodash.keys@3.1.2(transitive)
+ Addedlodash.keysin@3.0.8(transitive)
+ Addedlodash.merge@3.3.2(transitive)
+ Addedlodash.omit@3.1.0(transitive)
+ Addedlodash.restparam@3.6.1(transitive)
+ Addedlodash.toplainobject@3.0.0(transitive)
+ Addedminimatch@2.0.103.1.2(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addedmoment@2.30.1(transitive)
+ Addedms@2.0.0(transitive)
+ Addedmute-stream@0.0.4(transitive)
+ Addedneo-async@2.6.2(transitive)
+ Addednext-tick@1.1.0(transitive)
+ Addedno-shadow-relaxed@1.0.1(transitive)
+ Addednopt@3.0.6(transitive)
+ Addedobject-assign@2.1.14.1.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedoptionator@0.5.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-is-inside@1.0.2(transitive)
+ Addedprelude-ls@1.1.2(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedreadline2@0.1.1(transitive)
+ Addedrimraf@2.6.3(transitive)
+ Addedrun-async@0.1.0(transitive)
+ Addedrx@2.5.3(transitive)
+ Addedrx-lite@2.5.2(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedshelljs@0.3.0(transitive)
+ Addedsource-map@0.1.320.6.1(transitive)
+ Addedsource-map-support@0.3.3(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedstrip-ansi@2.0.1(transitive)
+ Addedstrip-json-comments@1.0.4(transitive)
+ Addedtext-table@0.2.0(transitive)
+ Addedto-double-quotes@1.0.2(transitive)
+ Addedto-single-quotes@1.0.4(transitive)
+ Addedtopo@1.1.0(transitive)
+ Addedtype@2.7.3(transitive)
+ Addedtype-check@0.3.2(transitive)
+ Addedtypedarray@0.0.6(transitive)
+ Addeduglify-js@3.19.3(transitive)
+ Addeduser-home@1.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwordwrap@0.0.31.0.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedwrite@0.2.1(transitive)
+ Addedxml-escape@1.0.0(transitive)