From 044ba9f36b457315748a5e5730db93dd35f7a003 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 Feb 2016 11:24:10 -0800 Subject: [PATCH 001/153] Updating deps --- package.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 1793ee9..471e5d9 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "preferGlobal": "true", "dependencies": { "async": "^0.9.0", - "chalk": "^1.0.0", + "chalk": "^1.1.1", "cli": "^0.8.0", "cli-color-keywords": "0.0.1", "content-formatter": "^1.1.0", @@ -38,26 +38,26 @@ "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", "optimist": "^0.6.1", - "roolz": "^1.0.0", + "roolz": "^1.0.2", "string-sub": "0.0.1", "update-notifier": "^0.5.0" }, "devDependencies": { "chai": "^2.2.0", - "chai-string": "^1.1.1", - "coveralls": "^2.11.2", + "chai-string": "^1.1.6", + "coveralls": "^2.11.6", "eslint-tester": "^0.6.0", - "gulp": "^3.8.11", + "gulp": "^3.9.1", "gulp-complexity": "^0.3.0", "gulp-coveralls": "^0.1.3", "gulp-doctoc": "^0.1.2", "gulp-istanbul": "^0.8.1", - "gulp-load-plugins": "^1.0.0-rc.1", - "gulp-mocha": "^2.0.1", + "gulp-load-plugins": "^1.2.0", + "gulp-mocha": "^2.2.0", "istanbul": "^0.3.13", - "mocha": "^2.2.4", - "run-sequence": "^1.0.2", - "sinon": "^1.14.1", + "mocha": "^2.4.5", + "run-sequence": "^1.1.5", + "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } } From 027432027d24622664065d4155e2d1860f2fe002 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 Feb 2016 11:36:35 -0800 Subject: [PATCH 002/153] Updating lodash --- package.json | 2 +- test/css.js | 2 +- test/html.js | 4 ++-- test/js.js | 2 +- test/rule_utils.js | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 471e5d9..af15578 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "getobject": "^0.1.0", "glob": "^5.0.5", "handlebars": "^3.0.1", - "lodash": "^3.6.0", + "lodash": "^4.3.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", "optimist": "^0.6.1", diff --git a/test/css.js b/test/css.js index 9b02151..a115dd0 100644 --- a/test/css.js +++ b/test/css.js @@ -259,7 +259,7 @@ describe( line: lineNum }; - return _.result(_.findWhere(errors, whereLine), 'msg') || ''; + return _.result(_.find(errors, whereLine), 'msg') || ''; }; it( diff --git a/test/html.js b/test/html.js index 60a9970..9433fb6 100644 --- a/test/html.js +++ b/test/html.js @@ -32,7 +32,7 @@ describe( line: lineNum }; - return _.result(_.findWhere(errors, whereLine), 'msg') || ''; + return _.result(_.find(errors, whereLine), 'msg') || ''; }; it( @@ -467,7 +467,7 @@ describe( line: lineNum }; - return _.result(_.findWhere(errors, whereLine), 'msg') || ''; + return _.result(_.find(errors, whereLine), 'msg') || ''; }; it( diff --git a/test/js.js b/test/js.js index d292d91..bc61dcd 100644 --- a/test/js.js +++ b/test/js.js @@ -16,7 +16,7 @@ var getErrorMsgByLine = function(lineNum, errors) { line: lineNum }; - return _.result(_.findWhere(errors, whereLine), 'msg') || ''; + return _.result(_.find(errors, whereLine), 'msg') || ''; }; describe( diff --git a/test/rule_utils.js b/test/rule_utils.js index 96af28e..c173b87 100644 --- a/test/rule_utils.js +++ b/test/rule_utils.js @@ -48,7 +48,7 @@ describe( function(node) { if (node.type === 'Program') { var constants = ruleUtils.getConstants(node); - var constantNames = _.pluck(_.pluck(constants, 'id'), 'name'); + var constantNames = _.map(_.map(constants, 'id'), 'name'); assert.equal(constants.length, 2); assert.equal(constantNames.join(''), 'XY'); @@ -70,7 +70,7 @@ describe( varStr, function(node) { if (node.type === 'Program') { - var variables = _.where( + var variables = _.filter( node.body, { type: 'VariableDeclaration' From c9d46aebc3d475d01bb71df8f99e2ebcbeb50f55 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 Feb 2016 11:40:52 -0800 Subject: [PATCH 003/153] Updating glob --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af15578..d5d8573 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "eslint": "^0.24.0", "falafel": "^0.3.1", "getobject": "^0.1.0", - "glob": "^5.0.5", + "glob": "^7.0.0", "handlebars": "^3.0.1", "lodash": "^4.3.0", "lodash-bindright": "^1.0.1", From e67ea4f0c2d0baf4fbb247be0d62edf8433b0b1b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 Feb 2016 11:46:18 -0800 Subject: [PATCH 004/153] Updating Handlebars --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5d8573..90b07b7 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "falafel": "^0.3.1", "getobject": "^0.1.0", "glob": "^7.0.0", - "handlebars": "^3.0.1", + "handlebars": "^4.0.5", "lodash": "^4.3.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", From 81d278cb8608bfb9df72581f8b01a503661c6a9b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 Feb 2016 11:57:39 -0800 Subject: [PATCH 005/153] Updating falafel --- package.json | 2 +- test/js.js | 2 +- test/rule_utils.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 90b07b7..823eade 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "content-logger-handlebars-helpers": "0.0.1", "drip": "^1.4.0", "eslint": "^0.24.0", - "falafel": "^0.3.1", + "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", "handlebars": "^4.0.5", diff --git a/test/js.js b/test/js.js index bc61dcd..a5db089 100644 --- a/test/js.js +++ b/test/js.js @@ -142,7 +142,7 @@ describe( var parseErrors = jsLoggerParse.getErrors(testFilePath); assert.equal(parseErrors.length, 1); - assert.equal(parseErrors[0].msg, 'Could not parse JavaScript: Unexpected token ;'); + assert.startsWith(parseErrors[0].msg, 'Could not parse JavaScript: Unexpected token '); var jsLoggerParseVerbose = new Logger.constructor(); var jsFormatterParseVerbose = new Formatter.JS(testFilePath, jsLoggerParseVerbose); diff --git a/test/rule_utils.js b/test/rule_utils.js index c173b87..9c238f3 100644 --- a/test/rule_utils.js +++ b/test/rule_utils.js @@ -13,7 +13,7 @@ var parse = function(contents, cb) { return falafel( contents, { - loc: true, + locations: true, tolerant: true }, cb From 86cf29df014284779275b01de757a9053e7f7568 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 Feb 2016 13:51:51 -0800 Subject: [PATCH 006/153] Adding ability to run a single test at a time --- gulpfile.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 9c4d5aa..eacea35 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var gulp = require('gulp'); var plugins = require('gulp-load-plugins')(); var runSequence = require('run-sequence'); @@ -19,6 +20,25 @@ gulp.task('test-complexity', function() { })); }); +gulp.task('test-file', function() { + var file = process.argv.slice(3).pop(); + + if (file) { + file = file.slice(2); + file = !_.startsWith(file, 'test/') ? 'test/' + file : file; + file = !_.endsWith(file, '.js') ? file + '.js' : file; + + file = [file]; + } + else { + file = ['test/**/*.js', '!test/fixture/*.js']; + } + process.argv.push('--display-raw'); + + return gulp.src(file) + .pipe(plugins.mocha()); +}); + gulp.task('test-unit', function() { process.argv.push('--display-raw'); From 0ba13a93f8853c1f3ffdf48f811b1b2c4184c2d7 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 Feb 2016 14:17:12 -0800 Subject: [PATCH 007/153] In updating the to the latest async version, it now throws an error if the callback is executed more than once. This exposed some weird logic in here where that would happen. Additionally, the async methods are guaranteed to be async, so we need some way to let the tests know when they can finish up, which is why the CLI object emits a 'finish' event. --- lib/cli.js | 368 +++++++++++++++++++++++++++++---------------------- package.json | 4 +- test/cli.js | 299 ++++++++++++++++++++++++++++++----------- 3 files changed, 437 insertions(+), 234 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 2783baf..9b7a1d4 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -15,6 +15,8 @@ var re = require('./re'); var File = require('./file'); var Formatter = require('./formatter'); +var EventEmitter = require('drip').EnhancedEmitter; + var Logger = require('./logger'); var MAP_OMIT = { @@ -39,6 +41,8 @@ var flags = _.reduce( var CLI = function(config) { config = config || {}; + EventEmitter.call(this); + this.flags = config.flags || flags; this._args = config.args || argv._; @@ -52,219 +56,269 @@ var CLI = function(config) { this._write = config.write || fs.writeFile.bind(fs); }; -CLI.prototype = { - constructor: CLI, +CLI.prototype = _.create( + EventEmitter.prototype, + { + constructor: CLI, + + init: function() { + var instance = this; - init: function() { - var instance = this; + this.emit('init'); + + var series = instance._args.map( + function(file) { + return instance.processFile.bind(instance, file); + } + ); - var series = instance._args.map( - function(file) { - return instance.processFile.bind(instance, file); + if (series.length) { + series.push(instance.checkMeta.bind(instance)); } - ); - series.push(instance.checkMeta.bind(instance)); + if (instance.flags.junit) { + series.push(instance.createReport.bind(instance)); + } - var flags = instance.flags; + instance._async.series(series, instance.afterFormat.bind(instance)); - if (flags.junit) { - series.push(instance.createReport.bind(instance)); - } + if (!series.length) { + this.onFinish(null, null); + } + }, - instance._async.series(series, instance.onFinish.bind(instance)); - }, + afterFormat: function(err, results) { + var instance = this; + + var series = []; - checkMeta: function(done) { - if (this._CHECK_META) { - require(this._metaCheckerPath).check( + if (instance.flags.inlineEdit) { + series = results.reduce( + function(prev, item, index) { + if (item && item.contents !== item.data) { + prev.push(instance.writeFile.bind(instance, item.file, item.contents)); + } + + return prev; + }, + series + ); + + instance._async.series(series, instance.onFinish.bind(instance)); + } + + if (!series.length) { + this.onFinish(err, results); + } + }, + + checkMeta: function(done) { + if (this._CHECK_META) { + require(this._metaCheckerPath).check( + { + done: done, + liferayModuleDir: this._liferayModuleDir + } + ); + } + else { + done(); + } + }, + + createReport: function(done) { + var instance = this; + + var junit = new this.junit( { - done: done, - liferayModuleDir: this._liferayModuleDir + flags: this.flags, + logger: this._logger } ); - } - else { - done(); - } - }, - createReport: function(done) { - var instance = this; + junit.generate(done); + }, - var junit = new this.junit( - { - flags: this.flags, - logger: this._logger - } - ); + formatFile: function(file, data) { + var formatter = Formatter.get(file, this._logger, this.flags); - junit.generate(done); - }, + var contents = null; - formatFile: function(file, data, done) { - var formatter = Formatter.get(file, this._logger, this.flags); + if (formatter) { + contents = this.processFileData(data, formatter); - if (formatter) { - this.processFileData(data, formatter, done); + this.isMetaCheckNeeded(file); + } - this.isMetaCheckNeeded(file); - } - }, + return contents; + }, - hasModulesFile: function(fileDir) { - return fs.existsSync(path.join(fileDir, 'modules.js')); - }, + hasModulesFile: function(fileDir) { + return fs.existsSync(path.join(fileDir, 'modules.js')); + }, - isMetaCheckNeeded: function(file) { - if (!this._CHECK_META && this.flags.checkMetadata && path.extname(file) === '.js') { - var fileDir = path.dirname(path.resolve(file)); + isMetaCheckNeeded: function(file) { + if (!this._CHECK_META && this.flags.checkMetadata && path.extname(file) === '.js') { + var fileDir = path.dirname(path.resolve(file)); - if (path.basename(fileDir) === 'liferay' && this.hasModulesFile(fileDir)) { - this._CHECK_META = true; - this._liferayModuleDir = fileDir; + if (path.basename(fileDir) === 'liferay' && this.hasModulesFile(fileDir)) { + this._CHECK_META = true; + this._liferayModuleDir = fileDir; + } } - } - }, + }, - logGeneralError: function(err) { - var msg = ''; + logGeneralError: function(err) { + var msg = ''; - if (err) { - msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); + if (err) { + msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); - this._log(msg); - } + this._log(msg); + } - return msg; - }, + return msg; + }, - logResults: function(out, file) { - if (out) { - this._log(out); - } + logResults: function(out, file) { + if (out) { + this._log(out); + } - var verboseDetails = this._logger.verboseDetails[file]; + var verboseDetails = this._logger.verboseDetails[file]; - if (verboseDetails) { - this._log(verboseDetails); - } - }, + if (verboseDetails) { + this._log(verboseDetails); + } + }, - onFinish: function(err, results) { - this.logGeneralError(err); + onFinish: function(err, results) { + this.logGeneralError(err); - if (this.flags.open) { - this.openFiles(err, results); - } - }, + if (this.flags.open) { + this.openFiles(err, results); + } - onRead: function(err, data, file, done) { - if (err) { - done = file; - file = data; + this.emit( + 'finish', + { + err: err, + results: results + } + ); + }, - this.onReadError(err, file); - } - else { - this.formatFile(file, data, done); - } + onRead: function(err, data, file, done) { + var results = null; - done(); - }, + if (err) { + done = file; + file = data; - onReadError: function(err, file) { - var errMsg = File.handleFileReadError(err, file); + this.onReadError(err, file); - if (errMsg) { - this._log(''); - this._log(errMsg); - this._log(''); - } - }, + err = null; + } + else { + results = this.formatFile(file, data); + } - onWrite: function(err, file, done) { - var writeResults = ''; + done(err, results); + }, - if (err) { - writeResults = File.handleFileWriteError(err, file); - } - else { - writeResults = util.format('Wrote file: %s', file); - } + onReadError: function(err, file) { + var errMsg = File.handleFileReadError(err, file); - this._log(writeResults); + if (errMsg) { + this._log(''); + this._log(errMsg); + this._log(''); + } + }, - if (_.isFunction(done)) { - done(); - } - }, + onWrite: function(err, file, done) { + var writeResults = ''; - openFiles: function(err, result) { - var instance = this; + if (err) { + writeResults = File.handleFileWriteError(err, file); + } + else { + writeResults = util.format('Wrote file: %s', file); + } - var errorFiles = Object.keys(instance._logger.getErrors()); + this._log(writeResults); - if (errorFiles.length) { - instance._exec( - 'git config --get user.editor', - function(res) { - instance._exec( - 'open -a "' + res[0] + '" "' + errorFiles.join('" "') + '"' - ); - } - ); - } - }, + done(); + }, + + openFiles: function(err, result) { + var instance = this; + + var errorFiles = Object.keys(instance._logger.getErrors()); + + if (errorFiles.length) { + instance._exec( + 'git config --get user.editor', + function(res) { + instance._exec( + 'open -a "' + res[0] + '" "' + errorFiles.join('" "') + '"' + ); + } + ); + } + }, - processFile: function(file, done) { - this._read(file, 'utf-8', _.bindRight(this.onRead, this, file, done)); - }, + processFile: function(file, done) { + this._read(file, 'utf-8', _.bindRight(this.onRead, this, file, done)); + }, - processFileData: function(data, formatter, done) { - var file = formatter.file; + processFileData: function(data, formatter) { + var file = formatter.file; - var contents = formatter.format(data); + var contents = formatter.format(data); - this.logResults(this.renderOutput(file), file); + this.logResults(this.renderOutput(file), file); - if (contents !== data && this.flags.inlineEdit) { - this.writeFile(file, contents, done); - } - }, + return { + file: file, + contents: contents, + data: data + }; + }, - renderOutput: function(file) { - var flags = this.flags; + renderOutput: function(file) { + var flags = this.flags; - var config = { - showColumns: flags.showColumns - }; + var config = { + showColumns: flags.showColumns + }; - var out; + var out; - if (flags.relative) { - config.relative = this._cwd; - } + if (flags.relative) { + config.relative = this._cwd; + } - if (flags.filenames) { - out = this._logger.renderFileNames(file, config); - } - else { - config.showBanner = flags.quiet; - config.showLintIds = flags.lintIds; + if (flags.filenames) { + out = this._logger.renderFileNames(file, config); + } + else { + config.showBanner = flags.quiet; + config.showLintIds = flags.lintIds; - out = this._logger.render(file, config); - } + out = this._logger.render(file, config); + } - return out; - }, + return out; + }, - writeFile: function(file, contents, done) { - this._write(file, contents, _.bindRight(this.onWrite, this, file, done)); - }, + writeFile: function(file, contents, done) { + this._write(file, contents, _.bindRight(this.onWrite, this, file, done)); + }, - _metaCheckerPath: './meta' -}; + _metaCheckerPath: './meta' + } +); var cliInstance = new CLI(); diff --git a/package.json b/package.json index 823eade..4c5b43f 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "preferGlobal": "true", "dependencies": { - "async": "^0.9.0", + "async": "^1.5.2", "chalk": "^1.1.1", "cli": "^0.8.0", "cli-color-keywords": "0.0.1", @@ -60,4 +60,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} +} \ No newline at end of file diff --git a/test/cli.js b/test/cli.js index 9503c2f..56f9794 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,3 +1,4 @@ +var async = require('async'); var chai = require('chai'); var fs = require('fs'); var path = require('path'); @@ -46,32 +47,42 @@ describe( it( 'should read files correctly', - function() { + function(done) { sandbox.stub(fs, 'readFile', invalidContentStub); + var logger = new Logger.constructor(); + var cliInstance = new cli.CLI( { args: ['foo.js', 'bar.html', 'baz.css'], log: sinon.log, - logger: new Logger.constructor() + logger: logger } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(fs.readFile.calledThrice, 'fs.readFile should have been called 3 times, it was instead called ' + fs.readFile.callCount + ' times'); + assert.isTrue(fs.readFile.calledWith('foo.js'), 'foo.js should have been read'); + assert.isTrue(fs.readFile.calledWith('bar.html'), 'bar.html should have been read'); + assert.isTrue(fs.readFile.calledWith('baz.css'), 'baz.css should have been read'); - assert.isTrue(fs.readFile.calledThrice, 'fs.read should have been called 3 times'); - assert.isTrue(fs.readFile.calledWith('foo.js'), 'foo.js should have been read'); - assert.isTrue(fs.readFile.calledWith('bar.html'), 'bar.html should have been read'); - assert.isTrue(fs.readFile.calledWith('baz.css'), 'baz.css should have been read'); + done(); + } + ); + cliInstance.init(); } ); it( 'should write files correctly', - function() { + function(done) { sandbox.stub(fs, 'readFile', invalidContentStub); - sandbox.stub(fs, 'writeFile', validContentStub); + sandbox.stub(fs, 'writeFile').callsArgWith(2, null); + + var log = sandbox.spy(); var cliInstance = new cli.CLI( { @@ -79,33 +90,43 @@ describe( flags: { inlineEdit: true }, - log: sinon.log, + log: log, logger: new Logger.constructor() } ); - cliInstance.init(); + sandbox.spy(cliInstance, 'logResults'); - assert.isTrue(fs.writeFile.calledThrice, 'fs.write should have been called 3 times'); - assert.isTrue(fs.writeFile.calledWith('foo.js'), 'foo.js should have been written to'); - assert.isTrue(fs.writeFile.calledWith('bar.html'), 'bar.html should have been written to'); - assert.isTrue(fs.writeFile.calledWith('baz.css'), 'baz.css should have been written to'); + cliInstance.on( + 'finish', + function() { + assert.isTrue(fs.writeFile.calledThrice, 'fs.writeFile should have been called 3 times, it was instead called ' + fs.writeFile.callCount + ' times'); + assert.isTrue(fs.writeFile.calledWith('foo.js'), 'foo.js should have been written to'); + assert.isTrue(fs.writeFile.calledWith('bar.html'), 'bar.html should have been written to'); + assert.isTrue(fs.writeFile.calledWith('baz.css'), 'baz.css should have been written to'); - fs.writeFile.args.forEach( - function(item, index) { - var path = item[0]; - var expectedContents = MAP_CONTENT[path][1]; + fs.writeFile.args.forEach( + function(item, index) { + var path = item[0]; + var expectedContents = MAP_CONTENT[path][1]; + + assert.equal(expectedContents, item[1], 'The contents passed to writeFile for ' + path + ' aren\'t what was expected'); + } + ); - assert.equal(expectedContents, item[1], 'The contents passed to writeFile for ' + path + ' aren\'t what was expected'); + assert.equal(log.callCount, 6, '.log should have been called 6 times, it was instead called ' + log.callCount + ' times'); + + done(); } ); + cliInstance.init(); } ); it( 'should handle file write errors', - function() { + function(done) { sandbox.stub(fs, 'readFile', invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, new Error('Something went wrong')); @@ -118,21 +139,27 @@ describe( inlineEdit: true }, log: sinon.log, - logger: new Logger.constructor(), - write: fs.writeFile + logger: new Logger.constructor() } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(fs.writeFile.calledOnce, 'fs.writeFile should have been called once, it was instead called ' + fs.writeFile.callCount + ' times'); + assert.isTrue(File.handleFileWriteError.calledOnce, 'File.handleFileWriteError should have been called once, it was instead called ' + File.handleFileWriteError.callCount + ' times'); + + done(); + } + ); - assert.isTrue(fs.writeFile.calledOnce, 'fs.write should have been called 3 times'); - assert.isTrue(File.handleFileWriteError.calledOnce, 'File.handleFileWriteError should have been called once'); + cliInstance.init(); } ); it( 'should ignore unrecognized files', - function() { + function(done) { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); var processFileData = sinon.spy(); @@ -147,15 +174,22 @@ describe( cliInstance.processFileData = processFileData; - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isFalse(processFileData.called, 'processFileData should not have been called for a non-recognized file, it was instead called ' + processFileData.callCount + ' times'); + + done(); + } + ); - assert.isFalse(processFileData.called, 'processFileData should not have been called for a non-recognized file'); + cliInstance.init(); } ); it( - 'should handle metadata checking', - function() { + 'should check metadata', + function(done) { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); sandbox.stub(fs, 'existsSync').returns(true); @@ -178,11 +212,26 @@ describe( var checkMeta = sandbox.stub(metaChecker, 'check').yieldsTo('done'); + cliInstance.on( + 'finish', + function() { + assert.isTrue(checkMeta.called, 'metaChecker.check should have been called, it was instead called ' + checkMeta.callCount + ' times'); + + done(); + } + ); + cliInstance.init(); + } + ); - assert.isTrue(checkMeta.called, 'metaChecker.check should have been called'); + it( + 'should not check metadata', + function(done) { + sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + sandbox.stub(fs, 'existsSync').returns(true); - cliInstance = new cli.CLI( + var cliInstance = new cli.CLI( { args: ['foo.js'], flags: { @@ -193,19 +242,30 @@ describe( } ); + var metaCheckerPath = path.join(__dirname, 'fixture', 'meta.js'); + cliInstance._metaCheckerPath = metaCheckerPath; - checkMeta.reset(); + var metaChecker = require(metaCheckerPath); + + var checkMeta = sandbox.stub(metaChecker, 'check').yieldsTo('done'); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(checkMeta.notCalled, 'metaChecker.check should not have been called, it was instead called ' + metaChecker.check.callCount + ' times'); - assert.isTrue(checkMeta.notCalled, 'metaChecker.check should not have been called'); + done(); + } + ); + + cliInstance.init(); } ); it( 'should log results properly', - function() { + function(done) { sandbox.stub(fs, 'readFile', validContentStub); var log = sandbox.spy(); @@ -218,21 +278,28 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); + + log.reset(); - assert.isTrue(log.calledOnce, 'log should have been called only once'); + cliInstance.logResults(null, 'foo.js'); - log.reset(); + assert.isTrue(log.notCalled, 'log should not have been called when logResults gets no input, it was instead called ' + log.callCount + ' times'); - cliInstance.logResults(null, 'foo.js'); + done(); + } + ); - assert.isTrue(log.notCalled, 'log should not have been called when logResults gets no input'); + cliInstance.init(); } ); it( 'should log verbose details properly', - function() { + function(done) { sandbox.stub(fs, 'readFile').callsArgWith(2, null, 'var x = ;'); var log = sandbox.spy(); @@ -250,15 +317,22 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledTwice, 'log should have been called twice, it was instead called ' + log.callCount + ' times'); + + done(); + } + ); - assert.isTrue(log.calledTwice, 'log should have been called twice'); + cliInstance.init(); } ); it( 'should log filenames properly', - function() { + function(done) { sandbox.stub( fs, 'readFile', @@ -282,12 +356,34 @@ describe( } ); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); + assert.equal(args.join(), log.args.join()); + + done(); + } + ); + cliInstance.init(); + } + ); - assert.isTrue(log.calledThrice, 'log should have been called 3 times'); - assert.equal(args.join(), log.args.join()); + it( + 'should log relative filenames properly', + function(done) { + sandbox.stub( + fs, + 'readFile', + function(filePath, encoding, callback) { + callback(null, MAP_CONTENT[path.basename(filePath)][0]); + } + ); + + var log = sandbox.spy(); - log.reset(); + var args = ['foo.js', 'bar.html', 'baz.css']; var pathArgs = args.map( function(item, index) { @@ -301,7 +397,7 @@ describe( } ); - cliInstance = new cli.CLI( + var cliInstance = new cli.CLI( { args: pathArgs, cwd: path.join('home', 'liferay', 'scripts', 'tests'), @@ -314,16 +410,23 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); + assert.equal(relativeArgs.join(), log.args.join()); + + done(); + } + ); - assert.isTrue(log.calledThrice, 'log should have been called 3 times'); - assert.equal(relativeArgs.join(), log.args.join()); + cliInstance.init(); } ); it( 'should log missing files properly', - function() { + function(done) { sandbox.stub(fs, 'readFile').callsArgWith(2, new Error()); sandbox.stub(File, 'handleFileReadError').returns('Missing file'); @@ -338,16 +441,23 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); + assert.isTrue(File.handleFileReadError.calledOnce, 'File.handleFileReadError should have been called, it was instead called ' + File.handleFileReadError.callCount + ' times'); - assert.isTrue(log.calledThrice, 'log should have been called 3 times'); - assert.isTrue(File.handleFileReadError.calledOnce, 'File.handleFileReadError should have been called'); + done(); + } + ); + + cliInstance.init(); } ); it( 'should ignore directories properly', - function() { + function(done) { var err = new Error(); err.errno = -21; @@ -367,10 +477,17 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.notCalled, 'log should not have been called, it was instead called ' + log.callCount + ' times'); + assert.isTrue(File.handleFileReadError.returned(''), 'File.handleFileReadError should have returned nothing'); - assert.isTrue(log.notCalled, 'log should not have been called'); - assert.isTrue(File.handleFileReadError.returned(''), 'File.handleFileReadError should have returned nothing'); + done(); + } + ); + + cliInstance.init(); } ); @@ -389,14 +506,14 @@ describe( cliInstance.logGeneralError(new Error('Something general happened....')); - assert.isTrue(log.calledOnce, 'log should have been called once'); + assert.isTrue(log.calledOnce, 'log should have been called once, it was instead called ' + log.callCount + ' times'); assert.startsWith(log.args[0][0], 'Something went wrong'); } ); it( 'should open files properly', - function() { + function(done) { sandbox.stub(fs, 'readFile', invalidContentStub); var cliModule = require('cli'); @@ -424,15 +541,40 @@ describe( } ); + cliInstance.on( + 'finish', + function() { + assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); + assert.isTrue(cliModule.exec.calledTwice, 'cliModule.exec should have been called 2 times, it was instead called ' + cliModule.exec.callCount + ' times'); + + done(); + } + ); + cliInstance.init(); + } + ); + + it( + 'should not log without arguments', + function() { + sandbox.stub(fs, 'readFile', invalidContentStub); + + var cliModule = require('cli'); - assert.isTrue(log.calledOnce, 'log should have been called only once'); - assert.isTrue(cliModule.exec.calledTwice, 'log should have been called 2 times'); + sandbox.stub( + cliModule, + 'exec', + function(command, callback) { + if (callback) { + callback(['sublime']); + } + } + ); - log.reset(); - cliModule.exec.reset(); + var log = sandbox.spy(); - cliInstance = new cli.CLI( + var cliInstance = new cli.CLI( { args: [], flags: { @@ -445,21 +587,21 @@ describe( cliInstance.init(); - assert.isTrue(log.notCalled, 'log should not have been called'); - assert.isTrue(cliModule.exec.notCalled, 'log should not have been called'); + assert.isTrue(log.notCalled, 'log should not have been called, it was instead called ' + log.callCount + ' times'); + assert.isTrue(cliModule.exec.notCalled, 'cliModule.exec should not have been called, it was instead called ' + cliModule.exec.callCount + ' times'); } ); it( 'should call junit generate', - function() { + function(done) { sandbox.stub(fs, 'readFile', invalidContentStub); var junitReporter = require('../lib/junit'); var junit = sandbox.spy(junitReporter); - sandbox.stub(junit.prototype, 'generate'); + sandbox.stub(junit.prototype, 'generate').callsArg(0); var cliInstance = new cli.CLI( { @@ -473,10 +615,17 @@ describe( } ); - cliInstance.init(); + cliInstance.on( + 'finish', + function() { + assert.isTrue(junit.calledWithNew(), 'junit should have been instantiated'); + assert.isTrue(junit.prototype.generate.called, 'junit.prototype.generate should have been called, it was instead called ' + junit.prototype.generate.callCount + ' times'); - assert.isTrue(junit.calledWithNew(), 'junit should have been instantiated'); - assert.isTrue(junit.prototype.generate.called, 'junit.prototype.generate should have been called'); + done(); + } + ); + + cliInstance.init(); } ); } From 5ffce1f9bb49b7533a654b1364ecb7876ae09faa Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 12 Feb 2016 13:28:51 -0800 Subject: [PATCH 008/153] Update chai version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4c5b43f..0164464 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "update-notifier": "^0.5.0" }, "devDependencies": { - "chai": "^2.2.0", + "chai": "^3.5.0", "chai-string": "^1.1.6", "coveralls": "^2.11.6", "eslint-tester": "^0.6.0", @@ -60,4 +60,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} \ No newline at end of file +} From 72f6b5ce6b7128d94d3970f852a9cfcb469bb855 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 17 Feb 2016 11:14:46 -0800 Subject: [PATCH 009/153] Updating eslint to 1.10.3 (part 1 of migrating to 2) --- lib/eslint_config.js | 13 +-- lib/eslint_config_jsp.js | 2 +- lib/lint_rules/no_undef.js | 2 +- lib/lint_rules/no_use_before_define.js | 110 ++++++++++++++++------ package.json | 4 +- test/lint_rules/array_spacing.js | 10 +- test/lint_rules/array_spacing_chars.js | 10 +- test/lint_rules/catch_arg_name.js | 10 +- test/lint_rules/catch_format.js | 10 +- test/lint_rules/dot_notation.js | 10 +- test/lint_rules/format_args.js | 10 +- test/lint_rules/format_constants.js | 10 +- test/lint_rules/format_multiline_vars.js | 10 +- test/lint_rules/liferay_language_get.js | 10 +- test/lint_rules/liferay_provide_format.js | 10 +- test/lint_rules/multiple_vars.js | 10 +- test/lint_rules/no_extra_semi.js | 10 +- test/lint_rules/no_is_prefix.js | 10 +- test/lint_rules/no_undef.js | 10 +- test/lint_rules/no_unused_vars.js | 20 ++-- test/lint_rules/no_use_before_define.js | 55 ++++++++--- test/lint_rules/sort_constants.js | 10 +- test/lint_rules/sort_props.js | 14 +-- test/lint_rules/sort_requires.js | 10 +- test/lint_rules/sort_vars.js | 10 +- 25 files changed, 257 insertions(+), 133 deletions(-) diff --git a/lib/eslint_config.js b/lib/eslint_config.js index 0d0e8be..6c8c7e6 100644 --- a/lib/eslint_config.js +++ b/lib/eslint_config.js @@ -41,7 +41,7 @@ module.exports = { 'csf-no-extra-semi': 2, 'csf-no-is-prefix': 2, 'csf-no-unused-vars': 2, - 'csf-no-use-before-define': [2, {'samescope': true}], + 'csf-no-use-before-define': [2, null, {'samescope': true}], 'csf-sort-constants': 2, 'csf-sort-props': 2, 'csf-sort-requires': 2, @@ -84,7 +84,7 @@ module.exports = { 'no-duplicate-case': 2, 'no-else-return': 2, 'no-empty': 0, - 'no-empty-class': 2, + 'no-empty-character-class': 2, 'no-empty-label': 2, 'no-eq-null': 0, 'no-eval': 2, @@ -132,7 +132,7 @@ module.exports = { 'no-proto': 2, 'no-redeclare': 2, 'no-regex-spaces': 2, - 'no-reserved-keys': 0, + 'quote-props': 0, 'no-restricted-modules': 0, 'no-return-assign': 2, 'no-script-url': 0, @@ -158,7 +158,7 @@ module.exports = { 'no-void': 0, 'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }], 'no-with': 2, - 'no-wrap-func': 2, + 'no-extra-parens': 2, 'one-var': 0, 'operator-assignment': [2, 'always'], 'padded-blocks': 0, @@ -171,12 +171,13 @@ module.exports = { 'space-after-keywords': [2, 'always'], 'space-before-blocks': [2, 'always'], 'space-before-function-paren': [2, 'never'], - 'space-in-brackets': [0, 'never'], + 'byobject-curly-spacing': [0, 'never'], + 'array-bracket-spacing': [0, 'never'], 'space-in-parens': [2, 'never'], 'space-infix-ops': 2, 'space-return-throw-case': 2, 'space-unary-ops': [1, {'words': true, 'nonwords': false}], - 'spaced-line-comment': [2, 'always'], + 'spaced-comment': [2, 'always'], 'strict': 0, 'use-isnan': 2, 'valid-jsdoc': 0, diff --git a/lib/eslint_config_jsp.js b/lib/eslint_config_jsp.js index 7b94ab8..f246091 100644 --- a/lib/eslint_config_jsp.js +++ b/lib/eslint_config_jsp.js @@ -8,7 +8,7 @@ module.exports = { 'rules': { 'block-scoped-var': 0, 'csf-dot-notation': 2, - 'csf-no-undef': 2, + 'csf-no-undef': [2, {}], 'csf-no-unused-vars': [2, {'jsp': true}], 'indent': [0, 'tab'], 'dot-notation': 0, diff --git a/lib/lint_rules/no_undef.js b/lib/lint_rules/no_undef.js index 7c51586..e6dbae2 100644 --- a/lib/lint_rules/no_undef.js +++ b/lib/lint_rules/no_undef.js @@ -14,7 +14,7 @@ module.exports = function(context) { } }; - _.defaults(mockContext, context); + _.defaults(mockContext, context, {options: context.options}); return { 'Program:exit': function(node) { diff --git a/lib/lint_rules/no_use_before_define.js b/lib/lint_rules/no_use_before_define.js index 868536a..694602f 100644 --- a/lib/lint_rules/no_use_before_define.js +++ b/lib/lint_rules/no_use_before_define.js @@ -1,8 +1,17 @@ /** * @fileoverview Rule to flag use of variables before they are defined * @author Ilya Volodin + * @copyright 2013 Ilya Volodin. All rights reserved. */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var astUtils = require("eslint/lib/ast-utils"); + //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ @@ -15,43 +24,40 @@ var NO_FUNC = "nofunc"; module.exports = function(context) { - "use strict"; - - function findDeclaration(name, scope) { - //try searching in the current scope first - for (var i = 0, l = scope.variables.length; i < l; i++) { - if (scope.variables[i].name === name) { - return scope.variables[i]; - } - } - //check if there's upper scope and call recursivly till we find the variable - if (scope.upper) { - return findDeclaration(name, scope.upper); - } - } - - function findVariables() { - var scope = context.getScope(); - var configuration = context.options[0] || {}; - var typeOption = configuration.nofunc ? NO_FUNC : null; + /** + * Finds and validates all variables in a given scope. + * @param {Scope} scope The scope object. + * @returns {void} + * @private + */ + function findVariablesInScope(scope) { + var typeOption = context.options[0]; + var configuration = context.options[1] || {}; var scopeOption = configuration.samescope; + /** + * Report the node + * @param {object} reference reference object + * @param {ASTNode} declaration node to evaluate + * @returns {void} + * @private + */ function checkLocationAndReport(reference, declaration) { if ((typeOption !== NO_FUNC || declaration.defs[0].type !== "FunctionName") && (!scopeOption || reference.from.variableScope === declaration.scope)) { if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) { - context.report(reference.identifier, "{{a}} was used before it was defined", {a: reference.identifier.name}); + context.report(reference.identifier, "\"{{a}}\" was used before it was defined", {a: reference.identifier.name}); } } } scope.references.forEach(function(reference) { - //if the reference is resolved check for declaration location - //if not, it could be function invocation, try to find manually + // if the reference is resolved check for declaration location + // if not, it could be function invocation, try to find manually if (reference.resolved && reference.resolved.identifiers.length > 0) { checkLocationAndReport(reference, reference.resolved); } else { - var declaration = findDeclaration(reference.identifier.name, scope); - //if there're no identifiers, this is a global environment variable + var declaration = astUtils.getVariableByName(scope, reference.identifier.name); + // if there're no identifiers, this is a global environment variable if (declaration && declaration.identifiers.length !== 0) { checkLocationAndReport(reference, declaration); } @@ -59,9 +65,55 @@ module.exports = function(context) { }); } - return { - "Program": findVariables, - "FunctionExpression": findVariables, - "FunctionDeclaration": findVariables + + /** + * Validates variables inside of a node's scope. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function findVariables() { + var scope = context.getScope(); + findVariablesInScope(scope); + } + + var ruleDefinition = { + "Program": function() { + var scope = context.getScope(); + findVariablesInScope(scope); + + // both Node.js and Modules have an extra scope + if (context.ecmaFeatures.globalReturn || context.ecmaFeatures.modules) { + findVariablesInScope(scope.childScopes[0]); + } + } }; -}; \ No newline at end of file + + if (context.ecmaFeatures.blockBindings) { + ruleDefinition.BlockStatement = ruleDefinition.SwitchStatement = findVariables; + + ruleDefinition.ArrowFunctionExpression = function(node) { + if (node.body.type !== "BlockStatement") { + findVariables(node); + } + }; + } else { + ruleDefinition.FunctionExpression = ruleDefinition.FunctionDeclaration = ruleDefinition.ArrowFunctionExpression = findVariables; + } + + return ruleDefinition; +}; + +module.exports.schema = [ + { + 'enum': ['nofunc', null] + }, + { + 'type': 'object', + 'properties': { + 'samescope': { + 'type': 'boolean' + } + } + } +]; \ No newline at end of file diff --git a/package.json b/package.json index 0164464..d63c1fe 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", "drip": "^1.4.0", - "eslint": "^0.24.0", + "eslint": "^1.10.3", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", @@ -60,4 +60,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} +} \ No newline at end of file diff --git a/test/lint_rules/array_spacing.js b/test/lint_rules/array_spacing.js index ec19b5e..bfacd01 100644 --- a/test/lint_rules/array_spacing.js +++ b/test/lint_rules/array_spacing.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ '[1, 2, 3]' diff --git a/test/lint_rules/array_spacing_chars.js b/test/lint_rules/array_spacing_chars.js index 194f6b7..65def35 100644 --- a/test/lint_rules/array_spacing_chars.js +++ b/test/lint_rules/array_spacing_chars.js @@ -3,13 +3,15 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); var STR_ERROR = 'Array items should be separated by exactly one space:'; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ '[1, 2, 3]', diff --git a/test/lint_rules/catch_arg_name.js b/test/lint_rules/catch_arg_name.js index bb3a06f..5ebf0b3 100644 --- a/test/lint_rules/catch_arg_name.js +++ b/test/lint_rules/catch_arg_name.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'try{}catch(e){}' diff --git a/test/lint_rules/catch_format.js b/test/lint_rules/catch_format.js index db256a1..72a7832 100644 --- a/test/lint_rules/catch_format.js +++ b/test/lint_rules/catch_format.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'try{}catch(e){\n}' diff --git a/test/lint_rules/dot_notation.js b/test/lint_rules/dot_notation.js index f36f919..52b60b1 100644 --- a/test/lint_rules/dot_notation.js +++ b/test/lint_rules/dot_notation.js @@ -5,8 +5,9 @@ var base = require('../../lib/base.js'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); var validRules = [ 'document["some-prop"];' @@ -19,8 +20,9 @@ _.forEach( } ); -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: validRules, diff --git a/test/lint_rules/format_args.js b/test/lint_rules/format_args.js index f2ff31b..f080855 100644 --- a/test/lint_rules/format_args.js +++ b/test/lint_rules/format_args.js @@ -3,8 +3,9 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); /* alert({}, 1); alert(function() {}, 1); @@ -39,8 +40,9 @@ alert(function() { alert(function() {alert('foo');}, 1); alert({x: 1}, 1); */ -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'alert();', diff --git a/test/lint_rules/format_constants.js b/test/lint_rules/format_constants.js index a20deb9..9350d0a 100644 --- a/test/lint_rules/format_constants.js +++ b/test/lint_rules/format_constants.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var FOO1 = \'\';\n\nvar FOO2 = \'\';' diff --git a/test/lint_rules/format_multiline_vars.js b/test/lint_rules/format_multiline_vars.js index 826181f..52099c4 100644 --- a/test/lint_rules/format_multiline_vars.js +++ b/test/lint_rules/format_multiline_vars.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var FOO1;', diff --git a/test/lint_rules/liferay_language_get.js b/test/lint_rules/liferay_language_get.js index a1797f5..059d416 100644 --- a/test/lint_rules/liferay_language_get.js +++ b/test/lint_rules/liferay_language_get.js @@ -3,8 +3,9 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); var invalidTests = ['1', 'function(){}', '/f/', 'new Date()', 'foo'].map( function(item, index) { @@ -15,8 +16,9 @@ var invalidTests = ['1', 'function(){}', '/f/', 'new Date()', 'foo'].map( } ); -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'Liferay.Language.get("foo")', diff --git a/test/lint_rules/liferay_provide_format.js b/test/lint_rules/liferay_provide_format.js index 32374f5..c98ca2e 100644 --- a/test/lint_rules/liferay_provide_format.js +++ b/test/lint_rules/liferay_provide_format.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'Liferay.provide(window, "foo", function(){}, ["dep"])', diff --git a/test/lint_rules/multiple_vars.js b/test/lint_rules/multiple_vars.js index 2468e37..f0e07b5 100644 --- a/test/lint_rules/multiple_vars.js +++ b/test/lint_rules/multiple_vars.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var x = 1;\nvar y = 2;', diff --git a/test/lint_rules/no_extra_semi.js b/test/lint_rules/no_extra_semi.js index 8ae7322..e1d4b41 100644 --- a/test/lint_rules/no_extra_semi.js +++ b/test/lint_rules/no_extra_semi.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ ';(function(){});' diff --git a/test/lint_rules/no_is_prefix.js b/test/lint_rules/no_is_prefix.js index da9dccf..23bf431 100644 --- a/test/lint_rules/no_is_prefix.js +++ b/test/lint_rules/no_is_prefix.js @@ -3,13 +3,15 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); var STR_ERROR = 'Variable/property names should not start with is*: '; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var isString = A.Lang.isString;', diff --git a/test/lint_rules/no_undef.js b/test/lint_rules/no_undef.js index 5b63ff5..d0d8730 100644 --- a/test/lint_rules/no_undef.js +++ b/test/lint_rules/no_undef.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ '_PN_foo()', diff --git a/test/lint_rules/no_unused_vars.js b/test/lint_rules/no_unused_vars.js index 84361c1..3b8f6d2 100644 --- a/test/lint_rules/no_unused_vars.js +++ b/test/lint_rules/no_unused_vars.js @@ -3,31 +3,33 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -var args = [2, {'jsp': true}]; +var ruleTester = new RuleTester(); -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var options = [{'jsp': true}]; + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var _PN_xyz = 1;', { code: '(function(){ var _PN_xyz = function(){}; });', - args: args + options: options }, { code: '(function(){ function _PN_xyz(){} })', - args: args + options: options }, ], invalid: [ { code: '(function(){ var _PN_xyz = 1; });', - errors: [ { message: '_PN_xyz is defined but never used' } ], - args: args + errors: [ { message: '"_PN_xyz" is defined but never used' } ], + options: options } ] } diff --git a/test/lint_rules/no_use_before_define.js b/test/lint_rules/no_use_before_define.js index 2eacaa3..9e6deb6 100644 --- a/test/lint_rules/no_use_before_define.js +++ b/test/lint_rules/no_use_before_define.js @@ -3,26 +3,59 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ "var a=10; alert(a);", "function b(a) { alert(a); }", "Object.hasOwnProperty.call(a);", "function a() { alert(arguments);}", - { code: "a(); function a() { alert(arguments); }", args: [1, {'nofunc': true}] }, - { code: "function a() { alert(b); } function b() { alert(arguments); }", args: [1, {'samescope': true}] } + { code: "(() => { var a = 42; alert(a); })();", ecmaFeatures: {arrowFunctions: true} }, + { code: "a(); function a() { alert(arguments); }", options: ['nofunc'] }, + { code: "function a() { alert(b); } function b() { alert(arguments); }", options: [null, {'samescope': true}] }, + { code: "a(); try { throw new Error() } catch (a) {}" }, + + // Block level bindings + { code: "\"use strict\"; a(); { function a() {} }", ecmaFeatures: { blockBindings: true } }, + { code: "\"use strict\"; { a(); function a() {} }", options: ["nofunc"], ecmaFeatures: { blockBindings: true } }, + { code: "switch (foo) { case 1: { a(); } default: { let a; }}", ecmaFeatures: { blockBindings: true }}, + { code: "a(); { let a = function () {}; }", ecmaFeatures: { blockBindings: true } }, + { code: "var b = (a) => { return a + 1; }; var a = 1;", ecmaFeatures: { arrowFunctions: true, blockBindings: true } } + ], invalid: [ - { code: "a++; var a=19;", errors: [{ message: "a was used before it was defined"}] }, - { code: "a(); var a=function() {};", errors: [{ message: "a was used before it was defined"}] }, - { code: "alert(a[1]); var a=[1,3];", errors: [{ message: "a was used before it was defined"}] }, - { code: "a(); function a() { alert(b); var b=10; a(); }", errors: [{ message: "a was used before it was defined"}, { message: "b was used before it was defined"}] }, - { code: "a(); var a=function() {};", args: [1, "nofunc"], errors: [{ message: "a was used before it was defined"}] } + { code: "a++; var a=19;", ecmaFeatures: { modules: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "a++; var a=19;", ecmaFeatures: { globalReturn: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "a++; var a=19;", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "a(); var a=function() {};", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "alert(a[1]); var a=[1,3];", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "a(); function a() { alert(b); var b=10; a(); }", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}, { message: "\"b\" was used before it was defined", type: "Identifier"}] }, + { code: "a(); var a=function() {};", options: [ "nofunc"], errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, + { code: "(() => { alert(a); var a = 42; })();", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "(() => a())(); function a() { }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "\"use strict\"; a(); { function a() {} }", errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "a(); try { throw new Error() } catch (foo) {var a;}", errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "var f = () => a; var a;", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + + // Block-level bindings + { code: "a++; { var a; }", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "\"use strict\"; { a(); function a() {} }", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "{a; let a = 1}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]}, + { code: "switch (foo) { case 1: a();\n default: \n let a;}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]}, + { code: "var f = () => a; var a;", ecmaFeatures: { arrowFunctions: true, blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, + { code: "if (true) { function foo() { a; } let a;}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]} + + // { code: "a++; var a=19;", errors: [{ message: '"a" was used before it was defined'}] }, + // { code: 'a(); var a=function() {};', errors: [{ message: '"a" was used before it was defined'}] }, + // { code: 'alert(a[1]); var a=[1,3];', errors: [{ message: '"a" was used before it was defined'}] }, + // { code: 'a(); function a() { alert(b); var b=10; a(); }', errors: [{ message: '"a" was used before it was defined'}, { message: '"b" was used before it was defined'}] }, + // { code: "a(); var a=function() {};", options: ["nofunc"], errors: [{ message: '"a" was used before it was defined'}] } ] } ); \ No newline at end of file diff --git a/test/lint_rules/sort_constants.js b/test/lint_rules/sort_constants.js index 9eb4295..fa690d9 100644 --- a/test/lint_rules/sort_constants.js +++ b/test/lint_rules/sort_constants.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var ABC = 123;\n\nvar DEF = 456;', diff --git a/test/lint_rules/sort_props.js b/test/lint_rules/sort_props.js index 22d79b6..9984a05 100644 --- a/test/lint_rules/sort_props.js +++ b/test/lint_rules/sort_props.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ '({init: function(){}, initializer: function(){}, renderUI: function(){}, bindUI: function(){}, syncUI: function(){}, destructor: function(){}})', @@ -19,11 +21,11 @@ eslintTester.addRuleTest( '({ ATTRS: {a: 1,\nb: 2,}})', { code: '({initString: 1, initsTriangle: 2})', - args: [2, {'casesensitive': true}] + options: [{'casesensitive': true}] }, { code: '({initsTriangle: 1, initString: 2})', - args: [2, {'casesensitive': false}] + options: [{'casesensitive': false}] } ], diff --git a/test/lint_rules/sort_requires.js b/test/lint_rules/sort_requires.js index b89bd82..fb1d75f 100644 --- a/test/lint_rules/sort_requires.js +++ b/test/lint_rules/sort_requires.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ '({requires: []})', diff --git a/test/lint_rules/sort_vars.js b/test/lint_rules/sort_vars.js index 55ab366..0dd9dce 100644 --- a/test/lint_rules/sort_vars.js +++ b/test/lint_rules/sort_vars.js @@ -3,11 +3,13 @@ var path = require('path'); var lint = require('../../lib/lint'); var linter = lint.linter; -var ESLintTester = require('eslint-tester'); -var eslintTester = new ESLintTester(linter); +var RuleTester = lint.eslint.RuleTester; -eslintTester.addRuleTest( - path.resolve(__dirname, '../', '../', 'lib/lint_rules/' + path.basename(__filename)), +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ 'var xyz = 123;', From a0139b053de9d97ba240ae145fb155d211b17524 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 17 Feb 2016 14:04:35 -0800 Subject: [PATCH 010/153] Initial update of eslint to 2.1.0 --- lib/eslint_config.js | 4 +- lib/lint_rules/no_undef.js | 10 +- lib/lint_rules/no_unused_vars.js | 12 +- lib/lint_rules/no_use_before_define.js | 168 ++++++++---------------- package.json | 2 +- test/lint_rules/no_undef.js | 2 +- test/lint_rules/no_unused_vars.js | 2 +- test/lint_rules/no_use_before_define.js | 46 +------ 8 files changed, 78 insertions(+), 168 deletions(-) diff --git a/lib/eslint_config.js b/lib/eslint_config.js index 6c8c7e6..cc4a90d 100644 --- a/lib/eslint_config.js +++ b/lib/eslint_config.js @@ -41,7 +41,7 @@ module.exports = { 'csf-no-extra-semi': 2, 'csf-no-is-prefix': 2, 'csf-no-unused-vars': 2, - 'csf-no-use-before-define': [2, null, {'samescope': true}], + 'csf-no-use-before-define': [2, {'functions': true, 'classes': true, 'samescope': true}], 'csf-sort-constants': 2, 'csf-sort-props': 2, 'csf-sort-requires': 2, @@ -153,7 +153,7 @@ module.exports = { 'no-unreachable': 2, 'no-unused-expressions': 2, 'no-unused-vars': [2, {'vars': 'local', 'args': 'none'}], - 'no-use-before-define': 0, + 'no-use-before-define': [0], 'no-var': 0, 'no-void': 0, 'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }], diff --git a/lib/lint_rules/no_undef.js b/lib/lint_rules/no_undef.js index e6dbae2..3703658 100644 --- a/lib/lint_rules/no_undef.js +++ b/lib/lint_rules/no_undef.js @@ -4,13 +4,13 @@ var base = require('../base'); var stubs = base.stubs; module.exports = function(context) { - var noUndef = require('../../node_modules/eslint/lib/rules/no-undef'); + var noUndef = require('eslint/lib/rules/no-undef'); var collectedReport = []; var mockContext = { - report: function() { - collectedReport.push(arguments); + report: function(obj) { + collectedReport.push(obj); } }; @@ -22,10 +22,10 @@ module.exports = function(context) { collectedReport.forEach( function(item, index) { - var name = item[0].name; + var name = item.node.name; if (!stubs[name] && name.indexOf('_PN_') !== 0) { - context.report.apply(context, item); + context.report(item); } } ); diff --git a/lib/lint_rules/no_unused_vars.js b/lib/lint_rules/no_unused_vars.js index 31920f4..ac64091 100644 --- a/lib/lint_rules/no_unused_vars.js +++ b/lib/lint_rules/no_unused_vars.js @@ -17,13 +17,13 @@ module.exports = function(context) { var options = context.options; if (options.length && options[0].jsp === true) { - var noUnused = require('../../node_modules/eslint/lib/rules/no-unused-vars'); + var noUnused = require('eslint/lib/rules/no-unused-vars'); var collectedReport = []; var mockContext = { - report: function() { - collectedReport.push(arguments); + report: function(obj) { + collectedReport.push(obj); }, options: [{'vars': 'local', 'args': 'none'}] }; @@ -33,9 +33,11 @@ module.exports = function(context) { lintRules['Program:exit'] = function(node) { noUnused(mockContext)['Program:exit'](node); + // console.log(collectedReport); + collectedReport.forEach( function(item, index) { - var declaration = item[0]; + var declaration = item.node; var name = declaration.name; var namespacedVar = name.indexOf(portletNS) === 0; @@ -56,7 +58,7 @@ module.exports = function(context) { } if (!stubs[name] && !namespacedVar || (namespacedVar && !namespacedFn)) { - context.report.apply(context, item); + context.report(item); } } ); diff --git a/lib/lint_rules/no_use_before_define.js b/lib/lint_rules/no_use_before_define.js index 694602f..0d184d9 100644 --- a/lib/lint_rules/no_use_before_define.js +++ b/lib/lint_rules/no_use_before_define.js @@ -1,119 +1,65 @@ -/** - * @fileoverview Rule to flag use of variables before they are defined - * @author Ilya Volodin - * @copyright 2013 Ilya Volodin. All rights reserved. - */ +var _ = require('lodash'); -"use strict"; +var base = require('../base'); +var stubs = base.stubs; -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ +module.exports = function(context) { + var noUse = require('eslint/lib/rules/no-use-before-define'); -var astUtils = require("eslint/lib/ast-utils"); + var collectedReport = []; -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ + var options = context.options; -var NO_FUNC = "nofunc"; + var sameScope = false; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ + if (_.isPlainObject(options[0])) { + sameScope = options[0].samescope; -module.exports = function(context) { + options[0] = _.omit(options[0], 'samescope'); + } + + var mockContext = { + report: function(obj) { + var report = true; + + if (sameScope) { + var scope = mockContext.getScope(); + + scope.references.forEach( + function(reference) { + if (reference.identifier !== obj.node) { + return; + } + + var variable = reference.resolved; + + report = reference.from.variableScope === variable.scope; + } + ); + } + + if (report) { + collectedReport.push(obj); + } + } + }; + + _.defaults(mockContext, context); + + var defaultRule = noUse(mockContext); + + return _.defaults( + { + 'Program:exit': function(node) { + defaultRule['Program:exit'](node); - /** - * Finds and validates all variables in a given scope. - * @param {Scope} scope The scope object. - * @returns {void} - * @private - */ - function findVariablesInScope(scope) { - var typeOption = context.options[0]; - var configuration = context.options[1] || {}; - var scopeOption = configuration.samescope; - - /** - * Report the node - * @param {object} reference reference object - * @param {ASTNode} declaration node to evaluate - * @returns {void} - * @private - */ - function checkLocationAndReport(reference, declaration) { - if ((typeOption !== NO_FUNC || declaration.defs[0].type !== "FunctionName") && (!scopeOption || reference.from.variableScope === declaration.scope)) { - if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) { - context.report(reference.identifier, "\"{{a}}\" was used before it was defined", {a: reference.identifier.name}); - } - } - } - - scope.references.forEach(function(reference) { - // if the reference is resolved check for declaration location - // if not, it could be function invocation, try to find manually - if (reference.resolved && reference.resolved.identifiers.length > 0) { - checkLocationAndReport(reference, reference.resolved); - } else { - var declaration = astUtils.getVariableByName(scope, reference.identifier.name); - // if there're no identifiers, this is a global environment variable - if (declaration && declaration.identifiers.length !== 0) { - checkLocationAndReport(reference, declaration); - } - } - }); - } - - - /** - * Validates variables inside of a node's scope. - * @param {ASTNode} node The node to check. - * @returns {void} - * @private - */ - function findVariables() { - var scope = context.getScope(); - findVariablesInScope(scope); - } - - var ruleDefinition = { - "Program": function() { - var scope = context.getScope(); - findVariablesInScope(scope); - - // both Node.js and Modules have an extra scope - if (context.ecmaFeatures.globalReturn || context.ecmaFeatures.modules) { - findVariablesInScope(scope.childScopes[0]); - } - } - }; - - if (context.ecmaFeatures.blockBindings) { - ruleDefinition.BlockStatement = ruleDefinition.SwitchStatement = findVariables; - - ruleDefinition.ArrowFunctionExpression = function(node) { - if (node.body.type !== "BlockStatement") { - findVariables(node); - } - }; - } else { - ruleDefinition.FunctionExpression = ruleDefinition.FunctionDeclaration = ruleDefinition.ArrowFunctionExpression = findVariables; - } - - return ruleDefinition; -}; - -module.exports.schema = [ - { - 'enum': ['nofunc', null] - }, - { - 'type': 'object', - 'properties': { - 'samescope': { - 'type': 'boolean' - } - } - } -]; \ No newline at end of file + collectedReport.forEach( + function(item, index) { + context.report(item); + } + ); + } + }, + defaultRule + ); +}; \ No newline at end of file diff --git a/package.json b/package.json index d63c1fe..1d7667f 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", "drip": "^1.4.0", - "eslint": "^1.10.3", + "eslint": "^2.1.0", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", diff --git a/test/lint_rules/no_undef.js b/test/lint_rules/no_undef.js index d0d8730..bde49ce 100644 --- a/test/lint_rules/no_undef.js +++ b/test/lint_rules/no_undef.js @@ -21,7 +21,7 @@ ruleTester.run( invalid: [ { code: 'var a = b;', - errors: [ { message: '"b" is not defined.' } ] + errors: [ { message: "'b' is not defined." } ] } ] } diff --git a/test/lint_rules/no_unused_vars.js b/test/lint_rules/no_unused_vars.js index 3b8f6d2..4b4412b 100644 --- a/test/lint_rules/no_unused_vars.js +++ b/test/lint_rules/no_unused_vars.js @@ -28,7 +28,7 @@ ruleTester.run( invalid: [ { code: '(function(){ var _PN_xyz = 1; });', - errors: [ { message: '"_PN_xyz" is defined but never used' } ], + errors: [ { message: "'_PN_xyz' is defined but never used" } ], options: options } ] diff --git a/test/lint_rules/no_use_before_define.js b/test/lint_rules/no_use_before_define.js index 9e6deb6..7b18fca 100644 --- a/test/lint_rules/no_use_before_define.js +++ b/test/lint_rules/no_use_before_define.js @@ -12,50 +12,12 @@ ruleTester.run( require('../../lib/lint_rules/' + path.basename(__filename)), { valid: [ - "var a=10; alert(a);", - "function b(a) { alert(a); }", - "Object.hasOwnProperty.call(a);", - "function a() { alert(arguments);}", - { code: "(() => { var a = 42; alert(a); })();", ecmaFeatures: {arrowFunctions: true} }, - { code: "a(); function a() { alert(arguments); }", options: ['nofunc'] }, - { code: "function a() { alert(b); } function b() { alert(arguments); }", options: [null, {'samescope': true}] }, - { code: "a(); try { throw new Error() } catch (a) {}" }, - - // Block level bindings - { code: "\"use strict\"; a(); { function a() {} }", ecmaFeatures: { blockBindings: true } }, - { code: "\"use strict\"; { a(); function a() {} }", options: ["nofunc"], ecmaFeatures: { blockBindings: true } }, - { code: "switch (foo) { case 1: { a(); } default: { let a; }}", ecmaFeatures: { blockBindings: true }}, - { code: "a(); { let a = function () {}; }", ecmaFeatures: { blockBindings: true } }, - { code: "var b = (a) => { return a + 1; }; var a = 1;", ecmaFeatures: { arrowFunctions: true, blockBindings: true } } - + { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': true}] } ], invalid: [ - { code: "a++; var a=19;", ecmaFeatures: { modules: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "a++; var a=19;", ecmaFeatures: { globalReturn: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "a++; var a=19;", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "a(); var a=function() {};", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "alert(a[1]); var a=[1,3];", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "a(); function a() { alert(b); var b=10; a(); }", errors: [{ message: '"a" was used before it was defined', type: "Identifier"}, { message: "\"b\" was used before it was defined", type: "Identifier"}] }, - { code: "a(); var a=function() {};", options: [ "nofunc"], errors: [{ message: '"a" was used before it was defined', type: "Identifier"}] }, - { code: "(() => { alert(a); var a = 42; })();", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "(() => a())(); function a() { }", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "\"use strict\"; a(); { function a() {} }", errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "a(); try { throw new Error() } catch (foo) {var a;}", errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "var f = () => a; var a;", ecmaFeatures: { arrowFunctions: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - - // Block-level bindings - { code: "a++; { var a; }", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "\"use strict\"; { a(); function a() {} }", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "{a; let a = 1}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]}, - { code: "switch (foo) { case 1: a();\n default: \n let a;}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]}, - { code: "var f = () => a; var a;", ecmaFeatures: { arrowFunctions: true, blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }] }, - { code: "if (true) { function foo() { a; } let a;}", ecmaFeatures: { blockBindings: true }, errors: [{ message: '"a" was used before it was defined', type: "Identifier" }]} - - // { code: "a++; var a=19;", errors: [{ message: '"a" was used before it was defined'}] }, - // { code: 'a(); var a=function() {};', errors: [{ message: '"a" was used before it was defined'}] }, - // { code: 'alert(a[1]); var a=[1,3];', errors: [{ message: '"a" was used before it was defined'}] }, - // { code: 'a(); function a() { alert(b); var b=10; a(); }', errors: [{ message: '"a" was used before it was defined'}, { message: '"b" was used before it was defined'}] }, - // { code: "a(); var a=function() {};", options: ["nofunc"], errors: [{ message: '"a" was used before it was defined'}] } + { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': false}], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] }, + { code: "function a() { alert(b); } var b = 1;", options: ['nofunc'], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] }, + { code: "function a() { alert(b); var b = 1; }", options: [{'samescope': true}], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] } ] } ); \ No newline at end of file From 91fe8176af90fc77a094751955cb699f7ff3bce2 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 06:21:53 -0800 Subject: [PATCH 011/153] Update ESLint to support React/ES6 rules --- lib/eslint_config.js | 97 ++++++++++++++++++++++++++++++++++++++++---- lib/lint.js | 6 ++- 2 files changed, 94 insertions(+), 9 deletions(-) diff --git a/lib/eslint_config.js b/lib/eslint_config.js index cc4a90d..812408e 100644 --- a/lib/eslint_config.js +++ b/lib/eslint_config.js @@ -3,9 +3,23 @@ module.exports = { 'amd': false, 'browser': true, 'mocha': true, - 'node': true + 'node': true, + 'jest': true, }, + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module', + 'ecmaFeatures': { + 'experimentalObjectRestSpread': true, + 'jsx': true + } + }, + + 'plugins': [ + 'react' + ], + 'globals': { 'alert': true, 'AUI': true, @@ -19,6 +33,9 @@ module.exports = { }, 'rules': { + 'jsx-uses-react': 2, + 'jsx-uses-vars': 2, + 'csf-liferay-language-get': 2, 'csf-liferay-provide-format': 2, 'block-scoped-var': 2, @@ -85,7 +102,7 @@ module.exports = { 'no-else-return': 2, 'no-empty': 0, 'no-empty-character-class': 2, - 'no-empty-label': 2, + 'no-labels': 2, 'no-eq-null': 0, 'no-eval': 2, 'no-ex-assign': 2, @@ -158,7 +175,7 @@ module.exports = { 'no-void': 0, 'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }], 'no-with': 2, - 'no-extra-parens': 2, + // 'no-extra-parens': 2, 'one-var': 0, 'operator-assignment': [2, 'always'], 'padded-blocks': 0, @@ -168,16 +185,17 @@ module.exports = { 'semi': [2, 'always'], 'semi-spacing': [2, {before: false, after: true}], 'sort-vars': [2, {ignoreCase: true}], - 'space-after-keywords': [2, 'always'], + 'keyword-spacing': [2, {before: true, after: true}], 'space-before-blocks': [2, 'always'], 'space-before-function-paren': [2, 'never'], - 'byobject-curly-spacing': [0, 'never'], - 'array-bracket-spacing': [0, 'never'], + 'object-curly-spacing': [2, 'never'], + 'array-bracket-spacing': [2, 'never'], 'space-in-parens': [2, 'never'], 'space-infix-ops': 2, - 'space-return-throw-case': 2, 'space-unary-ops': [1, {'words': true, 'nonwords': false}], 'spaced-comment': [2, 'always'], + 'template-curly-spacing': [2, 'never'], + 'no-self-assign': 2, 'strict': 0, 'use-isnan': 2, 'valid-jsdoc': 0, @@ -185,6 +203,69 @@ module.exports = { 'vars-on-top': 0, 'wrap-iife': 0, 'wrap-regex': 0, - 'yoda': 2 + 'yoda': 2, + + // Investigate + 'jsx-quotes': 0, + 'no-continue': 0, + 'no-invalid-this': 0, + 'no-magic-numbers': 0, + 'no-implicit-globals': 0, + 'no-negated-condition': 0, + 'no-restricted-syntax': 0, + + // Need conditional parsing if ES6 is enabled + 'arrow-body-style': 0, + 'arrow-parens': 0, + 'object-shorthand': 0, + 'prefer-arrow-callback': 0, + 'no-new-symbol': 2, + 'prefer-const': 0, + 'prefer-rest-params': 0, + 'prefer-spread': 0, + 'prefer-template': 0, + + 'accessor-pairs': 0, + 'array-callback-return': 2, + 'arrow-spacing': [2, {before: true, after: true}], + 'block-spacing': 0, + 'callback-return': 0, + 'computed-property-spacing': [2, 'never'], + 'constructor-super': 2, + 'global-require': 2, + 'id-blacklist': 0, + 'id-length': 0, + 'id-match': 0, + 'init-declarations': 0, + 'linebreak-style': [2, 'unix'], + 'lines-around-comment': [2, { 'beforeBlockComment': true, 'afterBlockComment': true, 'beforeLineComment': true, 'afterLineComment': true }], + 'newline-per-chained-call': 0, + 'no-case-declarations': 2, + 'no-class-assign': 2, + 'no-confusing-arrow': 2, + 'no-const-assign': 2, + 'no-dupe-class-members': 2, + 'no-empty-function': 0, + 'no-empty-pattern': 2, + 'no-extra-label': 2, + 'no-implicit-coercion': [2, {allow: ['!!', '*', '+']}], + 'no-restricted-imports': 0, + 'no-this-before-super': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': 2, + 'no-unused-labels': 0, + 'no-useless-call': 2, + 'no-useless-concat': 2, + 'no-useless-constructor': 2, + 'no-whitespace-before-property': 2, + 'object-curly-spacing': [2, 'never'], + 'one-var-declaration-per-line': 0, + 'operator-linebreak': [2, 'after'], + 'prefer-reflect': 0, + 'require-jsdoc': 0, + 'require-yield': 0, + 'sort-imports': [0, { ignoreCase: true }], + 'yield-star-spacing': 0 } }; \ No newline at end of file diff --git a/lib/lint.js b/lib/lint.js index b9052c3..630b8e1 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -6,6 +6,10 @@ var path = require('path'); var customRules = {}; +var reactRules = require('eslint-plugin-react').rules; + +_.defaults(customRules, reactRules); + var convertNameToRuleId = function(item) { var baseName = path.basename(item, '.js'); @@ -47,7 +51,7 @@ module.exports = function(contents, file, config) { } ); - eslint.linter.defineRules(customRules); + // eslint.linter.defineRules(customRules); return runLinter(contents, file, customRules, config); }; From d5a4c96d6810bf76bd46e8aa32332feef633514b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 06:22:48 -0800 Subject: [PATCH 012/153] Update constants reference checking to be more robust --- lib/lint_rules/sort_constants.js | 37 +++++++++++++++++++++++++++++-- test/lint_rules/sort_constants.js | 18 +++++++++------ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/lint_rules/sort_constants.js b/lib/lint_rules/sort_constants.js index 07b2566..e773633 100644 --- a/lib/lint_rules/sort_constants.js +++ b/lib/lint_rules/sort_constants.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var base = require('../base'); var utils = require('../rule_utils'); @@ -6,6 +7,32 @@ var sub = require('string-sub'); var REGEX_UNDERSCORE = /_/g; module.exports = function(context) { + // Recursive function for collecting identifiers from node + var getIdentifiers = function(node, obj) { + obj = obj || {}; + + if (node) { + var type = node.type; + + if (type === 'BinaryExpression') { + obj = getIdentifiers(node.left, obj); + obj = getIdentifiers(node.right, obj); + } + else if (type === 'Identifier') { + obj[node.name] = true; + } + else if (type === 'CallExpression') { + obj = getIdentifiers(node.callee, obj); + } + else if (type === 'MemberExpression') { + obj = getIdentifiers(node.object, obj); + obj = getIdentifiers(node.property, obj); + } + } + + return obj; + }; + var checkSort = function(node) { var constants = utils.getConstants(node); @@ -23,9 +50,15 @@ module.exports = function(context) { var diff = utils.getLineDistance(prev, item); if (diff === 2 && prevName.replace(REGEX_UNDERSCORE, '') > itemName.replace(REGEX_UNDERSCORE, '')) { - var re = new RegExp('\\b' + prevConstants.join('|') + '\\b'); + var identifiers = getIdentifiers(item.init); + + var hasReference = prevConstants.some( + function(item, index) { + return identifiers[item]; + } + ); - if (!re.test(context.getSource(item))) { + if (!hasReference) { var message = sub('Sort constants: {0} {1}', prevName, itemName); context.report(prev, message); diff --git a/test/lint_rules/sort_constants.js b/test/lint_rules/sort_constants.js index fa690d9..819dc71 100644 --- a/test/lint_rules/sort_constants.js +++ b/test/lint_rules/sort_constants.js @@ -14,7 +14,9 @@ ruleTester.run( valid: [ 'var ABC = 123;\n\nvar DEF = 456;', 'var DEF = 456;\n\nvar ABC = "FOO" + DEF;', - 'var DEF = 456;\n\nvar GHI = 789;\n\nvar ABC = DEF;' + 'var DEF = 456;\n\nvar GHI = 789;\n\nvar ABC = DEF;', + 'var DEF = 456;\n\nvar ABC = some.method[DEF];', + 'var DEF = function(){};\n\nvar ABC = DEF();' ], invalid: [ @@ -25,13 +27,15 @@ ruleTester.run( { code: 'var DEF = 456;\n\nvar DEF_XYZ = "FOO";\n\nvar ABC = 123;', errors: [ { message: 'Sort constants: DEF_XYZ ABC' } ] + }, + { + code: 'var DEF = 456;\n\nvar ABC = "DEF";', + errors: [ { message: 'Sort constants: DEF ABC' } ] + }, + { + code: 'var DEF = 456;\n\nvar ABC;', + errors: [ { message: 'Sort constants: DEF ABC' } ] } - // , - // Should add in the future - // { - // code: 'var DEF = 456;\n\nvar ABC = "DEF";', - // errors: [ { message: 'Sort constants: DEF ABC' } ] - // }, ] } ); \ No newline at end of file From 78e65fcc635047f3ca5ee138560d4c2fa938caff Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 06:25:25 -0800 Subject: [PATCH 013/153] Add support for checking arrow functions and call expressions --- lib/lint_rules/format_args.js | 9 ++++++--- test/lint_rules/format_args.js | 11 ++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/lint_rules/format_args.js b/lib/lint_rules/format_args.js index 7802b1d..f7f5030 100644 --- a/lib/lint_rules/format_args.js +++ b/lib/lint_rules/format_args.js @@ -36,7 +36,7 @@ module.exports = function(context) { var type = callee.type; - if (type === 'FunctionExpression') { + if (type === 'FunctionExpression' || type === 'ArrowFunctionExpression' || type === 'CallExpression') { lineBounds = getFnExpLines(lineBounds, node); } else if (type === 'MemberExpression') { @@ -58,12 +58,15 @@ module.exports = function(context) { var type = callee.type; - if (type === 'FunctionExpression') { + if (type === 'FunctionExpression' || type === 'ArrowFunctionExpression') { fnName = getAnonymousFnName(fnName); } else if (type === 'MemberExpression') { fnName = getMethodName(callee); } + else if (type === 'CallExpression') { + fnName = callee.callee.name; + } return fnName; }; @@ -160,7 +163,7 @@ module.exports = function(context) { if (type === 'FunctionExpression' && item.body.body.length) { hasNonEmptyFunctionArg = true; } - else if (type === 'ObjectExpression' && item.properties.length) { + else if (type === 'ObjectExpression' && item.properties.length && _.findIndex(item.properties, ['shorthand', true]) === -1) { hasNonEmptyObjectArg = true; } diff --git a/test/lint_rules/format_args.js b/test/lint_rules/format_args.js index f080855..c411a72 100644 --- a/test/lint_rules/format_args.js +++ b/test/lint_rules/format_args.js @@ -50,7 +50,8 @@ ruleTester.run( 'alert(function() {}, 1);', 'alert(\nfunction() {\n},\n1\n);', '(function foo(){\n}());', - '(function(){\n}(\n));' + '(function(){\n}(\n));', + 'alert(\n{\nx: 1\n}\n)(foo);' ], invalid: [ @@ -93,6 +94,14 @@ ruleTester.run( { code: '(function(){\n}(\n{x: 1},2,3\n));', errors: [ { message: 'Args should each be on their own line (args on same line): (...)' } ] + }, + { + code: 'alert({\nx: 1\n})(foo);', + errors: [ { message: 'Args should each be on their own line (args on start line): alert(...)' } ] + }, + { + code: 'alert()(foo, {\nx: 1\n});', + errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] } ] } From 30a93af2cc10f7947a15255ade106f9471dbab68 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 06:26:17 -0800 Subject: [PATCH 014/153] Add support for destructuring assignment --- lib/lint_rules/format_multiline_vars.js | 42 ++++++++++++++++++++--- test/lint_rules/format_multiline_vars.js | 43 ++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/lib/lint_rules/format_multiline_vars.js b/lib/lint_rules/format_multiline_vars.js index db8a5bf..e7a9b86 100644 --- a/lib/lint_rules/format_multiline_vars.js +++ b/lib/lint_rules/format_multiline_vars.js @@ -58,19 +58,51 @@ module.exports = function(context) { var allowedFormat = isSameLine(id, init); if (!allowedFormat) { - if (init.type === 'LogicalExpression') { + var message = 'Variable values should start on the same line as the variable name "{{identifier}}"'; + var info = { + identifier: id.name + }; + + if (init.type === 'LogicalExpression' || init.type === 'JSXElement') { var token = context.getTokenBefore(init); allowedFormat = (token.value === '(' && isSameLine(id, token)); } + else if (id.type === 'ObjectPattern' || id.type === 'ArrayPattern') { + var startToken = context.getFirstToken(id); + var endToken = context.getLastToken(id); + var keywordToken = context.getTokenBefore(id); + + var startOnSameLineAsKeyword = isSameLine(keywordToken, startToken); + var endOnSameLineAsInit = isSameLine(init, endToken); + + allowedFormat = startOnSameLineAsKeyword && endOnSameLineAsInit; + + if (!allowedFormat) { + info = { + startToken: startToken.value, + endToken: endToken.value, + keywordToken: keywordToken.value, + initName: init.name || context.getSourceCode().getText(init) + }; + + if (!startOnSameLineAsKeyword && !endOnSameLineAsInit) { + message = 'Destructured assignments should have "{{startToken}}" on the same line as "{{keywordToken}}" and "{{endToken}}" should be on the same line as "{{initName}}"'; + } + else if (!startOnSameLineAsKeyword) { + message = 'Destructured assignments should have "{{startToken}}" on the same line as "{{keywordToken}}"'; + } + else { + message = 'Destructured assignments should have "{{endToken}}" on the same line as "{{initName}}"'; + } + } + } if (!allowedFormat) { context.report( node, - 'Variable values should start on the same line as the variable name "{{identifier}}"', - { - identifier: id.name - } + message, + info ); } } diff --git a/test/lint_rules/format_multiline_vars.js b/test/lint_rules/format_multiline_vars.js index 52099c4..1cf8a3c 100644 --- a/test/lint_rules/format_multiline_vars.js +++ b/test/lint_rules/format_multiline_vars.js @@ -1,4 +1,5 @@ var path = require('path'); +var sub = require('string-sub'); var lint = require('../../lib/lint'); @@ -7,6 +8,12 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); +var addES6 = function(item, index) { + item.parserOptions = { ecmaVersion: 6 }; + + return item; +}; + ruleTester.run( path.basename(__filename, '.js'), require('../../lib/lint_rules/' + path.basename(__filename)), @@ -22,7 +29,12 @@ ruleTester.run( 'FOO1 = \'something\' +\nLiferay.foo();', 'FOO1 = \'something\' +\nLiferay.foo() + \'foo\';', 'FOO1 = (\nbar && baz\n);' - ], + ].concat( + [ + {code: 'var {\nFOO1,\nFOO2\n} = {FOO1: 1, FOO2: 2};'}, + {code: 'var [\nFOO1,\nFOO2\n] = [1, 2];'}, + ].map(addES6) + ), invalid: [ { @@ -77,6 +89,33 @@ ruleTester.run( code: 'FOO1 =\n(\nbar && baz\n);', errors: [ { message: 'Variable values should start on the same line as the variable name "FOO1"' } ] } - ] + ].concat( + [ + { + code: 'var\n{\nFOO1,\nFOO2\n}\n= {FOO1: 1, FOO2: 2};', + errors: [{ message: sub('Destructured assignments should have "{startToken}" on the same line as "{keywordToken}" and "{endToken}" should be on the same line as "{initName}"', {startToken: '{', keywordToken: 'var', endToken: '}', initName: '{FOO1: 1, FOO2: 2}'}) }] + }, + { + code: 'var\n[\nFOO1,\nFOO2\n]\n= [1, 2];', + errors: [{ message: sub('Destructured assignments should have "{startToken}" on the same line as "{keywordToken}" and "{endToken}" should be on the same line as "{initName}"', {startToken: '[', keywordToken: 'var', endToken: ']', initName: '[1, 2]'}) }] + }, + { + code: 'var\n{\nFOO1,\nFOO2\n}\n= FOO;', + errors: [{ message: sub('Destructured assignments should have "{startToken}" on the same line as "{keywordToken}" and "{endToken}" should be on the same line as "{initName}"', {startToken: '{', keywordToken: 'var', endToken: '}', initName: 'FOO'}) }] + }, + { + code: 'var\n[\nFOO1,\nFOO2\n]\n= FOO;', + errors: [{ message: sub('Destructured assignments should have "{startToken}" on the same line as "{keywordToken}" and "{endToken}" should be on the same line as "{initName}"', {startToken: '[', keywordToken: 'var', endToken: ']', initName: 'FOO'}) }] + }, + { + code: 'var\n{\nFOO1,\nFOO2\n} = FOO;', + errors: [{ message: 'Destructured assignments should have "{" on the same line as "var"' }] + }, + { + code: 'var {\nFOO1,\nFOO2\n}\n= FOO;', + errors: [{ message: 'Destructured assignments should have "}" on the same line as "FOO"' }] + }, + ].map(addES6) + ) } ); \ No newline at end of file From 9b23d53ea63f2e86d5cc5f85e92ce02d019a57e3 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 06:27:53 -0800 Subject: [PATCH 015/153] Add support for handling computed properties and the Object spread operator --- lib/lint_rules/sort_props.js | 228 ++++++++++++++++++++++++---------- test/lint_rules/sort_props.js | 32 ++++- 2 files changed, 189 insertions(+), 71 deletions(-) diff --git a/lib/lint_rules/sort_props.js b/lib/lint_rules/sort_props.js index 10a88c2..e62a6c0 100644 --- a/lib/lint_rules/sort_props.js +++ b/lib/lint_rules/sort_props.js @@ -6,74 +6,156 @@ var sub = require('string-sub'); var ruleUtils = require('../rule_utils'); -var LIFECYCLE_METHODS = { - init: -1100, - initializer: -1000, - renderUI: -900, - bindUI: -800, - syncUI: -700, - destructor: -600 -}; - -var getCacheKey = function() { - return Array.prototype.join.call(arguments, '_'); -}; - -var getPropName = function(obj) { - return obj.name || obj.value; -}; - -var inAttrs = function(parent) { - var insideAttrs = false; - - var grandParent = parent && parent.parent; - - if (grandParent && grandParent.type === 'Property' && grandParent.key.name === 'ATTRS') { - insideAttrs = true; - } - - return insideAttrs; -}; - -var isFunctionExpression = function(obj) { - return obj.type === 'FunctionExpression'; -}; - -var isLifecycle = _.memoize( - function(propName, prevPropName) { - return (LIFECYCLE_METHODS.hasOwnProperty(propName) || LIFECYCLE_METHODS.hasOwnProperty(prevPropName)); - }, - getCacheKey -); - -var isMatchingCase = _.memoize( - function(propName, prevPropName) { - return isUpper(propName) === isUpper(prevPropName); - }, - getCacheKey -); - -var isMatchingType = function(item, prev) { - return isFunctionExpression(prev.value) === isFunctionExpression(item.value); -}; - -var isPrivate = _.memoize( - function(str) { - return _.isString(str) && str.charAt(0) === '_'; - } -); - -var RE_UPPER = /^[^a-z]+$/; - -var isUpper = _.memoize( - function(str) { - return RE_UPPER.test(str); - } -); - -var naturalCompare = ruleUtils.naturalCompare; - module.exports = function(context) { + var LIFECYCLE_METHODS = { + init: -1100, + initializer: -1000, + renderUI: -900, + bindUI: -800, + syncUI: -700, + destructor: -600 + }; + + var getCacheKey = function() { + return Array.prototype.join.call(arguments, '_'); + }; + + // Recursive function for collection node values + // var getVals = function(obj, arr) { + // var type = obj.type; + + // if (type === 'BinaryExpression') { + // arr = getVals(obj.left, arr); + // arr = getVals(obj.right, arr); + // } + // else if (type === 'Literal') { + // arr.push(obj.value); + // } + // else if (type === 'Identifier') { + // arr.push(obj.name); + // } + // else if (type === 'CallExpression') { + // arr = getVals(obj.callee, arr); + // } + // else if (type === 'MemberExpression') { + // arr = getVals(obj.object, arr); + // arr = getVals(obj.property, arr); + // } + + // return arr; + // }; + + // var getPropertyNames = function(node, names) { + // names = names || []; + + // if (node.type === 'MemberExpression') { + // var obj = node.object; + + // if (obj.type === 'Identifier') { + // names.push(obj.name); + // } + // else if (obj.type === 'MemberExpression') { + // names = getPropertyNames(obj, names); + // } + + // names.push(node.property.name); + // } + + // return names; + // }; + + var getPropName = function(obj) { + var propName = ''; + + // propName = getVals(obj, []).join(''); + + var type = obj.type; + + if (type === 'Literal' || type === 'Identifier') { + propName = obj.name || obj.value; + } + else { + propName = context.getSourceCode().getText(obj); + } + + // if (type === 'Literal' || type === 'Identifier') { + // propName = obj.name || obj.value; + // } + // if (type === 'CallExpression') { + // if (obj.callee.type === 'Identifier') { + // propName = obj.callee.name; + // } + // else if (obj.callee.type === 'MemberExpression') { + // propName = getPropertyNames(obj.callee).join('.'); + // } + // } + // else if (type === 'MemberExpression') { + // propName = getPropertyNames(obj).join('.'); + // } + // else if (type === 'BinaryExpression') { + + // console.log(context.getSourceCode().getText(obj)); + // } + + return propName; + }; + + var sourceCode = context.getSourceCode(); + + var getComputedPropertyName = function(obj) { + return sourceCode.getTokenBefore(obj).value + sourceCode.getText(obj) + sourceCode.getTokenAfter(obj).value; + }; + + var inAttrs = function(parent) { + var insideAttrs = false; + + var grandParent = parent && parent.parent; + + if (grandParent && grandParent.type === 'Property' && grandParent.key.name === 'ATTRS') { + insideAttrs = true; + } + + return insideAttrs; + }; + + var isFunctionExpression = function(obj) { + return obj.type === 'FunctionExpression' || obj.type === 'ArrowFunctionExpression'; + }; + + var isLifecycle = _.memoize( + function(propName, prevPropName) { + return (LIFECYCLE_METHODS.hasOwnProperty(propName) || LIFECYCLE_METHODS.hasOwnProperty(prevPropName)); + }, + getCacheKey + ); + + var isMatchingCase = _.memoize( + function(propName, prevPropName) { + return isUpper(propName) === isUpper(prevPropName); + }, + getCacheKey + ); + + var isMatchingType = function(item, prev) { + return isFunctionExpression(prev.value) === isFunctionExpression(item.value); + }; + + var isPrivate = _.memoize( + function(str) { + return _.isString(str) && str.charAt(0) === '_'; + } + ); + + var RE_UPPER = /^[^a-z]+$/; + + var isUpper = _.memoize( + function(str) { + return RE_UPPER.test(str); + } + ); + + var naturalCompare = ruleUtils.naturalCompare; + var configuration = context.options[0] || {}; var caseSensitive = configuration.casesensitive; @@ -134,7 +216,7 @@ module.exports = function(context) { node.properties.forEach( function(item, index, collection) { - if (index > 0) { + if (index > 0 && item.type !== 'ExperimentalSpreadProperty' && prev.type !== 'ExperimentalSpreadProperty') { var key = item.key; var prevKey = prev.key; @@ -146,7 +228,15 @@ module.exports = function(context) { if (needsSort) { var note = isLifecycle(propName, prevPropName) ? ' (Lifecycle methods should come first)' : ''; - var message = sub('Sort properties: {0} {1}{2}', prevPropName, propName, note); + var displayPropName = propName; + var displayPrevPropName = prevPropName; + + if (item.computed) { + displayPropName = getComputedPropertyName(key); + displayPrevPropName = getComputedPropertyName(prevKey); + } + + var message = sub('Sort properties: {0} {1}{2}', displayPrevPropName, displayPropName, note); context.report(item, message); } diff --git a/test/lint_rules/sort_props.js b/test/lint_rules/sort_props.js index 9984a05..c620d63 100644 --- a/test/lint_rules/sort_props.js +++ b/test/lint_rules/sort_props.js @@ -7,6 +7,17 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); +var addES6 = function(item, index) { + item.parserOptions = { + ecmaVersion: 6, + ecmaFeatures: { + experimentalObjectRestSpread: true + } + }; + + return item; +}; + ruleTester.run( path.basename(__filename, '.js'), require('../../lib/lint_rules/' + path.basename(__filename)), @@ -27,7 +38,13 @@ ruleTester.run( code: '({initsTriangle: 1, initString: 2})', options: [{'casesensitive': false}] } - ], + ].concat( + [ + { code: '({[bar]: 1, [foo]: 1})' }, + { code: '({a: 1, [bar()]: 1, [foo]: 1, [obj.bar()]: 1, [obj.foo]: 1, [str + \'other\']: 1 })' }, + { code: '({...baz, bar: 1, foo})' }, + ].map(addES6) + ), invalid: [ { @@ -66,6 +83,17 @@ ruleTester.run( code: '({ ATTRS: {z: 1,\n\nb: {}}})', errors: [ { message: 'Sort properties: z b' } ] } - ] + ].concat( + [ + { + code: '({[foo]: 1, [bar]: 1})', + errors: [ { message: 'Sort properties: [foo] [bar]' } ] + }, + { + code: '({a: 1, [str + \'other\']: 1, [bar()]: 1, [foo]: 1, [obj.bar()]: 1, [obj.foo]: 1 })', + errors: [ { message: 'Sort properties: [str + \'other\'] [bar()]' } ] + }, + ].map(addES6) + ) } ); \ No newline at end of file From df10ce11a682bbbfd863357e5571055022033da5 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 07:28:45 -0800 Subject: [PATCH 016/153] Add support for checking var order in destructured object assignment --- lib/lint_rules/sort_vars.js | 31 ++++++++++++++++++++++++++++++- test/lint_rules/sort_vars.js | 25 +++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/lint_rules/sort_vars.js b/lib/lint_rules/sort_vars.js index fb88a30..268739b 100644 --- a/lib/lint_rules/sort_vars.js +++ b/lib/lint_rules/sort_vars.js @@ -14,11 +14,18 @@ module.exports = function(context) { var variables = []; + var destructuredVars = []; + var findVars = function(node) { if (!REGEX_FOR.test(node.parent.type)) { node.declarations.forEach( function(val, key) { - variables.push(val); + if (val.init && val.init.type === 'Literal') { + variables.push(val); + } + else if (val.id.type === 'ObjectPattern') { + destructuredVars.push(val.id.properties); + } } ); } @@ -47,6 +54,28 @@ module.exports = function(context) { }, variables[0] ); + + destructuredVars.forEach( + function(item, index) { + var destructuredVarGroups = item.reduce( + function(prev, item, index) { + var prevName = prev.key.name; + var curName = item.key.name; + + var result = naturalCompare(curName, prevName, !caseSensitive); + + if (result === -1) { + var message = sub('Sort variables: {0} {1}', prevName, curName); + + context.report(prev, message); + } + + return item; + }, + item[0] + ); + } + ); }, VariableDeclaration: findVars diff --git a/test/lint_rules/sort_vars.js b/test/lint_rules/sort_vars.js index 0dd9dce..758e0bd 100644 --- a/test/lint_rules/sort_vars.js +++ b/test/lint_rules/sort_vars.js @@ -7,6 +7,15 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); +var addES6 = function(item, index) { + item.parserOptions = { + ecmaVersion: 6, + ecmaFeatures: {} + }; + + return item; +}; + ruleTester.run( path.basename(__filename, '.js'), require('../../lib/lint_rules/' + path.basename(__filename)), @@ -18,7 +27,12 @@ ruleTester.run( 'var cde = 123;\nvar def = 123;\n\nvar abc = 456;', 'for (var i = 0; i < 10; i++) {\nvar current = 1;\n}', 'for (var i in obj) {\nvar current = 1;\n}' - ], + ].concat( + [ + { code: 'const {bar, foo} = refs;' }, + { code: 'const [foo, bar] = refs;' } + ].map(addES6) + ), invalid: [ { @@ -29,6 +43,13 @@ ruleTester.run( code: 'var def = 456;\n\nvar def_xyz = "FOO";\nvar abc = 123;', errors: [ { message: 'Sort variables: def_xyz abc' } ] } - ] + ].concat( + [ + { + code: 'const {foo, bar} = refs', + errors: [ { message: 'Sort variables: foo bar' } ] + } + ].map(addES6) + ) } ); \ No newline at end of file From 1f782b23dafe7b50914f5a5977dd84d18f311558 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 07:30:20 -0800 Subject: [PATCH 017/153] Update lint files --- lib/js.js | 2 +- lib/lint.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/js.js b/lib/js.js index 1b06bbe..9aa2c14 100644 --- a/lib/js.js +++ b/lib/js.js @@ -102,7 +102,7 @@ Formatter.JS = Formatter.create( if (lint !== false) { var linter = require('./lint'); - var results = linter(contents, this.file, lint); + var results = linter(contents, this.file, lint)/*.results[0].messages*/; if (results.length) { this._logLintResults(results); diff --git a/lib/lint.js b/lib/lint.js index 630b8e1..aa29a4f 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -24,7 +24,17 @@ var runLinter = function(contents, file, customRules, config) { function(item, index) { var configItem = _.namespace(config, item); + // if (Array.isArray(ESLINT_CONFIG[item])) { + // if (!Array.isArray(configItem)) { + // configItem = []; + // } + + // config[item] = _.union(configItem, ESLINT_CONFIG[item]); + // } + // else { + // } _.defaults(configItem, ESLINT_CONFIG[item]); + } ); } @@ -32,6 +42,14 @@ var runLinter = function(contents, file, customRules, config) { config = ESLINT_CONFIG; } + // var cli = new eslint.CLIEngine({ + // envs: Object.keys(config.env), + // baseConfig: config, + // useEslintrc: false + // }); + + // return cli.executeOnText(contents, file); + return eslint.linter.verify(contents, config, file); }; From e51982dade40f43edad2982f31d13ad5400a7f32 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 07:31:06 -0800 Subject: [PATCH 018/153] Source formatting --- lib/js.js | 2 +- lib/lint.js | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/lib/js.js b/lib/js.js index 9aa2c14..1b06bbe 100644 --- a/lib/js.js +++ b/lib/js.js @@ -102,7 +102,7 @@ Formatter.JS = Formatter.create( if (lint !== false) { var linter = require('./lint'); - var results = linter(contents, this.file, lint)/*.results[0].messages*/; + var results = linter(contents, this.file, lint); if (results.length) { this._logLintResults(results); diff --git a/lib/lint.js b/lib/lint.js index aa29a4f..77a5739 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -24,15 +24,6 @@ var runLinter = function(contents, file, customRules, config) { function(item, index) { var configItem = _.namespace(config, item); - // if (Array.isArray(ESLINT_CONFIG[item])) { - // if (!Array.isArray(configItem)) { - // configItem = []; - // } - - // config[item] = _.union(configItem, ESLINT_CONFIG[item]); - // } - // else { - // } _.defaults(configItem, ESLINT_CONFIG[item]); } @@ -42,14 +33,6 @@ var runLinter = function(contents, file, customRules, config) { config = ESLINT_CONFIG; } - // var cli = new eslint.CLIEngine({ - // envs: Object.keys(config.env), - // baseConfig: config, - // useEslintrc: false - // }); - - // return cli.executeOnText(contents, file); - return eslint.linter.verify(contents, config, file); }; From f5a23e56286a30d33b68fb98d3ff4772b822440d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 8 Mar 2016 07:31:46 -0800 Subject: [PATCH 019/153] Updating eslint and adding eslint-react plugin --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1d7667f..9115f78 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", "drip": "^1.4.0", - "eslint": "^2.1.0", + "eslint": "^2.3.0", + "eslint-plugin-react": "^4.1.0", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", @@ -60,4 +61,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} \ No newline at end of file +} From f9c9138cd701530c4bc103457002c88adab88a88 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 15 Mar 2016 08:39:55 -0700 Subject: [PATCH 020/153] Fix destructured variable check --- lib/lint_rules/sort_vars.js | 14 +++++++++++++- test/lint_rules/sort_vars.js | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/lint_rules/sort_vars.js b/lib/lint_rules/sort_vars.js index 268739b..79e6322 100644 --- a/lib/lint_rules/sort_vars.js +++ b/lib/lint_rules/sort_vars.js @@ -24,7 +24,13 @@ module.exports = function(context) { variables.push(val); } else if (val.id.type === 'ObjectPattern') { - destructuredVars.push(val.id.properties); + var props = val.id.properties.filter( + function(item, index) { + return item.key; + } + ); + + destructuredVars.push(props); } } ); @@ -59,6 +65,12 @@ module.exports = function(context) { function(item, index) { var destructuredVarGroups = item.reduce( function(prev, item, index) { + // if (!prev.key) { + // console.log(context.getSource(prev)); + // } + // if (!item.key) { + // console.log(context.getSource(item), item.type); + // } var prevName = prev.key.name; var curName = item.key.name; diff --git a/test/lint_rules/sort_vars.js b/test/lint_rules/sort_vars.js index 758e0bd..e2be46a 100644 --- a/test/lint_rules/sort_vars.js +++ b/test/lint_rules/sort_vars.js @@ -30,7 +30,9 @@ ruleTester.run( ].concat( [ { code: 'const {bar, foo} = refs;' }, - { code: 'const [foo, bar] = refs;' } + { code: 'const [foo, bar] = refs;' }/*, + Need to add the below as soon as I figure out what to do about es7/babel-eslint, etc + { code: 'const {foo, ...bar} = refs;' }*/ ].map(addES6) ), From 1ae295e36d8d761c4461b3aa8914077adf6a66a4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 15 Mar 2016 08:46:33 -0700 Subject: [PATCH 021/153] _.merge is already recursive --- lib/lint.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/lint.js b/lib/lint.js index 77a5739..1efd032 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -20,14 +20,7 @@ var runLinter = function(contents, file, customRules, config) { eslint.linter.defineRules(customRules); if (_.isObject(config)) { - Object.keys(ESLINT_CONFIG).forEach( - function(item, index) { - var configItem = _.namespace(config, item); - - _.defaults(configItem, ESLINT_CONFIG[item]); - - } - ); + config = _.merge({}, ESLINT_CONFIG, config); } else { config = ESLINT_CONFIG; From 3ed57abafe30847f727142ab4728907ca69cddb0 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 15 Mar 2016 08:50:58 -0700 Subject: [PATCH 022/153] Add babel-eslint as the parser (may revert) --- lib/eslint_config.js | 4 +++- package.json | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/eslint_config.js b/lib/eslint_config.js index 812408e..b575460 100644 --- a/lib/eslint_config.js +++ b/lib/eslint_config.js @@ -7,8 +7,10 @@ module.exports = { 'jest': true, }, + 'parser': 'babel-eslint', + 'parserOptions': { - 'ecmaVersion': 6, + 'ecmaVersion': 7, 'sourceType': 'module', 'ecmaFeatures': { 'experimentalObjectRestSpread': true, diff --git a/package.json b/package.json index 9115f78..b4aa202 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "preferGlobal": "true", "dependencies": { "async": "^1.5.2", + "babel-eslint": "^6.0.0-beta.5", "chalk": "^1.1.1", "cli": "^0.8.0", "cli-color-keywords": "0.0.1", From a81322a8bb37f40d4e745f309a4653f65abdec0d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 15 Mar 2016 08:51:50 -0700 Subject: [PATCH 023/153] Update eslint to 2.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b4aa202..dcc0ccb 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", "drip": "^1.4.0", - "eslint": "^2.3.0", + "eslint": "^2.4.0", "eslint-plugin-react": "^4.1.0", "falafel": "^1.2.0", "getobject": "^0.1.0", From 0a3ec14d622781a33f4f3737560ca43a7ada2699 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 18 Mar 2016 15:06:02 -0700 Subject: [PATCH 024/153] Handle sorting of imported members --- lib/eslint_config.js | 2 +- lib/lint_rules/sort_vars.js | 76 ++++++++++++++++++++++++++---------- test/lint_rules/sort_vars.js | 11 +++++- 3 files changed, 67 insertions(+), 22 deletions(-) diff --git a/lib/eslint_config.js b/lib/eslint_config.js index b575460..2483663 100644 --- a/lib/eslint_config.js +++ b/lib/eslint_config.js @@ -267,7 +267,7 @@ module.exports = { 'prefer-reflect': 0, 'require-jsdoc': 0, 'require-yield': 0, - 'sort-imports': [0, { ignoreCase: true }], + 'sort-imports': [0, { ignoreCase: true, memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'] }], 'yield-star-spacing': 0 } }; \ No newline at end of file diff --git a/lib/lint_rules/sort_vars.js b/lib/lint_rules/sort_vars.js index 79e6322..1edd52a 100644 --- a/lib/lint_rules/sort_vars.js +++ b/lib/lint_rules/sort_vars.js @@ -13,27 +13,43 @@ module.exports = function(context) { var caseSensitive = configuration.casesensitive; var variables = []; - var destructuredVars = []; + var imports = []; var findVars = function(node) { if (!REGEX_FOR.test(node.parent.type)) { - node.declarations.forEach( - function(val, key) { - if (val.init && val.init.type === 'Literal') { - variables.push(val); + var declarations = node.declarations; + var specifiers = node.specifiers; + + if (declarations) { + declarations.forEach( + function(val, key) { + if (val.init && val.init.type === 'Literal') { + variables.push(val); + } + else if (val.id.type === 'ObjectPattern') { + var props = val.id.properties.filter( + function(item, index) { + return item.key; + } + ); + + destructuredVars.push(props); + } } - else if (val.id.type === 'ObjectPattern') { - var props = val.id.properties.filter( - function(item, index) { - return item.key; - } - ); - - destructuredVars.push(props); + ); + } + else { + specifiers = specifiers.filter( + function(item, index) { + return item.type !== 'ImportDefaultSpecifier'; } + ); + + if (specifiers.length > 1) { + imports.push(specifiers); } - ); + } } }; @@ -65,12 +81,6 @@ module.exports = function(context) { function(item, index) { var destructuredVarGroups = item.reduce( function(prev, item, index) { - // if (!prev.key) { - // console.log(context.getSource(prev)); - // } - // if (!item.key) { - // console.log(context.getSource(item), item.type); - // } var prevName = prev.key.name; var curName = item.key.name; @@ -88,8 +98,34 @@ module.exports = function(context) { ); } ); + + imports.forEach( + function(item, index) { + var importGroups = item.reduce( + function(prev, item, index) { + var prevName = prev.local.name; + var curName = item.local.name; + + if (prevName === prev.imported.name && curName === item.imported.name) { + var result = naturalCompare(curName, prevName, !caseSensitive); + + if (result === -1) { + var message = sub('Sort imported members: {0} {1}', prevName, curName); + + context.report(prev, message); + } + } + + return item; + }, + item[0] + ); + } + ); }, + ImportDeclaration: findVars, + VariableDeclaration: findVars }; }; \ No newline at end of file diff --git a/test/lint_rules/sort_vars.js b/test/lint_rules/sort_vars.js index e2be46a..dcdf498 100644 --- a/test/lint_rules/sort_vars.js +++ b/test/lint_rules/sort_vars.js @@ -10,7 +10,8 @@ var ruleTester = new RuleTester(); var addES6 = function(item, index) { item.parserOptions = { ecmaVersion: 6, - ecmaFeatures: {} + ecmaFeatures: {}, + sourceType: 'module' }; return item; @@ -30,6 +31,10 @@ ruleTester.run( ].concat( [ { code: 'const {bar, foo} = refs;' }, + { code: 'import Foo, {bar, baz} from "somefile";' }, + { code: 'import Foo, {bar as doo, baz} from "somefile";' }, + { code: 'import Foo from "somefile";' }, + { code: 'import "somefile";' }, { code: 'const [foo, bar] = refs;' }/*, Need to add the below as soon as I figure out what to do about es7/babel-eslint, etc { code: 'const {foo, ...bar} = refs;' }*/ @@ -50,6 +55,10 @@ ruleTester.run( { code: 'const {foo, bar} = refs', errors: [ { message: 'Sort variables: foo bar' } ] + }, + { + code: 'import Foo, {baz, bar} from "somefile";', + errors: [ { message: 'Sort imported members: baz bar' } ] } ].map(addES6) ) From 6fbb4d99761278fff7b0ea42efbeafb56c299f84 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 22 Mar 2016 14:22:57 -0700 Subject: [PATCH 025/153] I wasn't collecting the references that were being used as arguments to other functions --- lib/lint_rules/sort_constants.js | 2 ++ test/lint_rules/sort_constants.js | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/lint_rules/sort_constants.js b/lib/lint_rules/sort_constants.js index e773633..176a26f 100644 --- a/lib/lint_rules/sort_constants.js +++ b/lib/lint_rules/sort_constants.js @@ -23,6 +23,8 @@ module.exports = function(context) { } else if (type === 'CallExpression') { obj = getIdentifiers(node.callee, obj); + + node.arguments.forEach(_.ary(_.bindRight(getIdentifiers, null, obj), 1)); } else if (type === 'MemberExpression') { obj = getIdentifiers(node.object, obj); diff --git a/test/lint_rules/sort_constants.js b/test/lint_rules/sort_constants.js index 819dc71..f8816be 100644 --- a/test/lint_rules/sort_constants.js +++ b/test/lint_rules/sort_constants.js @@ -16,7 +16,8 @@ ruleTester.run( 'var DEF = 456;\n\nvar ABC = "FOO" + DEF;', 'var DEF = 456;\n\nvar GHI = 789;\n\nvar ABC = DEF;', 'var DEF = 456;\n\nvar ABC = some.method[DEF];', - 'var DEF = function(){};\n\nvar ABC = DEF();' + 'var DEF = function(){};\n\nvar ABC = DEF();', + 'var DEF = function(){};\n\nvar ABC = foo(DEF);' ], invalid: [ From 22398051b0da8cf53d252ecd6e5982b19df0d6d9 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 28 Mar 2016 12:34:49 -0700 Subject: [PATCH 026/153] Moving config files for eslint to config directory --- lib/{eslint_config.js => config/eslint.js} | 3 +-- lib/{eslint_config_jsp.js => config/eslint_jsp.js} | 0 lib/html.js | 2 +- lib/lint.js | 2 +- test/js.js | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) rename lib/{eslint_config.js => config/eslint.js} (99%) rename lib/{eslint_config_jsp.js => config/eslint_jsp.js} (100%) diff --git a/lib/eslint_config.js b/lib/config/eslint.js similarity index 99% rename from lib/eslint_config.js rename to lib/config/eslint.js index 2483663..e5d2bfc 100644 --- a/lib/eslint_config.js +++ b/lib/config/eslint.js @@ -3,8 +3,7 @@ module.exports = { 'amd': false, 'browser': true, 'mocha': true, - 'node': true, - 'jest': true, + 'node': true }, 'parser': 'babel-eslint', diff --git a/lib/eslint_config_jsp.js b/lib/config/eslint_jsp.js similarity index 100% rename from lib/eslint_config_jsp.js rename to lib/config/eslint_jsp.js diff --git a/lib/html.js b/lib/html.js index 09fe7d9..3f871ce 100644 --- a/lib/html.js +++ b/lib/html.js @@ -184,7 +184,7 @@ Formatter.HTML = Formatter.create( formatJs: function(scriptBlocks) { var jsFormatter = new Formatter.JS(this.file, this.logger, this.flags); - var esLintConfig = require('./eslint_config_jsp'); + var esLintConfig = require('./config/eslint_jsp'); jsFormatter.lintLogFilter = this._jsLogFilter.bind(this); diff --git a/lib/lint.js b/lib/lint.js index 1efd032..906dfa9 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -1,6 +1,6 @@ var _ = require('lodash'); var eslint = require('eslint'); -var ESLINT_CONFIG = require('./eslint_config'); +var ESLINT_CONFIG = require('./config/eslint'); var glob = require('glob'); var path = require('path'); diff --git a/test/js.js b/test/js.js index a5db089..c56f0fd 100644 --- a/test/js.js +++ b/test/js.js @@ -243,7 +243,7 @@ describe( function() { 'use strict'; - var esLintConfig = require('../lib/eslint_config'); + var esLintConfig = require('../lib/config/eslint'); var testFilePath = path.join(__dirname, 'fixture', 'test.js'); From b3914bee4fc0f083acf45f3c8c9b54ee9f72c5a4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 28 Mar 2016 15:47:46 -0700 Subject: [PATCH 027/153] Adding ability to define a custom config --- lib/cli.js | 73 ++++++++--- lib/config/eslint.js | 25 +--- lib/config/eslint_es6.js | 32 +++++ lib/formatter.js | 2 + lib/html.js | 5 +- lib/js.js | 4 + lib/lint.js | 8 ++ package.json | 6 +- test/cli.js | 130 ++++++++++++++++++++ test/fixture/config/bad_config/.gitkeep | 0 test/fixture/config/filenames/csf.config.js | 2 + test/fixture/config/flags/csf.config.js | 5 + test/js.js | 80 +++++++++++- 13 files changed, 325 insertions(+), 47 deletions(-) create mode 100644 lib/config/eslint_es6.js create mode 100644 test/fixture/config/bad_config/.gitkeep create mode 100644 test/fixture/config/filenames/csf.config.js create mode 100644 test/fixture/config/flags/csf.config.js diff --git a/lib/cli.js b/lib/cli.js index 9b7a1d4..5a1a7ff 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,5 +1,6 @@ var async = require('async'); var cli = require('cli'); +var cosmiconfig = require('cosmiconfig'); var fs = require('fs'); var path = require('path'); var util = require('util'); @@ -64,27 +65,39 @@ CLI.prototype = _.create( init: function() { var instance = this; - this.emit('init'); - - var series = instance._args.map( - function(file) { - return instance.processFile.bind(instance, file); + cosmiconfig( + 'csf', + { + cwd: instance._cwd, + packageProp: 'csfConfig' } - ); + ).then( + function(obj) { + if (obj) { + var config = obj.config; - if (series.length) { - series.push(instance.checkMeta.bind(instance)); - } + instance._config = config; - if (instance.flags.junit) { - series.push(instance.createReport.bind(instance)); - } + if (config.flags) { + _.merge(instance.flags, config.flags); + } - instance._async.series(series, instance.afterFormat.bind(instance)); + if (!instance.flags.filenames) { + instance._log('Using local config from ', obj.filepath); + } + } - if (!series.length) { - this.onFinish(null, null); - } + instance._start(); + } + ).catch( + function(err) { + if (instance.flags.verbose) { + instance._log('Could not resolve any local config: ', err); + } + + instance._start(); + } + ); }, afterFormat: function(err, results) { @@ -145,6 +158,8 @@ CLI.prototype = _.create( var contents = null; if (formatter) { + formatter._config = this._config; + contents = this.processFileData(data, formatter); this.isMetaCheckNeeded(file); @@ -316,6 +331,32 @@ CLI.prototype = _.create( this._write(file, contents, _.bindRight(this.onWrite, this, file, done)); }, + _start: function() { + var instance = this; + + instance.emit('init'); + + var series = instance._args.map( + function(file) { + return instance.processFile.bind(instance, file); + } + ); + + if (series.length) { + series.push(instance.checkMeta.bind(instance)); + } + + if (instance.flags.junit) { + series.push(instance.createReport.bind(instance)); + } + + instance._async.series(series, instance.afterFormat.bind(instance)); + + if (!series.length) { + this.onFinish(null, null); + } + }, + _metaCheckerPath: './meta' } ); diff --git a/lib/config/eslint.js b/lib/config/eslint.js index e5d2bfc..4cca721 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -9,18 +9,9 @@ module.exports = { 'parser': 'babel-eslint', 'parserOptions': { - 'ecmaVersion': 7, - 'sourceType': 'module', - 'ecmaFeatures': { - 'experimentalObjectRestSpread': true, - 'jsx': true - } + 'ecmaVersion': 5 }, - 'plugins': [ - 'react' - ], - 'globals': { 'alert': true, 'AUI': true, @@ -34,9 +25,6 @@ module.exports = { }, 'rules': { - 'jsx-uses-react': 2, - 'jsx-uses-vars': 2, - 'csf-liferay-language-get': 2, 'csf-liferay-provide-format': 2, 'block-scoped-var': 2, @@ -215,17 +203,6 @@ module.exports = { 'no-negated-condition': 0, 'no-restricted-syntax': 0, - // Need conditional parsing if ES6 is enabled - 'arrow-body-style': 0, - 'arrow-parens': 0, - 'object-shorthand': 0, - 'prefer-arrow-callback': 0, - 'no-new-symbol': 2, - 'prefer-const': 0, - 'prefer-rest-params': 0, - 'prefer-spread': 0, - 'prefer-template': 0, - 'accessor-pairs': 0, 'array-callback-return': 2, 'arrow-spacing': [2, {before: true, after: true}], diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js new file mode 100644 index 0000000..3dbbd84 --- /dev/null +++ b/lib/config/eslint_es6.js @@ -0,0 +1,32 @@ +module.exports = { + 'env': { + 'es6': true + }, + + 'parserOptions': { + 'sourceType': 'module', + 'ecmaFeatures': { + 'experimentalObjectRestSpread': true, + 'jsx': true + } + }, + + 'plugins': [ + 'react' + ], + + 'rules': { + 'jsx-uses-react': 2, + 'jsx-uses-vars': 2, + + 'arrow-body-style': [2, 'as-needed'], + 'arrow-parens': [2, 'as-needed'], + 'object-shorthand': [2, 'always', { 'ignoreConstructors': true }], + 'prefer-arrow-callback': 2, + 'no-new-symbol': 2, + 'prefer-const': 2, + 'prefer-rest-params': 2, + 'prefer-spread': 2, + 'prefer-template': 2 + } +}; \ No newline at end of file diff --git a/lib/formatter.js b/lib/formatter.js index f89c1fe..530961c 100644 --- a/lib/formatter.js +++ b/lib/formatter.js @@ -11,6 +11,8 @@ var RULES = require('./rules'); Formatter.on( 'init', function(instance) { + instance._config = {}; + var ruleInstance = new re(RULES); instance._re = ruleInstance; diff --git a/lib/html.js b/lib/html.js index 3f871ce..ac8901b 100644 --- a/lib/html.js +++ b/lib/html.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var base = require('./base'); var REGEX = require('./regex'); @@ -186,11 +187,13 @@ Formatter.HTML = Formatter.create( var jsFormatter = new Formatter.JS(this.file, this.logger, this.flags); var esLintConfig = require('./config/eslint_jsp'); + var lint = _.merge({}, esLintConfig, _.get(this._config, 'js.lint'), _.get(this._config, 'html.lint.js')); + jsFormatter.lintLogFilter = this._jsLogFilter.bind(this); return scriptBlocks.map( function(item, index) { - return jsFormatter.format(item.contents, esLintConfig); + return jsFormatter.format(item.contents, lint); } ); }, diff --git a/lib/js.js b/lib/js.js index 1b06bbe..11b2184 100644 --- a/lib/js.js +++ b/lib/js.js @@ -102,6 +102,10 @@ Formatter.JS = Formatter.create( if (lint !== false) { var linter = require('./lint'); + lint = _.isObjectLike(lint) ? lint : {}; + + _.merge(lint, _.get(this._config, 'js.lint')); + var results = linter(contents, this.file, lint); if (results.length) { diff --git a/lib/lint.js b/lib/lint.js index 906dfa9..53ad039 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -26,6 +26,14 @@ var runLinter = function(contents, file, customRules, config) { config = ESLINT_CONFIG; } + var ecmaVersion = _.get(config, 'parserOptions.ecmaVersion'); + + if (ecmaVersion > 5) { + var es6Config = require('./config/eslint_es6'); + + _.merge(config, es6Config); + } + return eslint.linter.verify(contents, config, file); }; diff --git a/package.json b/package.json index dcc0ccb..ff68655 100644 --- a/package.json +++ b/package.json @@ -29,14 +29,15 @@ "content-formatter": "^1.1.0", "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", + "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^2.4.0", + "eslint": "^2.5.3", "eslint-plugin-react": "^4.1.0", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", "handlebars": "^4.0.5", - "lodash": "^4.3.0", + "lodash": "^4.6.1", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", "optimist": "^0.6.1", @@ -48,7 +49,6 @@ "chai": "^3.5.0", "chai-string": "^1.1.6", "coveralls": "^2.11.6", - "eslint-tester": "^0.6.0", "gulp": "^3.9.1", "gulp-complexity": "^0.3.0", "gulp-coveralls": "^0.1.3", diff --git a/test/cli.js b/test/cli.js index 56f9794..eed66d9 100644 --- a/test/cli.js +++ b/test/cli.js @@ -628,5 +628,135 @@ describe( cliInstance.init(); } ); + + it( + 'should handle custom config', + function(done) { + sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + + var cliInstance = new cli.CLI( + { + args: ['foo.js'], + cwd: path.join(__dirname, 'fixture/config/flags'), + flags: { + quiet: false + }, + log: sinon.log, + logger: new Logger.constructor() + } + ); + + cliInstance.on( + 'finish', + function() { + assert.isTrue(cliInstance.flags.quiet); + + done(); + } + ); + + cliInstance.init(); + } + ); + + it( + 'should handle custom config misc', + function(done) { + sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + + var log = sandbox.spy(); + + var cliInstance = new cli.CLI( + { + args: ['foo.js'], + cwd: path.join(__dirname, 'fixture/config/filenames'), + flags: { + filenames: true + }, + log: log, + logger: new Logger.constructor() + } + ); + + cliInstance.on( + 'finish', + function() { + assert.isNotTrue(cliInstance.flags.quiet); + assert.isUndefined(log.args[0]); + + done(); + } + ); + + cliInstance.init(); + } + ); + + it( + 'should handle invalid config', + function(done) { + sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + + var log = sandbox.spy(); + + var cliInstance = new cli.CLI( + { + args: ['foo.js'], + cwd: path.join(__dirname, 'fixture/config/bad_config'), + flags: { + verbose: false + }, + log: log, + logger: new Logger.constructor() + } + ); + + cliInstance.on( + 'finish', + function() { + assert.isFalse(cliInstance.flags.verbose); + assert.notStartsWith(log.args[0][0], 'Could not resolve any local config'); + + done(); + } + ); + + cliInstance.init(); + } + ); + + it( + 'should handle invalid config logging', + function(done) { + sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + + var log = sandbox.spy(); + + var cliInstance = new cli.CLI( + { + args: ['foo.js'], + cwd: path.join(__dirname, 'fixture/config/bad_config'), + flags: { + quiet: false, + verbose: true + }, + log: log, + logger: new Logger.constructor() + } + ); + + cliInstance.on( + 'finish', + function() { + assert.isTrue(cliInstance.flags.verbose); + assert.startsWith(log.args[0][0], 'Could not resolve any local config'); + + done(); + } + ); + + cliInstance.init(); + } + ); } ); \ No newline at end of file diff --git a/test/fixture/config/bad_config/.gitkeep b/test/fixture/config/bad_config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/config/filenames/csf.config.js b/test/fixture/config/filenames/csf.config.js new file mode 100644 index 0000000..e180b24 --- /dev/null +++ b/test/fixture/config/filenames/csf.config.js @@ -0,0 +1,2 @@ +module.exports = { +}; \ No newline at end of file diff --git a/test/fixture/config/flags/csf.config.js b/test/fixture/config/flags/csf.config.js new file mode 100644 index 0000000..9e1f489 --- /dev/null +++ b/test/fixture/config/flags/csf.config.js @@ -0,0 +1,5 @@ +module.exports = { + flags: { + quiet: true + } +}; \ No newline at end of file diff --git a/test/js.js b/test/js.js index c56f0fd..a779a64 100644 --- a/test/js.js +++ b/test/js.js @@ -243,6 +243,20 @@ describe( function() { 'use strict'; + var sandbox; + + beforeEach( + function() { + sandbox = sinon.sandbox.create(); + } + ); + + afterEach( + function() { + sandbox.restore(); + } + ); + var esLintConfig = require('../lib/config/eslint'); var testFilePath = path.join(__dirname, 'fixture', 'test.js'); @@ -251,13 +265,15 @@ describe( var jsFormatter = new Formatter.JS(testFilePath, jsLogger); var source = fs.readFileSync(testFilePath, 'utf-8'); - jsFormatter.format(source, true); - - var jsErrors = jsLogger.getErrors(testFilePath); + var lint = require('../lib/lint'); it( 'should find at least one lint error', function() { + jsFormatter.format(source, true); + + var jsErrors = jsLogger.getErrors(testFilePath); + var foundLintErrors = _.reduce( jsErrors, function(res, item, index) { @@ -282,5 +298,63 @@ describe( assert.isTrue(hasLintError); } ); + + it( + 'should use default configuration properties', + function() { + var eslint = lint.eslint; + + var verify = function(contents, config, file) { + return { + line: 1, + message: '', + column: 0, + ruleId: '' + } + }; + + sandbox.stub(eslint.linter, 'verify', verify); + + lint.runLinter(source, testFilePath, {}); + + var args = eslint.linter.verify.args[0]; + + assert.equal(args[1].parserOptions.ecmaVersion, 5); + assert.isUndefined(args[1].plugins); + } + ); + + it( + 'should merge configuration properties', + function() { + + var eslint = lint.eslint; + + var verify = function(contents, config, file) { + return { + line: 1, + message: '', + column: 0, + ruleId: '' + } + }; + + sandbox.stub(eslint.linter, 'verify', verify); + + jsFormatter.format( + source, + { + parserOptions: { + ecmaVersion: 6 + } + } + ); + + var args = eslint.linter.verify.args[0]; + + assert.equal(args[1].parserOptions.ecmaVersion, 6); + assert.isArray(args[1].plugins); + } + ); } ); \ No newline at end of file From f6a58d8a79a38c4b20e7672b022b6e038ce1562e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 10:58:34 -0700 Subject: [PATCH 028/153] Allow configuration to be customized --- lib/cli.js | 31 +++---- lib/config.js | 90 +++++++++++++++++++ lib/config/eslint_es6.js | 2 +- lib/formatter.js | 56 +++++++++++- lib/html.js | 11 ++- lib/js.js | 2 +- package.json | 1 + test/config.js | 65 ++++++++++++++ .../fixture/config/path_configs/csf.config.js | 17 ++++ test/formatter.js | 49 ++++++++++ test/html.js | 43 +++++++++ 11 files changed, 342 insertions(+), 25 deletions(-) create mode 100644 lib/config.js create mode 100644 test/config.js create mode 100644 test/fixture/config/path_configs/csf.config.js create mode 100644 test/formatter.js diff --git a/lib/cli.js b/lib/cli.js index 5a1a7ff..644a1de 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,6 +1,5 @@ var async = require('async'); var cli = require('cli'); -var cosmiconfig = require('cosmiconfig'); var fs = require('fs'); var path = require('path'); var util = require('util'); @@ -13,6 +12,7 @@ var colors = require('cli-color-keywords')(); var junit = require('./junit'); var re = require('./re'); +var Config = require('./config'); var File = require('./file'); var Formatter = require('./formatter'); @@ -65,19 +65,16 @@ CLI.prototype = _.create( init: function() { var instance = this; - cosmiconfig( - 'csf', - { - cwd: instance._cwd, - packageProp: 'csfConfig' - } - ).then( - function(obj) { - if (obj) { - var config = obj.config; + var cfgPromise = Config.load(instance._cwd); - instance._config = config; + cfgPromise.then( + function(config) { + var obj = config._paths.obj; + var err = config._paths.err; + instance._config = config; + + if (obj) { if (config.flags) { _.merge(instance.flags, config.flags); } @@ -86,13 +83,8 @@ CLI.prototype = _.create( instance._log('Using local config from ', obj.filepath); } } - - instance._start(); - } - ).catch( - function(err) { - if (instance.flags.verbose) { - instance._log('Could not resolve any local config: ', err); + else if (err && instance.flags.verbose) { + instance._log('Could not resolve any local config: ', err, err.stack); } instance._start(); @@ -350,6 +342,7 @@ CLI.prototype = _.create( series.push(instance.createReport.bind(instance)); } + instance._async.series(series, instance.afterFormat.bind(instance)); if (!series.length) { diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..f187b01 --- /dev/null +++ b/lib/config.js @@ -0,0 +1,90 @@ +var _ = require('lodash'); +var cosmiconfig = require('cosmiconfig'); + +var CONFIG_DEFAULT = { + _paths: { + configs: [], + keys: [] + } +}; + +var Config = function(obj) { + this._config = this._normalize(obj); + + return this._config; +}; + +Config.prototype = { + toJSON: function(){ + return _.omit(this._config, '_paths'); + }, + + _get: function(key) { + return key ? _.result(this._config, key) : this._config; + }, + + _normalize: function(obj) { + var fn = this._get.bind(this); + + fn.toJSON = this.toJSON.bind(this); + fn.toString = JSON.stringify.bind(JSON, fn); + fn.inspect = fn.toString; + + return _.merge(fn, CONFIG_DEFAULT, obj); + } +}; + +Config.load = function(cwd) { + return cosmiconfig( + 'csf', + { + cwd: cwd, + packageProp: 'csfConfig' + } + ).then( + function(obj) { + var config = new Config(obj ? obj.config : {}); + + config._paths.cwd = cwd; + + if (obj) { + var STR_PATH = 'path:'; + + var paths = Object.keys(config).reduce( + function(prev, item, index) { + if (item.indexOf(STR_PATH) === 0) { + var pathKey = item.slice(STR_PATH.length); + + var pathConfig = config[item]; + + prev.configs.push(pathConfig); + + delete config[item]; + + prev.keys.push(pathKey); + } + + return prev; + }, + config._paths + ); + + paths.obj = obj; + } + + return config; + } + ).catch( + function(err) { + var config = new Config(); + + config._paths.cwd = cwd; + + config._paths.err = err; + + return config; + } + ); +}; + +module.exports = Config; \ No newline at end of file diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 3dbbd84..dc67e19 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -19,7 +19,7 @@ module.exports = { 'jsx-uses-react': 2, 'jsx-uses-vars': 2, - 'arrow-body-style': [2, 'as-needed'], + 'arrow-body-style': [0, 'as-needed'], 'arrow-parens': [2, 'as-needed'], 'object-shorthand': [2, 'always', { 'ignoreConstructors': true }], 'prefer-arrow-callback': 2, diff --git a/lib/formatter.js b/lib/formatter.js index 530961c..ae1acec 100644 --- a/lib/formatter.js +++ b/lib/formatter.js @@ -1,17 +1,71 @@ +var _ = require('lodash'); +var path = require('path'); + require('./css'); require('./html'); require('./js'); var Formatter = module.exports = require('content-formatter'); +var Config = require('./config'); var re = require('./re'); var RULES = require('./rules'); +var minimatch = require('minimatch'); + +var configCache = {}; + +Formatter.prototype.config = function(key) { + var abspath = this._abspath; + + if (!abspath) { + abspath = path.resolve(this._config._paths.cwd, this.file); + + this._abspath = abspath; + } + + var configObj = configCache[abspath]; + + if (!configObj) { + var config = this._config; + + var paths = config._paths; + var configs = paths.configs; + + var filteredConfigs = _.reduce( + paths.keys, + function(prev, item, index) { + if (minimatch(abspath, item)) { + prev.push(configs[index]); + } + + return prev; + }, + [] + ); + + if (filteredConfigs.length) { + filteredConfigs.unshift(new Config(), config); + + configObj = _.merge.apply(_, filteredConfigs); + + delete configObj._paths; + } + else { + configObj = config; + } + + configCache[abspath] = configObj; + } + + return configObj(key); +}; + Formatter.on( 'init', function(instance) { - instance._config = {}; + instance._config = new Config(); var ruleInstance = new re(RULES); diff --git a/lib/html.js b/lib/html.js index ac8901b..a5a5206 100644 --- a/lib/html.js +++ b/lib/html.js @@ -174,7 +174,9 @@ Formatter.HTML = Formatter.create( }, formatCSS: function(styleBlocks) { - var cssFormatter = new Formatter.CSS(this.file, this.logger, this.flags); + var cssFormatter = new Formatter.CSS(this.file, this.logger, this.flags, this._config); + + cssFormatter._abspath = this._abspath; return styleBlocks.map( function(item, index) { @@ -184,10 +186,13 @@ Formatter.HTML = Formatter.create( }, formatJs: function(scriptBlocks) { - var jsFormatter = new Formatter.JS(this.file, this.logger, this.flags); + var jsFormatter = new Formatter.JS(this.file, this.logger, this.flags, this._config); + + jsFormatter._config = this._config; + var esLintConfig = require('./config/eslint_jsp'); - var lint = _.merge({}, esLintConfig, _.get(this._config, 'js.lint'), _.get(this._config, 'html.lint.js')); + var lint = _.merge({}, esLintConfig, this.config('js.lint'), this.config('html.lint.js')); jsFormatter.lintLogFilter = this._jsLogFilter.bind(this); diff --git a/lib/js.js b/lib/js.js index 11b2184..d011ab1 100644 --- a/lib/js.js +++ b/lib/js.js @@ -104,7 +104,7 @@ Formatter.JS = Formatter.create( lint = _.isObjectLike(lint) ? lint : {}; - _.merge(lint, _.get(this._config, 'js.lint')); + _.merge(lint, this.config('js.lint')); var results = linter(contents, this.file, lint); diff --git a/package.json b/package.json index ff68655..9497680 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "lodash": "^4.6.1", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", + "minimatch": "^3.0.0", "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", diff --git a/test/config.js b/test/config.js new file mode 100644 index 0000000..58e6a53 --- /dev/null +++ b/test/config.js @@ -0,0 +1,65 @@ +var async = require('async'); +var chai = require('chai'); + +var Config = require('../lib/config'); + +chai.use(require('chai-string')); + +var assert = chai.assert; + +describe( + 'Config', + function() { + 'use strict'; + + it( + 'should be a function', + function() { + assert.isTrue(typeof new Config() === 'function'); + } + ); + + it( + 'should exclude _paths property when logging', + function() { + var config = new Config(); + + assert.isTrue(JSON.stringify(config) === "{}"); + assert.isTrue(typeof config._paths === 'object'); + } + ); + + it( + 'should return property by key', + function() { + var config = new Config( + { + foo: 1, + bar: function() { + return 'hello world'; + } + } + ); + + assert.isTrue(config('foo') === 1); + assert.isTrue(config('bar') === 'hello world'); + } + ); + + it( + 'should return entire config when called without a key', + function() { + var config = new Config( + { + foo: 1, + bar: function() { + return 'hello world'; + } + } + ); + + assert.isTrue(config() === config); + } + ); + } +); \ No newline at end of file diff --git a/test/fixture/config/path_configs/csf.config.js b/test/fixture/config/path_configs/csf.config.js new file mode 100644 index 0000000..17e24b2 --- /dev/null +++ b/test/fixture/config/path_configs/csf.config.js @@ -0,0 +1,17 @@ +module.exports = { + flags: { + quiet: true + }, + + 'path:**/foo.css': { + flags: { + quiet: false + } + }, + + 'path:**/foo.js': { + flags: { + quiet: true + } + } +}; \ No newline at end of file diff --git a/test/formatter.js b/test/formatter.js new file mode 100644 index 0000000..0ec4622 --- /dev/null +++ b/test/formatter.js @@ -0,0 +1,49 @@ +var async = require('async'); +var chai = require('chai'); +var path = require('path'); + +var Config = require('../lib/config'); +var Formatter = require('../lib/formatter'); +var Logger = require('../lib/logger'); + +chai.use(require('chai-string')); + +var assert = chai.assert; + +describe( + 'Formatter', + function() { + 'use strict'; + + var logger = new Logger.constructor(); + + it( + 'should have a config object', + function() { + var formatter = Formatter.get('foo.css', logger, {}); + + assert.isTrue(typeof formatter._config === 'function'); + assert.isObject(formatter._config._paths); + } + ); + + it( + 'should get merged config by path', + function(done) { + var cwd = path.join(__dirname, 'fixture/config/path_configs'); + + Config.load(cwd).then( + function(config) { + var formatter = Formatter.get('foo.css', logger, {quiet: true}); + + formatter._config = config; + + assert.isFalse(formatter.config('flags.quiet')); + + done(); + } + ); + } + ); + } +); \ No newline at end of file diff --git a/test/html.js b/test/html.js index 9433fb6..95e3676 100644 --- a/test/html.js +++ b/test/html.js @@ -454,6 +454,49 @@ describe( assert.equal(contents, '\nvoid 0;\n/* scriptlet block\nvoid 0; */\nvoid 0;\n'); } ); + + // it( + // 'should merge lint config properly', + // function() { + // var ESLINT_CONFIG = require('../lib/config/eslint'); + // var ESLINT_CONFIG_JSP = require('../lib/config/eslint_jsp'); + + // var rules = _.reduce( + // ESLINT_CONFIG.rules, + // function(prev, item, index) { + // var ruleVal = item; + + // if (_.isArray(ruleVal)) { + // ruleVal = ruleVal[0]; + // } + + // var jspRuleVal = ESLINT_CONFIG_JSP.rules[index]; + + // if (_.isArray(jspRuleVal)) { + // jspRuleVal = jspRuleVal[0]; + // } + + // if (ruleVal > 0 && jspRuleVal === 0) { + // prev.push(index); + // } + + // return prev; + // }, + // [] + // ); + + // var results = _.find( + // htmlErrors, + // function(item) { + // var type = item.type; + + // return rules.indexOf(type) > -1; + // } + // ); + + // console.log(results, rules); + // } + // ); } ); From b80d10d2a8bea8e3c3b594b14d68ee54c52ec2f8 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 11:50:42 -0700 Subject: [PATCH 029/153] Updating readme --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/README.md b/README.md index 2668765..c1e9607 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,66 @@ You can install it via a couple of steps: You can read more on [the project page](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting). Thanks to [Drew Brokke](https://github.com/drewbrokke) for writing the plugin and publishing it. +## Custom configuration +Starting in version 2, you can now customize the configuration of the engine in a few different ways. +Here are the items you can currently customize: + - CLI Flags + - ESLint rules + +I'm planning on expanding this into more areas, but currently those are the two sections that can be modified. + +How do you define a custom configuration? + +We are currently using [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to look for configuration files, which means you can define custom configuration by adding any one of the following files somewhere in the current working directory or one of the parent directories: +- Inside of `package.json`, using a custom key of `csfConfig` +- `csf.config.js` +- `.csfrc` in JSON or YAML format + +Also note, the configuration will stop searching after it finds the first file it can find and that configurations are *NOT* merged (I may change this in the future). + +What does the structure of the configuration look like? + +Let's say we create a `.csf.config.js` file, our configuration, at the very least, should export a JSON object like so: +``` + module.exports = {}; +``` + +Here is an example of a config with all keys defined: +``` + module.exports = { + flags: {}, + js: { + lint: {} + }, + html: { + js: { + lint: {} + } + }, + 'path:**/*.something.js': { + js: { + lint: {} + } + } + }; +``` + +(please note, if using one of the JSON files, you'll need to quote the Object keys, however, there are some benefits to using a plain JS file, which I'll mention below). +And here are the descriptions of what they do: +- `flags` - This will default any of the flags listed above to whatever option you specify (.e.g. `quiet`). You *must* use the long form the flag, however. +- `lint` - These accept any option that can be passed to [ESLint](http://eslint.org/docs/user-guide/configuring), you can set here. This includes any environment or globals you wish to define, rules you wish to define, etc.
+This means anywhere the lint object is called, you can set the rules. + +The `html.js.lint` property is only applied for script blocks inside of HTML-like files that go through the HTML formatter. This property is merged on top of anything specified in `js.lint`. + +You'll also notice that a key there of `path:**/*.something.js`. This allows you to specify a configuration to a specific file path, or a glob referencing a file path. +Any files matching that glob will apply those rules on top of the ones inside of `js.lint`, and `html.js.lint`. + +#### Benefits to using `.js` over `.json`? +As I mentioned before, there are some benefits to using a `.js` file, but mainly is that it's less strict about what can go inside of the file, so you can use comments, and unquoted keys. +But also, any configuration you define with a function as the value, that function will be executed, and anything you return from there will be used as the value. +This means you can dynamically configure the script at runtime. + ## Known issues The following are known issues where it will say there's an error, but there's not (or where there should be an error but there's not) From ae0adf90e283d83dc57b2a3a1ce18eb290c70c6f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 17:34:00 -0700 Subject: [PATCH 030/153] v2.0.0-rc.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9497680..d7c616e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "1.1.10", + "version": "2.0.0-rc.1", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { @@ -63,4 +63,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} +} \ No newline at end of file From 3b46e50131db60ae8448365aa03496b570d8c487 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 17:54:04 -0700 Subject: [PATCH 031/153] Adding proper dir check back --- test/fixture/config/bad_config/{ => package.json}/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/fixture/config/bad_config/{ => package.json}/.gitkeep (100%) diff --git a/test/fixture/config/bad_config/.gitkeep b/test/fixture/config/bad_config/package.json/.gitkeep similarity index 100% rename from test/fixture/config/bad_config/.gitkeep rename to test/fixture/config/bad_config/package.json/.gitkeep From 82fd866f3dde876d4fddf9cd0b1ca624637090ed Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 17:54:23 -0700 Subject: [PATCH 032/153] 2.0.0-rc.2 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d7c616e..78a6a0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.1", + "version": "2.0.0-rc.2", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { @@ -63,4 +63,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} \ No newline at end of file +} From 0fc9ff2377d889a39b5ec411d0903e4ee54dfca0 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 18:01:53 -0700 Subject: [PATCH 033/153] Adding npmignore --- .npmignore | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e5b53e7 --- /dev/null +++ b/.npmignore @@ -0,0 +1,26 @@ +test +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Deployed apps should consider commenting this line out: +# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git +node_modules \ No newline at end of file From 38eb55f2e4b3320d8e6bc4c60c4c6f618d94496c Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 4 Apr 2016 18:02:09 -0700 Subject: [PATCH 034/153] 2.0.0-rc.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 78a6a0b..da26c63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc.3", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { From 5ff3ed09cd01f17fb428956e98c7c4f9a8628081 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 6 Apr 2016 07:13:26 -0700 Subject: [PATCH 035/153] Adding rules for es6 --- lib/config/eslint_es6.js | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index dc67e19..8634b41 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -18,6 +18,52 @@ module.exports = { 'rules': { 'jsx-uses-react': 2, 'jsx-uses-vars': 2, + 'jsx-curly-spacing': [2, 'never'], + 'jsx-indent': [2, 'tab'], + 'jsx-indent-props': [2, 'tab'], + 'jsx-key': 2, + 'jsx-equals-spacing': [2, 'never'], + 'jsx-no-undef': 2, + 'jsx-no-duplicate-props': 2, + 'jsx-no-literals': 2, + 'jsx-closing-bracket-location': 2, + 'jsx-pascal-case': 2, + 'jsx-space-before-closing': [2, 'always'], + 'jsx-sort-props': [2, {'ignoreCase': true}], + 'no-multi-comp': [2/*, {'ignoreStateless': true}*/], + 'wrap-multilines': [2/*, {'ignoreStateless': true}*/], + 'no-unknown-property': 2, + 'sort-comp': [2, { + order: [ + 'static-methods', + 'lifecycle', + 'everything-else', + 'render' + ], + groups: { + lifecycle: [ + 'constructor', + 'displayName', + 'mixins', + 'propTypes', + 'statics', + 'defaultProps', + 'getDefaultProps', + 'getInitialState', + 'state', + 'componentWillMount', + 'componentDidMount', + 'componentWillReceiveProps', + 'componentWillUpdate', + 'componentDidUpdate', + 'componentWillUnmount', + 'shouldComponentUpdate', + 'getChildContext', + 'childContextTypes', + 'contextTypes', + ] + } + }], 'arrow-body-style': [0, 'as-needed'], 'arrow-parens': [2, 'as-needed'], From b5504f8b6d55c7e52c8d8f7fd6b66f36c583ed94 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 6 Apr 2016 07:28:53 -0700 Subject: [PATCH 036/153] Rename lint to lint_js --- lib/js.js | 2 +- lib/{lint.js => lint_js.js} | 2 +- lib/{lint_rules => lint_js_rules}/array_spacing.js | 0 lib/{lint_rules => lint_js_rules}/array_spacing_chars.js | 0 lib/{lint_rules => lint_js_rules}/catch_arg_name.js | 0 lib/{lint_rules => lint_js_rules}/catch_format.js | 0 lib/{lint_rules => lint_js_rules}/dot_notation.js | 0 lib/{lint_rules => lint_js_rules}/format_args.js | 0 lib/{lint_rules => lint_js_rules}/format_constants.js | 0 lib/{lint_rules => lint_js_rules}/format_multiline_vars.js | 0 lib/{lint_rules => lint_js_rules}/liferay_language_get.js | 0 lib/{lint_rules => lint_js_rules}/liferay_provide_format.js | 0 lib/{lint_rules => lint_js_rules}/multiple_vars.js | 0 lib/{lint_rules => lint_js_rules}/no_extra_semi.js | 0 lib/{lint_rules => lint_js_rules}/no_is_prefix.js | 0 lib/{lint_rules => lint_js_rules}/no_undef.js | 0 lib/{lint_rules => lint_js_rules}/no_unused_vars.js | 0 lib/{lint_rules => lint_js_rules}/no_use_before_define.js | 0 lib/{lint_rules => lint_js_rules}/sort_constants.js | 0 lib/{lint_rules => lint_js_rules}/sort_props.js | 0 lib/{lint_rules => lint_js_rules}/sort_requires.js | 0 lib/{lint_rules => lint_js_rules}/sort_vars.js | 0 test/js.js | 2 +- test/{lint_rules => lint_js_rules}/array_spacing.js | 4 ++-- test/{lint_rules => lint_js_rules}/array_spacing_chars.js | 4 ++-- test/{lint_rules => lint_js_rules}/catch_arg_name.js | 4 ++-- test/{lint_rules => lint_js_rules}/catch_format.js | 4 ++-- test/{lint_rules => lint_js_rules}/dot_notation.js | 4 ++-- test/{lint_rules => lint_js_rules}/format_args.js | 4 ++-- test/{lint_rules => lint_js_rules}/format_constants.js | 4 ++-- test/{lint_rules => lint_js_rules}/format_multiline_vars.js | 4 ++-- test/{lint_rules => lint_js_rules}/liferay_language_get.js | 4 ++-- test/{lint_rules => lint_js_rules}/liferay_provide_format.js | 4 ++-- test/{lint_rules => lint_js_rules}/multiple_vars.js | 4 ++-- test/{lint_rules => lint_js_rules}/no_extra_semi.js | 4 ++-- test/{lint_rules => lint_js_rules}/no_is_prefix.js | 4 ++-- test/{lint_rules => lint_js_rules}/no_undef.js | 4 ++-- test/{lint_rules => lint_js_rules}/no_unused_vars.js | 4 ++-- test/{lint_rules => lint_js_rules}/no_use_before_define.js | 4 ++-- test/{lint_rules => lint_js_rules}/sort_constants.js | 4 ++-- test/{lint_rules => lint_js_rules}/sort_props.js | 4 ++-- test/{lint_rules => lint_js_rules}/sort_requires.js | 4 ++-- test/{lint_rules => lint_js_rules}/sort_vars.js | 4 ++-- 43 files changed, 43 insertions(+), 43 deletions(-) rename lib/{lint.js => lint_js.js} (95%) rename lib/{lint_rules => lint_js_rules}/array_spacing.js (100%) rename lib/{lint_rules => lint_js_rules}/array_spacing_chars.js (100%) rename lib/{lint_rules => lint_js_rules}/catch_arg_name.js (100%) rename lib/{lint_rules => lint_js_rules}/catch_format.js (100%) rename lib/{lint_rules => lint_js_rules}/dot_notation.js (100%) rename lib/{lint_rules => lint_js_rules}/format_args.js (100%) rename lib/{lint_rules => lint_js_rules}/format_constants.js (100%) rename lib/{lint_rules => lint_js_rules}/format_multiline_vars.js (100%) rename lib/{lint_rules => lint_js_rules}/liferay_language_get.js (100%) rename lib/{lint_rules => lint_js_rules}/liferay_provide_format.js (100%) rename lib/{lint_rules => lint_js_rules}/multiple_vars.js (100%) rename lib/{lint_rules => lint_js_rules}/no_extra_semi.js (100%) rename lib/{lint_rules => lint_js_rules}/no_is_prefix.js (100%) rename lib/{lint_rules => lint_js_rules}/no_undef.js (100%) rename lib/{lint_rules => lint_js_rules}/no_unused_vars.js (100%) rename lib/{lint_rules => lint_js_rules}/no_use_before_define.js (100%) rename lib/{lint_rules => lint_js_rules}/sort_constants.js (100%) rename lib/{lint_rules => lint_js_rules}/sort_props.js (100%) rename lib/{lint_rules => lint_js_rules}/sort_requires.js (100%) rename lib/{lint_rules => lint_js_rules}/sort_vars.js (100%) rename test/{lint_rules => lint_js_rules}/array_spacing.js (83%) rename test/{lint_rules => lint_js_rules}/array_spacing_chars.js (89%) rename test/{lint_rules => lint_js_rules}/catch_arg_name.js (77%) rename test/{lint_rules => lint_js_rules}/catch_format.js (77%) rename test/{lint_rules => lint_js_rules}/dot_notation.js (83%) rename test/{lint_rules => lint_js_rules}/format_args.js (95%) rename test/{lint_rules => lint_js_rules}/format_constants.js (83%) rename test/{lint_rules => lint_js_rules}/format_multiline_vars.js (97%) rename test/{lint_rules => lint_js_rules}/liferay_language_get.js (89%) rename test/{lint_rules => lint_js_rules}/liferay_provide_format.js (93%) rename test/{lint_rules => lint_js_rules}/multiple_vars.js (82%) rename test/{lint_rules => lint_js_rules}/no_extra_semi.js (75%) rename test/{lint_rules => lint_js_rules}/no_is_prefix.js (91%) rename test/{lint_rules => lint_js_rules}/no_undef.js (77%) rename test/{lint_rules => lint_js_rules}/no_unused_vars.js (84%) rename test/{lint_rules => lint_js_rules}/no_use_before_define.js (87%) rename test/{lint_rules => lint_js_rules}/sort_constants.js (90%) rename test/{lint_rules => lint_js_rules}/sort_props.js (96%) rename test/{lint_rules => lint_js_rules}/sort_requires.js (85%) rename test/{lint_rules => lint_js_rules}/sort_vars.js (93%) diff --git a/lib/js.js b/lib/js.js index d011ab1..1434b20 100644 --- a/lib/js.js +++ b/lib/js.js @@ -100,7 +100,7 @@ Formatter.JS = Formatter.create( _lint: function(contents, lint) { if (lint !== false) { - var linter = require('./lint'); + var linter = require('./lint_js'); lint = _.isObjectLike(lint) ? lint : {}; diff --git a/lib/lint.js b/lib/lint_js.js similarity index 95% rename from lib/lint.js rename to lib/lint_js.js index 53ad039..7e16bed 100644 --- a/lib/lint.js +++ b/lib/lint_js.js @@ -43,7 +43,7 @@ var globOptions = { module.exports = function(contents, file, config) { glob.sync( - './lint_rules/*.js', + './lint_js_rules/*.js', globOptions ).forEach( function(item, index) { diff --git a/lib/lint_rules/array_spacing.js b/lib/lint_js_rules/array_spacing.js similarity index 100% rename from lib/lint_rules/array_spacing.js rename to lib/lint_js_rules/array_spacing.js diff --git a/lib/lint_rules/array_spacing_chars.js b/lib/lint_js_rules/array_spacing_chars.js similarity index 100% rename from lib/lint_rules/array_spacing_chars.js rename to lib/lint_js_rules/array_spacing_chars.js diff --git a/lib/lint_rules/catch_arg_name.js b/lib/lint_js_rules/catch_arg_name.js similarity index 100% rename from lib/lint_rules/catch_arg_name.js rename to lib/lint_js_rules/catch_arg_name.js diff --git a/lib/lint_rules/catch_format.js b/lib/lint_js_rules/catch_format.js similarity index 100% rename from lib/lint_rules/catch_format.js rename to lib/lint_js_rules/catch_format.js diff --git a/lib/lint_rules/dot_notation.js b/lib/lint_js_rules/dot_notation.js similarity index 100% rename from lib/lint_rules/dot_notation.js rename to lib/lint_js_rules/dot_notation.js diff --git a/lib/lint_rules/format_args.js b/lib/lint_js_rules/format_args.js similarity index 100% rename from lib/lint_rules/format_args.js rename to lib/lint_js_rules/format_args.js diff --git a/lib/lint_rules/format_constants.js b/lib/lint_js_rules/format_constants.js similarity index 100% rename from lib/lint_rules/format_constants.js rename to lib/lint_js_rules/format_constants.js diff --git a/lib/lint_rules/format_multiline_vars.js b/lib/lint_js_rules/format_multiline_vars.js similarity index 100% rename from lib/lint_rules/format_multiline_vars.js rename to lib/lint_js_rules/format_multiline_vars.js diff --git a/lib/lint_rules/liferay_language_get.js b/lib/lint_js_rules/liferay_language_get.js similarity index 100% rename from lib/lint_rules/liferay_language_get.js rename to lib/lint_js_rules/liferay_language_get.js diff --git a/lib/lint_rules/liferay_provide_format.js b/lib/lint_js_rules/liferay_provide_format.js similarity index 100% rename from lib/lint_rules/liferay_provide_format.js rename to lib/lint_js_rules/liferay_provide_format.js diff --git a/lib/lint_rules/multiple_vars.js b/lib/lint_js_rules/multiple_vars.js similarity index 100% rename from lib/lint_rules/multiple_vars.js rename to lib/lint_js_rules/multiple_vars.js diff --git a/lib/lint_rules/no_extra_semi.js b/lib/lint_js_rules/no_extra_semi.js similarity index 100% rename from lib/lint_rules/no_extra_semi.js rename to lib/lint_js_rules/no_extra_semi.js diff --git a/lib/lint_rules/no_is_prefix.js b/lib/lint_js_rules/no_is_prefix.js similarity index 100% rename from lib/lint_rules/no_is_prefix.js rename to lib/lint_js_rules/no_is_prefix.js diff --git a/lib/lint_rules/no_undef.js b/lib/lint_js_rules/no_undef.js similarity index 100% rename from lib/lint_rules/no_undef.js rename to lib/lint_js_rules/no_undef.js diff --git a/lib/lint_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js similarity index 100% rename from lib/lint_rules/no_unused_vars.js rename to lib/lint_js_rules/no_unused_vars.js diff --git a/lib/lint_rules/no_use_before_define.js b/lib/lint_js_rules/no_use_before_define.js similarity index 100% rename from lib/lint_rules/no_use_before_define.js rename to lib/lint_js_rules/no_use_before_define.js diff --git a/lib/lint_rules/sort_constants.js b/lib/lint_js_rules/sort_constants.js similarity index 100% rename from lib/lint_rules/sort_constants.js rename to lib/lint_js_rules/sort_constants.js diff --git a/lib/lint_rules/sort_props.js b/lib/lint_js_rules/sort_props.js similarity index 100% rename from lib/lint_rules/sort_props.js rename to lib/lint_js_rules/sort_props.js diff --git a/lib/lint_rules/sort_requires.js b/lib/lint_js_rules/sort_requires.js similarity index 100% rename from lib/lint_rules/sort_requires.js rename to lib/lint_js_rules/sort_requires.js diff --git a/lib/lint_rules/sort_vars.js b/lib/lint_js_rules/sort_vars.js similarity index 100% rename from lib/lint_rules/sort_vars.js rename to lib/lint_js_rules/sort_vars.js diff --git a/test/js.js b/test/js.js index a779a64..37859f1 100644 --- a/test/js.js +++ b/test/js.js @@ -265,7 +265,7 @@ describe( var jsFormatter = new Formatter.JS(testFilePath, jsLogger); var source = fs.readFileSync(testFilePath, 'utf-8'); - var lint = require('../lib/lint'); + var lint = require('../lib/lint_js'); it( 'should find at least one lint error', diff --git a/test/lint_rules/array_spacing.js b/test/lint_js_rules/array_spacing.js similarity index 83% rename from test/lint_rules/array_spacing.js rename to test/lint_js_rules/array_spacing.js index bfacd01..75c952a 100644 --- a/test/lint_rules/array_spacing.js +++ b/test/lint_js_rules/array_spacing.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ '[1, 2, 3]' diff --git a/test/lint_rules/array_spacing_chars.js b/test/lint_js_rules/array_spacing_chars.js similarity index 89% rename from test/lint_rules/array_spacing_chars.js rename to test/lint_js_rules/array_spacing_chars.js index 65def35..05dbbd4 100644 --- a/test/lint_rules/array_spacing_chars.js +++ b/test/lint_js_rules/array_spacing_chars.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -11,7 +11,7 @@ var STR_ERROR = 'Array items should be separated by exactly one space:'; ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ '[1, 2, 3]', diff --git a/test/lint_rules/catch_arg_name.js b/test/lint_js_rules/catch_arg_name.js similarity index 77% rename from test/lint_rules/catch_arg_name.js rename to test/lint_js_rules/catch_arg_name.js index 5ebf0b3..351ecbd 100644 --- a/test/lint_rules/catch_arg_name.js +++ b/test/lint_js_rules/catch_arg_name.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'try{}catch(e){}' diff --git a/test/lint_rules/catch_format.js b/test/lint_js_rules/catch_format.js similarity index 77% rename from test/lint_rules/catch_format.js rename to test/lint_js_rules/catch_format.js index 72a7832..dc58f41 100644 --- a/test/lint_rules/catch_format.js +++ b/test/lint_js_rules/catch_format.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'try{}catch(e){\n}' diff --git a/test/lint_rules/dot_notation.js b/test/lint_js_rules/dot_notation.js similarity index 83% rename from test/lint_rules/dot_notation.js rename to test/lint_js_rules/dot_notation.js index 52b60b1..0ddc108 100644 --- a/test/lint_rules/dot_notation.js +++ b/test/lint_js_rules/dot_notation.js @@ -2,7 +2,7 @@ var _ = require('lodash'); var path = require('path'); var base = require('../../lib/base.js'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -22,7 +22,7 @@ _.forEach( ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: validRules, diff --git a/test/lint_rules/format_args.js b/test/lint_js_rules/format_args.js similarity index 95% rename from test/lint_rules/format_args.js rename to test/lint_js_rules/format_args.js index c411a72..d8d28bf 100644 --- a/test/lint_rules/format_args.js +++ b/test/lint_js_rules/format_args.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -42,7 +42,7 @@ alert({x: 1}, 1); */ ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'alert();', diff --git a/test/lint_rules/format_constants.js b/test/lint_js_rules/format_constants.js similarity index 83% rename from test/lint_rules/format_constants.js rename to test/lint_js_rules/format_constants.js index 9350d0a..7ee73c7 100644 --- a/test/lint_rules/format_constants.js +++ b/test/lint_js_rules/format_constants.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var FOO1 = \'\';\n\nvar FOO2 = \'\';' diff --git a/test/lint_rules/format_multiline_vars.js b/test/lint_js_rules/format_multiline_vars.js similarity index 97% rename from test/lint_rules/format_multiline_vars.js rename to test/lint_js_rules/format_multiline_vars.js index 1cf8a3c..85d53fa 100644 --- a/test/lint_rules/format_multiline_vars.js +++ b/test/lint_js_rules/format_multiline_vars.js @@ -1,7 +1,7 @@ var path = require('path'); var sub = require('string-sub'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -16,7 +16,7 @@ var addES6 = function(item, index) { ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var FOO1;', diff --git a/test/lint_rules/liferay_language_get.js b/test/lint_js_rules/liferay_language_get.js similarity index 89% rename from test/lint_rules/liferay_language_get.js rename to test/lint_js_rules/liferay_language_get.js index 059d416..fe2f67f 100644 --- a/test/lint_rules/liferay_language_get.js +++ b/test/lint_js_rules/liferay_language_get.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -18,7 +18,7 @@ var invalidTests = ['1', 'function(){}', '/f/', 'new Date()', 'foo'].map( ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'Liferay.Language.get("foo")', diff --git a/test/lint_rules/liferay_provide_format.js b/test/lint_js_rules/liferay_provide_format.js similarity index 93% rename from test/lint_rules/liferay_provide_format.js rename to test/lint_js_rules/liferay_provide_format.js index c98ca2e..ff3159a 100644 --- a/test/lint_rules/liferay_provide_format.js +++ b/test/lint_js_rules/liferay_provide_format.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'Liferay.provide(window, "foo", function(){}, ["dep"])', diff --git a/test/lint_rules/multiple_vars.js b/test/lint_js_rules/multiple_vars.js similarity index 82% rename from test/lint_rules/multiple_vars.js rename to test/lint_js_rules/multiple_vars.js index f0e07b5..18456f9 100644 --- a/test/lint_rules/multiple_vars.js +++ b/test/lint_js_rules/multiple_vars.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var x = 1;\nvar y = 2;', diff --git a/test/lint_rules/no_extra_semi.js b/test/lint_js_rules/no_extra_semi.js similarity index 75% rename from test/lint_rules/no_extra_semi.js rename to test/lint_js_rules/no_extra_semi.js index e1d4b41..95aca79 100644 --- a/test/lint_rules/no_extra_semi.js +++ b/test/lint_js_rules/no_extra_semi.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ ';(function(){});' diff --git a/test/lint_rules/no_is_prefix.js b/test/lint_js_rules/no_is_prefix.js similarity index 91% rename from test/lint_rules/no_is_prefix.js rename to test/lint_js_rules/no_is_prefix.js index 23bf431..75362bd 100644 --- a/test/lint_rules/no_is_prefix.js +++ b/test/lint_js_rules/no_is_prefix.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -11,7 +11,7 @@ var STR_ERROR = 'Variable/property names should not start with is*: '; ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var isString = A.Lang.isString;', diff --git a/test/lint_rules/no_undef.js b/test/lint_js_rules/no_undef.js similarity index 77% rename from test/lint_rules/no_undef.js rename to test/lint_js_rules/no_undef.js index bde49ce..c41570f 100644 --- a/test/lint_rules/no_undef.js +++ b/test/lint_js_rules/no_undef.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ '_PN_foo()', diff --git a/test/lint_rules/no_unused_vars.js b/test/lint_js_rules/no_unused_vars.js similarity index 84% rename from test/lint_rules/no_unused_vars.js rename to test/lint_js_rules/no_unused_vars.js index 4b4412b..3a3f27f 100644 --- a/test/lint_rules/no_unused_vars.js +++ b/test/lint_js_rules/no_unused_vars.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -11,7 +11,7 @@ var options = [{'jsp': true}]; ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var _PN_xyz = 1;', diff --git a/test/lint_rules/no_use_before_define.js b/test/lint_js_rules/no_use_before_define.js similarity index 87% rename from test/lint_rules/no_use_before_define.js rename to test/lint_js_rules/no_use_before_define.js index 7b18fca..f8453eb 100644 --- a/test/lint_rules/no_use_before_define.js +++ b/test/lint_js_rules/no_use_before_define.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': true}] } diff --git a/test/lint_rules/sort_constants.js b/test/lint_js_rules/sort_constants.js similarity index 90% rename from test/lint_rules/sort_constants.js rename to test/lint_js_rules/sort_constants.js index f8816be..ce59d70 100644 --- a/test/lint_rules/sort_constants.js +++ b/test/lint_js_rules/sort_constants.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var ABC = 123;\n\nvar DEF = 456;', diff --git a/test/lint_rules/sort_props.js b/test/lint_js_rules/sort_props.js similarity index 96% rename from test/lint_rules/sort_props.js rename to test/lint_js_rules/sort_props.js index c620d63..7831131 100644 --- a/test/lint_rules/sort_props.js +++ b/test/lint_js_rules/sort_props.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -20,7 +20,7 @@ var addES6 = function(item, index) { ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ '({init: function(){}, initializer: function(){}, renderUI: function(){}, bindUI: function(){}, syncUI: function(){}, destructor: function(){}})', diff --git a/test/lint_rules/sort_requires.js b/test/lint_js_rules/sort_requires.js similarity index 85% rename from test/lint_rules/sort_requires.js rename to test/lint_js_rules/sort_requires.js index fb1d75f..b61cce2 100644 --- a/test/lint_rules/sort_requires.js +++ b/test/lint_js_rules/sort_requires.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ '({requires: []})', diff --git a/test/lint_rules/sort_vars.js b/test/lint_js_rules/sort_vars.js similarity index 93% rename from test/lint_rules/sort_vars.js rename to test/lint_js_rules/sort_vars.js index dcdf498..2ac6ad1 100644 --- a/test/lint_rules/sort_vars.js +++ b/test/lint_js_rules/sort_vars.js @@ -1,6 +1,6 @@ var path = require('path'); -var lint = require('../../lib/lint'); +var lint = require('../../lib/lint_js'); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -19,7 +19,7 @@ var addES6 = function(item, index) { ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_rules/' + path.basename(__filename)), + require('../../lib/lint_js_rules/' + path.basename(__filename)), { valid: [ 'var xyz = 123;', From aff7eb4c1910fcfb7a926d116e863909d9eabff6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 18 Apr 2016 09:39:09 -0700 Subject: [PATCH 037/153] Converting away from using async to using promises --- lib/cli.js | 196 +++++++++++++++++++------------------------------- lib/junit.js | 15 ++-- lib/meta.js | 46 +++++------- package.json | 1 + test/cli.js | 153 ++++++++++++++++++--------------------- test/junit.js | 41 +++++------ 6 files changed, 189 insertions(+), 263 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 644a1de..351071a 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,6 +1,7 @@ var async = require('async'); var cli = require('cli'); -var fs = require('fs'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var util = require('util'); @@ -53,8 +54,8 @@ var CLI = function(config) { this.junit = config.junit || junit; this._log = config.log || console.log.bind(console); this._logger = config.logger || Logger; - this._read = config.read || fs.readFile.bind(fs); - this._write = config.write || fs.writeFile.bind(fs); + this._read = config.read || fs.readFileAsync.bind(fs); + this._write = config.write || fs.writeFileAsync.bind(fs); }; CLI.prototype = _.create( @@ -67,32 +68,13 @@ CLI.prototype = _.create( var cfgPromise = Config.load(instance._cwd); - cfgPromise.then( - function(config) { - var obj = config._paths.obj; - var err = config._paths.err; - - instance._config = config; - - if (obj) { - if (config.flags) { - _.merge(instance.flags, config.flags); - } - - if (!instance.flags.filenames) { - instance._log('Using local config from ', obj.filepath); - } - } - else if (err && instance.flags.verbose) { - instance._log('Could not resolve any local config: ', err, err.stack); - } - - instance._start(); - } - ); + return Promise.resolve(cfgPromise) + .bind(this) + .then(instance._loadConfig) + .then(instance._start); }, - afterFormat: function(err, results) { + afterFormat: function(results) { var instance = this; var series = []; @@ -100,59 +82,55 @@ CLI.prototype = _.create( if (instance.flags.inlineEdit) { series = results.reduce( function(prev, item, index) { - if (item && item.contents !== item.data) { - prev.push(instance.writeFile.bind(instance, item.file, item.contents)); + if (item && !item.err && item.contents !== item.data) { + prev.push(instance.writeFile(item.file, item.contents)); } return prev; }, series ); - - instance._async.series(series, instance.onFinish.bind(instance)); } - if (!series.length) { - this.onFinish(err, results); - } + return Promise.all(series) + .then(instance.onFinish.bind(instance)) + .catch(instance.logGeneralError.bind(instance)); }, - checkMeta: function(done) { + checkMeta: function(results) { if (this._CHECK_META) { require(this._metaCheckerPath).check( { - done: done, liferayModuleDir: this._liferayModuleDir } ); } - else { - done(); - } + + return results; }, - createReport: function(done) { - var instance = this; + createReport: function(results) { + if (this.flags.junit) { + var junit = new this.junit( + { + flags: this.flags, + logger: this._logger + } + ); - var junit = new this.junit( - { - flags: this.flags, - logger: this._logger - } - ); + results = junit.generate().return(results); + } - junit.generate(done); + return results; }, - formatFile: function(file, data) { + formatFile: function(contents, file) { var formatter = Formatter.get(file, this._logger, this.flags); - var contents = null; - if (formatter) { formatter._config = this._config; - contents = this.processFileData(data, formatter); + contents = this.processFileData(contents, formatter); this.isMetaCheckNeeded(file); } @@ -176,13 +154,9 @@ CLI.prototype = _.create( }, logGeneralError: function(err) { - var msg = ''; - - if (err) { - msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); + var msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); - this._log(msg); - } + this._log(msg); return msg; }, @@ -199,38 +173,16 @@ CLI.prototype = _.create( } }, - onFinish: function(err, results) { - this.logGeneralError(err); - + onFinish: function(results) { if (this.flags.open) { - this.openFiles(err, results); + this.openFiles(results); } - this.emit( - 'finish', - { - err: err, - results: results - } - ); + return results; }, - onRead: function(err, data, file, done) { - var results = null; - - if (err) { - done = file; - file = data; - - this.onReadError(err, file); - - err = null; - } - else { - results = this.formatFile(file, data); - } - - done(err, results); + onRead: function(contents, file) { + return this.formatFile(contents, file); }, onReadError: function(err, file) { @@ -241,24 +193,15 @@ CLI.prototype = _.create( this._log(errMsg); this._log(''); } - }, - - onWrite: function(err, file, done) { - var writeResults = ''; - - if (err) { - writeResults = File.handleFileWriteError(err, file); - } - else { - writeResults = util.format('Wrote file: %s', file); - } - - this._log(writeResults); - done(); + return { + contents: '', + err: err, + file: file + }; }, - openFiles: function(err, result) { + openFiles: function(result) { var instance = this; var errorFiles = Object.keys(instance._logger.getErrors()); @@ -275,8 +218,10 @@ CLI.prototype = _.create( } }, - processFile: function(file, done) { - this._read(file, 'utf-8', _.bindRight(this.onRead, this, file, done)); + processFile: function(file) { + return this._read(file, 'utf-8') + .then(_.bindKeyRight(this, 'onRead', file)) + .error(_.bindKeyRight(this, 'onReadError', file)); }, processFileData: function(data, formatter) { @@ -319,35 +264,44 @@ CLI.prototype = _.create( return out; }, - writeFile: function(file, contents, done) { - this._write(file, contents, _.bindRight(this.onWrite, this, file, done)); + writeFile: function(file, contents) { + return this._write(file, contents) + .then(util.format.bind(util, 'Wrote file: %s', file)) + .error(File.handleFileWriteError.bind(this, file)) + .then(_.unary(this._log).bind(this)); }, - _start: function() { - var instance = this; + _loadConfig: function(config) { + var obj = config._paths.obj; + var err = config._paths.err; - instance.emit('init'); + this._config = config; - var series = instance._args.map( - function(file) { - return instance.processFile.bind(instance, file); + if (obj) { + if (config.flags) { + _.merge(this.flags, config.flags); } - ); - if (series.length) { - series.push(instance.checkMeta.bind(instance)); + if (!this.flags.filenames) { + this._log('Using local config from ', obj.filepath); + } } - - if (instance.flags.junit) { - series.push(instance.createReport.bind(instance)); + else if (err && this.flags.verbose) { + this._log('Could not resolve any local config: ', err, err.stack); } + return config; + }, - instance._async.series(series, instance.afterFormat.bind(instance)); - - if (!series.length) { - this.onFinish(null, null); - } + _start: function() { + this.emit('init'); + + return Promise.all(this._args) + .bind(this) + .map(_.unary(this.processFile)) + .then(this.checkMeta) + .then(this.createReport) + .then(this.afterFormat); }, _metaCheckerPath: './meta' diff --git a/lib/junit.js b/lib/junit.js index bea55d1..2c4bf93 100644 --- a/lib/junit.js +++ b/lib/junit.js @@ -1,5 +1,6 @@ var _ = require('lodash'); -var fs = require('fs'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs')); var Handlebars = require('content-logger-handlebars-helpers')(); var path = require('path'); @@ -11,15 +12,15 @@ var A = base.A; var JUnitReporter = function(config) { this.flags = config.flags || {}; this.logger = config.logger || Logger; - this.read = config.read || fs.readFile.bind(fs); - this.write = config.write || fs.writeFile.bind(fs); + this.read = config.read || fs.readFileAsync.bind(fs); + this.write = config.write || fs.writeFileAsync.bind(fs); }; JUnitReporter.prototype = { TPL_PATH: path.join(__dirname, 'tpl', 'junit_report.tpl'), - generate: function(done) { - this.read(this.TPL_PATH, 'utf-8', _.bindRight(this.onRead, this, done)); + generate: function() { + return this.read(this.TPL_PATH, 'utf-8').then(this.onRead.bind(this)); }, getContext: function() { @@ -82,13 +83,13 @@ JUnitReporter.prototype = { return outputPath; }, - onRead: function(err, result, done) { + onRead: function(result) { var context = this.getContext(); var outputPath = this.getOutputPath(); var xml = this.renderTPL(result, context); - this.write(outputPath, xml, done); + return this.write(outputPath, xml); }, renderTPL: function(tpl, context) { diff --git a/lib/meta.js b/lib/meta.js index 36d459d..49d9e3e 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -2,7 +2,8 @@ var _ = require('lodash'); var falafel = require('falafel'); var async = require('async'); var path = require('path'); -var fs = require('fs'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs')); var argv = require('./argv'); var base = require('./base'); var colors = require('cli-color-keywords')(); @@ -95,22 +96,17 @@ var extractFileMetaData = function(node, moduleInfo, fileName) { return moduleInfo; }; -var readFile = function(filePath, fileName, moduleInfo, done) { - fs.readFile( - filePath, - function(err, contents) { - if (!err) { - contents = falafel( - contents.toString(), - function(node) { - moduleInfo = extractFileMetaData(node, moduleInfo, fileName); - } - ); - } - - done(); +var readFile = function(filePath, fileName, moduleInfo) { + return fs.readFileAsync(filePath).then( + function(contents) { + contents = falafel( + contents.toString(), + function(node) { + moduleInfo = extractFileMetaData(node, moduleInfo, fileName); + } + ); } - ); + ).catch(_.noop); }; var checkMissingModuleInfo = function(files, metaDataObj) { @@ -179,9 +175,8 @@ var checkMetaData = function(config) { var fileSeries = []; - fs.readdir( - liferayModuleDir, - function(err, files) { + fs.readdirAsync(liferayModuleDir).then( + function(files) { files = files.filter( function(item, index) { return path.extname(item) == '.js' && item !== 'modules.js'; @@ -194,16 +189,11 @@ var checkMetaData = function(config) { files.forEach( function(item, index) { - fileSeries.push( - function(done) { - readFile(path.join(liferayModuleDir, item), item, moduleInfo, done); - } - ); + fileSeries.push(readFile(path.join(liferayModuleDir, item), item, moduleInfo)); } ); - async.series( - fileSeries, + return Promsie.all(fileSeries).then( function(results) { var moduleKeys = Object.keys(moduleInfo.meta); var fileModuleKeys = Object.keys(moduleInfo.fileMeta); @@ -318,8 +308,6 @@ var checkMetaData = function(config) { console.log(colors.subtle('----')); } - - done(); } ); } @@ -328,6 +316,6 @@ var checkMetaData = function(config) { module.exports = { check: function(config) { - checkMetaData(config); + return checkMetaData(config); } }; \ No newline at end of file diff --git a/package.json b/package.json index da26c63..819d397 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "dependencies": { "async": "^1.5.2", "babel-eslint": "^6.0.0-beta.5", + "bluebird": "^3.3.5", "chalk": "^1.1.1", "cli": "^0.8.0", "cli-color-keywords": "0.0.1", diff --git a/test/cli.js b/test/cli.js index eed66d9..c28d40f 100644 --- a/test/cli.js +++ b/test/cli.js @@ -3,6 +3,7 @@ var chai = require('chai'); var fs = require('fs'); var path = require('path'); var sinon = require('sinon'); +var Promise = require('bluebird'); var cli = require('../lib/cli'); var File = require('../lib/file'); @@ -24,7 +25,19 @@ describe( }; var invalidContentStub = function(path, encoding, callback) { - callback(null, MAP_CONTENT[path][0]); + var file = MAP_CONTENT[path]; + + if (file) { + callback(null, file[0]); + } + else { + var err = new Error('File missing'); + + err.errno = 34; + err.code = 'ENOENT'; + + callback(err); + } }; var validContentStub = function(path, contents, callback) { @@ -60,8 +73,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(fs.readFile.calledThrice, 'fs.readFile should have been called 3 times, it was instead called ' + fs.readFile.callCount + ' times'); assert.isTrue(fs.readFile.calledWith('foo.js'), 'foo.js should have been read'); @@ -71,8 +83,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -97,8 +107,7 @@ describe( sandbox.spy(cliInstance, 'logResults'); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(fs.writeFile.calledThrice, 'fs.writeFile should have been called 3 times, it was instead called ' + fs.writeFile.callCount + ' times'); assert.isTrue(fs.writeFile.calledWith('foo.js'), 'foo.js should have been written to'); @@ -119,8 +128,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -143,8 +150,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(fs.writeFile.calledOnce, 'fs.writeFile should have been called once, it was instead called ' + fs.writeFile.callCount + ' times'); assert.isTrue(File.handleFileWriteError.calledOnce, 'File.handleFileWriteError should have been called once, it was instead called ' + File.handleFileWriteError.callCount + ' times'); @@ -152,8 +158,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -174,16 +178,13 @@ describe( cliInstance.processFileData = processFileData; - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isFalse(processFileData.called, 'processFileData should not have been called for a non-recognized file, it was instead called ' + processFileData.callCount + ' times'); done(); } ); - - cliInstance.init(); } ); @@ -210,18 +211,14 @@ describe( var metaChecker = require(metaCheckerPath); - var checkMeta = sandbox.stub(metaChecker, 'check').yieldsTo('done'); + var checkMeta = sandbox.stub(metaChecker, 'check'); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(checkMeta.called, 'metaChecker.check should have been called, it was instead called ' + checkMeta.callCount + ' times'); - - done(); } - ); - - cliInstance.init(); + ) + .done(done); } ); @@ -248,18 +245,13 @@ describe( var metaChecker = require(metaCheckerPath); - var checkMeta = sandbox.stub(metaChecker, 'check').yieldsTo('done'); + var checkMeta = sandbox.stub(metaChecker, 'check'); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(checkMeta.notCalled, 'metaChecker.check should not have been called, it was instead called ' + metaChecker.check.callCount + ' times'); - - done(); } - ); - - cliInstance.init(); + ).done(done); } ); @@ -278,8 +270,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); @@ -292,8 +283,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -317,16 +306,13 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledTwice, 'log should have been called twice, it was instead called ' + log.callCount + ' times'); done(); } ); - - cliInstance.init(); } ); @@ -356,8 +342,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.equal(args.join(), log.args.join()); @@ -365,8 +350,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -410,8 +393,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.equal(relativeArgs.join(), log.args.join()); @@ -419,8 +401,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -441,8 +421,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.isTrue(File.handleFileReadError.calledOnce, 'File.handleFileReadError should have been called, it was instead called ' + File.handleFileReadError.callCount + ' times'); @@ -450,8 +429,37 @@ describe( done(); } ); + } + ); - cliInstance.init(); + it( + 'should not write missing files', + function(done) { + sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'writeFile').callsArgWith(2, null); + + sandbox.stub(File, 'handleFileReadError').returns('Missing file'); + + var log = sandbox.spy(); + + var cliInstance = new cli.CLI( + { + args: ['foo.js', 'bar.html', 'not_a_file.css'], + flags: { + inlineEdit: true + }, + log: log, + logger: new Logger.constructor() + } + ); + + cliInstance.init().then( + function() { + assert.isTrue(fs.writeFile.calledTwice, 'writeFile should have been called only 2 times, it was instead called ' + fs.writeFile.callCount + ' times'); + + done(); + } + ); } ); @@ -477,8 +485,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.notCalled, 'log should not have been called, it was instead called ' + log.callCount + ' times'); assert.isTrue(File.handleFileReadError.returned(''), 'File.handleFileReadError should have returned nothing'); @@ -486,8 +493,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -541,8 +546,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); assert.isTrue(cliModule.exec.calledTwice, 'cliModule.exec should have been called 2 times, it was instead called ' + cliModule.exec.callCount + ' times'); @@ -550,8 +554,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -601,7 +603,7 @@ describe( var junit = sandbox.spy(junitReporter); - sandbox.stub(junit.prototype, 'generate').callsArg(0); + sandbox.stub(junit.prototype, 'generate').returns(Promise.resolve()); var cliInstance = new cli.CLI( { @@ -615,17 +617,12 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(junit.calledWithNew(), 'junit should have been instantiated'); assert.isTrue(junit.prototype.generate.called, 'junit.prototype.generate should have been called, it was instead called ' + junit.prototype.generate.callCount + ' times'); - - done(); } - ); - - cliInstance.init(); + ).done(done); } ); @@ -646,16 +643,13 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(cliInstance.flags.quiet); done(); } ); - - cliInstance.init(); } ); @@ -678,8 +672,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isNotTrue(cliInstance.flags.quiet); assert.isUndefined(log.args[0]); @@ -687,8 +680,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -711,8 +702,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isFalse(cliInstance.flags.verbose); assert.notStartsWith(log.args[0][0], 'Could not resolve any local config'); @@ -720,8 +710,6 @@ describe( done(); } ); - - cliInstance.init(); } ); @@ -745,8 +733,7 @@ describe( } ); - cliInstance.on( - 'finish', + cliInstance.init().then( function() { assert.isTrue(cliInstance.flags.verbose); assert.startsWith(log.args[0][0], 'Could not resolve any local config'); @@ -754,8 +741,6 @@ describe( done(); } ); - - cliInstance.init(); } ); } diff --git a/test/junit.js b/test/junit.js index 5b47906..34c44d6 100644 --- a/test/junit.js +++ b/test/junit.js @@ -32,7 +32,7 @@ describe( it( 'should generate a JUnit report', - function() { + function(done) { var logger = new Logger.constructor(); logger.log(1, 'Content is not valid', 'foo.js'); @@ -65,20 +65,19 @@ describe( } ); - var cb = sandbox.spy(); - var reporter = new junit( { logger: logger } ); - reporter.generate(cb); + reporter.generate().then( + function(results) { + assert.isTrue(fs.writeFile.called, 'writeFile should have been called'); - assert.isTrue(fs.writeFile.called, 'writeFile should have been called'); - assert.isTrue(cb.called, 'cb should have been executed'); - - assert.equal(cb.args[0][1], fs.readFileSync(path.join(__dirname, 'fixture', 'result.xml'), 'utf-8'), 'The result should match what we expect'); + assert.equal(results, fs.readFileSync(path.join(__dirname, 'fixture', 'result.xml'), 'utf-8'), 'The result should match what we expect'); + } + ).done(done); } ); @@ -117,22 +116,23 @@ describe( this.timeout(5000); - var cb = sandbox.spy(); - var reporter = new junit( { logger: logger } ); - reporter.generate(cb); - - xsd.validateXML( - cb.args[0][1], - path.join(__dirname, 'fixture', 'junit-4.xsd'), - function(err, result) { - assert.isTrue(result.valid, err); - done(); + reporter.generate().then( + function(results) { + xsd.validateXML( + results, + path.join(__dirname, 'fixture', 'junit-4.xsd'), + function(err, result) { + assert.isTrue(result.valid, err); + + done(); + } + ); } ); } @@ -153,15 +153,12 @@ describe( function(path, content, callback) { callback(null, content); - assert.isTrue(cb.called, 'cb should have been executed'); assert.equal(path, 'custom_result.xml'); done(); } ); - var cb = sandbox.spy(); - var reporter = new junit( { flags: { @@ -170,7 +167,7 @@ describe( } ); - reporter.generate(cb); + reporter.generate(); } ); } From 9866f0d5b39b81e55e2d37d3e71f698b8e9be08e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 19 Apr 2016 08:20:02 -0700 Subject: [PATCH 038/153] Nested function calls will trigger a false positive. Fixes #13 --- lib/lint_js_rules/format_args.js | 40 ++++++++++++++++++++++++------- test/lint_js_rules/format_args.js | 21 +++++++++++++++- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/lint_js_rules/format_args.js b/lib/lint_js_rules/format_args.js index f7f5030..4f5dfee 100644 --- a/lib/lint_js_rules/format_args.js +++ b/lib/lint_js_rules/format_args.js @@ -4,6 +4,14 @@ var base = require('../base'); var sub = require('string-sub'); module.exports = function(context) { + var isFunctionExpression = function(type) { + return _.endsWith(type, 'FunctionExpression'); + }; + + var isCallable = function(type) { + return isFunctionExpression(type) || type === 'CallExpression'; + }; + var getAnonymousFnName = function(fnName) { if (!fnName) { fnName = ''; @@ -12,14 +20,30 @@ module.exports = function(context) { return fnName; }; + var sc = context.getSourceCode(); + var getFnExpLines = function(lineBounds, node) { - var end = getLineBounds(node, 'end'); - var start = end; + var end = lineBounds.end; + var start = lineBounds.start; + + if (isFunctionExpression(node.callee.type)) { + start = end; + } node.arguments.forEach( function(item, index) { - start = item.loc.start.line; - end = item.loc.end.line; + var type = item.type; + + if (isCallable(type)) { + var lineBounds = getFnLines(item); + + start = Math.min(lineBounds.start, start); + end = Math.max(lineBounds.end, end); + } + else { + start = item.loc.start.line; + end = item.loc.end.line; + } } ); @@ -36,7 +60,7 @@ module.exports = function(context) { var type = callee.type; - if (type === 'FunctionExpression' || type === 'ArrowFunctionExpression' || type === 'CallExpression') { + if (isCallable(type)) { lineBounds = getFnExpLines(lineBounds, node); } else if (type === 'MemberExpression') { @@ -58,7 +82,7 @@ module.exports = function(context) { var type = callee.type; - if (type === 'FunctionExpression' || type === 'ArrowFunctionExpression') { + if (isFunctionExpression(type)) { fnName = getAnonymousFnName(fnName); } else if (type === 'MemberExpression') { @@ -117,7 +141,7 @@ module.exports = function(context) { var logArgError = function(fnLines, fnName, node) { var message; - var obj = processArgs(node.arguments, fnLines); + var obj = processArgs(node.arguments, fnLines, node); var error = obj.error; @@ -128,7 +152,7 @@ module.exports = function(context) { } }; - var processArgs = function(args, options) { + var processArgs = function(args, options, node) { var obj = {}; var fnStart = options.start; diff --git a/test/lint_js_rules/format_args.js b/test/lint_js_rules/format_args.js index d8d28bf..5275248 100644 --- a/test/lint_js_rules/format_args.js +++ b/test/lint_js_rules/format_args.js @@ -39,6 +39,11 @@ alert(function() { alert(function() {alert('foo');}, 1); alert({x: 1}, 1); +firstFn(arg1)( + secondFn(arg2)( + thirdFn() + ) +) */ ruleTester.run( path.basename(__filename, '.js'), @@ -51,7 +56,9 @@ ruleTester.run( 'alert(\nfunction() {\n},\n1\n);', '(function foo(){\n}());', '(function(){\n}(\n));', - 'alert(\n{\nx: 1\n}\n)(foo);' + 'alert(\n{\nx: 1\n}\n)(foo);', + 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n)\n)', + 'firstFn(arg1)(\nsecondFn(\n{\nx: 1\n}\n)(\nthirdFn()\n)\n)' ], invalid: [ @@ -102,6 +109,18 @@ ruleTester.run( { code: 'alert()(foo, {\nx: 1\n});', errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] + }, + { + code: 'firstFn(arg1)(secondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n)\n)', + errors: [ { message: 'Args should each be on their own line (args on start line): firstFn(...)' } ] + }, + { + code: 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n))', + errors: [ { message: 'Args should each be on their own line (args on end line): firstFn(...)' } ] + }, + { + code: 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(\n{\nx: 1\n})(\nfifthFn()\n)\n)\n)\n)', + errors: [ { message: 'Args should each be on their own line (args on end line): fourthFn(...)' } ] } ] } From 57773f10b1270507b0fdce50a07ef05d01f5c43b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 19 Apr 2016 09:47:36 -0700 Subject: [PATCH 039/153] Update deps and enable new rules --- lib/config/eslint_es6.js | 34 ++++++++++++++++++++++++++++++---- package.json | 6 +++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 8634b41..10209be 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -30,10 +30,10 @@ module.exports = { 'jsx-pascal-case': 2, 'jsx-space-before-closing': [2, 'always'], 'jsx-sort-props': [2, {'ignoreCase': true}], - 'no-multi-comp': [2/*, {'ignoreStateless': true}*/], + 'no-multi-comp': [2, {'ignoreStateless': true}], 'wrap-multilines': [2/*, {'ignoreStateless': true}*/], 'no-unknown-property': 2, - 'sort-comp': [2, { + 'sort-comp': [0, { order: [ 'static-methods', 'lifecycle', @@ -65,10 +65,36 @@ module.exports = { } }], + 'prop-types': 0, + 'display-name': 0, + 'no-danger': 0, + 'no-set-state': 0, + 'no-is-mounted': 0, + 'no-deprecated': 0, + 'no-did-mount-set-state': 0, + 'no-did-update-set-state': 0, + 'react-in-jsx-scope': 0, + 'jsx-handler-names': 0, + 'jsx-boolean-value': 0, + 'require-extension': 0, + 'jsx-max-props-per-line': 0, + 'no-string-refs': 0, + 'prefer-stateless-function': 0, + + 'require-render-return': 2, + 'jsx-first-prop-new-line': [2, 'multiline'], + 'self-closing-comp': 2, + 'sort-prop-types': 2, + 'no-direct-mutation-state': 2, + + 'forbid-prop-types': 0, + 'jsx-no-bind': 0, + 'prefer-es6-class': 0, + 'arrow-body-style': [0, 'as-needed'], 'arrow-parens': [2, 'as-needed'], - 'object-shorthand': [2, 'always', { 'ignoreConstructors': true }], - 'prefer-arrow-callback': 2, + 'object-shorthand': [2, 'always', {'ignoreConstructors': true}], + 'prefer-arrow-callback': [2, {'allowNamedFunctions': true}], 'no-new-symbol': 2, 'prefer-const': 2, 'prefer-rest-params': 2, diff --git a/package.json b/package.json index 819d397..3724093 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,13 @@ "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^2.5.3", - "eslint-plugin-react": "^4.1.0", + "eslint": "^2.8.0", + "eslint-plugin-react": "^5.0.1", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", "handlebars": "^4.0.5", - "lodash": "^4.6.1", + "lodash": "^4.11.1", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", "minimatch": "^3.0.0", From 9e61f9c04c2bed5efa72e80be9b21af0f4ea52e6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 25 Apr 2016 10:07:32 -0700 Subject: [PATCH 040/153] Warn when creating functions in the render method --- lib/config/eslint_es6.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 10209be..bff6f3c 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -88,7 +88,7 @@ module.exports = { 'no-direct-mutation-state': 2, 'forbid-prop-types': 0, - 'jsx-no-bind': 0, + 'jsx-no-bind': 2, 'prefer-es6-class': 0, 'arrow-body-style': [0, 'as-needed'], From 182d56e8e89af52fe1c4746ff5cea1b32ad00a82 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 25 Apr 2016 10:14:55 -0700 Subject: [PATCH 041/153] Update usage of eslints dotnotation rule --- lib/lint_js_rules/dot_notation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lint_js_rules/dot_notation.js b/lib/lint_js_rules/dot_notation.js index 60fddf9..452bbdb 100644 --- a/lib/lint_js_rules/dot_notation.js +++ b/lib/lint_js_rules/dot_notation.js @@ -7,9 +7,9 @@ module.exports = function(context) { var propertyType = node.property.type; if (propertyType === 'Literal' && !REGEX.STUBS.test(propertyValue)) { - var dotNotation = require('../../node_modules/eslint/lib/rules/dot-notation'); + var dotNotation = require('eslint/lib/rules/dot-notation'); - dotNotation(context).MemberExpression(node); + dotNotation.create(context).MemberExpression(node); } } }; From fe8abec650c9a3bec1b1f97cf10c6f8cb7ba8dd4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 25 Apr 2016 10:55:52 -0700 Subject: [PATCH 042/153] Pinning babel-eslint to 6.0.2 for now, as 6.0.3 throws an error --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3724093..ab629db 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "preferGlobal": "true", "dependencies": { "async": "^1.5.2", - "babel-eslint": "^6.0.0-beta.5", + "babel-eslint": "6.0.2", "bluebird": "^3.3.5", "chalk": "^1.1.1", "cli": "^0.8.0", @@ -64,4 +64,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} +} \ No newline at end of file From 5c5414db866b1d08ef2799b490f606b76c179e0c Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 25 Apr 2016 11:11:45 -0700 Subject: [PATCH 043/153] 2.0.0-rc.4 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ab629db..7212193 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.3", + "version": "2.0.0-rc.4", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { @@ -64,4 +64,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} \ No newline at end of file +} From 4d82ffbd795ac033532d8fa9010bcf8867733572 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 25 Apr 2016 12:00:38 -0700 Subject: [PATCH 044/153] Update update-notifier --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7212193..d26a62c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "update-notifier": "^0.5.0" + "update-notifier": "^0.6.3" }, "devDependencies": { "chai": "^3.5.0", From 734a0a3c68847d74189a54dbcc572b8f8708ad32 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 26 Apr 2016 11:53:34 -0700 Subject: [PATCH 045/153] Disabling this rule for now --- lib/config/eslint_es6.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index bff6f3c..d174cf8 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -30,7 +30,7 @@ module.exports = { 'jsx-pascal-case': 2, 'jsx-space-before-closing': [2, 'always'], 'jsx-sort-props': [2, {'ignoreCase': true}], - 'no-multi-comp': [2, {'ignoreStateless': true}], + 'no-multi-comp': [0, {'ignoreStateless': true}], 'wrap-multilines': [2/*, {'ignoreStateless': true}*/], 'no-unknown-property': 2, 'sort-comp': [0, { From f2b0ac4adc7714ae78c3385c136c0933e10753cd Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 28 Apr 2016 14:19:32 -0700 Subject: [PATCH 046/153] Fixing cases where the args checking would throw errors... still need to revisit the tests --- lib/lint_js_rules/format_args.js | 57 +++++++++++++++++-------------- test/lint_js_rules/format_args.js | 12 ++++++- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/lib/lint_js_rules/format_args.js b/lib/lint_js_rules/format_args.js index 4f5dfee..db86a7d 100644 --- a/lib/lint_js_rules/format_args.js +++ b/lib/lint_js_rules/format_args.js @@ -26,26 +26,28 @@ module.exports = function(context) { var end = lineBounds.end; var start = lineBounds.start; - if (isFunctionExpression(node.callee.type)) { + if (node.callee && isFunctionExpression(node.callee.type)) { start = end; } - node.arguments.forEach( - function(item, index) { - var type = item.type; - - if (isCallable(type)) { - var lineBounds = getFnLines(item); - - start = Math.min(lineBounds.start, start); - end = Math.max(lineBounds.end, end); - } - else { - start = item.loc.start.line; - end = item.loc.end.line; + if (node.arguments && node.arguments.length) { + node.arguments.forEach( + function(item, index) { + var type = item.type; + + if (isCallable(type)) { + var argLineBounds = getFnLines(item); + + start = Math.min(argLineBounds.start, start); + end = Math.max(argLineBounds.end, end); + } + else { + start = item.loc.start.line; + end = item.loc.end.line; + } } - } - ); + ); + } lineBounds.end = end; lineBounds.start = start; @@ -54,19 +56,24 @@ module.exports = function(context) { }; var getFnLines = function(node) { - var callee = node.callee; - var lineBounds = getLineBounds(node); - var type = callee.type; + var callee = node.callee; - if (isCallable(type)) { - lineBounds = getFnExpLines(lineBounds, node); - } - else if (type === 'MemberExpression') { - lineBounds.end = getLineBounds(node, 'end'); - lineBounds.start = getLineBounds(callee, 'end'); + if (callee) { + var type = callee.type; + + if (isCallable(type)) { + lineBounds = getFnExpLines(lineBounds, node); + } + else if (type === 'MemberExpression') { + lineBounds.end = getLineBounds(node, 'end'); + lineBounds.start = getLineBounds(callee, 'end'); + } } + // else if (isFunctionExpression(node.type)) { + // lineBounds = getFnExpLines(lineBounds, node); + // } lineBounds.multi = (lineBounds.end > lineBounds.start); diff --git a/test/lint_js_rules/format_args.js b/test/lint_js_rules/format_args.js index 5275248..4c463b7 100644 --- a/test/lint_js_rules/format_args.js +++ b/test/lint_js_rules/format_args.js @@ -58,7 +58,13 @@ ruleTester.run( '(function(){\n}(\n));', 'alert(\n{\nx: 1\n}\n)(foo);', 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n)\n)', - 'firstFn(arg1)(\nsecondFn(\n{\nx: 1\n}\n)(\nthirdFn()\n)\n)' + 'firstFn(arg1)(\nsecondFn(\n{\nx: 1\n}\n)(\nthirdFn()\n)\n)', + // I need to come back to this test... + // It passes if the identifier is the last argument, + // but fails when it's the first. + // I also wonder about variations of this, like (var, fn, var) or (fn, var, obj, var), etc + // UPDATE: (var, obj), (fn, var, fn), and (fn, var, obj) fail as well + // '(function(arg1) {\nreturn function(){\n};\n})(\nobj,\nfunction(exp){\nreturn "";\n}\n);' ], invalid: [ @@ -121,6 +127,10 @@ ruleTester.run( { code: 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(\n{\nx: 1\n})(\nfifthFn()\n)\n)\n)\n)', errors: [ { message: 'Args should each be on their own line (args on end line): fourthFn(...)' } ] + }, + { + code: '(function(arg1) {\nreturn function(){};\n})(obj, function(exp){\n});', + errors: [ { message: 'Args should each be on their own line (args on same line): (...)' } ] } ] } From d391e78a86e06beed03270f19785e01220e5c1a7 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 28 Apr 2016 14:48:35 -0700 Subject: [PATCH 047/153] Hopefully I'll be able to move to template strings in the future, but for now, I want to keep new line sensitive tests obvious --- test/lint_js_rules/format_args.js | 132 +++++++++++++++++++++++++----- test/test_utils/index.js | 7 ++ 2 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 test/test_utils/index.js diff --git a/test/lint_js_rules/format_args.js b/test/lint_js_rules/format_args.js index 4c463b7..d6f8279 100644 --- a/test/lint_js_rules/format_args.js +++ b/test/lint_js_rules/format_args.js @@ -2,6 +2,8 @@ var path = require('path'); var lint = require('../../lib/lint_js'); +var nl = require('../test_utils').nl; + var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -45,6 +47,7 @@ firstFn(arg1)( ) ) */ + ruleTester.run( path.basename(__filename, '.js'), require('../../lib/lint_js_rules/' + path.basename(__filename)), @@ -53,47 +56,96 @@ ruleTester.run( 'alert();', 'alert({}, 1);', 'alert(function() {}, 1);', - 'alert(\nfunction() {\n},\n1\n);', - '(function foo(){\n}());', - '(function(){\n}(\n));', - 'alert(\n{\nx: 1\n}\n)(foo);', - 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n)\n)', - 'firstFn(arg1)(\nsecondFn(\n{\nx: 1\n}\n)(\nthirdFn()\n)\n)', + + nl('alert(', + 'function() {', + '},', + '1', + ');'), + + nl('(function foo(){', + '}());'), + + nl('(function(){', + '}(', + '));'), + + nl('alert(', + '{', + 'x: 1', + '}', + ')(foo);'), + nl('firstFn(arg1)(', + 'secondFn(arg2)(', + 'thirdFn(', + 'fourthFn(arg3)(', + 'fifthFn()', + ')', + ')', + ')', + ')'), + nl('firstFn(arg1)(', + 'secondFn(', + '{', + 'x: 1', + '}', + ')(', + 'thirdFn()', + ')', + ')'), // I need to come back to this test... // It passes if the identifier is the last argument, // but fails when it's the first. // I also wonder about variations of this, like (var, fn, var) or (fn, var, obj, var), etc // UPDATE: (var, obj), (fn, var, fn), and (fn, var, obj) fail as well - // '(function(arg1) {\nreturn function(){\n};\n})(\nobj,\nfunction(exp){\nreturn "";\n}\n);' + // nl('(function(arg1) {', + // 'return function(){', + // '};', + // '})(', + // 'obj,', + // 'function(exp){', + // 'return "";', + // '}', + // ');') ], invalid: [ { - code: 'alert(function() {\n}, 1, 2);', + code: nl('alert(function() {', + '}, 1, 2);'), errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] }, { - code: 'alert(\n1, 2, 3\n);', + code: nl('alert(', + '1, 2, 3', + ');'), errors: [ { message: 'Function call can be all on one line: alert(...)' } ] }, { - code: 'alert(\n);', + code: nl('alert(', + ');'), errors: [ { message: 'Function call without arguments should be on one line: alert()' } ] }, { - code: 'alert(function() {\n},\n1);', + code: nl('alert(function() {', + '},', + '1);'), errors: [ { message: 'Args should each be on their own line (args on end line): alert(...)' } ] }, { - code: 'alert(function() {\n},\n1\n);', + code: nl('alert(function() {', + '},', + '1', + ');'), errors: [ { message: 'Args should each be on their own line (args on start line): alert(...)' } ] }, { - code: 'alert(function() {\n});', + code: nl('alert(function() {', + '});'), errors: [ { message: 'Args should each be on their own line (args on start line): alert(...)' } ] }, { - code: 'alert(function() {alert(\'foo\');}, 1);', + code: nl('alert(function() {alert(\'foo\');}, 1);'), errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] }, { @@ -101,35 +153,71 @@ ruleTester.run( errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] }, { - code: 'AUI()[\'add\'](function(){\n});', + code: nl('AUI()[\'add\'](function(){', + '});'), errors: [ { message: 'Args should each be on their own line (args on start line): AUI(...)' } ] }, { - code: '(function(){\n}(\n{x: 1},2,3\n));', + code: nl('(function(){', + '}(', + '{x: 1},2,3', + '));'), errors: [ { message: 'Args should each be on their own line (args on same line): (...)' } ] }, { - code: 'alert({\nx: 1\n})(foo);', + code: nl('alert({', + 'x: 1', + '})(foo);'), errors: [ { message: 'Args should each be on their own line (args on start line): alert(...)' } ] }, { - code: 'alert()(foo, {\nx: 1\n});', + code: nl('alert()(foo, {', + 'x: 1', + '});'), errors: [ { message: 'Args should each be on their own line (args on same line): alert(...)' } ] }, { - code: 'firstFn(arg1)(secondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n)\n)', + code: nl('firstFn(arg1)(secondFn(arg2)(', + 'thirdFn(', + 'fourthFn(arg3)(', + 'fifthFn()', + ')', + ')', + ')', + ')'), errors: [ { message: 'Args should each be on their own line (args on start line): firstFn(...)' } ] }, { - code: 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(arg3)(\nfifthFn()\n)\n)\n))', + code: nl('firstFn(arg1)(', + 'secondFn(arg2)(', + 'thirdFn(', + 'fourthFn(arg3)(', + 'fifthFn()', + ')', + ')', + '))'), errors: [ { message: 'Args should each be on their own line (args on end line): firstFn(...)' } ] }, { - code: 'firstFn(arg1)(\nsecondFn(arg2)(\nthirdFn(\nfourthFn(\n{\nx: 1\n})(\nfifthFn()\n)\n)\n)\n)', + code: nl('firstFn(arg1)(', + 'secondFn(arg2)(', + 'thirdFn(', + 'fourthFn(', + '{', + 'x: 1', + '})(', + 'fifthFn()', + ')', + ')', + ')', + ')'), errors: [ { message: 'Args should each be on their own line (args on end line): fourthFn(...)' } ] }, { - code: '(function(arg1) {\nreturn function(){};\n})(obj, function(exp){\n});', + code: nl('(function(arg1) {', + 'return function(){};', + '})(obj, function(exp){', + '});'), errors: [ { message: 'Args should each be on their own line (args on same line): (...)' } ] } ] diff --git a/test/test_utils/index.js b/test/test_utils/index.js new file mode 100644 index 0000000..15359e2 --- /dev/null +++ b/test/test_utils/index.js @@ -0,0 +1,7 @@ +var _ = require('lodash'); + +function nl() { + return _.toArray(arguments).join('\n'); +} + +exports.nl = nl; \ No newline at end of file From c7de659882ab50976afcd2b6ece5adcd8f0f490c Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 4 May 2016 10:46:19 -0700 Subject: [PATCH 048/153] Ignore prop case --- lib/config/eslint_es6.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index d174cf8..9ea57c0 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -84,7 +84,7 @@ module.exports = { 'require-render-return': 2, 'jsx-first-prop-new-line': [2, 'multiline'], 'self-closing-comp': 2, - 'sort-prop-types': 2, + 'sort-prop-types': [2, {'ignoreCase': true}], 'no-direct-mutation-state': 2, 'forbid-prop-types': 0, From 5cb0614d57739488e51610427f33786f6f9b2298 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 4 May 2016 10:47:27 -0700 Subject: [PATCH 049/153] ESLint has changed their exported object format. Fixes #14 --- lib/lint_js_rules/no_undef.js | 2 +- lib/lint_js_rules/no_unused_vars.js | 2 +- lib/lint_js_rules/no_use_before_define.js | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/lint_js_rules/no_undef.js b/lib/lint_js_rules/no_undef.js index 3703658..7dc4a0d 100644 --- a/lib/lint_js_rules/no_undef.js +++ b/lib/lint_js_rules/no_undef.js @@ -4,7 +4,7 @@ var base = require('../base'); var stubs = base.stubs; module.exports = function(context) { - var noUndef = require('eslint/lib/rules/no-undef'); + var noUndef = require('eslint/lib/rules/no-undef').create; var collectedReport = []; diff --git a/lib/lint_js_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js index ac64091..64bf5a1 100644 --- a/lib/lint_js_rules/no_unused_vars.js +++ b/lib/lint_js_rules/no_unused_vars.js @@ -17,7 +17,7 @@ module.exports = function(context) { var options = context.options; if (options.length && options[0].jsp === true) { - var noUnused = require('eslint/lib/rules/no-unused-vars'); + var noUnused = require('eslint/lib/rules/no-unused-vars').create; var collectedReport = []; diff --git a/lib/lint_js_rules/no_use_before_define.js b/lib/lint_js_rules/no_use_before_define.js index 0d184d9..4f2c0ac 100644 --- a/lib/lint_js_rules/no_use_before_define.js +++ b/lib/lint_js_rules/no_use_before_define.js @@ -4,7 +4,7 @@ var base = require('../base'); var stubs = base.stubs; module.exports = function(context) { - var noUse = require('eslint/lib/rules/no-use-before-define'); + var noUse = require('eslint/lib/rules/no-use-before-define').create; var collectedReport = []; diff --git a/package.json b/package.json index d26a62c..4b0f60c 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^2.8.0", + "eslint": "^2.9.0", "eslint-plugin-react": "^5.0.1", "falafel": "^1.2.0", "getobject": "^0.1.0", From 8696f87f7a0d41a58c5bcec2032a05269408943f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 4 May 2016 11:35:33 -0700 Subject: [PATCH 050/153] 2.0.0-rc.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b0f60c..afe5887 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.4", + "version": "2.0.0-rc.5", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { From f12a2da3b73a8f9167f2c9f64f3896edb6941d64 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 5 May 2016 14:48:01 -0700 Subject: [PATCH 051/153] Extract ES6 iterator for tests into test_utils --- test/lint_js_rules/format_multiline_vars.js | 6 +----- test/lint_js_rules/sort_props.js | 11 ++++------- test/lint_js_rules/sort_vars.js | 11 ++++------- test/test_utils/index.js | 12 ++++++++++-- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/test/lint_js_rules/format_multiline_vars.js b/test/lint_js_rules/format_multiline_vars.js index 85d53fa..7302043 100644 --- a/test/lint_js_rules/format_multiline_vars.js +++ b/test/lint_js_rules/format_multiline_vars.js @@ -8,11 +8,7 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); -var addES6 = function(item, index) { - item.parserOptions = { ecmaVersion: 6 }; - - return item; -}; +var addES6 = require('../test_utils').addES6(); ruleTester.run( path.basename(__filename, '.js'), diff --git a/test/lint_js_rules/sort_props.js b/test/lint_js_rules/sort_props.js index 7831131..2ba886a 100644 --- a/test/lint_js_rules/sort_props.js +++ b/test/lint_js_rules/sort_props.js @@ -7,16 +7,13 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); -var addES6 = function(item, index) { - item.parserOptions = { - ecmaVersion: 6, +var addES6 = require('../test_utils').addES6( + { ecmaFeatures: { experimentalObjectRestSpread: true } - }; - - return item; -}; + } +); ruleTester.run( path.basename(__filename, '.js'), diff --git a/test/lint_js_rules/sort_vars.js b/test/lint_js_rules/sort_vars.js index 2ac6ad1..0589f85 100644 --- a/test/lint_js_rules/sort_vars.js +++ b/test/lint_js_rules/sort_vars.js @@ -7,15 +7,12 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); -var addES6 = function(item, index) { - item.parserOptions = { - ecmaVersion: 6, +var addES6 = require('../test_utils').addES6( + { ecmaFeatures: {}, sourceType: 'module' - }; - - return item; -}; + } +); ruleTester.run( path.basename(__filename, '.js'), diff --git a/test/test_utils/index.js b/test/test_utils/index.js index 15359e2..7f7a667 100644 --- a/test/test_utils/index.js +++ b/test/test_utils/index.js @@ -1,7 +1,15 @@ var _ = require('lodash'); -function nl() { +exports.nl = function() { return _.toArray(arguments).join('\n'); } -exports.nl = nl; \ No newline at end of file +exports.addES6 = function(config) { + var parserOptions = _.merge({ ecmaVersion: 6 }, config); + + return function(item, index) { + item.parserOptions = parserOptions; + + return item; + }; +}; \ No newline at end of file From 805827a4ced3064bb53e3c3350a51546671a9a9c Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 5 May 2016 14:49:31 -0700 Subject: [PATCH 052/153] Add test for es6 arrow functions and arguments --- test/lint_js_rules/format_args.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/lint_js_rules/format_args.js b/test/lint_js_rules/format_args.js index d6f8279..46d139b 100644 --- a/test/lint_js_rules/format_args.js +++ b/test/lint_js_rules/format_args.js @@ -2,7 +2,11 @@ var path = require('path'); var lint = require('../../lib/lint_js'); -var nl = require('../test_utils').nl; +var testUtils = require('../test_utils'); + +var nl = testUtils.nl; + +var addES6 = testUtils.addES6(); var linter = lint.linter; var RuleTester = lint.eslint.RuleTester; @@ -107,7 +111,16 @@ ruleTester.run( // 'return "";', // '}', // ');') - ], + ].concat( + [ + { code: nl( + 'doSomethingPromisable()', + '.then((foo) => doSomethingMorePromisable(foo))', + '.then((bar) => finish(bar))' + ) + } + ].map(addES6) + ), invalid: [ { From a6f7a59902334efb4ab6c9f09f782e31cbf3a421 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 10:35:32 -0700 Subject: [PATCH 053/153] Allow es6 configurations to be overwritten (before, default configs were able to be overwritten, but merging in user configs was done before es6 configs were brought in) --- lib/lint_js.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/lint_js.js b/lib/lint_js.js index 7e16bed..fe79ea7 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -19,21 +19,22 @@ var convertNameToRuleId = function(item) { var runLinter = function(contents, file, customRules, config) { eslint.linter.defineRules(customRules); - if (_.isObject(config)) { - config = _.merge({}, ESLINT_CONFIG, config); - } - else { - config = ESLINT_CONFIG; - } - var ecmaVersion = _.get(config, 'parserOptions.ecmaVersion'); + var configs = [{}, ESLINT_CONFIG]; + if (ecmaVersion > 5) { var es6Config = require('./config/eslint_es6'); - _.merge(config, es6Config); + configs.push(es6Config); } + if (_.isObject(config)) { + configs.push(config); + } + + config = _.merge.apply(_, configs); + return eslint.linter.verify(contents, config, file); }; From f36100a4904ee1dff2f50f93829d8c0f003a7b47 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 10:46:41 -0700 Subject: [PATCH 054/153] Updating deps --- package.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index afe5887..8b57cf9 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,7 @@ "async": "^1.5.2", "babel-eslint": "6.0.2", "bluebird": "^3.3.5", - "chalk": "^1.1.1", - "cli": "^0.8.0", + "cli": "^0.11.2", "cli-color-keywords": "0.0.1", "content-formatter": "^1.1.0", "content-logger": "^0.0.3", @@ -33,19 +32,18 @@ "cosmiconfig": "^1.1.0", "drip": "^1.4.0", "eslint": "^2.9.0", - "eslint-plugin-react": "^5.0.1", + "eslint-plugin-react": "^5.1.1", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.0", - "handlebars": "^4.0.5", - "lodash": "^4.11.1", + "lodash": "^4.12.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", "minimatch": "^3.0.0", "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "update-notifier": "^0.6.3" + "update-notifier": "^0.7.0" }, "devDependencies": { "chai": "^3.5.0", From ad87f70b521bdf975ec00454e7710c8a13c63b49 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 11:41:44 -0700 Subject: [PATCH 055/153] Not recreating the context object on every iteration of a file (still need to do it for the CSS formatter, but split up the props for when I get a chance to revisit) --- lib/css.js | 21 ++++++++++++--------- lib/html.js | 13 +++++++------ lib/js.js | 19 ++++++++++--------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/css.js b/lib/css.js index 008e8ca..1217e00 100644 --- a/lib/css.js +++ b/lib/css.js @@ -109,6 +109,11 @@ Formatter.CSS = Formatter.create( }, _getContext: function(content, index, collection, logger) { + var context = { + collection: collection, + file: this.file + }; + var lineNum = index + 1; var nextItem = collection[lineNum] && collection[lineNum].trim(); var previousItem = null; @@ -120,15 +125,13 @@ Formatter.CSS = Formatter.create( var propertyRules = this._re.rules.css._properties; - return context = { - collection: collection, - content: content, - file: this.file, - index: index, - lineNum: lineNum, - nextItem: nextItem, - previousItem: previousItem - }; + context.content = content; + context.index = index; + context.lineNum = lineNum; + context.nextItem = nextItem; + context.previousItem = previousItem; + + return context; }, } } diff --git a/lib/html.js b/lib/html.js index a5a5206..8743b5c 100644 --- a/lib/html.js +++ b/lib/html.js @@ -132,6 +132,10 @@ Formatter.HTML = Formatter.create( var re = instance._re; + var context = { + file: filePath + }; + return iterateLines( contents, function(content, index, collection) { @@ -155,12 +159,9 @@ Formatter.HTML = Formatter.create( rawContent = instance._attrRestoreScriptlets(rawContent, lineNum); rawContent = instance._attrRestoreTags(rawContent, lineNum); - var context = { - content: content, - file: filePath, - lineNum: lineNum, - rawContent: rawContent - }; + context.content = content; + context.lineNum = lineNum; + context.rawContent = rawContent; rawContent = re.iterateRules('common', context); diff --git a/lib/js.js b/lib/js.js index 1434b20..f306518 100644 --- a/lib/js.js +++ b/lib/js.js @@ -58,6 +58,12 @@ Formatter.JS = Formatter.create( var re = this._re; + var context = { + customIgnore: re.rules.js.IGNORE, + file: filePath, + hasSheBang: hasSheBang + }; + return iterateLines( contents, function(content, index, collection) { @@ -69,15 +75,10 @@ Formatter.JS = Formatter.create( var lineNum = index + 1; - var context = { - content: content, - customIgnore: re.rules.js.IGNORE, - file: filePath, - hasSheBang: hasSheBang, - lineNum: lineNum, - nextItem: collection[lineNum] && collection[lineNum].trim(), - rawContent: rawContent - }; + context.content = content; + context.lineNum = lineNum; + context.nextItem = collection[lineNum] && collection[lineNum].trim(); + context.rawContent = rawContent; rawContent = re.iterateRules('common', context); From c42aeb841eb60c9f44b320b4ebe71f1b9810b61f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 13:14:23 -0700 Subject: [PATCH 056/153] Restructing linting to pass along a context of the app to the rule configs --- lib/js.js | 31 ++++++++++++++++++------------- lib/lint_js.js | 12 +++++++++--- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/js.js b/lib/js.js index f306518..4dd3cd4 100644 --- a/lib/js.js +++ b/lib/js.js @@ -38,11 +38,24 @@ Formatter.JS = Formatter.create( format: function(contents, lint) { var hasSheBang = this._hasSheBang(contents); + var rawContents = contents; + if (hasSheBang) { contents = '//' + contents; } - this._lint(contents, this.flags.lint !== false && lint); + var filePath = this.file; + + var re = this._re; + + var context = { + customIgnore: re.rules.js.IGNORE, + file: filePath, + hasSheBang: hasSheBang, + lintConfig: this.flags.lint !== false && lint + }; + + this._lint(contents, context); if (this.flags.verbose) { this._processSyntax(contents); @@ -52,18 +65,8 @@ Formatter.JS = Formatter.create( contents = contents.substr(2, contents.length); } - var filePath = this.file; - var logger = this.log.bind(this); - var re = this._re; - - var context = { - customIgnore: re.rules.js.IGNORE, - file: filePath, - hasSheBang: hasSheBang - }; - return iterateLines( contents, function(content, index, collection) { @@ -99,7 +102,9 @@ Formatter.JS = Formatter.create( return contents && contents[0] === '#' && contents[1] === '!'; }, - _lint: function(contents, lint) { + _lint: function(contents, context) { + var lint = context.lintConfig; + if (lint !== false) { var linter = require('./lint_js'); @@ -107,7 +112,7 @@ Formatter.JS = Formatter.create( _.merge(lint, this.config('js.lint')); - var results = linter(contents, this.file, lint); + var results = linter(contents, this.file, context); if (results.length) { this._logLintResults(results); diff --git a/lib/lint_js.js b/lib/lint_js.js index fe79ea7..d978350 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -16,9 +16,13 @@ var convertNameToRuleId = function(item) { return 'csf-' + baseName.replace(/_/g, '-'); }; -var runLinter = function(contents, file, customRules, config) { +var runLinter = function(contents, file, context) { + var customRules = context.customRules || {}; + eslint.linter.defineRules(customRules); + var config = context.lintConfig; + var ecmaVersion = _.get(config, 'parserOptions.ecmaVersion'); var configs = [{}, ESLINT_CONFIG]; @@ -42,7 +46,9 @@ var globOptions = { cwd: __dirname }; -module.exports = function(contents, file, config) { +module.exports = function(contents, file, context) { + context.customRules = customRules; + glob.sync( './lint_js_rules/*.js', globOptions @@ -56,7 +62,7 @@ module.exports = function(contents, file, config) { // eslint.linter.defineRules(customRules); - return runLinter(contents, file, customRules, config); + return runLinter(contents, file, context); }; module.exports.convertNameToRuleId = convertNameToRuleId; From f552b0389ef77dce4016c45dea025698b238dd5a Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 13:59:43 -0700 Subject: [PATCH 057/153] WIP to allow rule configs to be functions (going to revert immediately, because there are some perf consequences here, so I'll need to revisit) --- lib/lint_js.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/lint_js.js b/lib/lint_js.js index d978350..d335033 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -37,7 +37,18 @@ var runLinter = function(contents, file, context) { configs.push(config); } - config = _.merge.apply(_, configs); + config = context.lintConfig = _.merge.apply(_, configs); + + config.rules = _.mapValues( + config.rules, + function(item, index) { + if (_.isFunction(item)) { + item = item(context, index); + } + + return item; + } + ); return eslint.linter.verify(contents, config, file); }; From 229948cbd433584f3878fa161ec0967f47f6595e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 14:00:54 -0700 Subject: [PATCH 058/153] Revert "WIP to allow rule configs to be functions (going to revert immediately, because there are some perf consequences here, so I'll need to revisit)" This reverts commit f552b0389ef77dce4016c45dea025698b238dd5a. --- lib/lint_js.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/lint_js.js b/lib/lint_js.js index d335033..d978350 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -37,18 +37,7 @@ var runLinter = function(contents, file, context) { configs.push(config); } - config = context.lintConfig = _.merge.apply(_, configs); - - config.rules = _.mapValues( - config.rules, - function(item, index) { - if (_.isFunction(item)) { - item = item(context, index); - } - - return item; - } - ); + config = _.merge.apply(_, configs); return eslint.linter.verify(contents, config, file); }; From 85a205249e316b3065814992e624c59306530e72 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 11 May 2016 15:09:17 -0700 Subject: [PATCH 059/153] Fixing config not being sent along to the linter --- lib/js.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js.js b/lib/js.js index 4dd3cd4..1be8c3e 100644 --- a/lib/js.js +++ b/lib/js.js @@ -110,7 +110,7 @@ Formatter.JS = Formatter.create( lint = _.isObjectLike(lint) ? lint : {}; - _.merge(lint, this.config('js.lint')); + context.lintConfig = _.merge(lint, this.config('js.lint')); var results = linter(contents, this.file, context); From b23a4383b1e176d4a5c17ebeaa3fce17fd3fb8ff Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 16 May 2016 11:12:13 -0700 Subject: [PATCH 060/153] No unusued vars wasn't marking scriptlet blocks as being used --- lib/lint_js_rules/no_unused_vars.js | 4 +++- test/lint_js_rules/no_unused_vars.js | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/lint_js_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js index 64bf5a1..ec16f29 100644 --- a/lib/lint_js_rules/no_unused_vars.js +++ b/lib/lint_js_rules/no_unused_vars.js @@ -4,6 +4,8 @@ var base = require('../base'); var stubs = base.stubs; var portletNS = base.jspLintStubs.namespace; +var STUB_RE = new RegExp('^' + Object.keys(stubs).join('|')); + module.exports = function(context) { function useInstance(node) { context.markVariableAsUsed('instance'); @@ -40,7 +42,7 @@ module.exports = function(context) { var declaration = item.node; var name = declaration.name; - var namespacedVar = name.indexOf(portletNS) === 0; + var namespacedVar = STUB_RE.test(name); var namespacedFn = false; diff --git a/test/lint_js_rules/no_unused_vars.js b/test/lint_js_rules/no_unused_vars.js index 3a3f27f..b943ad7 100644 --- a/test/lint_js_rules/no_unused_vars.js +++ b/test/lint_js_rules/no_unused_vars.js @@ -23,6 +23,10 @@ ruleTester.run( code: '(function(){ function _PN_xyz(){} })', options: options }, + { + code: '(function(){ function _SCRIPTLET_xyz(){} })', + options: options + }, ], invalid: [ From a5096fb2e2414ad46b4dc28229ca2478d2da2eb0 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 16 May 2016 11:12:32 -0700 Subject: [PATCH 061/153] Add prefer-double-quotes for JSX --- lib/config/eslint_es6.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 9ea57c0..95703fc 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -16,6 +16,7 @@ module.exports = { ], 'rules': { + 'jsx-quotes': [2, 'prefer-double'], 'jsx-uses-react': 2, 'jsx-uses-vars': 2, 'jsx-curly-spacing': [2, 'never'], From 6b3a5d66111c8f2b8c455d2920f589ea5f95b9f2 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 16 May 2016 11:14:00 -0700 Subject: [PATCH 062/153] Silence comment warning for JSP's, since we inject comments to replace JSP code blocks --- lib/config/eslint_jsp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config/eslint_jsp.js b/lib/config/eslint_jsp.js index f246091..9e32622 100644 --- a/lib/config/eslint_jsp.js +++ b/lib/config/eslint_jsp.js @@ -15,6 +15,7 @@ module.exports = { 'no-trailing-spaces': 0, 'no-undef': 0, 'no-unused-vars': 0, - 'no-use-before-define': 0 + 'no-use-before-define': 0, + 'lines-around-comment': 0 } }; \ No newline at end of file From ea79eeb7d5ac7d334b176e097ccd3e095efb5aed Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 17 May 2016 10:21:43 -0700 Subject: [PATCH 063/153] Updating eslint --- lib/config/eslint.js | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config/eslint.js b/lib/config/eslint.js index 4cca721..8741007 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -25,6 +25,7 @@ module.exports = { }, 'rules': { + 'object-property-newline': 2, 'csf-liferay-language-get': 2, 'csf-liferay-provide-format': 2, 'block-scoped-var': 2, diff --git a/package.json b/package.json index 8b57cf9..1936f14 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^2.9.0", + "eslint": "^2.10.2", "eslint-plugin-react": "^5.1.1", "falafel": "^1.2.0", "getobject": "^0.1.0", From d47729fc844608268b7e52c415e6ef62b28c1668 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 24 May 2016 14:08:31 -0700 Subject: [PATCH 064/153] csf-sort-vars wasn't picking up non-literal variables --- lib/lint_js_rules/sort_vars.js | 6 ++++-- test/lint_js_rules/sort_vars.js | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/lint_js_rules/sort_vars.js b/lib/lint_js_rules/sort_vars.js index 1edd52a..8d80a8f 100644 --- a/lib/lint_js_rules/sort_vars.js +++ b/lib/lint_js_rules/sort_vars.js @@ -6,7 +6,9 @@ var naturalCompare = utils.naturalCompare; var sub = require('string-sub'); -var REGEX_FOR = /For.*Statement/ +var REGEX_FOR = /For.*Statement/; + +var REGEX_VAR = /Literal|CallExpression/; module.exports = function(context) { var configuration = context.options[0] || {}; @@ -24,7 +26,7 @@ module.exports = function(context) { if (declarations) { declarations.forEach( function(val, key) { - if (val.init && val.init.type === 'Literal') { + if (val.init && REGEX_VAR.test(val.init.type)) { variables.push(val); } else if (val.id.type === 'ObjectPattern') { diff --git a/test/lint_js_rules/sort_vars.js b/test/lint_js_rules/sort_vars.js index 0589f85..4e96ac8 100644 --- a/test/lint_js_rules/sort_vars.js +++ b/test/lint_js_rules/sort_vars.js @@ -23,6 +23,7 @@ ruleTester.run( 'var abc = 123;\nvar def = 456;', 'var abc = 123; var def = 456;', 'var cde = 123;\nvar def = 123;\n\nvar abc = 456;', + 'var cde = 123;\nvar def = foo();\n\nvar abc = bar(def);', 'for (var i = 0; i < 10; i++) {\nvar current = 1;\n}', 'for (var i in obj) {\nvar current = 1;\n}' ].concat( @@ -46,6 +47,10 @@ ruleTester.run( { code: 'var def = 456;\n\nvar def_xyz = "FOO";\nvar abc = 123;', errors: [ { message: 'Sort variables: def_xyz abc' } ] + }, + { + code: 'var def = 456;\n\nvar def_xyz = foo();\nvar abc = def_xyz.bar();', + errors: [ { message: 'Sort variables: def_xyz abc' } ] } ].concat( [ From a3032738b0705c197c723af9909287a289bb22f6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 26 May 2016 07:42:00 -0700 Subject: [PATCH 065/153] Adding new rule --- lib/config/eslint_es6.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 95703fc..e37153e 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -16,6 +16,7 @@ module.exports = { ], 'rules': { + 'object-property-newline': 0, 'jsx-quotes': [2, 'prefer-double'], 'jsx-uses-react': 2, 'jsx-uses-vars': 2, From 29ed00e7a0d4748badf26cdab25298be2a73c712 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 31 May 2016 12:42:21 -0700 Subject: [PATCH 066/153] 2.0.0-rc.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1936f14..5a5f779 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.5", + "version": "2.0.0-rc.6", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { From 19e080aea5afff5858bc0b5e7dc67e120cbdb755 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 9 Jun 2016 13:40:50 -0700 Subject: [PATCH 067/153] Fixing an issue where vars are being ignored improperly (instead of using REGEX_VAR to check for valid variables, we should just make sure we're not dealing with destructuring patterns --- lib/lint_js_rules/sort_vars.js | 10 +++++++--- test/lint_js_rules/sort_vars.js | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/lint_js_rules/sort_vars.js b/lib/lint_js_rules/sort_vars.js index 8d80a8f..da84821 100644 --- a/lib/lint_js_rules/sort_vars.js +++ b/lib/lint_js_rules/sort_vars.js @@ -8,7 +8,7 @@ var sub = require('string-sub'); var REGEX_FOR = /For.*Statement/; -var REGEX_VAR = /Literal|CallExpression/; +var REGEX_ASSIGNMENT_PATTERNS = /(Object|Array)Pattern/; module.exports = function(context) { var configuration = context.options[0] || {}; @@ -26,10 +26,14 @@ module.exports = function(context) { if (declarations) { declarations.forEach( function(val, key) { - if (val.init && REGEX_VAR.test(val.init.type)) { + var varType = val.id.type; + + var destructuredVar = REGEX_ASSIGNMENT_PATTERNS.test(varType); + + if (val.init && !destructuredVar) { variables.push(val); } - else if (val.id.type === 'ObjectPattern') { + else if (destructuredVar && varType === 'ObjectPattern') { var props = val.id.properties.filter( function(item, index) { return item.key; diff --git a/test/lint_js_rules/sort_vars.js b/test/lint_js_rules/sort_vars.js index 4e96ac8..6122aab 100644 --- a/test/lint_js_rules/sort_vars.js +++ b/test/lint_js_rules/sort_vars.js @@ -24,6 +24,7 @@ ruleTester.run( 'var abc = 123; var def = 456;', 'var cde = 123;\nvar def = 123;\n\nvar abc = 456;', 'var cde = 123;\nvar def = foo();\n\nvar abc = bar(def);', + 'var cde = 123;\nvar def = window.foo();\n\nvar abc = window.bar(def);', 'for (var i = 0; i < 10; i++) {\nvar current = 1;\n}', 'for (var i in obj) {\nvar current = 1;\n}' ].concat( @@ -51,6 +52,18 @@ ruleTester.run( { code: 'var def = 456;\n\nvar def_xyz = foo();\nvar abc = def_xyz.bar();', errors: [ { message: 'Sort variables: def_xyz abc' } ] + }, + { + code: 'var def = 456;\n\nvar def_xyz = window.foo;\nvar abc = def_xyz.bar;', + errors: [ { message: 'Sort variables: def_xyz abc' } ] + }, + { + code: 'var def = 456;\n\nvar def_xyz =[];\nvar abc = [];', + errors: [ { message: 'Sort variables: def_xyz abc' } ] + }, + { + code: 'var def = 456;\n\nvar def_xyz ={};\nvar abc = {};', + errors: [ { message: 'Sort variables: def_xyz abc' } ] } ].concat( [ From be0dfc21bfe777d1767fedc3eb91d696f5f7f724 Mon Sep 17 00:00:00 2001 From: Bryce Osterhaus Date: Tue, 5 Jul 2016 12:27:17 -0700 Subject: [PATCH 068/153] Add atom linter to docs --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c1e9607..5403610 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,12 @@ You can install it via a couple of steps: You can read more on [the project page](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting). Thanks to [Drew Brokke](https://github.com/drewbrokke) for writing the plugin and publishing it. +### As an Atom Linter plugin +- Install [liferay-linter](https://atom.io/packages/linter-liferay) via `apm install linter linter-liferay` + +You can read more on [the github page](https://github.com/mthadley/linter-liferay). +Thanks to [Michael Hadley](https://github.com/mthadley) for writing the plugin and publishing it. + ## Custom configuration Starting in version 2, you can now customize the configuration of the engine in a few different ways. Here are the items you can currently customize: From 8cb21b5b710a9a854ed6918d67ab75885297d86a Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 6 Jul 2016 07:49:30 -0700 Subject: [PATCH 069/153] Node 6 changes behavior a little bit when it comes to binding a toJSON method. Still need to research the underlying cause --- lib/config.js | 2 +- test/config.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/config.js b/lib/config.js index f187b01..50e4a2e 100644 --- a/lib/config.js +++ b/lib/config.js @@ -26,7 +26,7 @@ Config.prototype = { _normalize: function(obj) { var fn = this._get.bind(this); - fn.toJSON = this.toJSON.bind(this); + fn.toJSON = _.bindKey(this, 'toJSON'); fn.toString = JSON.stringify.bind(JSON, fn); fn.inspect = fn.toString; diff --git a/test/config.js b/test/config.js index 58e6a53..4403561 100644 --- a/test/config.js +++ b/test/config.js @@ -24,8 +24,8 @@ describe( function() { var config = new Config(); - assert.isTrue(JSON.stringify(config) === "{}"); - assert.isTrue(typeof config._paths === 'object'); + assert.isTrue(JSON.stringify(config) === '{}', 'Should be an empty object {}'); + assert.isTrue(typeof config._paths === 'object', '_paths should still exists in config'); } ); From ed6849a8e2ff85b4019ad180446cd36ba9a264f4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 6 Jul 2016 07:53:37 -0700 Subject: [PATCH 070/153] Update travis.yml --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5b7815d..2f0fc30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: node_js node_js: - - "5.0" - - "4.0" + - "6" + - "5" + - "4" - "0.12" - "0.11" - "0.10" From cfb645f12f2403902df30f370b8b8d22ffd7c4f4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 6 Jul 2016 13:29:42 -0700 Subject: [PATCH 071/153] 2.0.0-rc.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a5f779..c5f8b5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "check-source-formatting", - "version": "2.0.0-rc.6", + "version": "2.0.0-rc.7", "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { From abd7209a7b209ce41b7d3c6cf615c144d8a160a6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 11 Jul 2016 10:26:23 -0700 Subject: [PATCH 072/153] Adding support for detecting preceding or trailing new lines in a function --- lib/config/eslint.js | 1 + lib/lint_js_rules/function_spacing.js | 32 +++++++++++++++++++ lib/rule_utils.js | 6 ++-- test/lint_js_rules/function_spacing.js | 44 ++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 lib/lint_js_rules/function_spacing.js create mode 100644 test/lint_js_rules/function_spacing.js diff --git a/lib/config/eslint.js b/lib/config/eslint.js index 8741007..ece3a52 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -26,6 +26,7 @@ module.exports = { 'rules': { 'object-property-newline': 2, + 'csf-function-spacing': 2, 'csf-liferay-language-get': 2, 'csf-liferay-provide-format': 2, 'block-scoped-var': 2, diff --git a/lib/lint_js_rules/function_spacing.js b/lib/lint_js_rules/function_spacing.js new file mode 100644 index 0000000..f1ecff2 --- /dev/null +++ b/lib/lint_js_rules/function_spacing.js @@ -0,0 +1,32 @@ +var utils = require('../rule_utils'); + +var sub = require('string-sub'); + +module.exports = function(context) { + var testFunctionSpacing = function(node) { + var nodeBody = node.body; + var fnBody = nodeBody.body; + + if (fnBody.length) { + var firstStatement = fnBody[0]; + var lastStatement = fnBody[fnBody.length - 1]; + + var startLineDistance = utils.getLineDistance(nodeBody, firstStatement, 'start'); + + if (startLineDistance !== 1) { + context.report(node, sub('There should be exactly one line between the start of the function and the first statement, not {0} lines', startLineDistance)); + } + + var endLineDistance = utils.getLineDistance(lastStatement, nodeBody, 'end', 'end'); + + if (endLineDistance !== 1) { + context.report(lastStatement, sub('There should be exactly one line between the last statement and the end of the function, not {0} lines', endLineDistance)); + } + } + }; + + return { + FunctionExpression: testFunctionSpacing, + FunctionDeclaration: testFunctionSpacing + }; +}; \ No newline at end of file diff --git a/lib/rule_utils.js b/lib/rule_utils.js index fd93a81..0a17545 100644 --- a/lib/rule_utils.js +++ b/lib/rule_utils.js @@ -23,9 +23,11 @@ exports.getConstants = function(node) { }; // Gets distance between the end of "left" and the start of "right" +// Or, pass in leftEnd or rightStart to define whether +// it's the end or start of a line -exports.getLineDistance = function(left, right) { - return right.loc.start.line - left.loc.end.line; +exports.getLineDistance = function(left, right, leftEnd, rightStart) { + return right.loc[rightStart || 'start'].line - left.loc[leftEnd || 'end'].line; }; var compare = function(a, b) { diff --git a/test/lint_js_rules/function_spacing.js b/test/lint_js_rules/function_spacing.js new file mode 100644 index 0000000..ce48cf9 --- /dev/null +++ b/test/lint_js_rules/function_spacing.js @@ -0,0 +1,44 @@ +var path = require('path'); + +var lint = require('../../lib/lint_js'); + +var linter = lint.linter; +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); + +var STR_END_ERROR = 'There should be exactly one line between the last statement and the end of the function, not '; + +var STR_START_ERROR = 'There should be exactly one line between the start of the function and the first statement, not '; + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_js_rules/' + path.basename(__filename)), + { + valid: [ + 'function foo() {}', + 'function foo() {\n}', + 'function foo() {\nalert("test");\n}' + ], + + invalid: [ + { + code: 'function foo() {\n\nalert("test");\n}', + errors: [ { message: STR_START_ERROR + '2 lines' } ] + }, + { + code: 'function foo() {\nalert("test");\n\n}', + errors: [ { message: STR_END_ERROR + '2 lines' } ] + }, + { + code: 'function foo() {alert("test");\n}', + errors: [ { message: STR_START_ERROR + '0 lines' } ] + }, + { + code: 'function foo() {\nalert("test");}', + errors: [ { message: STR_END_ERROR + '0 lines' } ] + }, + + ] + } +); \ No newline at end of file From 869368d25c8a21fd796153d6ee7b07fba7480138 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 08:19:12 -0700 Subject: [PATCH 073/153] Detect trailing newline in file --- lib/re.js | 4 +++- test/re.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/re.js b/lib/re.js index 3085f84..948a0c5 100644 --- a/lib/re.js +++ b/lib/re.js @@ -10,7 +10,9 @@ re.prototype.hasExtraNewLines = function(item, index, collection) { var extraNewLines = false; if (item === '') { - extraNewLines = (index === 0 && collection.length > 1) || collection[index - 1] === ''; + var length = collection.length; + + extraNewLines = (index === 0 && length > 1) || collection[index - 1] === '' || (index === length - 1 && length > 1); } if (extraNewLines) { diff --git a/test/re.js b/test/re.js index b3ec9fa..d0ddacc 100644 --- a/test/re.js +++ b/test/re.js @@ -55,7 +55,7 @@ describe( it( 'should find extra newlines at end', function() { - var endingNewLine = ['foo', '', '']; + var endingNewLine = ['foo', '']; endingNewLine.forEach( function(item, index, collection) { From 61633ab94291fef9247a67d1ec5d3b3500b598ea Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 08:21:05 -0700 Subject: [PATCH 074/153] Remove async dep --- lib/cli.js | 2 -- lib/meta.js | 1 - package.json | 1 - 3 files changed, 4 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 351071a..e51b4e2 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,4 +1,3 @@ -var async = require('async'); var cli = require('cli'); var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); @@ -49,7 +48,6 @@ var CLI = function(config) { this._args = config.args || argv._; this._cwd = config.cwd || base.CWD; - this._async = config.async || async; this._exec = config.exec || cli.exec.bind(cli); this.junit = config.junit || junit; this._log = config.log || console.log.bind(console); diff --git a/lib/meta.js b/lib/meta.js index 49d9e3e..3ecc61b 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -1,6 +1,5 @@ var _ = require('lodash'); var falafel = require('falafel'); -var async = require('async'); var path = require('path'); var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); diff --git a/package.json b/package.json index c5f8b5f..6548f42 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ }, "preferGlobal": "true", "dependencies": { - "async": "^1.5.2", "babel-eslint": "6.0.2", "bluebird": "^3.3.5", "cli": "^0.11.2", From f41c4ef3747bbc2d8fe1f08674f7f234b0dd3e74 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 08:31:15 -0700 Subject: [PATCH 075/153] Updating eslint to 3.0.0 (and since eslint dropped support for node < 4, we have to as well) --- .travis.yml | 3 --- package.json | 6 +++--- test/cli.js | 1 - test/config.js | 1 - test/formatter.js | 1 - 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f0fc30..7a970ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,5 @@ node_js: - "6" - "5" - "4" - - "0.12" - - "0.11" - - "0.10" after_success: - npm run coveralls \ No newline at end of file diff --git a/package.json b/package.json index 6548f42..a3dfbfe 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "author": "Nate Cavanaugh", "license": "BSD", "engines": { - "node": ">=0.10.0" + "node": ">=4" }, "repository": { "type": "git", @@ -30,7 +30,7 @@ "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^2.10.2", + "eslint": "^3.0.1", "eslint-plugin-react": "^5.1.1", "falafel": "^1.2.0", "getobject": "^0.1.0", @@ -61,4 +61,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} +} \ No newline at end of file diff --git a/test/cli.js b/test/cli.js index c28d40f..4dd24c6 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,4 +1,3 @@ -var async = require('async'); var chai = require('chai'); var fs = require('fs'); var path = require('path'); diff --git a/test/config.js b/test/config.js index 4403561..e454af1 100644 --- a/test/config.js +++ b/test/config.js @@ -1,4 +1,3 @@ -var async = require('async'); var chai = require('chai'); var Config = require('../lib/config'); diff --git a/test/formatter.js b/test/formatter.js index 0ec4622..67fcb54 100644 --- a/test/formatter.js +++ b/test/formatter.js @@ -1,4 +1,3 @@ -var async = require('async'); var chai = require('chai'); var path = require('path'); From 1e0548015263d257b301ae2ca3d6d4bb87382f35 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 09:22:55 -0700 Subject: [PATCH 076/153] Update deps (and move the babel-eslint parser to being es6 only --- lib/config/eslint.js | 2 -- lib/config/eslint_es6.js | 2 ++ package.json | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/config/eslint.js b/lib/config/eslint.js index ece3a52..b4b24b3 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -6,8 +6,6 @@ module.exports = { 'node': true }, - 'parser': 'babel-eslint', - 'parserOptions': { 'ecmaVersion': 5 }, diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index e37153e..c50daed 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -3,6 +3,8 @@ module.exports = { 'es6': true }, + 'parser': 'babel-eslint', + 'parserOptions': { 'sourceType': 'module', 'ecmaFeatures': { diff --git a/package.json b/package.json index a3dfbfe..06fa555 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ }, "preferGlobal": "true", "dependencies": { - "babel-eslint": "6.0.2", - "bluebird": "^3.3.5", + "babel-eslint": "^6.1.2", + "bluebird": "^3.4.1", "cli": "^0.11.2", "cli-color-keywords": "0.0.1", "content-formatter": "^1.1.0", @@ -31,18 +31,18 @@ "cosmiconfig": "^1.1.0", "drip": "^1.4.0", "eslint": "^3.0.1", - "eslint-plugin-react": "^5.1.1", + "eslint-plugin-react": "^5.2.2", "falafel": "^1.2.0", "getobject": "^0.1.0", - "glob": "^7.0.0", - "lodash": "^4.12.0", + "glob": "^7.0.5", + "lodash": "^4.13.1", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", - "minimatch": "^3.0.0", + "minimatch": "^3.0.2", "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "update-notifier": "^0.7.0" + "update-notifier": "^1.0.2" }, "devDependencies": { "chai": "^3.5.0", @@ -61,4 +61,4 @@ "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } -} \ No newline at end of file +} From 0e873d09e5c2e0499968fbe903a997cfa5ea0a4e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 09:24:17 -0700 Subject: [PATCH 077/153] Update devDeps --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 06fa555..dfdbe4c 100644 --- a/package.json +++ b/package.json @@ -47,17 +47,17 @@ "devDependencies": { "chai": "^3.5.0", "chai-string": "^1.1.6", - "coveralls": "^2.11.6", + "coveralls": "^2.11.11", "gulp": "^3.9.1", "gulp-complexity": "^0.3.0", "gulp-coveralls": "^0.1.3", "gulp-doctoc": "^0.1.2", - "gulp-istanbul": "^0.8.1", - "gulp-load-plugins": "^1.2.0", + "gulp-istanbul": "^1.0.0", + "gulp-load-plugins": "^1.2.4", "gulp-mocha": "^2.2.0", - "istanbul": "^0.3.13", - "mocha": "^2.4.5", - "run-sequence": "^1.1.5", + "istanbul": "^0.4.4", + "mocha": "^2.5.3", + "run-sequence": "^1.2.2", "sinon": "^1.17.3", "xsd-schema-validator": "^0.3.0" } From 32f00d20f104653bab9f983e283b414551c6cab4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Jul 2016 10:41:35 -0700 Subject: [PATCH 078/153] Add extraneous new line checking for script/style blocks --- lib/html.js | 23 ++++++++++++++++++++--- test/fixture/test.jsp | 8 ++++++++ test/html.js | 8 ++++---- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/html.js b/lib/html.js index 8743b5c..f19f4b7 100644 --- a/lib/html.js +++ b/lib/html.js @@ -229,13 +229,22 @@ Formatter.HTML = Formatter.create( scriptBlocks = scriptBlocks.map( function(item, index) { - var contents = item.contents; item = instance._jsIterateRules(item); item = instance._jsRemoveScriptletBlocks(item); item = instance._jsHandleScriptletWhitespace(item); item = instance._jsPadLines(item, token); + var contents = item.contents; + + var lastIndex = contents.lastIndexOf('\n'); + + if (!contents.substr(lastIndex, contents.length).trim()) { + contents = contents.substr(0, lastIndex); + } + + item.contents = contents; + return item; } ); @@ -250,12 +259,20 @@ Formatter.HTML = Formatter.create( styleBlocks = styleBlocks.map( function(item, index) { - var contents = item.contents; - item = instance._jsRemoveScriptletBlocks(item); item = instance._jsHandleScriptletWhitespace(item); item = instance._jsPadLines(item, token); + var contents = item.contents; + + var lastIndex = contents.lastIndexOf('\n'); + + if (!contents.substr(lastIndex, contents.length).trim()) { + contents = contents.substr(0, lastIndex); + } + + item.contents = contents; + return item; } ); diff --git a/test/fixture/test.jsp b/test/fixture/test.jsp index 52c62ac..71da0b0 100644 --- a/test/fixture/test.jsp +++ b/test/fixture/test.jsp @@ -71,5 +71,13 @@
"> + + + + + window.foo = 'foo'; \ No newline at end of file diff --git a/test/html.js b/test/html.js index 95e3676..4106c03 100644 --- a/test/html.js +++ b/test/html.js @@ -98,7 +98,7 @@ describe( var scriptBlocks = htmlFormatter.parseJs(source); assert.isArray(scriptBlocks); - assert.equal(scriptBlocks.length, 4); + assert.equal(scriptBlocks.length, 5); scriptBlocks.forEach(assert.isString); } ); @@ -119,7 +119,7 @@ describe( var scriptBlocks = htmlFormatter.extractJs(source); assert.isArray(scriptBlocks); - assert.equal(scriptBlocks.length, 4); + assert.equal(scriptBlocks.length, 5); scriptBlocks.forEach(assert.isObject); scriptBlocks = htmlFormatter.extractJs(''); @@ -144,7 +144,7 @@ describe( var styleBlocks = htmlFormatter.parseCSS(source); assert.isArray(styleBlocks); - assert.equal(styleBlocks.length, 1); + assert.equal(styleBlocks.length, 2); styleBlocks.forEach(assert.isString); } ); @@ -165,7 +165,7 @@ describe( var styleBlocks = htmlFormatter.extractCSS(source); assert.isArray(styleBlocks); - assert.equal(styleBlocks.length, 1); + assert.equal(styleBlocks.length, 2); styleBlocks.forEach(assert.isObject); styleBlocks = htmlFormatter.extractCSS(''); From d29006687dd70176d0b95dfdace75bae58d65c7c Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 Aug 2016 07:04:42 -0700 Subject: [PATCH 079/153] Adding gulp-debug --- gulpfile.js | 2 ++ package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index eacea35..d3f1cf3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -33,9 +33,11 @@ gulp.task('test-file', function() { else { file = ['test/**/*.js', '!test/fixture/*.js']; } + process.argv.push('--display-raw'); return gulp.src(file) + // .pipe(plugins.debug()) .pipe(plugins.mocha()); }); diff --git a/package.json b/package.json index dfdbe4c..33483dc 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "gulp": "^3.9.1", "gulp-complexity": "^0.3.0", "gulp-coveralls": "^0.1.3", + "gulp-debug": "^2.1.2", "gulp-doctoc": "^0.1.2", "gulp-istanbul": "^1.0.0", "gulp-load-plugins": "^1.2.4", From 272742dfb17b7acd5aaae512642bc584c393d164 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 Aug 2016 07:04:48 -0700 Subject: [PATCH 080/153] Fixing sort constants so it checks objects for usage of previous constants --- lib/lint_js_rules/sort_constants.js | 24 +++++++++++++++++------- test/lint_js_rules/sort_constants.js | 10 +++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/lint_js_rules/sort_constants.js b/lib/lint_js_rules/sort_constants.js index 176a26f..3c78a8a 100644 --- a/lib/lint_js_rules/sort_constants.js +++ b/lib/lint_js_rules/sort_constants.js @@ -14,17 +14,27 @@ module.exports = function(context) { if (node) { var type = node.type; - if (type === 'BinaryExpression') { + if (type === 'Identifier') { + obj[node.name] = true; + } + else if (type === 'Property') { + obj = getIdentifiers(node.key, obj); + obj = getIdentifiers(node.value, obj); + } + else if (type === 'BinaryExpression') { obj = getIdentifiers(node.left, obj); obj = getIdentifiers(node.right, obj); } - else if (type === 'Identifier') { - obj[node.name] = true; - } - else if (type === 'CallExpression') { - obj = getIdentifiers(node.callee, obj); + else if (type === 'CallExpression' || type === 'ObjectExpression') { + var prop = 'properties'; + + if (type === 'CallExpression') { + obj = getIdentifiers(node.callee, obj); + + prop = 'arguments'; + } - node.arguments.forEach(_.ary(_.bindRight(getIdentifiers, null, obj), 1)); + node[prop].forEach(_.ary(_.bindRight(getIdentifiers, null, obj), 1)); } else if (type === 'MemberExpression') { obj = getIdentifiers(node.object, obj); diff --git a/test/lint_js_rules/sort_constants.js b/test/lint_js_rules/sort_constants.js index ce59d70..9f1cb0b 100644 --- a/test/lint_js_rules/sort_constants.js +++ b/test/lint_js_rules/sort_constants.js @@ -7,6 +7,8 @@ var RuleTester = lint.eslint.RuleTester; var ruleTester = new RuleTester(); +var addES6 = require('../test_utils').addES6(); + ruleTester.run( path.basename(__filename, '.js'), require('../../lib/lint_js_rules/' + path.basename(__filename)), @@ -16,9 +18,15 @@ ruleTester.run( 'var DEF = 456;\n\nvar ABC = "FOO" + DEF;', 'var DEF = 456;\n\nvar GHI = 789;\n\nvar ABC = DEF;', 'var DEF = 456;\n\nvar ABC = some.method[DEF];', + 'var DEF = 456;\n\nvar ABC = {key: DEF};', + 'var DEF = 456;\n\nvar ABC = {key: {someOtherKey: DEF}};', 'var DEF = function(){};\n\nvar ABC = DEF();', 'var DEF = function(){};\n\nvar ABC = foo(DEF);' - ], + ].concat( + [ + {code: 'var DEF = "Hello";\n\nvar ABC = {[DEF]: 1};'}, + ].map(addES6) + ), invalid: [ { From 315eecd28471a88ba5cc7a47cac9fd5ec23b2ddf Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 19 Aug 2016 13:42:57 -0700 Subject: [PATCH 081/153] Updating deps --- package.json | 30 +++++++++++----------- test/lint_js_rules/no_unused_vars.js | 2 +- test/lint_js_rules/no_use_before_define.js | 6 ++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 33483dc..ffce2be 100644 --- a/package.json +++ b/package.json @@ -23,22 +23,22 @@ "dependencies": { "babel-eslint": "^6.1.2", "bluebird": "^3.4.1", - "cli": "^0.11.2", + "cli": "^1.0.0", "cli-color-keywords": "0.0.1", "content-formatter": "^1.1.0", "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^1.1.0", "drip": "^1.4.0", - "eslint": "^3.0.1", - "eslint-plugin-react": "^5.2.2", + "eslint": "^3.3.1", + "eslint-plugin-react": "^6.1.2", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.5", - "lodash": "^4.13.1", + "lodash": "^4.15.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", - "minimatch": "^3.0.2", + "minimatch": "^3.0.3", "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", @@ -46,20 +46,20 @@ }, "devDependencies": { "chai": "^3.5.0", - "chai-string": "^1.1.6", - "coveralls": "^2.11.11", + "chai-string": "^1.2.0", + "coveralls": "^2.11.12", "gulp": "^3.9.1", - "gulp-complexity": "^0.3.0", - "gulp-coveralls": "^0.1.3", + "gulp-complexity": "^0.3.2", + "gulp-coveralls": "^0.1.4", "gulp-debug": "^2.1.2", - "gulp-doctoc": "^0.1.2", - "gulp-istanbul": "^1.0.0", + "gulp-doctoc": "^0.1.4", + "gulp-istanbul": "^1.1.0", "gulp-load-plugins": "^1.2.4", - "gulp-mocha": "^2.2.0", + "gulp-mocha": "^3.0.1", "istanbul": "^0.4.4", - "mocha": "^2.5.3", + "mocha": "^3.0.2", "run-sequence": "^1.2.2", - "sinon": "^1.17.3", - "xsd-schema-validator": "^0.3.0" + "sinon": "^1.17.5", + "xsd-schema-validator": "^0.3.1" } } diff --git a/test/lint_js_rules/no_unused_vars.js b/test/lint_js_rules/no_unused_vars.js index b943ad7..b1ab289 100644 --- a/test/lint_js_rules/no_unused_vars.js +++ b/test/lint_js_rules/no_unused_vars.js @@ -32,7 +32,7 @@ ruleTester.run( invalid: [ { code: '(function(){ var _PN_xyz = 1; });', - errors: [ { message: "'_PN_xyz' is defined but never used" } ], + errors: [ { message: "'_PN_xyz' is defined but never used." } ], options: options } ] diff --git a/test/lint_js_rules/no_use_before_define.js b/test/lint_js_rules/no_use_before_define.js index f8453eb..a0bd9a6 100644 --- a/test/lint_js_rules/no_use_before_define.js +++ b/test/lint_js_rules/no_use_before_define.js @@ -15,9 +15,9 @@ ruleTester.run( { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': true}] } ], invalid: [ - { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': false}], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] }, - { code: "function a() { alert(b); } var b = 1;", options: ['nofunc'], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] }, - { code: "function a() { alert(b); var b = 1; }", options: [{'samescope': true}], errors: [{ message: "'b' was used before it was defined", type: "Identifier" }] } + { code: "function a() { alert(b); } var b = 1;", options: [{'samescope': false}], errors: [{ message: "'b' was used before it was defined.", type: "Identifier" }] }, + { code: "function a() { alert(b); } var b = 1;", options: ['nofunc'], errors: [{ message: "'b' was used before it was defined.", type: "Identifier" }] }, + { code: "function a() { alert(b); var b = 1; }", options: [{'samescope': true}], errors: [{ message: "'b' was used before it was defined.", type: "Identifier" }] } ] } ); \ No newline at end of file From 0fc0faafb6e7d33081b3a92c613e6678faf537e3 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 30 Aug 2016 12:42:24 -0700 Subject: [PATCH 082/153] Updating eslint-plugin rules --- lib/config/eslint_es6.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index c50daed..2e6b194 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -35,7 +35,7 @@ module.exports = { 'jsx-space-before-closing': [2, 'always'], 'jsx-sort-props': [2, {'ignoreCase': true}], 'no-multi-comp': [0, {'ignoreStateless': true}], - 'wrap-multilines': [2/*, {'ignoreStateless': true}*/], + 'jsx-wrap-multilines': [2/*, {'ignoreStateless': true}*/], 'no-unknown-property': 2, 'sort-comp': [0, { order: [ From f2db26299fa34cbf1429d348e1f3ceba4dc6a704 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 30 Aug 2016 12:52:29 -0700 Subject: [PATCH 083/153] Fixing trailing undefined when writing a file --- lib/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli.js b/lib/cli.js index e51b4e2..1e3ec27 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -264,7 +264,7 @@ CLI.prototype = _.create( writeFile: function(file, contents) { return this._write(file, contents) - .then(util.format.bind(util, 'Wrote file: %s', file)) + .then(_.bind(_.ary(util.format, 2), util, 'Wrote file: %s', file)) .error(File.handleFileWriteError.bind(this, file)) .then(_.unary(this._log).bind(this)); }, From 610dde7b100c6921df7ede5221f2a4c1ba189385 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 2 Sep 2016 11:59:01 -0700 Subject: [PATCH 084/153] Add ability to generate lint rule and tests --- gulpfile.js | 61 ++++++++++++++++++++++++++++++++++- lib/tpl/lint_rules/js/rule.js | 29 +++++++++++++++++ lib/tpl/lint_rules/js/test.js | 25 ++++++++++++++ package.json | 3 ++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 lib/tpl/lint_rules/js/rule.js create mode 100644 lib/tpl/lint_rules/js/test.js diff --git a/gulpfile.js b/gulpfile.js index d3f1cf3..17eeeb4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,6 +2,7 @@ var _ = require('lodash'); var gulp = require('gulp'); var plugins = require('gulp-load-plugins')(); var runSequence = require('run-sequence'); +var inquirer = require('inquirer'); gulp.task('coveralls', function () { gulp.src('coverage/**/lcov.info') @@ -73,4 +74,62 @@ gulp.task('toc', function(done) { ) ) .pipe(gulp.dest('./')); -}); \ No newline at end of file +}); + +gulp.task( + 'new-rule', + function(done) { + inquirer.prompt( + [ + { + type: 'list', + choices: ['ESLint'/*, 'Stylelint'*/], + message: 'What kind of linting rule do you wish to create?', + name: 'type' + }, + { + type: 'input', + default: 'my-new-rule', + filter: _.snakeCase, + message: 'What do you want to name it?', + name: 'name' + }, + { + type: 'input', + default: 'Checks for this issue.', + message: 'Type a short description', + name: 'description' + } + ] + ) + .then( + function(res) { + var srcDir = 'js'; + var destDir = 'lint_js_rules'; + + if (res.type !== 'ESLint') { + srcDir = 'css'; + destDir = 'lint_css_rules'; + } + + gulp.src('./lib/tpl/lint_rules/' + srcDir + '/*.js') + // .pipe(plugins.debug()) + .pipe( + plugins.rename( + function(path) { + var baseDir = path.basename === 'rule' ? 'lib' : 'test'; + + path.dirname = './' + baseDir + '/lint_' + srcDir + '_rules'; + + path.basename = res.name; + } + ) + ) + .pipe(plugins.template(res)) + .pipe(gulp.dest('./')); + + done(); + } + ); + } +); \ No newline at end of file diff --git a/lib/tpl/lint_rules/js/rule.js b/lib/tpl/lint_rules/js/rule.js new file mode 100644 index 0000000..f985997 --- /dev/null +++ b/lib/tpl/lint_rules/js/rule.js @@ -0,0 +1,29 @@ +var _ = require('lodash'); +var sub = require('string-sub'); + +var base = require('../base'); +var utils = require('../rule_utils'); + +module.exports = { + meta: { + docs: { + description: '<%= description %>', + category: 'Fill me in', + recommended: false + }, + fixable: null, // or "code" or "whitespace" + schema: [ + // fill in your schema + ] + }, + + create: function(context) { + return { + + // ReturnStatement: function(node) { + // .... + // } + + }; + } +}; \ No newline at end of file diff --git a/lib/tpl/lint_rules/js/test.js b/lib/tpl/lint_rules/js/test.js new file mode 100644 index 0000000..c8e7059 --- /dev/null +++ b/lib/tpl/lint_rules/js/test.js @@ -0,0 +1,25 @@ +var path = require('path'); + +var lint = require('../../lib/lint_js'); + +var linter = lint.linter; +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_js_rules/' + path.basename(__filename)), + { + valid: [ + // Code that won't give a warning + ], + + invalid: [ + // { + // code: '', + // errors: [ { message: 'Something went wrong' } ] + // } + ] + } +); \ No newline at end of file diff --git a/package.json b/package.json index ffce2be..be9bfd5 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,9 @@ "gulp-istanbul": "^1.1.0", "gulp-load-plugins": "^1.2.4", "gulp-mocha": "^3.0.1", + "gulp-rename": "^1.2.2", + "gulp-template": "^4.0.0", + "inquirer": "^1.1.3", "istanbul": "^0.4.4", "mocha": "^3.0.2", "run-sequence": "^1.2.2", From 28fb8deae28a12440231e851266567cd828f8c47 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 6 Sep 2016 11:06:03 -0700 Subject: [PATCH 085/153] Adding no-multiple-return check --- lib/config/eslint.js | 2 + lib/lint_js_rules/no_multiple_return.js | 55 ++++++++++++++++++ lib/rule_utils.js | 8 +++ test/lint_js_rules/no_multiple_return.js | 71 ++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 lib/lint_js_rules/no_multiple_return.js create mode 100644 test/lint_js_rules/no_multiple_return.js diff --git a/lib/config/eslint.js b/lib/config/eslint.js index b4b24b3..d28cef3 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -24,6 +24,8 @@ module.exports = { 'rules': { 'object-property-newline': 2, + 'csf-no-multiple-return': 2, + // 'csf-no-lonely-if': 2, 'csf-function-spacing': 2, 'csf-liferay-language-get': 2, 'csf-liferay-provide-format': 2, diff --git a/lib/lint_js_rules/no_multiple_return.js b/lib/lint_js_rules/no_multiple_return.js new file mode 100644 index 0000000..bb45c22 --- /dev/null +++ b/lib/lint_js_rules/no_multiple_return.js @@ -0,0 +1,55 @@ +var _ = require('lodash'); +var sub = require('string-sub'); + +var base = require('../base'); +var utils = require('../rule_utils'); + +module.exports = { + meta: { + docs: { + description: 'Enforces keeping a single return within a function', + category: 'Fill me in', + recommended: false + }, + fixable: null, // or "code" or "whitespace" + schema: [ + // fill in your schema + ] + }, + + create: function(context) { + var funcInfo = null; + + var checkReturns = function(node) { + if (funcInfo.returnCount > 1) { + context.report( + { + message: 'Functions should only have one return statement', + node: node + } + ); + } + }; + + return { + onCodePathStart: function(codePath) { + funcInfo = { + upper: funcInfo, + returnCount: 0 + }; + }, + onCodePathEnd: function() { + funcInfo = funcInfo.upper; + }, + + ReturnStatement: function(node) { + funcInfo.returnCount += 1; + }, + + 'Program:exit': checkReturns, + 'FunctionDeclaration:exit': checkReturns, + 'FunctionExpression:exit': checkReturns, + 'ArrowFunctionExpression:exit': checkReturns + }; + } +}; \ No newline at end of file diff --git a/lib/rule_utils.js b/lib/rule_utils.js index 0a17545..845d088 100644 --- a/lib/rule_utils.js +++ b/lib/rule_utils.js @@ -84,4 +84,12 @@ exports.naturalCompare = function(a, b, caseInsensitive) { } return result; +}; + +var startsWithUpperCase = exports.startsWithUpperCase = function(str) { + return str[0] === str[0].toLocaleLowerCase(); +}; + +exports.isConstructor = function(node) { + return node.id && startsWithUpperCase(node.id.name); }; \ No newline at end of file diff --git a/test/lint_js_rules/no_multiple_return.js b/test/lint_js_rules/no_multiple_return.js new file mode 100644 index 0000000..99cc2e7 --- /dev/null +++ b/test/lint_js_rules/no_multiple_return.js @@ -0,0 +1,71 @@ +var path = require('path'); + +var lint = require('../../lib/lint_js'); + +var linter = lint.linter; +var RuleTester = lint.eslint.RuleTester; + +var ruleTester = new RuleTester(); + +var addES6 = require('../test_utils').addES6(); + +ruleTester.run( + path.basename(__filename, '.js'), + require('../../lib/lint_js_rules/' + path.basename(__filename)), + { + valid: [ + 'function foo() {return 1;}', + 'function foo() {}', + 'function foo() {bar();}', + 'function foo() {var f = function(){return 1;}; return f();}', + 'function foo() {var f = function(){return 1;};}' + ].concat( + [ + { code: 'var foo = () => {return 1;}' }, + { code: 'var foo = () => {}' }, + { code: 'var foo = () => {bar();}' }, + { code: 'var foo = () => {var f = n => {return 1}; return f();}' }, + { code: 'var foo = () => {var f = n => {return 1};}' }, + + ].map(addES6) + ), + + invalid: [ + { + code: 'function foo() {if (x) {return x;} return;}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'function foo() {if (x) {return x;} else {return 1;}}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'function foo() {return 1; return 2;}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'function foo() {var f = function(){if (foo) {return foo;} return 1;};}', + errors: [ { message: 'Functions should only have one return statement' } ] + } + ].concat( + [ + { + code: 'var foo = () => {if (x) {return x;} return;}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'var foo = () => {if (x) {return x;} else {return 1;}}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'var foo = () => {return 1; return 2;}', + errors: [ { message: 'Functions should only have one return statement' } ] + }, + { + code: 'var foo = () => {var f = () => {if (foo) {return foo;} return 1;};}', + errors: [ { message: 'Functions should only have one return statement' } ] + } + ] + ).map(addES6) + } +); \ No newline at end of file From d3778e814a4723c8a154633fafab01091ff80d3f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 6 Sep 2016 12:12:34 -0700 Subject: [PATCH 086/153] Removing unused functions --- lib/rule_utils.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/rule_utils.js b/lib/rule_utils.js index 845d088..0a17545 100644 --- a/lib/rule_utils.js +++ b/lib/rule_utils.js @@ -84,12 +84,4 @@ exports.naturalCompare = function(a, b, caseInsensitive) { } return result; -}; - -var startsWithUpperCase = exports.startsWithUpperCase = function(str) { - return str[0] === str[0].toLocaleLowerCase(); -}; - -exports.isConstructor = function(node) { - return node.id && startsWithUpperCase(node.id.name); }; \ No newline at end of file From 97a4d621badc5295f1e79cc6f4c0bc0b741b8186 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 6 Sep 2016 12:57:33 -0700 Subject: [PATCH 087/153] Adding ability to apply eslint fixes when passing -i --- lib/js.js | 10 ++++++++-- lib/lint_js.js | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/js.js b/lib/js.js index 1be8c3e..d5ea599 100644 --- a/lib/js.js +++ b/lib/js.js @@ -55,7 +55,7 @@ Formatter.JS = Formatter.create( lintConfig: this.flags.lint !== false && lint }; - this._lint(contents, context); + contents = this._lint(contents, context); if (this.flags.verbose) { this._processSyntax(contents); @@ -112,12 +112,18 @@ Formatter.JS = Formatter.create( context.lintConfig = _.merge(lint, this.config('js.lint')); - var results = linter(contents, this.file, context); + var lintResults = linter(contents, this.file, context); + + var results = lintResults.results; if (results.length) { this._logLintResults(results); + + contents = lintResults.contents; } } + + return contents; }, _logLintResults: function(results) { diff --git a/lib/lint_js.js b/lib/lint_js.js index d978350..793072f 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -1,5 +1,6 @@ var _ = require('lodash'); var eslint = require('eslint'); +var SourceCodeFixer = require('eslint/lib/util/source-code-fixer'); var ESLINT_CONFIG = require('./config/eslint'); var glob = require('glob'); var path = require('path'); @@ -39,7 +40,20 @@ var runLinter = function(contents, file, context) { config = _.merge.apply(_, configs); - return eslint.linter.verify(contents, config, file); + var results = eslint.linter.verify(contents, config, file); + + if (results.length) { + var fixedContent = SourceCodeFixer.applyFixes(eslint.linter.getSourceCode(), results); + + if (fixedContent.fixed) { + contents = fixedContent.output; + } + } + + return { + contents: contents, + results: results + }; }; var globOptions = { From cf2eca03d4dc4dfe00f2d02a0083e4d96d269412 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 9 Sep 2016 11:11:53 -0700 Subject: [PATCH 088/153] Adding fixer for function spacing --- lib/lint_js_rules/function_spacing.js | 70 +++++++++++++++++++-------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/lib/lint_js_rules/function_spacing.js b/lib/lint_js_rules/function_spacing.js index f1ecff2..c78c0b9 100644 --- a/lib/lint_js_rules/function_spacing.js +++ b/lib/lint_js_rules/function_spacing.js @@ -2,31 +2,63 @@ var utils = require('../rule_utils'); var sub = require('string-sub'); -module.exports = function(context) { - var testFunctionSpacing = function(node) { - var nodeBody = node.body; - var fnBody = nodeBody.body; +module.exports = { + create: function(context) { + var testFunctionSpacing = function(node) { + var nodeBody = node.body; + var fnBody = nodeBody.body; - if (fnBody.length) { - var firstStatement = fnBody[0]; - var lastStatement = fnBody[fnBody.length - 1]; + var range = []; - var startLineDistance = utils.getLineDistance(nodeBody, firstStatement, 'start'); + var sourceCode = context.getSourceCode(); - if (startLineDistance !== 1) { - context.report(node, sub('There should be exactly one line between the start of the function and the first statement, not {0} lines', startLineDistance)); + function fix(fixer) { + return fixer.replaceTextRange(range, '\n'); } - var endLineDistance = utils.getLineDistance(lastStatement, nodeBody, 'end', 'end'); + if (fnBody.length) { + var firstStatement = fnBody[0]; + var lastStatement = fnBody[fnBody.length - 1]; - if (endLineDistance !== 1) { - context.report(lastStatement, sub('There should be exactly one line between the last statement and the end of the function, not {0} lines', endLineDistance)); + var startLineDistance = utils.getLineDistance(nodeBody, firstStatement, 'start'); + + if (startLineDistance !== 1) { + range[0] = sourceCode.getFirstToken(nodeBody).range[1]; + range[1] = sourceCode.getFirstToken(firstStatement).range[0] - 1; + + context.report( + { + node: node, + message: sub('There should be exactly one line between the start of the function and the first statement, not {0} lines', startLineDistance), + fix: fix + } + ); + } + + var endLineDistance = utils.getLineDistance(lastStatement, nodeBody, 'end', 'end'); + + if (endLineDistance !== 1) { + range[0] = sourceCode.getLastToken(lastStatement).range[1]; + range[1] = sourceCode.getLastToken(nodeBody).range[0]; + + context.report( + { + node: lastStatement, + message: sub('There should be exactly one line between the last statement and the end of the function, not {0} lines', endLineDistance), + fix: fix + } + ); + } } - } - }; + }; + + return { + FunctionExpression: testFunctionSpacing, + FunctionDeclaration: testFunctionSpacing + }; + }, - return { - FunctionExpression: testFunctionSpacing, - FunctionDeclaration: testFunctionSpacing - }; + meta: { + fixable: 'whitespace' + } }; \ No newline at end of file From 17e43f17bc34b667ef2601ee3ca45718f93241a8 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 12 Sep 2016 13:11:44 -0700 Subject: [PATCH 089/153] Don't show ignored files if passing quiet in as the flag --- lib/cli.js | 11 +++++++++++ lib/logger.js | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/cli.js b/lib/cli.js index 1e3ec27..fbed024 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -39,6 +39,10 @@ var flags = _.reduce( {} ); +var filterFileErrors = function(errors) { + return _.reject(errors, ['type', 'ignored']); +}; + var CLI = function(config) { config = config || {}; @@ -256,6 +260,13 @@ CLI.prototype = _.create( config.showBanner = flags.quiet; config.showLintIds = flags.lintIds; + if (flags.quiet) { + this._logger.filterFileErrors( + file, + filterFileErrors + ); + } + out = this._logger.render(file, config); } diff --git a/lib/logger.js b/lib/logger.js index c89bd1d..506af33 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var Logger = require('content-logger'); var contentLogger = Logger.create( @@ -8,6 +9,8 @@ var contentLogger = Logger.create( failures: 0 }; + this._errorStack = []; + this.on( 'add', function(error) { @@ -16,6 +19,22 @@ var contentLogger = Logger.create( } } ); + }, + + filterFileErrors: function(file, fn) { + var fileErrors; + + var errors = this.getErrors(file); + + this._errorStack.push(errors); + + var filteredErrors = fn(errors); + + filteredErrors.errorMap = {}; + + this.fileErrors[file] = filteredErrors; + + return fileErrors; } } } From 3420dcc25c9ec290cbcbe38b2857ff77ac1d353e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 13 Sep 2016 14:24:27 -0700 Subject: [PATCH 090/153] Updating function spacing rule, still needs some work for edge cases --- lib/lint_js_rules/function_spacing.js | 36 +++++++++++++++++++++----- test/lint_js_rules/function_spacing.js | 27 +++++++++++++++++-- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/lib/lint_js_rules/function_spacing.js b/lib/lint_js_rules/function_spacing.js index c78c0b9..c380f0a 100644 --- a/lib/lint_js_rules/function_spacing.js +++ b/lib/lint_js_rules/function_spacing.js @@ -6,6 +6,7 @@ module.exports = { create: function(context) { var testFunctionSpacing = function(node) { var nodeBody = node.body; + var fnBody = nodeBody.body; var range = []; @@ -20,32 +21,55 @@ module.exports = { var firstStatement = fnBody[0]; var lastStatement = fnBody[fnBody.length - 1]; + var leadingComments = sourceCode.getComments(firstStatement).leading; + var trailingComments = sourceCode.getComments(lastStatement).trailing; + var startLineDistance = utils.getLineDistance(nodeBody, firstStatement, 'start'); + if (leadingComments.length) { + var lastLeadingComment = leadingComments[leadingComments.length - 1]; + var firstLeadingComment = leadingComments[0]; + + var startCommentAfterDistance = utils.getLineDistance(lastLeadingComment, firstStatement, 'start'); + var startCommentBeforeDistance = utils.getLineDistance(nodeBody, firstLeadingComment, 'start'); + + startLineDistance = Math.max(startCommentBeforeDistance, startCommentAfterDistance); + } + if (startLineDistance !== 1) { range[0] = sourceCode.getFirstToken(nodeBody).range[1]; range[1] = sourceCode.getFirstToken(firstStatement).range[0] - 1; context.report( { - node: node, + fix: fix, message: sub('There should be exactly one line between the start of the function and the first statement, not {0} lines', startLineDistance), - fix: fix + node: node } ); } var endLineDistance = utils.getLineDistance(lastStatement, nodeBody, 'end', 'end'); + if (trailingComments.length) { + var firstTrailingComment = trailingComments[0]; + var lastTrailingComment = trailingComments[trailingComments.length - 1]; + + var endCommentAfterDistance = utils.getLineDistance(lastTrailingComment, nodeBody, 'end', 'end'); + var endCommentBeforeDistance = utils.getLineDistance(lastStatement, firstTrailingComment, 'end', 'end'); + + endLineDistance = Math.max(endCommentBeforeDistance, endCommentAfterDistance); + } + if (endLineDistance !== 1) { range[0] = sourceCode.getLastToken(lastStatement).range[1]; range[1] = sourceCode.getLastToken(nodeBody).range[0]; context.report( { - node: lastStatement, + fix: fix, message: sub('There should be exactly one line between the last statement and the end of the function, not {0} lines', endLineDistance), - fix: fix + node: lastStatement } ); } @@ -53,8 +77,8 @@ module.exports = { }; return { - FunctionExpression: testFunctionSpacing, - FunctionDeclaration: testFunctionSpacing + FunctionDeclaration: testFunctionSpacing, + FunctionExpression: testFunctionSpacing }; }, diff --git a/test/lint_js_rules/function_spacing.js b/test/lint_js_rules/function_spacing.js index ce48cf9..3066a4b 100644 --- a/test/lint_js_rules/function_spacing.js +++ b/test/lint_js_rules/function_spacing.js @@ -18,7 +18,11 @@ ruleTester.run( valid: [ 'function foo() {}', 'function foo() {\n}', - 'function foo() {\nalert("test");\n}' + 'function foo() {\nalert("test");\n}', + 'function foo() {\n/*Test*/\nalert("test");\n}', + 'function foo() {\nalert("test");\n/*Test*/\n}', + 'function foo() {\n/*Test*/\nalert("test");\n/*Test*/\n}', + 'function foo() {\n// Test\nalert("test");\n// Test\n}', ], invalid: [ @@ -38,7 +42,26 @@ ruleTester.run( code: 'function foo() {\nalert("test");}', errors: [ { message: STR_END_ERROR + '0 lines' } ] }, - + { + code: 'function foo() {\n/*Test*/\n\nalert("test");\n}', + errors: [ { message: STR_START_ERROR + '2 lines' } ] + }, + { + code: 'function foo() {\n\n/*Test*/\nalert("test");\n}', + errors: [ { message: STR_START_ERROR + '2 lines' } ] + }, + { + code: 'function foo() {\nalert("test");\n/*Test*/\n\n}', + errors: [ { message: STR_END_ERROR + '2 lines' } ] + }, + // { + // code: 'function foo() {\n/*Test*/\n\n/*Test*/\nalert("test");\n}', + // errors: [ { message: STR_START_ERROR + '2 lines' } ] + // }, + // { + // code: 'function foo() {\nalert("test");\n/*Test*/\n\n/*Test*/\n}', + // errors: [ { message: STR_END_ERROR + '2 lines' } ] + // } ] } ); \ No newline at end of file From c0d0f8f4a9da46010e96538a1c8a0f832fdefc53 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 10 Oct 2016 13:58:09 -0700 Subject: [PATCH 091/153] Fixing duplicate key warning for replaced EL expressions --- lib/html.js | 7 ++++++- lib/lint_js_rules/no_undef.js | 4 ++++ test/fixture/test.jsp | 7 +++++++ test/html.js | 4 ++-- test/lint_js_rules/no_undef.js | 3 ++- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/html.js b/lib/html.js index f19f4b7..625d55e 100644 --- a/lib/html.js +++ b/lib/html.js @@ -667,7 +667,12 @@ Formatter.HTML = Formatter.create( var contents = scriptBlock.contents; - contents = contents.replace(/\$\{.*?\}/g, jspLintStubs.elExpression) + contents = contents.replace( + /\$\{.*?\}/g, + function(m, index, str) { + return jspLintStubs.elExpression + index; + } + ) .replace( /<%[^>]+>/g, function(m, index) { diff --git a/lib/lint_js_rules/no_undef.js b/lib/lint_js_rules/no_undef.js index 7dc4a0d..c8c7089 100644 --- a/lib/lint_js_rules/no_undef.js +++ b/lib/lint_js_rules/no_undef.js @@ -24,6 +24,10 @@ module.exports = function(context) { function(item, index) { var name = item.node.name; + if (/_EL_EXPRESSION_\d+/.test(name)) { + name = '_EL_EXPRESSION_'; + } + if (!stubs[name] && name.indexOf('_PN_') !== 0) { context.report(item); } diff --git a/test/fixture/test.jsp b/test/fixture/test.jsp index 71da0b0..aac94b5 100644 --- a/test/fixture/test.jsp +++ b/test/fixture/test.jsp @@ -79,5 +79,12 @@ window.foo = 'foo'; + + + var SOME_OBJ = { + '${foo}': 'bar', + '${bar}': 'baz' + }; + \ No newline at end of file diff --git a/test/html.js b/test/html.js index 4106c03..8b08254 100644 --- a/test/html.js +++ b/test/html.js @@ -98,7 +98,7 @@ describe( var scriptBlocks = htmlFormatter.parseJs(source); assert.isArray(scriptBlocks); - assert.equal(scriptBlocks.length, 5); + assert.equal(scriptBlocks.length, 6); scriptBlocks.forEach(assert.isString); } ); @@ -119,7 +119,7 @@ describe( var scriptBlocks = htmlFormatter.extractJs(source); assert.isArray(scriptBlocks); - assert.equal(scriptBlocks.length, 5); + assert.equal(scriptBlocks.length, 6); scriptBlocks.forEach(assert.isObject); scriptBlocks = htmlFormatter.extractJs(''); diff --git a/test/lint_js_rules/no_undef.js b/test/lint_js_rules/no_undef.js index c41570f..af15a73 100644 --- a/test/lint_js_rules/no_undef.js +++ b/test/lint_js_rules/no_undef.js @@ -15,7 +15,8 @@ ruleTester.run( '_PN_foo()', '_PN_()', '_PN_.foo', - 'var a = _PN_;' + 'var a = _PN_;', + 'var b = _EL_EXPRESSION_1' ], invalid: [ From dbc39b9fb831fe600a98f707d3a03b874052fc94 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 17 Jan 2017 09:52:43 -0800 Subject: [PATCH 092/153] Fixing eslint error message --- test/lint_js_rules/no_unused_vars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lint_js_rules/no_unused_vars.js b/test/lint_js_rules/no_unused_vars.js index b1ab289..2aa6a98 100644 --- a/test/lint_js_rules/no_unused_vars.js +++ b/test/lint_js_rules/no_unused_vars.js @@ -32,7 +32,7 @@ ruleTester.run( invalid: [ { code: '(function(){ var _PN_xyz = 1; });', - errors: [ { message: "'_PN_xyz' is defined but never used." } ], + errors: [ { message: "'_PN_xyz' is assigned a value but never used." } ], options: options } ] From f2ade61286604696a905b925caf3171ec77ebf09 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 10:48:48 -0700 Subject: [PATCH 093/153] Add ability to load a config relative to the file's location instead of the cwd of the script --- lib/argv.js | 4 + lib/cli.js | 82 +++++++++---- lib/config.js | 118 +++++++++++++------ package.json | 4 +- test/cli.js | 148 +++++++++++++++++++----- test/fixture/config/flags/csf.config.js | 6 +- test/formatter.js | 2 +- test/test_utils/index.js | 22 ++++ 8 files changed, 293 insertions(+), 93 deletions(-) diff --git a/lib/argv.js b/lib/argv.js index 0debb54..d8dd06d 100644 --- a/lib/argv.js +++ b/lib/argv.js @@ -2,6 +2,10 @@ var optimist = require('optimist') .usage('Usage: $0 -qo') .options( { + config: { + default: true, + string: true + }, 'display-raw': { boolean: true, default: false diff --git a/lib/cli.js b/lib/cli.js index fbed024..6767bce 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -48,7 +48,9 @@ var CLI = function(config) { EventEmitter.call(this); - this.flags = config.flags || flags; + this._configs = {}; + + this.flags = _.defaults(config.flags, flags); this._args = config.args || argv._; this._cwd = config.cwd || base.CWD; @@ -68,12 +70,21 @@ CLI.prototype = _.create( init: function() { var instance = this; - var cfgPromise = Config.load(instance._cwd); + this._config = new Config.Loader( + { + cwd: instance._cwd + } + ); + + return this._loadConfigs().then( + function(configs) { + instance._configs = configs; - return Promise.resolve(cfgPromise) - .bind(this) - .then(instance._loadConfig) - .then(instance._start); + return configs; + } + ) + .bind(instance) + .then(instance._start); }, afterFormat: function(results) { @@ -130,7 +141,7 @@ CLI.prototype = _.create( var formatter = Formatter.get(file, this._logger, this.flags); if (formatter) { - formatter._config = this._config; + formatter._config = this._configs[file]; contents = this.processFileData(contents, formatter); @@ -281,27 +292,56 @@ CLI.prototype = _.create( }, _loadConfig: function(config) { - var obj = config._paths.obj; - var err = config._paths.err; - - this._config = config; + if (this.flags.config) { + var obj = config._paths.obj; + var err = config._paths.err; - if (obj) { - if (config.flags) { - _.merge(this.flags, config.flags); - } - - if (!this.flags.filenames) { - this._log('Using local config from ', obj.filepath); + if (this.flags.verbose && !this.flags.filenames) { + if (obj) { + this._log('Using local config from ', obj.filepath); + } + else if (err) { + this._log('Could not resolve any local config: ', err, err.stack); + } } } - else if (err && this.flags.verbose) { - this._log('Could not resolve any local config: ', err, err.stack); - } return config; }, + _loadConfigs: function() { + var instance = this; + + return Promise.reduce( + instance._args, + function(prev, item, index) { + var filePath = path.resolve(instance._cwd, path.dirname(item)); + + var res; + + if (instance.flags.config) { + res = instance._config.load(filePath); + } + else { + var cfg = new Config({}); + + cfg._paths.cwd = instance._cwd; + + res = Promise.resolve(cfg); + } + + return res.then( + function(config) { + prev[item] = instance._loadConfig(config); + + return prev; + } + ); + }, + {} + ); + }, + _start: function() { this.emit('init'); diff --git a/lib/config.js b/lib/config.js index 50e4a2e..d1513d4 100644 --- a/lib/config.js +++ b/lib/config.js @@ -26,65 +26,107 @@ Config.prototype = { _normalize: function(obj) { var fn = this._get.bind(this); - fn.toJSON = _.bindKey(this, 'toJSON'); - fn.toString = JSON.stringify.bind(JSON, fn); - fn.inspect = fn.toString; + Object.defineProperty( + fn, + 'toJSON', + { + enumerable: false, + value: _.bindKey(this, 'toJSON') + } + ); + + Object.defineProperty( + fn, + 'toString', + { + enumerable: false, + value: JSON.stringify.bind(JSON, fn) + } + ); + + Object.defineProperty( + fn, + 'inspect', + { + enumerable: false, + value: fn.toString + } + ); + + Object.defineProperty( + fn, + '_paths', + { + enumerable: false, + value: {} + } + ); return _.merge(fn, CONFIG_DEFAULT, obj); } }; -Config.load = function(cwd) { - return cosmiconfig( - 'csf', +var Loader = function(options) { + options = _.defaults( + options, { - cwd: cwd, + cwd: process.cwd(), packageProp: 'csfConfig' } - ).then( - function(obj) { - var config = new Config(obj ? obj.config : {}); + ); - config._paths.cwd = cwd; + this._config = cosmiconfig('csf', options); +} - if (obj) { - var STR_PATH = 'path:'; +Loader.prototype = { + load: function(cwd) { + return this._config.load(cwd).then( + function(obj) { + var config = new Config(obj ? obj.config : {}); - var paths = Object.keys(config).reduce( - function(prev, item, index) { - if (item.indexOf(STR_PATH) === 0) { - var pathKey = item.slice(STR_PATH.length); + config._paths.cwd = cwd; - var pathConfig = config[item]; + if (obj) { + var STR_PATH = 'path:'; - prev.configs.push(pathConfig); + var paths = Object.keys(config).reduce( + function(prev, item, index) { + if (item.indexOf(STR_PATH) === 0) { + var pathKey = item.slice(STR_PATH.length); - delete config[item]; + var pathConfig = config[item]; - prev.keys.push(pathKey); - } + prev.configs.push(pathConfig); - return prev; - }, - config._paths - ); + delete config[item]; - paths.obj = obj; - } + prev.keys.push(pathKey); + } - return config; - } - ).catch( - function(err) { - var config = new Config(); + return prev; + }, + config._paths + ); - config._paths.cwd = cwd; + paths.obj = obj; + } - config._paths.err = err; + return config; + } + ).catch( + function(err) { + var config = new Config(); - return config; - } - ); + config._paths.cwd = cwd; + + config._paths.err = err; + + return config; + } + ); + } }; +Config.Loader = Loader; + module.exports = Config; \ No newline at end of file diff --git a/package.json b/package.json index be9bfd5..0f54d85 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "content-formatter": "^1.1.0", "content-logger": "^0.0.3", "content-logger-handlebars-helpers": "0.0.1", - "cosmiconfig": "^1.1.0", + "cosmiconfig": "^2.1.0", "drip": "^1.4.0", "eslint": "^3.3.1", "eslint-plugin-react": "^6.1.2", @@ -62,7 +62,7 @@ "istanbul": "^0.4.4", "mocha": "^3.0.2", "run-sequence": "^1.2.2", - "sinon": "^1.17.5", + "sinon": "^2.1.0", "xsd-schema-validator": "^0.3.1" } } diff --git a/test/cli.js b/test/cli.js index 4dd24c6..b3840f3 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var chai = require('chai'); var fs = require('fs'); var path = require('path'); @@ -7,6 +8,9 @@ var Promise = require('bluebird'); var cli = require('../lib/cli'); var File = require('../lib/file'); var Logger = require('../lib/logger'); +var config = require('../lib/config/eslint'); + +var getRule = require('./test_utils').getRule; chai.use(require('chai-string')); @@ -67,14 +71,14 @@ describe( var cliInstance = new cli.CLI( { args: ['foo.js', 'bar.html', 'baz.css'], - log: sinon.log, + log: _.noop, logger: logger } ); cliInstance.init().then( function() { - assert.isTrue(fs.readFile.calledThrice, 'fs.readFile should have been called 3 times, it was instead called ' + fs.readFile.callCount + ' times'); + assert.isTrue(fs.readFile.callCount >= 3, 'fs.readFile should have been called 3 times, it was instead called ' + fs.readFile.callCount + ' times'); assert.isTrue(fs.readFile.calledWith('foo.js'), 'foo.js should have been read'); assert.isTrue(fs.readFile.calledWith('bar.html'), 'bar.html should have been read'); assert.isTrue(fs.readFile.calledWith('baz.css'), 'baz.css should have been read'); @@ -144,7 +148,7 @@ describe( flags: { inlineEdit: true }, - log: sinon.log, + log: _.noop, logger: new Logger.constructor() } ); @@ -170,7 +174,7 @@ describe( var cliInstance = new cli.CLI( { args: ['foo.NOOP'], - log: sinon.log, + log: _.noop, logger: new Logger.constructor() } ); @@ -199,7 +203,7 @@ describe( flags: { checkMetadata: true }, - log: sinon.log, + log: _.noop, logger: new Logger.constructor() } ); @@ -233,7 +237,7 @@ describe( flags: { checkMetadata: true }, - log: sinon.log, + log: _.noop, logger: new Logger.constructor() } ); @@ -298,6 +302,7 @@ describe( { args: ['foo.js'], flags: { + config: false, verbose: true }, log: log, @@ -593,6 +598,42 @@ describe( } ); + it( + 'should not log files without errors when quiet is set', + function(done) { + sandbox.stub(fs, 'readFile').callsFake(validContentStub); + + var log = sandbox.spy(); + + var logger = new Logger.constructor(); + + var filterFileErrors = sandbox.spy(logger, 'filterFileErrors'); + + var cliInstance = new cli.CLI( + { + args: ['bar.html'], + flags: { + // config: false, + quiet: true, + }, + log: log, + logger: logger + } + ); + + var spy = sandbox.spy(cliInstance, '_loadConfigs'); + + cliInstance.init().then( + function() { + assert.isTrue(log.notCalled, 'log should not have been called'); + assert.isTrue(filterFileErrors.called, 'filterFileErrors should have been called'); + + done(); + } + ).catch(done); + } + ); + it( 'should call junit generate', function(done) { @@ -611,7 +652,7 @@ describe( junit: true }, junit: junit, - log: sinon.log, + log: _.noop, logger: new Logger.constructor() } ); @@ -628,27 +669,40 @@ describe( it( 'should handle custom config', function(done) { - sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + var filePath = path.join(__dirname, 'fixture/config/flags/foo.js'); + + var log = sandbox.spy(); var cliInstance = new cli.CLI( { - args: ['foo.js'], - cwd: path.join(__dirname, 'fixture/config/flags'), + args: [filePath], flags: { - quiet: false + verbose: true }, - log: sinon.log, - logger: new Logger.constructor() + log: log, + logger: new Logger.constructor(), + read: function() { + return new Promise( + function(resolve, reject) { + resolve(''); + } + ); + } } ); cliInstance.init().then( function() { - assert.isTrue(cliInstance.flags.quiet); + var configs = cliInstance._configs; + var config = configs[filePath]; - done(); + assert.isObject(configs); + + assert.notDeepEqual(getRule(0, false, _.get(config, 'js.lint', {})), getRule(0)); + + assert.startsWith(log.args[0][0], 'Using local config from '); } - ); + ).done(done); } ); @@ -661,8 +715,7 @@ describe( var cliInstance = new cli.CLI( { - args: ['foo.js'], - cwd: path.join(__dirname, 'fixture/config/filenames'), + args: [path.join(__dirname, 'fixture/config/filenames/foo.js')], flags: { filenames: true }, @@ -675,10 +728,8 @@ describe( function() { assert.isNotTrue(cliInstance.flags.quiet); assert.isUndefined(log.args[0]); - - done(); } - ); + ).done(done); } ); @@ -689,22 +740,62 @@ describe( var log = sandbox.spy(); + var filePath = path.join(__dirname, 'fixture/config/bad_config/foo.js'); + + var cliInstance = new cli.CLI( + { + args: [filePath], + log: log, + logger: new Logger.constructor(), + read: function() { + return Promise.resolve(''); + } + } + ); + + cliInstance.init().then( + function() { + assert.lengthOf(Object.keys(cliInstance._configs[filePath]), 0); + } + ) + .done(done); + } + ); + + it( + 'should handle invalid config logging', + function(done) { + var log = sandbox.spy(); + var cliInstance = new cli.CLI( { args: ['foo.js'], cwd: path.join(__dirname, 'fixture/config/bad_config'), flags: { - verbose: false + quiet: true, + verbose: true }, log: log, - logger: new Logger.constructor() + logger: new Logger.constructor(), + read: function(file, options) { + var retVal; + + if (file === 'foo.js') { + retVal = Promise.resolve(''); + } + else { + retVal = fs.readFileAsync(file, options); + } + + return retVal; + } } ); cliInstance.init().then( function() { - assert.isFalse(cliInstance.flags.verbose); - assert.notStartsWith(log.args[0][0], 'Could not resolve any local config'); + assert.isTrue(cliInstance.flags.verbose); + assert.startsWith(log.args[0][0], 'Could not resolve any local config'); done(); } @@ -713,9 +804,9 @@ describe( ); it( - 'should handle invalid config logging', + 'should not load a config when config is false', function(done) { - sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); + sandbox.stub(fs, 'readFile', invalidContentStub); var log = sandbox.spy(); @@ -724,7 +815,6 @@ describe( args: ['foo.js'], cwd: path.join(__dirname, 'fixture/config/bad_config'), flags: { - quiet: false, verbose: true }, log: log, @@ -735,7 +825,7 @@ describe( cliInstance.init().then( function() { assert.isTrue(cliInstance.flags.verbose); - assert.startsWith(log.args[0][0], 'Could not resolve any local config'); + assert.notStartsWith(log.args[0][0], 'Could not resolve any local config'); done(); } diff --git a/test/fixture/config/flags/csf.config.js b/test/fixture/config/flags/csf.config.js index 9e1f489..81636bb 100644 --- a/test/fixture/config/flags/csf.config.js +++ b/test/fixture/config/flags/csf.config.js @@ -1,5 +1,7 @@ +var getRule = require('../../../test_utils').getRule; + module.exports = { - flags: { - quiet: true + js: { + lint: getRule(0, true) } }; \ No newline at end of file diff --git a/test/formatter.js b/test/formatter.js index 67fcb54..63f0156 100644 --- a/test/formatter.js +++ b/test/formatter.js @@ -31,7 +31,7 @@ describe( function(done) { var cwd = path.join(__dirname, 'fixture/config/path_configs'); - Config.load(cwd).then( + (new Config.Loader).load(cwd).then( function(config) { var formatter = Formatter.get('foo.css', logger, {quiet: true}); diff --git a/test/test_utils/index.js b/test/test_utils/index.js index 7f7a667..fc805f7 100644 --- a/test/test_utils/index.js +++ b/test/test_utils/index.js @@ -1,5 +1,7 @@ var _ = require('lodash'); +var lintRules = require('../../lib/config/eslint').rules; + exports.nl = function() { return _.toArray(arguments).join('\n'); } @@ -12,4 +14,24 @@ exports.addES6 = function(config) { return item; }; +}; + +var invertValue = _.cond([[_.partial(_.eq, 0), _.constant(2)], [_.partial(_.eq, 2), _.constant(0)]]); + +exports.getRule = function(ruleName, invert, obj) { + var rule; + + var rules = obj || lintRules; + + if (_.isNumber(ruleName)) { + ruleName = Object.keys(rules)[ruleName]; + } + + var retVal = _.pick(rules, ruleName); + + if (invert) { + retVal[ruleName] = invertValue(retVal[ruleName]); + } + + return retVal; }; \ No newline at end of file From 570f73d02252ec0b5b60f78c59a90f7a6daa1443 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 11:07:38 -0700 Subject: [PATCH 094/153] Updating to remove deprecated sinon methods --- test/cli.js | 34 +++++++++++++--------------------- test/js.js | 4 ++-- test/junit.js | 20 +++++--------------- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/test/cli.js b/test/cli.js index b3840f3..216a1eb 100644 --- a/test/cli.js +++ b/test/cli.js @@ -64,7 +64,7 @@ describe( it( 'should read files correctly', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var logger = new Logger.constructor(); @@ -92,7 +92,7 @@ describe( it( 'should write files correctly', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, null); var log = sandbox.spy(); @@ -137,7 +137,7 @@ describe( it( 'should handle file write errors', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, new Error('Something went wrong')); sandbox.stub(File, 'handleFileWriteError'); @@ -261,7 +261,7 @@ describe( it( 'should log results properly', function(done) { - sandbox.stub(fs, 'readFile', validContentStub); + sandbox.stub(fs, 'readFile').callsFake(validContentStub); var log = sandbox.spy(); @@ -323,9 +323,7 @@ describe( it( 'should log filenames properly', function(done) { - sandbox.stub( - fs, - 'readFile', + sandbox.stub(fs, 'readFile').callsFake( function(filePath, encoding, callback) { callback(null, MAP_CONTENT[path.basename(filePath)][0]); } @@ -360,9 +358,7 @@ describe( it( 'should log relative filenames properly', function(done) { - sandbox.stub( - fs, - 'readFile', + sandbox.stub(fs, 'readFile').callsFake( function(filePath, encoding, callback) { callback(null, MAP_CONTENT[path.basename(filePath)][0]); } @@ -439,7 +435,7 @@ describe( it( 'should not write missing files', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, null); sandbox.stub(File, 'handleFileReadError').returns('Missing file'); @@ -523,13 +519,11 @@ describe( it( 'should open files properly', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var cliModule = require('cli'); - sandbox.stub( - cliModule, - 'exec', + sandbox.stub(cliModule, 'exec').callsFake( function(command, callback) { if (callback) { callback(['sublime']); @@ -564,13 +558,11 @@ describe( it( 'should not log without arguments', function() { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var cliModule = require('cli'); - sandbox.stub( - cliModule, - 'exec', + sandbox.stub(cliModule, 'exec').callsFake( function(command, callback) { if (callback) { callback(['sublime']); @@ -637,7 +629,7 @@ describe( it( 'should call junit generate', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var junitReporter = require('../lib/junit'); @@ -806,7 +798,7 @@ describe( it( 'should not load a config when config is false', function(done) { - sandbox.stub(fs, 'readFile', invalidContentStub); + sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var log = sandbox.spy(); diff --git a/test/js.js b/test/js.js index 37859f1..ad94a8e 100644 --- a/test/js.js +++ b/test/js.js @@ -313,7 +313,7 @@ describe( } }; - sandbox.stub(eslint.linter, 'verify', verify); + sandbox.stub(eslint.linter, 'verify').callsFake(verify); lint.runLinter(source, testFilePath, {}); @@ -339,7 +339,7 @@ describe( } }; - sandbox.stub(eslint.linter, 'verify', verify); + sandbox.stub(eslint.linter, 'verify').callsFake(verify); jsFormatter.format( source, diff --git a/test/junit.js b/test/junit.js index 34c44d6..790ba1f 100644 --- a/test/junit.js +++ b/test/junit.js @@ -45,9 +45,7 @@ describe( logger.log(1, 'Content is not valid', 'baz.css', 'error'); logger.log('N/A', 'This file was ignored. Pass the "force" flag if you wish to have it included.', 'bar.min.js', 'ignored'); - sandbox.stub( - fs, - 'readFile', + sandbox.stub(fs, 'readFile').callsFake( function(path, encoding, callback) { if (path.indexOf('junit_report.tpl') > -1) { return callback(null, fs.readFileSync(path, encoding)); @@ -57,9 +55,7 @@ describe( } ); - sandbox.stub( - fs, - 'writeFile', + sandbox.stub(fs, 'writeFile').callsFake( function(path, content, callback) { callback(null, content); } @@ -91,9 +87,7 @@ describe( logger.log(39, ' -1) { return callback(null, fs.readFileSync(path, encoding)); @@ -103,9 +97,7 @@ describe( } ); - sandbox.stub( - fs, - 'writeFile', + sandbox.stub(fs, 'writeFile').callsFake( function(path, content, callback) { callback(null, content); } @@ -147,9 +139,7 @@ describe( sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); - sandbox.stub( - fs, - 'writeFile', + sandbox.stub(fs, 'writeFile').callsFake( function(path, content, callback) { callback(null, content); From f75dd8053b014712ae3765a7e6f726242e37d13b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 11:09:01 -0700 Subject: [PATCH 095/153] Adding node 7 for travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7a970ab..34e7afb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - "7" - "6" - "5" - "4" From 02d705856094475a97cfb0972a01c30d2b41343d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 13:55:24 -0700 Subject: [PATCH 096/153] Fixing broken rule (eslint migrated to classes, so the methods are no longer enumerable) --- lib/lint_js_rules/no_unused_vars.js | 90 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/lib/lint_js_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js index ec16f29..4b2a205 100644 --- a/lib/lint_js_rules/no_unused_vars.js +++ b/lib/lint_js_rules/no_unused_vars.js @@ -6,66 +6,70 @@ var portletNS = base.jspLintStubs.namespace; var STUB_RE = new RegExp('^' + Object.keys(stubs).join('|')); -module.exports = function(context) { - function useInstance(node) { - context.markVariableAsUsed('instance'); - } +module.exports = { + create: function(context) { + function useInstance(node) { + context.markVariableAsUsed('instance'); + } - var lintRules = { - 'VariableDeclaration': useInstance, - 'ReturnStatement': useInstance - }; + var lintRules = { + 'VariableDeclaration': useInstance, + 'ReturnStatement': useInstance + }; - var options = context.options; + var options = context.options; - if (options.length && options[0].jsp === true) { - var noUnused = require('eslint/lib/rules/no-unused-vars').create; + if (options.length && options[0].jsp === true) { + var noUnused = require('eslint/lib/rules/no-unused-vars').create; - var collectedReport = []; + var collectedReport = []; - var mockContext = { - report: function(obj) { - collectedReport.push(obj); - }, - options: [{'vars': 'local', 'args': 'none'}] - }; + var mockContext = { + report: function(obj) { + collectedReport.push(obj); + }, + options: [{'vars': 'local', 'args': 'none'}] + }; + + _.defaults(mockContext, context); - _.defaults(mockContext, context); + mockContext.getSourceCode = context.getSourceCode; - lintRules['Program:exit'] = function(node) { - noUnused(mockContext)['Program:exit'](node); + lintRules['Program:exit'] = function(node) { + noUnused(mockContext)['Program:exit'](node); - // console.log(collectedReport); + // console.log(collectedReport); - collectedReport.forEach( - function(item, index) { - var declaration = item.node; - var name = declaration.name; + collectedReport.forEach( + function(item, index) { + var declaration = item.node; + var name = declaration.name; - var namespacedVar = STUB_RE.test(name); + var namespacedVar = STUB_RE.test(name); - var namespacedFn = false; + var namespacedFn = false; - if (namespacedVar) { - // item[0].name = name.replace(portletNS, ''); - // item[2].name = name.replace(portletNS, ''); + if (namespacedVar) { + // item[0].name = name.replace(portletNS, ''); + // item[2].name = name.replace(portletNS, ''); - var parentType = declaration.parent.type; + var parentType = declaration.parent.type; - if (parentType === 'FunctionDeclaration' || - (parentType === 'VariableDeclarator' && declaration.parent.init.type === 'FunctionExpression') - ) { - namespacedFn = true; + if (parentType === 'FunctionDeclaration' || + (parentType === 'VariableDeclarator' && declaration.parent.init.type === 'FunctionExpression') + ) { + namespacedFn = true; + } } - } - if (!stubs[name] && !namespacedVar || (namespacedVar && !namespacedFn)) { - context.report(item); + if (!stubs[name] && !namespacedVar || (namespacedVar && !namespacedFn)) { + context.report(item); + } } - } - ); + ); + } } - } - return lintRules; + return lintRules; + } }; \ No newline at end of file From f2d34974eb3662313dd30f8094272c4aebec927d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 11:27:39 -0700 Subject: [PATCH 097/153] Migrating to ES6 classes: CLI --- lib/cli.js | 485 ++++++++++++++++++++++++++--------------------------- 1 file changed, 241 insertions(+), 244 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 6767bce..a51d7dd 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,3 +1,5 @@ +'use strict'; + var cli = require('cli'); var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); @@ -43,319 +45,314 @@ var filterFileErrors = function(errors) { return _.reject(errors, ['type', 'ignored']); }; -var CLI = function(config) { - config = config || {}; - - EventEmitter.call(this); +class CLI extends EventEmitter { + constructor(config) { + super(); - this._configs = {}; + config = config || {}; - this.flags = _.defaults(config.flags, flags); + this._configs = {}; - this._args = config.args || argv._; - this._cwd = config.cwd || base.CWD; - this._exec = config.exec || cli.exec.bind(cli); - this.junit = config.junit || junit; - this._log = config.log || console.log.bind(console); - this._logger = config.logger || Logger; - this._read = config.read || fs.readFileAsync.bind(fs); - this._write = config.write || fs.writeFileAsync.bind(fs); -}; + this.flags = _.defaults(config.flags, flags); -CLI.prototype = _.create( - EventEmitter.prototype, - { - constructor: CLI, + this._args = config.args || argv._; + this._cwd = config.cwd || base.CWD; + this._exec = config.exec || cli.exec.bind(cli); + this.junit = config.junit || junit; + this._log = config.log || console.log.bind(console); + this._logger = config.logger || Logger; + this._read = config.read || fs.readFileAsync.bind(fs); + this._write = config.write || fs.writeFileAsync.bind(fs); + } - init: function() { - var instance = this; + init() { + var instance = this; - this._config = new Config.Loader( - { - cwd: instance._cwd - } - ); + this._config = new Config.Loader( + { + cwd: instance._cwd + } + ); - return this._loadConfigs().then( - function(configs) { - instance._configs = configs; + return this._loadConfigs().then( + function(configs) { + instance._configs = configs; - return configs; - } - ) - .bind(instance) - .then(instance._start); - }, + return configs; + } + ) + .bind(instance) + .then(instance._start); + } - afterFormat: function(results) { - var instance = this; + afterFormat(results) { + var instance = this; - var series = []; + var series = []; - if (instance.flags.inlineEdit) { - series = results.reduce( - function(prev, item, index) { - if (item && !item.err && item.contents !== item.data) { - prev.push(instance.writeFile(item.file, item.contents)); - } + if (instance.flags.inlineEdit) { + series = results.reduce( + function(prev, item, index) { + if (item && !item.err && item.contents !== item.data) { + prev.push(instance.writeFile(item.file, item.contents)); + } - return prev; - }, - series - ); - } + return prev; + }, + series + ); + } - return Promise.all(series) - .then(instance.onFinish.bind(instance)) - .catch(instance.logGeneralError.bind(instance)); - }, + return Promise.all(series) + .then(instance.onFinish.bind(instance)) + .catch(instance.logGeneralError.bind(instance)); + } - checkMeta: function(results) { - if (this._CHECK_META) { - require(this._metaCheckerPath).check( - { - liferayModuleDir: this._liferayModuleDir - } - ); - } + checkMeta(results) { + if (this._CHECK_META) { + require(this._metaCheckerPath).check( + { + liferayModuleDir: this._liferayModuleDir + } + ); + } - return results; - }, + return results; + } - createReport: function(results) { - if (this.flags.junit) { - var junit = new this.junit( - { - flags: this.flags, - logger: this._logger - } - ); + createReport(results) { + if (this.flags.junit) { + var junit = new this.junit( + { + flags: this.flags, + logger: this._logger + } + ); - results = junit.generate().return(results); - } + results = junit.generate().return(results); + } - return results; - }, + return results; + } - formatFile: function(contents, file) { - var formatter = Formatter.get(file, this._logger, this.flags); + formatFile(contents, file) { + var formatter = Formatter.get(file, this._logger, this.flags); - if (formatter) { - formatter._config = this._configs[file]; + if (formatter) { + formatter._config = this._configs[file]; - contents = this.processFileData(contents, formatter); + contents = this.processFileData(contents, formatter); - this.isMetaCheckNeeded(file); - } + this.isMetaCheckNeeded(file); + } - return contents; - }, + return contents; + } - hasModulesFile: function(fileDir) { - return fs.existsSync(path.join(fileDir, 'modules.js')); - }, + hasModulesFile(fileDir) { + return fs.existsSync(path.join(fileDir, 'modules.js')); + } - isMetaCheckNeeded: function(file) { - if (!this._CHECK_META && this.flags.checkMetadata && path.extname(file) === '.js') { - var fileDir = path.dirname(path.resolve(file)); + isMetaCheckNeeded(file) { + if (!this._CHECK_META && this.flags.checkMetadata && path.extname(file) === '.js') { + var fileDir = path.dirname(path.resolve(file)); - if (path.basename(fileDir) === 'liferay' && this.hasModulesFile(fileDir)) { - this._CHECK_META = true; - this._liferayModuleDir = fileDir; - } + if (path.basename(fileDir) === 'liferay' && this.hasModulesFile(fileDir)) { + this._CHECK_META = true; + this._liferayModuleDir = fileDir; } - }, + } + } - logGeneralError: function(err) { - var msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); + logGeneralError(err) { + var msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); - this._log(msg); + this._log(msg); - return msg; - }, + return msg; + } - logResults: function(out, file) { - if (out) { - this._log(out); - } + logResults(out, file) { + if (out) { + this._log(out); + } - var verboseDetails = this._logger.verboseDetails[file]; + var verboseDetails = this._logger.verboseDetails[file]; - if (verboseDetails) { - this._log(verboseDetails); - } - }, + if (verboseDetails) { + this._log(verboseDetails); + } + } - onFinish: function(results) { - if (this.flags.open) { - this.openFiles(results); - } + onFinish(results) { + if (this.flags.open) { + this.openFiles(results); + } - return results; - }, + return results; + } - onRead: function(contents, file) { - return this.formatFile(contents, file); - }, + onRead(contents, file) { + return this.formatFile(contents, file); + } - onReadError: function(err, file) { - var errMsg = File.handleFileReadError(err, file); + onReadError(err, file) { + var errMsg = File.handleFileReadError(err, file); - if (errMsg) { - this._log(''); - this._log(errMsg); - this._log(''); - } + if (errMsg) { + this._log(''); + this._log(errMsg); + this._log(''); + } - return { - contents: '', - err: err, - file: file - }; - }, - - openFiles: function(result) { - var instance = this; - - var errorFiles = Object.keys(instance._logger.getErrors()); - - if (errorFiles.length) { - instance._exec( - 'git config --get user.editor', - function(res) { - instance._exec( - 'open -a "' + res[0] + '" "' + errorFiles.join('" "') + '"' - ); - } - ); - } - }, + return { + contents: '', + err: err, + file: file + }; + } - processFile: function(file) { - return this._read(file, 'utf-8') - .then(_.bindKeyRight(this, 'onRead', file)) - .error(_.bindKeyRight(this, 'onReadError', file)); - }, + openFiles(result) { + var instance = this; - processFileData: function(data, formatter) { - var file = formatter.file; + var errorFiles = Object.keys(instance._logger.getErrors()); - var contents = formatter.format(data); + if (errorFiles.length) { + instance._exec( + 'git config --get user.editor', + function(res) { + instance._exec( + 'open -a "' + res[0] + '" "' + errorFiles.join('" "') + '"' + ); + } + ); + } + } - this.logResults(this.renderOutput(file), file); + processFile(file) { + return this._read(file, 'utf-8') + .then(_.bindKeyRight(this, 'onRead', file)) + .error(_.bindKeyRight(this, 'onReadError', file)); + } - return { - file: file, - contents: contents, - data: data - }; - }, + processFileData(data, formatter) { + var file = formatter.file; - renderOutput: function(file) { - var flags = this.flags; + var contents = formatter.format(data); - var config = { - showColumns: flags.showColumns - }; + this.logResults(this.renderOutput(file), file); - var out; + return { + file: file, + contents: contents, + data: data + }; + } - if (flags.relative) { - config.relative = this._cwd; - } + renderOutput(file) { + var flags = this.flags; - if (flags.filenames) { - out = this._logger.renderFileNames(file, config); - } - else { - config.showBanner = flags.quiet; - config.showLintIds = flags.lintIds; - - if (flags.quiet) { - this._logger.filterFileErrors( - file, - filterFileErrors - ); - } + var config = { + showColumns: flags.showColumns + }; + + var out; + + if (flags.relative) { + config.relative = this._cwd; + } - out = this._logger.render(file, config); + if (flags.filenames) { + out = this._logger.renderFileNames(file, config); + } + else { + config.showBanner = flags.quiet; + config.showLintIds = flags.lintIds; + + if (flags.quiet) { + this._logger.filterFileErrors( + file, + filterFileErrors + ); } - return out; - }, + out = this._logger.render(file, config); + } - writeFile: function(file, contents) { - return this._write(file, contents) - .then(_.bind(_.ary(util.format, 2), util, 'Wrote file: %s', file)) - .error(File.handleFileWriteError.bind(this, file)) - .then(_.unary(this._log).bind(this)); - }, + return out; + } - _loadConfig: function(config) { - if (this.flags.config) { - var obj = config._paths.obj; - var err = config._paths.err; + writeFile(file, contents) { + return this._write(file, contents) + .then(_.bind(_.ary(util.format, 2), util, 'Wrote file: %s', file)) + .error(File.handleFileWriteError.bind(this, file)) + .then(_.unary(this._log).bind(this)); + } - if (this.flags.verbose && !this.flags.filenames) { - if (obj) { - this._log('Using local config from ', obj.filepath); - } - else if (err) { - this._log('Could not resolve any local config: ', err, err.stack); - } + _loadConfig(config) { + if (this.flags.config) { + var obj = config._paths.obj; + var err = config._paths.err; + + if (this.flags.verbose && !this.flags.filenames) { + if (obj) { + this._log('Using local config from ', obj.filepath); + } + else if (err) { + this._log('Could not resolve any local config: ', err, err.stack); } } + } - return config; - }, + return config; + } - _loadConfigs: function() { - var instance = this; + _loadConfigs() { + var instance = this; - return Promise.reduce( - instance._args, - function(prev, item, index) { - var filePath = path.resolve(instance._cwd, path.dirname(item)); + return Promise.reduce( + instance._args, + function(prev, item, index) { + var filePath = path.resolve(instance._cwd, path.dirname(item)); - var res; + var res; - if (instance.flags.config) { - res = instance._config.load(filePath); - } - else { - var cfg = new Config({}); + if (instance.flags.config) { + res = instance._config.load(filePath); + } + else { + var cfg = new Config({}); - cfg._paths.cwd = instance._cwd; + cfg._paths.cwd = instance._cwd; - res = Promise.resolve(cfg); - } - - return res.then( - function(config) { - prev[item] = instance._loadConfig(config); + res = Promise.resolve(cfg); + } - return prev; - } - ); - }, - {} - ); - }, + return res.then( + function(config) { + prev[item] = instance._loadConfig(config); - _start: function() { - this.emit('init'); + return prev; + } + ); + }, + {} + ); + } - return Promise.all(this._args) - .bind(this) - .map(_.unary(this.processFile)) - .then(this.checkMeta) - .then(this.createReport) - .then(this.afterFormat); - }, + _start() { + this.emit('init'); - _metaCheckerPath: './meta' + return Promise.all(this._args) + .bind(this) + .map(_.unary(this.processFile)) + .then(this.checkMeta) + .then(this.createReport) + .then(this.afterFormat); } -); +}; + +CLI.prototype._metaCheckerPath = './meta'; var cliInstance = new CLI(); From 64fa0d90fe76e87cbfe8726d38a55512901e702d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 11:32:26 -0700 Subject: [PATCH 098/153] Migrating to ES6 classes: config --- lib/config.js | 70 ++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/lib/config.js b/lib/config.js index d1513d4..2a32b25 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,3 +1,5 @@ +'use strict'; + var _ = require('lodash'); var cosmiconfig = require('cosmiconfig'); @@ -8,23 +10,23 @@ var CONFIG_DEFAULT = { } }; -var Config = function(obj) { - this._config = this._normalize(obj); +class Config { + constructor(obj) { + this._config = this._normalize(obj); - return this._config; -}; + return this._config; + } -Config.prototype = { - toJSON: function(){ + toJSON() { return _.omit(this._config, '_paths'); - }, + } - _get: function(key) { + _get(key) { return key ? _.result(this._config, key) : this._config; - }, + } - _normalize: function(obj) { - var fn = this._get.bind(this); + _normalize(obj) { + const fn = this._get.bind(this); Object.defineProperty( fn, @@ -64,37 +66,37 @@ Config.prototype = { return _.merge(fn, CONFIG_DEFAULT, obj); } -}; +} -var Loader = function(options) { - options = _.defaults( - options, - { - cwd: process.cwd(), - packageProp: 'csfConfig' - } - ); +class Loader { + constructor(options) { + options = _.defaults( + options, + { + cwd: process.cwd(), + packageProp: 'csfConfig' + } + ); - this._config = cosmiconfig('csf', options); -} + this._config = cosmiconfig('csf', options); + } -Loader.prototype = { - load: function(cwd) { + load(cwd) { return this._config.load(cwd).then( - function(obj) { - var config = new Config(obj ? obj.config : {}); + obj => { + const config = new Config(obj ? obj.config : {}); config._paths.cwd = cwd; if (obj) { - var STR_PATH = 'path:'; + const STR_PATH = 'path:'; - var paths = Object.keys(config).reduce( - function(prev, item, index) { + const paths = Object.keys(config).reduce( + (prev, item, index) => { if (item.indexOf(STR_PATH) === 0) { - var pathKey = item.slice(STR_PATH.length); + const pathKey = item.slice(STR_PATH.length); - var pathConfig = config[item]; + const pathConfig = config[item]; prev.configs.push(pathConfig); @@ -114,8 +116,8 @@ Loader.prototype = { return config; } ).catch( - function(err) { - var config = new Config(); + err => { + const config = new Config(); config._paths.cwd = cwd; @@ -125,7 +127,7 @@ Loader.prototype = { } ); } -}; +} Config.Loader = Loader; From 664976d28bac8d93de4323e40dc6f929b8f565b4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 20 Apr 2017 14:15:44 -0700 Subject: [PATCH 099/153] Migrating to classes: junit --- lib/junit.js | 68 +++++++++++++++++++++++++++------------------------- test/cli.js | 9 +++---- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/lib/junit.js b/lib/junit.js index 2c4bf93..ad1f844 100644 --- a/lib/junit.js +++ b/lib/junit.js @@ -1,3 +1,5 @@ +'use strict'; + var _ = require('lodash'); var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); @@ -9,28 +11,26 @@ var Logger = require('./logger'); var A = base.A; -var JUnitReporter = function(config) { - this.flags = config.flags || {}; - this.logger = config.logger || Logger; - this.read = config.read || fs.readFileAsync.bind(fs); - this.write = config.write || fs.writeFileAsync.bind(fs); -}; - -JUnitReporter.prototype = { - TPL_PATH: path.join(__dirname, 'tpl', 'junit_report.tpl'), +class JUnitReporter { + constructor(config) { + this.flags = config.flags || {}; + this.logger = config.logger || Logger; + this.read = config.read || fs.readFileAsync.bind(fs); + this.write = config.write || fs.writeFileAsync.bind(fs); + } - generate: function() { + generate() { return this.read(this.TPL_PATH, 'utf-8').then(this.onRead.bind(this)); - }, + } - getContext: function() { - var flags = this.flags; - var logger = this.logger; + getContext() { + const flags = this.flags; + const logger = this.logger; - var fileErrors = logger.getErrors(); - var testStats = logger.testStats; + const fileErrors = logger.getErrors(); + const testStats = logger.testStats; - var result = { + const result = { files: [], showLintIds: flags['lint-ids'], stats: testStats @@ -38,14 +38,14 @@ JUnitReporter.prototype = { _.forEach( fileErrors, - function(fileErrors, fileName) { - var errors = []; + (fileErrors, fileName) => { + const errors = []; fileErrors = _.reject(fileErrors, {type: 'ignored'}); _.forEach( _.groupBy(fileErrors, 'type'), - function(violations, violationType) { + (violations, violationType) => { errors.push( { failure: { @@ -58,8 +58,8 @@ JUnitReporter.prototype = { } ); - var fileResult = { - errors: errors, + const fileResult = { + errors, file: fileName, stats: { failures: fileErrors.length @@ -71,32 +71,34 @@ JUnitReporter.prototype = { ); return result; - }, + } - getOutputPath: function() { - var outputPath = this.flags.junit; + getOutputPath() { + let outputPath = this.flags.junit; if (!_.isString(outputPath)) { outputPath = 'result.xml'; } return outputPath; - }, + } - onRead: function(result) { - var context = this.getContext(); - var outputPath = this.getOutputPath(); + onRead(result) { + const context = this.getContext(); + const outputPath = this.getOutputPath(); - var xml = this.renderTPL(result, context); + const xml = this.renderTPL(result, context); return this.write(outputPath, xml); - }, + } - renderTPL: function(tpl, context) { - var xmlTpl = Handlebars.compile(tpl); + renderTPL(tpl, context) { + const xmlTpl = Handlebars.compile(tpl); return xmlTpl(context); } }; +JUnitReporter.prototype.TPL_PATH = path.join(__dirname, 'tpl', 'junit_report.tpl'); + module.exports = JUnitReporter; \ No newline at end of file diff --git a/test/cli.js b/test/cli.js index 216a1eb..0443dbe 100644 --- a/test/cli.js +++ b/test/cli.js @@ -633,9 +633,7 @@ describe( var junitReporter = require('../lib/junit'); - var junit = sandbox.spy(junitReporter); - - sandbox.stub(junit.prototype, 'generate').returns(Promise.resolve()); + sandbox.stub(junitReporter.prototype, 'generate').returns(Promise.resolve()); var cliInstance = new cli.CLI( { @@ -643,7 +641,7 @@ describe( flags: { junit: true }, - junit: junit, + junit: junitReporter, log: _.noop, logger: new Logger.constructor() } @@ -651,8 +649,7 @@ describe( cliInstance.init().then( function() { - assert.isTrue(junit.calledWithNew(), 'junit should have been instantiated'); - assert.isTrue(junit.prototype.generate.called, 'junit.prototype.generate should have been called, it was instead called ' + junit.prototype.generate.callCount + ' times'); + assert.isTrue(junitReporter.prototype.generate.called, 'junit.prototype.generate should have been called, it was instead called ' + junitReporter.prototype.generate.callCount + ' times'); } ).done(done); } From b391ac99963828bab6c884e72040a0ecb4668e92 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 21 Apr 2017 08:34:59 -0700 Subject: [PATCH 100/153] Pass harmony flag to node process (this hack is needed because linux doesn't support passing more than one argument to /usr/bin/env) --- bin/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/index.js b/bin/index.js index dac419c..fcc462c 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,4 +1,5 @@ -#!/usr/bin/env node +#!/bin/sh +":" //# http://sambal.org/?p=1014 ; exec /usr/bin/env node --harmony "$0" "$@" var updateNotifier = require('update-notifier'); From 77945ff2f8ecb3a19014fc5aecfa320346aa1f5b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 21 Apr 2017 08:36:22 -0700 Subject: [PATCH 101/153] Add harmonize to the gulp file so that the harmony flag is added to the gulp process (could have done this in the bin/index.js file too, but it just seemed like extra overhead) --- gulpfile.js | 2 ++ package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 17eeeb4..6fba2f8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,5 @@ +require('harmonize')(); + var _ = require('lodash'); var gulp = require('gulp'); var plugins = require('gulp-load-plugins')(); diff --git a/package.json b/package.json index 0f54d85..c9a5e47 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "gulp-mocha": "^3.0.1", "gulp-rename": "^1.2.2", "gulp-template": "^4.0.0", + "harmonize": "^2.0.0", "inquirer": "^1.1.3", "istanbul": "^0.4.4", "mocha": "^3.0.2", From 7ccd592cf28b4eb52f339de27bf7434f92245872 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 21 Apr 2017 08:47:19 -0700 Subject: [PATCH 102/153] Using rest arguments --- lib/lint_js_rules/sort_props.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/lint_js_rules/sort_props.js b/lib/lint_js_rules/sort_props.js index e62a6c0..9d559ac 100644 --- a/lib/lint_js_rules/sort_props.js +++ b/lib/lint_js_rules/sort_props.js @@ -16,9 +16,7 @@ module.exports = function(context) { destructor: -600 }; - var getCacheKey = function() { - return Array.prototype.join.call(arguments, '_'); - }; + var getCacheKey = (...args) => args.join('_'); // Recursive function for collection node values // var getVals = function(obj, arr) { From b14e0966108290487e888dbbe990ce210dbdd53a Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 21 Apr 2017 12:04:45 -0700 Subject: [PATCH 103/153] Fixing cwd issue where cwd was being read from either an env variable called GIT_PWD, which was for relatively printing the file name. However, it was also being used as the cli's cwd, which caused issues with resolving the filename properly, and therefore trying to find a config file --- lib/base.js | 1 - lib/cli.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/base.js b/lib/base.js index 8c20774..e2fed6f 100644 --- a/lib/base.js +++ b/lib/base.js @@ -27,7 +27,6 @@ var stubs = _.transform( ); module.exports = { - CWD: process.env.GIT_PWD || process.cwd(), INDENT: ' ', REGEX_NEWLINE: REGEX_NEWLINE, diff --git a/lib/cli.js b/lib/cli.js index a51d7dd..8803fde 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -56,7 +56,7 @@ class CLI extends EventEmitter { this.flags = _.defaults(config.flags, flags); this._args = config.args || argv._; - this._cwd = config.cwd || base.CWD; + this._cwd = config.cwd || process.cwd(); this._exec = config.exec || cli.exec.bind(cli); this.junit = config.junit || junit; this._log = config.log || console.log.bind(console); @@ -259,7 +259,7 @@ class CLI extends EventEmitter { var out; if (flags.relative) { - config.relative = this._cwd; + config.relative = process.env.GIT_PWD || this._cwd; } if (flags.filenames) { From 7965b889a0fc270272ebc961292b71b5e883f455 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 21 Apr 2017 14:21:16 -0700 Subject: [PATCH 104/153] Handle logging of config files better --- lib/cli.js | 55 +++++++++++++++++++++------------ test/cli.js | 88 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 96 insertions(+), 47 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 8803fde..25ede7c 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -52,6 +52,7 @@ class CLI extends EventEmitter { config = config || {}; this._configs = {}; + this._configFiles = {}; this.flags = _.defaults(config.flags, flags); @@ -289,24 +290,6 @@ class CLI extends EventEmitter { .then(_.unary(this._log).bind(this)); } - _loadConfig(config) { - if (this.flags.config) { - var obj = config._paths.obj; - var err = config._paths.err; - - if (this.flags.verbose && !this.flags.filenames) { - if (obj) { - this._log('Using local config from ', obj.filepath); - } - else if (err) { - this._log('Could not resolve any local config: ', err, err.stack); - } - } - } - - return config; - } - _loadConfigs() { var instance = this; @@ -330,7 +313,13 @@ class CLI extends EventEmitter { return res.then( function(config) { - prev[item] = instance._loadConfig(config); + prev[item] = config; + + var obj = config._paths.obj; + + if (obj) { + instance._configFiles[obj.filepath] = true; + } return prev; } @@ -340,9 +329,37 @@ class CLI extends EventEmitter { ); } + _notifyConfig() { + if (this.flags.config && !this.flags.filenames) { + var configFiles = _.keys(this._configFiles); + + var configSize = configFiles.length; + + if (configSize) { + var msg; + + if (configSize === 1) { + msg = `Using local config from ${configFiles[0]}`; + } + else if (this.flags.verbose) { + msg = 'Using local config from: \n' + configFiles.join('\n'); + } + else { + msg = `Using local config from ${configSize} files. Pass -v to see all locations`; + } + + msg += '\n'; + + this._log(msg); + } + } + } + _start() { this.emit('init'); + this._notifyConfig(); + return Promise.all(this._args) .bind(this) .map(_.unary(this.processFile)) diff --git a/test/cli.js b/test/cli.js index 0443dbe..cc0ed24 100644 --- a/test/cli.js +++ b/test/cli.js @@ -752,43 +752,75 @@ describe( ); it( - 'should handle invalid config logging', + 'should handle config logging', function(done) { - var log = sandbox.spy(); + var read = function(file, options) { + var retVal; - var cliInstance = new cli.CLI( + if (file === 'foo.js') { + retVal = Promise.resolve(''); + } + else { + retVal = fs.readFileAsync(file, options); + } + + return retVal; + }; + + var files = ['filenames/foo.js', 'flags/bar.js']; + + var cwd = path.join(__dirname, 'fixture/config'); + + var configs = [ { - args: ['foo.js'], - cwd: path.join(__dirname, 'fixture/config/bad_config'), - flags: { - quiet: true, - verbose: true + config: { + args: files.slice(0, 1) }, - log: log, - logger: new Logger.constructor(), - read: function(file, options) { - var retVal; - - if (file === 'foo.js') { - retVal = Promise.resolve(''); - } - else { - retVal = fs.readFileAsync(file, options); + msg: 'Using local config from ' + path.join(cwd, 'filenames/csf.config.js') + '\n' + }, + { + config: { + args: files + }, + msg: 'Using local config from 2 files. Pass -v to see all locations\n' + }, + { + config: { + args: files, + flags: { + verbose: true } - - return retVal; - } + }, + msg: 'Using local config from: \n' + files.map(file => path.join(cwd, path.dirname(file), 'csf.config.js')).join('\n') + '\n' } - ); + ]; - cliInstance.init().then( - function() { - assert.isTrue(cliInstance.flags.verbose); - assert.startsWith(log.args[0][0], 'Could not resolve any local config'); + Promise.map( + configs, + function(item, index) { + var log = sandbox.spy(); + + var cfg = _.defaults( + item.config, + { + cwd: cwd, + log: log, + logger: new Logger.constructor(), + read: read + } + ); - done(); + var cliInstance = new cli.CLI(cfg); + + return cliInstance.init().then( + function() { + assert.equal(log.args[0][0], item.msg); + } + ); } - ); + ) + .then(_.ary(done, 0)) + .catch(done); } ); From 2bdfd0dfa647ec00852e3ae63e6822a256f61cc1 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 2 May 2017 13:46:23 -0700 Subject: [PATCH 105/153] Switching to mapSeries so that the output is at least ordered predictably --- lib/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli.js b/lib/cli.js index 25ede7c..c4d5f2c 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -362,7 +362,7 @@ class CLI extends EventEmitter { return Promise.all(this._args) .bind(this) - .map(_.unary(this.processFile)) + .mapSeries(_.unary(this.processFile)) .then(this.checkMeta) .then(this.createReport) .then(this.afterFormat); From 13a5f1966284e99e7e93fa8189bf3f16da5f839d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 5 May 2017 10:44:34 -0700 Subject: [PATCH 106/153] Defaulting to being able to parse es6 --- lib/config/eslint.js | 10 +++++++++- lib/config/eslint_es6.js | 22 +++++++++++----------- lib/lint_js.js | 6 ++++++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/config/eslint.js b/lib/config/eslint.js index d28cef3..19a04ae 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -2,12 +2,20 @@ module.exports = { 'env': { 'amd': false, 'browser': true, + 'es6': true, 'mocha': true, 'node': true }, + 'parser': 'babel-eslint', + 'parserOptions': { - 'ecmaVersion': 5 + 'sourceType': 'module', + 'ecmaVersion': 7, + 'ecmaFeatures': { + 'experimentalObjectRestSpread': true, + 'jsx': true + } }, 'globals': { diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 2e6b194..5de35c4 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -1,17 +1,17 @@ module.exports = { - 'env': { - 'es6': true - }, + // 'env': { + // 'es6': true + // }, - 'parser': 'babel-eslint', + // 'parser': 'babel-eslint', - 'parserOptions': { - 'sourceType': 'module', - 'ecmaFeatures': { - 'experimentalObjectRestSpread': true, - 'jsx': true - } - }, + // 'parserOptions': { + // 'sourceType': 'module', + // 'ecmaFeatures': { + // 'experimentalObjectRestSpread': true, + // 'jsx': true + // } + // }, 'plugins': [ 'react' diff --git a/lib/lint_js.js b/lib/lint_js.js index 793072f..3b35029 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -24,6 +24,12 @@ var runLinter = function(contents, file, context) { var config = context.lintConfig; + // The ecmaVersion variable is undefined here if no config was found + // But it's being used now for it's side effects + // because we're defaulting the parser to es7 so it doesn't error out + // but if it's specified in the config, we add the special + // es6 lint rule set + var ecmaVersion = _.get(config, 'parserOptions.ecmaVersion'); var configs = [{}, ESLINT_CONFIG]; From f96efc1d161ca8f0e174067edb45d8bab88eedc5 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 5 May 2017 13:15:51 -0700 Subject: [PATCH 107/153] Fix broken test since updating the default --- test/js.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/js.js b/test/js.js index ad94a8e..951bf54 100644 --- a/test/js.js +++ b/test/js.js @@ -319,7 +319,6 @@ describe( var args = eslint.linter.verify.args[0]; - assert.equal(args[1].parserOptions.ecmaVersion, 5); assert.isUndefined(args[1].plugins); } ); From a45e9c1bdd541cb7757054a8caadace16afdc758 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 10 May 2017 11:29:11 -0700 Subject: [PATCH 108/153] Updating deps --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c9a5e47..620e657 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "bluebird": "^3.4.1", "cli": "^1.0.0", "cli-color-keywords": "0.0.1", - "content-formatter": "^1.1.0", - "content-logger": "^0.0.3", + "content-formatter": "^2.0.1", + "content-logger": "^1.0.1", "content-logger-handlebars-helpers": "0.0.1", "cosmiconfig": "^2.1.0", "drip": "^1.4.0", From 03b9bba0f64c6c133c8d4571ea04d4782672d5f1 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 11:36:59 -0700 Subject: [PATCH 109/153] Allow config files to be able to specify an eslint plugin with either an absolute path to the plugin directory, or a path relative to the config file --- lib/js.js | 1 + lib/lint_js.js | 67 +++++++++++++++- package.json | 1 + test/fixture/eslint-plugin-custom-lint.js | 10 +++ test/js.js | 93 ++++++++++++++++++++++- 5 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 test/fixture/eslint-plugin-custom-lint.js diff --git a/lib/js.js b/lib/js.js index d5ea599..e08463c 100644 --- a/lib/js.js +++ b/lib/js.js @@ -51,6 +51,7 @@ Formatter.JS = Formatter.create( var context = { customIgnore: re.rules.js.IGNORE, file: filePath, + fileConfig: this._config, hasSheBang: hasSheBang, lintConfig: this.flags.lint !== false && lint }; diff --git a/lib/lint_js.js b/lib/lint_js.js index 3b35029..061744c 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -17,6 +17,45 @@ var convertNameToRuleId = function(item) { return 'csf-' + baseName.replace(/_/g, '-'); }; +var loadPlugin = function(pluginName, configPath) { + var rules; + + if (pluginName !== 'react') { + if (pluginName.indexOf('eslint-plugin-') === -1) { + pluginName = 'eslint-plugin-' + pluginName; + } + + var baseName = pluginName.replace('eslint-plugin-', ''); + + if (pluginName.indexOf('/') !== -1) { + baseName = path.basename(baseName); + + if (configPath && !path.isAbsolute(pluginName)) { + pluginName = path.resolve(configPath, pluginName); + } + } + + try { + rules = require(pluginName).rules; + } + catch (e) { + } + + if (rules) { + rules = _.mapKeys( + rules, + function(item, index) { + return baseName + '/' + index; + } + ); + + eslint.linter.defineRules(rules); + } + } + + return rules; +}; + var runLinter = function(contents, file, context) { var customRules = context.customRules || {}; @@ -44,7 +83,33 @@ var runLinter = function(contents, file, context) { configs.push(config); } - config = _.merge.apply(_, configs); + configs.push( + function(objValue, srcValue, key) { + var retVal; + + if (key === 'plugins' && _.isArray(objValue) && _.isArray(srcValue)) { + retVal = objValue.concat(srcValue); + } + + return retVal; + } + ); + + config = _.mergeWith.apply(_, configs); + + if (config.plugins) { + var configPath = _.get(context, 'fileConfig._paths.obj.filepath'); + + if (configPath) { + configPath = path.dirname(configPath); + } + + config.plugins.forEach( + function(item, index) { + loadPlugin(item, configPath); + } + ); + } var results = eslint.linter.verify(contents, config, file); diff --git a/package.json b/package.json index 620e657..c3ec88d 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "chai": "^3.5.0", "chai-string": "^1.2.0", "coveralls": "^2.11.12", + "eslint-plugin-dollar-sign": "^1.0.0", "gulp": "^3.9.1", "gulp-complexity": "^0.3.2", "gulp-coveralls": "^0.1.4", diff --git a/test/fixture/eslint-plugin-custom-lint.js b/test/fixture/eslint-plugin-custom-lint.js new file mode 100644 index 0000000..9bceadb --- /dev/null +++ b/test/fixture/eslint-plugin-custom-lint.js @@ -0,0 +1,10 @@ +module.exports = { + rules: { + foo: function(context) { + return { + 'Program:exit': function() { + } + }; + } + } +}; \ No newline at end of file diff --git a/test/js.js b/test/js.js index 951bf54..a985852 100644 --- a/test/js.js +++ b/test/js.js @@ -326,7 +326,6 @@ describe( it( 'should merge configuration properties', function() { - var eslint = lint.eslint; var verify = function(contents, config, file) { @@ -355,5 +354,97 @@ describe( assert.isArray(args[1].plugins); } ); + + it( + 'load a custom eslint plugin', + function() { + var eslint = lint.eslint; + + sandbox.spy(eslint.linter, 'verify'); + + lint.runLinter( + source, + testFilePath, + { + fileConfig: { + _paths: { + obj: { + filepath: path.join(__dirname, '../package.json') + } + } + }, + lintConfig: { + parserOptions: { + ecmaVersion: 7 + }, + plugins: ['dollar-sign'] + } + } + ); + + var linterRules = eslint.linter.getRules(); + + assert.isTrue(linterRules.has('dollar-sign/dollar-sign')); + } + ); + + it( + 'load a custom eslint plugin via path', + function() { + var eslint = lint.eslint; + + var linterRulesPrev = eslint.linter.getRules(); + + lint.runLinter( + source, + testFilePath, + { + fileConfig: { + _paths: { + obj: { + filepath: path.join(__dirname, '../package.json') + } + } + }, + lintConfig: { + parserOptions: { + ecmaVersion: 7 + }, + plugins: ['./test/fixture/eslint-plugin-custom-lint'] + } + } + ); + + var linterRules = eslint.linter.getRules(); + + assert.isTrue(linterRules.has('custom-lint/foo')); + } + ); + + it( + 'ignore non-existent rules', + function() { + var eslint = lint.eslint; + + var linterRulesPrev = eslint.linter.getRules(); + + lint.runLinter( + source, + testFilePath, + { + lintConfig: { + parserOptions: { + ecmaVersion: 7 + }, + plugins: ['non-existent-plugin', './other-non-existent-plugin'] + } + } + ); + + var linterRules = eslint.linter.getRules(); + + assert.equal(linterRulesPrev.size, linterRules.size); + } + ); } ); \ No newline at end of file From 45ae0a7a7210fc3c49378b04f494e96f8fe9f563 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 12:32:45 -0700 Subject: [PATCH 110/153] Updating tests to use the promise version instead of callbacks, wherever possible --- test/cli.js | 130 +++++++++++++++++----------------------------- test/css.js | 118 ++++++++++++++++------------------------- test/formatter.js | 6 +-- test/junit.js | 12 ++--- 4 files changed, 101 insertions(+), 165 deletions(-) diff --git a/test/cli.js b/test/cli.js index cc0ed24..a181f8d 100644 --- a/test/cli.js +++ b/test/cli.js @@ -63,7 +63,7 @@ describe( it( 'should read files correctly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var logger = new Logger.constructor(); @@ -76,14 +76,12 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(fs.readFile.callCount >= 3, 'fs.readFile should have been called 3 times, it was instead called ' + fs.readFile.callCount + ' times'); assert.isTrue(fs.readFile.calledWith('foo.js'), 'foo.js should have been read'); assert.isTrue(fs.readFile.calledWith('bar.html'), 'bar.html should have been read'); assert.isTrue(fs.readFile.calledWith('baz.css'), 'baz.css should have been read'); - - done(); } ); } @@ -91,7 +89,7 @@ describe( it( 'should write files correctly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, null); @@ -110,7 +108,7 @@ describe( sandbox.spy(cliInstance, 'logResults'); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(fs.writeFile.calledThrice, 'fs.writeFile should have been called 3 times, it was instead called ' + fs.writeFile.callCount + ' times'); assert.isTrue(fs.writeFile.calledWith('foo.js'), 'foo.js should have been written to'); @@ -127,8 +125,6 @@ describe( ); assert.equal(log.callCount, 6, '.log should have been called 6 times, it was instead called ' + log.callCount + ' times'); - - done(); } ); } @@ -136,7 +132,7 @@ describe( it( 'should handle file write errors', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, new Error('Something went wrong')); @@ -153,12 +149,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(fs.writeFile.calledOnce, 'fs.writeFile should have been called once, it was instead called ' + fs.writeFile.callCount + ' times'); assert.isTrue(File.handleFileWriteError.calledOnce, 'File.handleFileWriteError should have been called once, it was instead called ' + File.handleFileWriteError.callCount + ' times'); - - done(); } ); } @@ -166,7 +160,7 @@ describe( it( 'should ignore unrecognized files', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); var processFileData = sinon.spy(); @@ -181,11 +175,9 @@ describe( cliInstance.processFileData = processFileData; - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isFalse(processFileData.called, 'processFileData should not have been called for a non-recognized file, it was instead called ' + processFileData.callCount + ' times'); - - done(); } ); } @@ -193,7 +185,7 @@ describe( it( 'should check metadata', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); sandbox.stub(fs, 'existsSync').returns(true); @@ -216,18 +208,17 @@ describe( var checkMeta = sandbox.stub(metaChecker, 'check'); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(checkMeta.called, 'metaChecker.check should have been called, it was instead called ' + checkMeta.callCount + ' times'); } ) - .done(done); } ); it( 'should not check metadata', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); sandbox.stub(fs, 'existsSync').returns(true); @@ -250,17 +241,17 @@ describe( var checkMeta = sandbox.stub(metaChecker, 'check'); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(checkMeta.notCalled, 'metaChecker.check should not have been called, it was instead called ' + metaChecker.check.callCount + ' times'); } - ).done(done); + ); } ); it( 'should log results properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(validContentStub); var log = sandbox.spy(); @@ -273,7 +264,7 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); @@ -282,8 +273,6 @@ describe( cliInstance.logResults(null, 'foo.js'); assert.isTrue(log.notCalled, 'log should not have been called when logResults gets no input, it was instead called ' + log.callCount + ' times'); - - done(); } ); } @@ -291,7 +280,7 @@ describe( it( 'should log verbose details properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, 'var x = ;'); var log = sandbox.spy(); @@ -310,11 +299,9 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledTwice, 'log should have been called twice, it was instead called ' + log.callCount + ' times'); - - done(); } ); } @@ -322,7 +309,7 @@ describe( it( 'should log filenames properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake( function(filePath, encoding, callback) { callback(null, MAP_CONTENT[path.basename(filePath)][0]); @@ -344,12 +331,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.equal(args.join(), log.args.join()); - - done(); } ); } @@ -357,7 +342,7 @@ describe( it( 'should log relative filenames properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake( function(filePath, encoding, callback) { callback(null, MAP_CONTENT[path.basename(filePath)][0]); @@ -393,12 +378,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.equal(relativeArgs.join(), log.args.join()); - - done(); } ); } @@ -406,7 +389,7 @@ describe( it( 'should log missing files properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, new Error()); sandbox.stub(File, 'handleFileReadError').returns('Missing file'); @@ -421,12 +404,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledThrice, 'log should have been called 3 times, it was instead called ' + log.callCount + ' times'); assert.isTrue(File.handleFileReadError.calledOnce, 'File.handleFileReadError should have been called, it was instead called ' + File.handleFileReadError.callCount + ' times'); - - done(); } ); } @@ -434,7 +415,7 @@ describe( it( 'should not write missing files', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); sandbox.stub(fs, 'writeFile').callsArgWith(2, null); @@ -453,11 +434,9 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(fs.writeFile.calledTwice, 'writeFile should have been called only 2 times, it was instead called ' + fs.writeFile.callCount + ' times'); - - done(); } ); } @@ -465,7 +444,7 @@ describe( it( 'should ignore directories properly', - function(done) { + function() { var err = new Error(); err.errno = -21; @@ -485,12 +464,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.notCalled, 'log should not have been called, it was instead called ' + log.callCount + ' times'); assert.isTrue(File.handleFileReadError.returned(''), 'File.handleFileReadError should have returned nothing'); - - done(); } ); } @@ -518,7 +495,7 @@ describe( it( 'should open files properly', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var cliModule = require('cli'); @@ -544,12 +521,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.calledOnce, 'log should have been called only once, it was instead called ' + log.callCount + ' times'); assert.isTrue(cliModule.exec.calledTwice, 'cliModule.exec should have been called 2 times, it was instead called ' + cliModule.exec.callCount + ' times'); - - done(); } ); } @@ -592,7 +567,7 @@ describe( it( 'should not log files without errors when quiet is set', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(validContentStub); var log = sandbox.spy(); @@ -615,20 +590,18 @@ describe( var spy = sandbox.spy(cliInstance, '_loadConfigs'); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(log.notCalled, 'log should not have been called'); assert.isTrue(filterFileErrors.called, 'filterFileErrors should have been called'); - - done(); } - ).catch(done); + ); } ); it( 'should call junit generate', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var junitReporter = require('../lib/junit'); @@ -647,17 +620,17 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(junitReporter.prototype.generate.called, 'junit.prototype.generate should have been called, it was instead called ' + junitReporter.prototype.generate.callCount + ' times'); } - ).done(done); + ); } ); it( 'should handle custom config', - function(done) { + function() { var filePath = path.join(__dirname, 'fixture/config/flags/foo.js'); var log = sandbox.spy(); @@ -680,7 +653,7 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { var configs = cliInstance._configs; var config = configs[filePath]; @@ -691,13 +664,13 @@ describe( assert.startsWith(log.args[0][0], 'Using local config from '); } - ).done(done); + ); } ); it( 'should handle custom config misc', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); var log = sandbox.spy(); @@ -713,18 +686,18 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isNotTrue(cliInstance.flags.quiet); assert.isUndefined(log.args[0]); } - ).done(done); + ); } ); it( 'should handle invalid config', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsArgWith(2, null, ''); var log = sandbox.spy(); @@ -742,18 +715,17 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.lengthOf(Object.keys(cliInstance._configs[filePath]), 0); } - ) - .done(done); + ); } ); it( 'should handle config logging', - function(done) { + function() { var read = function(file, options) { var retVal; @@ -795,7 +767,7 @@ describe( } ]; - Promise.map( + return Promise.map( configs, function(item, index) { var log = sandbox.spy(); @@ -818,15 +790,13 @@ describe( } ); } - ) - .then(_.ary(done, 0)) - .catch(done); + ); } ); it( 'should not load a config when config is false', - function(done) { + function() { sandbox.stub(fs, 'readFile').callsFake(invalidContentStub); var log = sandbox.spy(); @@ -843,12 +813,10 @@ describe( } ); - cliInstance.init().then( + return cliInstance.init().then( function() { assert.isTrue(cliInstance.flags.verbose); assert.notStartsWith(log.args[0][0], 'Could not resolve any local config'); - - done(); } ); } diff --git a/test/css.js b/test/css.js index a115dd0..e40b6aa 100644 --- a/test/css.js +++ b/test/css.js @@ -3,6 +3,10 @@ var chai = require('chai'); var fs = require('fs'); var path = require('path'); +var Promise = require('bluebird'); + +Promise.promisifyAll(fs); + var Formatter = require('../lib/formatter'); var Logger = require('../lib/logger'); @@ -21,61 +25,48 @@ describe( var getFilePath = path.join.bind(path, cssTestsPath); - var testFile = function(filePath, cb, done) { + var testFile = function(filePath) { var cssFormatter = new Formatter.CSS(filePath, cssLogger); - fs.readFile( - filePath, - 'utf-8', - function(err, contents) { - if (!err) { - var newContents = cssFormatter.format(contents); - - cb(cssLogger.fileErrors[filePath], contents, newContents); - } + return fs.readFileAsync(filePath,'utf-8').then( + function(contents) { + var newContents = cssFormatter.format(contents); - if (done) { - done(); - } + return [cssLogger.fileErrors[filePath], contents, newContents]; } ); }; it( 'should detect lower case hex codes', - function(done) { - testFile( - getFilePath('hex_lower_case.css'), + function() { + return testFile(getFilePath('hex_lower_case.css')).spread( function(errors) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); - }, - done + } ); } ); it( 'should detect redundant hex codes', - function(done) { - testFile( - getFilePath('hex_redundant.css'), + function() { + return testFile(getFilePath('hex_redundant.css')).spread( function(errors) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Hex code can be reduced to'); - }, - done + } ); } ); it( 'should detect invalid border resets', - function(done) { - testFile( - getFilePath('invalid_border_reset.css'), + function() { + return testFile(getFilePath('invalid_border_reset.css')).spread( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); @@ -88,17 +79,15 @@ describe( assert.equal(borderErrors.length, errors.length); assert.notEqual(contents, newContents); - }, - done + } ); } ); it( 'should detect invalid formatting in property rules', - function(done) { - testFile( - getFilePath('invalid_format.css'), + function() { + return testFile(getFilePath('invalid_format.css')).spread( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); @@ -109,47 +98,41 @@ describe( ); assert.equal(formatErrors.length, errors.length); - }, - done + } ); } ); it( 'should detect missing integers', - function(done) { - testFile( - getFilePath('missing_integer.css'), + function() { + return testFile(getFilePath('missing_integer.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Missing integer'); - }, - done + } ); } ); it( 'should detect missing spaces in list values', - function(done) { - testFile( - getFilePath('missing_list_values_space.css'), + function() { + return testFile(getFilePath('missing_list_values_space.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Needs space between comma-separated values'); - }, - done + } ); } ); it( 'should detect missing newlines', - function(done) { - testFile( - getFilePath('missing_newlines.css'), + function() { + return testFile(getFilePath('missing_newlines.css')).spread( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); @@ -160,32 +143,28 @@ describe( ); assert.equal(formatErrors.length, errors.length); - }, - done + } ); } ); it( 'should detect missing spaces in selectors', - function(done) { - testFile( - getFilePath('missing_selector_space.css'), + function() { + return testFile(getFilePath('missing_selector_space.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Missing space between selector and bracket'); - }, - done + } ); } ); it( 'should detect needless quotes', - function(done) { - testFile( - getFilePath('needless_quotes.css'), + function() { + return testFile(getFilePath('needless_quotes.css')).spread( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); @@ -196,53 +175,46 @@ describe( ); assert.equal(formatErrors.length, errors.length); - }, - done + } ); } ); it( 'should detect needless units', - function(done) { - testFile( - getFilePath('needless_unit.css'), + function() { + return testFile(getFilePath('needless_unit.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Needless unit'); - }, - done + } ); } ); it( 'should detect property sort', - function(done) { - testFile( - getFilePath('property_sort.css'), + function() { + return testFile(getFilePath('property_sort.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Sort'); - }, - done + } ); } ); it( 'should detect trailing commas in selectors', - function(done) { - testFile( - getFilePath('trailing_comma.css'), + function() { + return testFile(getFilePath('trailing_comma.css')).spread( function(errors, contents, newContents) { assert.equal(errors.length, 1); assert.startsWith(errors[0].msg, 'Trailing comma in selector'); - }, - done + } ); } ); diff --git a/test/formatter.js b/test/formatter.js index 63f0156..e241cc9 100644 --- a/test/formatter.js +++ b/test/formatter.js @@ -28,18 +28,16 @@ describe( it( 'should get merged config by path', - function(done) { + function() { var cwd = path.join(__dirname, 'fixture/config/path_configs'); - (new Config.Loader).load(cwd).then( + return (new Config.Loader).load(cwd).then( function(config) { var formatter = Formatter.get('foo.css', logger, {quiet: true}); formatter._config = config; assert.isFalse(formatter.config('flags.quiet')); - - done(); } ); } diff --git a/test/junit.js b/test/junit.js index 790ba1f..b197daf 100644 --- a/test/junit.js +++ b/test/junit.js @@ -32,7 +32,7 @@ describe( it( 'should generate a JUnit report', - function(done) { + function() { var logger = new Logger.constructor(); logger.log(1, 'Content is not valid', 'foo.js'); @@ -67,19 +67,19 @@ describe( } ); - reporter.generate().then( + return reporter.generate().then( function(results) { assert.isTrue(fs.writeFile.called, 'writeFile should have been called'); assert.equal(results, fs.readFileSync(path.join(__dirname, 'fixture', 'result.xml'), 'utf-8'), 'The result should match what we expect'); } - ).done(done); + ); } ); it( 'should generate a valid JUnit report', - function(done) { + function() { var logger = new Logger.constructor(); logger.log(1, 'Content is not valid', 'foo.js'); @@ -114,15 +114,13 @@ describe( } ); - reporter.generate().then( + return reporter.generate().then( function(results) { xsd.validateXML( results, path.join(__dirname, 'fixture', 'junit-4.xsd'), function(err, result) { assert.isTrue(result.valid, err); - - done(); } ); } From 29a568d928fa970fde7367015bc8e39bc27112f0 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 12:34:08 -0700 Subject: [PATCH 111/153] Update deps --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c3ec88d..eb0a134 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,10 @@ "bluebird": "^3.4.1", "cli": "^1.0.0", "cli-color-keywords": "0.0.1", - "content-formatter": "^2.0.1", + "content-formatter": "^2.0.2", "content-logger": "^1.0.1", "content-logger-handlebars-helpers": "0.0.1", - "cosmiconfig": "^2.1.0", + "cosmiconfig": "^2.1.3", "drip": "^1.4.0", "eslint": "^3.3.1", "eslint-plugin-react": "^6.1.2", @@ -38,7 +38,7 @@ "lodash": "^4.15.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", - "minimatch": "^3.0.3", + "minimatch": "^3.0.4", "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", @@ -47,7 +47,7 @@ "devDependencies": { "chai": "^3.5.0", "chai-string": "^1.2.0", - "coveralls": "^2.11.12", + "coveralls": "^2.13.1", "eslint-plugin-dollar-sign": "^1.0.0", "gulp": "^3.9.1", "gulp-complexity": "^0.3.2", @@ -62,9 +62,9 @@ "harmonize": "^2.0.0", "inquirer": "^1.1.3", "istanbul": "^0.4.4", - "mocha": "^3.0.2", + "mocha": "^3.3.0", "run-sequence": "^1.2.2", - "sinon": "^2.1.0", + "sinon": "^2.2.0", "xsd-schema-validator": "^0.3.1" } } From b9dbdd271f66dadc9d7119cc3d3b29672bf16f63 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 12:38:33 -0700 Subject: [PATCH 112/153] Updating deps for major version updates --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index eb0a134..c80d0f6 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "preferGlobal": "true", "dependencies": { - "babel-eslint": "^6.1.2", + "babel-eslint": "^7.2.3", "bluebird": "^3.4.1", "cli": "^1.0.0", "cli-color-keywords": "0.0.1", @@ -31,7 +31,7 @@ "cosmiconfig": "^2.1.3", "drip": "^1.4.0", "eslint": "^3.3.1", - "eslint-plugin-react": "^6.1.2", + "eslint-plugin-react": "^7.0.0", "falafel": "^1.2.0", "getobject": "^0.1.0", "glob": "^7.0.5", @@ -42,7 +42,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "update-notifier": "^1.0.2" + "update-notifier": "^2.1.0" }, "devDependencies": { "chai": "^3.5.0", @@ -52,7 +52,7 @@ "gulp": "^3.9.1", "gulp-complexity": "^0.3.2", "gulp-coveralls": "^0.1.4", - "gulp-debug": "^2.1.2", + "gulp-debug": "^3.1.0", "gulp-doctoc": "^0.1.4", "gulp-istanbul": "^1.1.0", "gulp-load-plugins": "^1.2.4", @@ -60,11 +60,11 @@ "gulp-rename": "^1.2.2", "gulp-template": "^4.0.0", "harmonize": "^2.0.0", - "inquirer": "^1.1.3", + "inquirer": "^3.0.6", "istanbul": "^0.4.4", "mocha": "^3.3.0", "run-sequence": "^1.2.2", "sinon": "^2.2.0", - "xsd-schema-validator": "^0.3.1" + "xsd-schema-validator": "^0.5.0" } } From a6f80d62c28944ff37d3e9ef8ac103cf60372272 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 13:07:07 -0700 Subject: [PATCH 113/153] Replace deprecated rule --- lib/config/eslint_es6.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 5de35c4..4989594 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -32,7 +32,7 @@ module.exports = { 'jsx-no-literals': 2, 'jsx-closing-bracket-location': 2, 'jsx-pascal-case': 2, - 'jsx-space-before-closing': [2, 'always'], + 'jsx-tag-spacing': [2], 'jsx-sort-props': [2, {'ignoreCase': true}], 'no-multi-comp': [0, {'ignoreStateless': true}], 'jsx-wrap-multilines': [2/*, {'ignoreStateless': true}*/], From 2e5a380dbaead4806332052060e4edd24967dbdd Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 17 Mar 2016 15:02:47 -0700 Subject: [PATCH 114/153] Prelim testing with using stylelint --- lib/css.js | 86 +++++++++++++++++++++++++++++++++++++++- lib/engine_rules/css.js | 3 +- lib/html.js | 6 ++- lib/js.js | 5 ++- lib/lint_css.js | 64 ++++++++++++++++++++++++++++++ lib/stylelint_config.js | 14 +++++++ package.json | 2 +- test/css.js | 24 +++++------ test/engine_rules/css.js | 4 +- test/html.js | 24 +++++++++-- 10 files changed, 209 insertions(+), 23 deletions(-) create mode 100644 lib/lint_css.js create mode 100644 lib/stylelint_config.js diff --git a/lib/css.js b/lib/css.js index 1217e00..71e102f 100644 --- a/lib/css.js +++ b/lib/css.js @@ -1,6 +1,7 @@ var _ = require('lodash'); var base = require('./base'); var re = require('./re'); +var Promise = require('bluebird'); var REGEX = require('./regex'); @@ -39,12 +40,26 @@ Formatter.CSS = Formatter.create( var logger = this.log.bind(this); - return iterateLines( + var newContents = iterateLines( contents, function(item, index, collection) { return instance.processFile(item, index, collection, logger); } ); + + return this._lint(contents).then(function(results) { + instance._logLintResults(results.results); + + return newContents; + }).catch( + function(err) { + done(err, null); + } + ); + + return contents; + + return ; }, formatPropertyItem: function(content) { @@ -133,6 +148,75 @@ Formatter.CSS = Formatter.create( return context; }, + + _lint: function(contents, lint) { + var linter = require('./lint_css'); + + var results = linter(contents, this.file, lint); + + return results; + + // results.then(function(results) { + // console.log('promise', results); + // }) + + // if (results.length) { + // this._logLintResults(results); + // } + }, + + _logLintResults: function(results) { + var instance = this; + + var lintLogFilter = instance.lintLogFilter; + + if (!_.isFunction(lintLogFilter)) { + lintLogFilter = false; + } + + results[0].warnings.forEach( + function(item, index) { + if (lintLogFilter) { + item = lintLogFilter(item); + } +/*{ + source: "path/to/file.css", // The filepath or PostCSS identifier like + errored: true, // This is `true` if at least one rule with an "error"-level severity triggered a warning + warnings: [ // Array of rule violation warning objects, each like the following ... + { + line: 3, + column: 12, + rule: "block-no-empty", + severity: "error", + text: "You should not have an empty block (block-no-empty)" + }, + .. + ], + deprecations: [ // Array of deprecation warning objects, each like the following ... + { + text: "Feature X has been deprecated and will be removed in the next major version.", + reference: "http://stylelint.io/feature-x.md" + } + ], + invalidOptionWarnings: [ // Array of invalid option warning objects, each like the following ... + { + text: "Invalid option X for rule Y", + } + ] +}*/ + + instance.log( + item.line, + item.text, + item.rule, + { + column: item.column, + ruleId: item.rule + } + ); + } + ); + } } } ); diff --git a/lib/engine_rules/css.js b/lib/engine_rules/css.js index d60890b..d059a68 100644 --- a/lib/engine_rules/css.js +++ b/lib/engine_rules/css.js @@ -8,7 +8,8 @@ var REGEX = require('../regex'); module.exports = { hexLowerCase: { - message: 'Hex code should be all uppercase: {1}', + message: false, + // message: 'Hex code should be all uppercase: {1}', regex: /[a-f]/, replacer: function(result, rule, context) { var rawContent = context.rawContent; diff --git a/lib/html.js b/lib/html.js index 625d55e..1768989 100644 --- a/lib/html.js +++ b/lib/html.js @@ -1,4 +1,6 @@ var _ = require('lodash'); +var Promise = require('bluebird'); + var base = require('./base'); var REGEX = require('./regex'); @@ -136,7 +138,7 @@ Formatter.HTML = Formatter.create( file: filePath }; - return iterateLines( + var newContents = iterateLines( contents, function(content, index, collection) { var rawContent = content; @@ -172,6 +174,8 @@ Formatter.HTML = Formatter.create( return rawContent; } ); + + return Promise.resolve(newContents); }, formatCSS: function(styleBlocks) { diff --git a/lib/js.js b/lib/js.js index e08463c..c40a80b 100644 --- a/lib/js.js +++ b/lib/js.js @@ -1,4 +1,5 @@ var _ = require('lodash'); +var Promise = require('bluebird'); var base = require('./base'); var re = require('./re'); @@ -68,7 +69,7 @@ Formatter.JS = Formatter.create( var logger = this.log.bind(this); - return iterateLines( + var newContents = iterateLines( contents, function(content, index, collection) { var rawContent = content; @@ -97,6 +98,8 @@ Formatter.JS = Formatter.create( return rawContent; } ); + + return Promise.resolve(newContents); }, _hasSheBang: function(contents) { diff --git a/lib/lint_css.js b/lib/lint_css.js new file mode 100644 index 0000000..4732b9e --- /dev/null +++ b/lib/lint_css.js @@ -0,0 +1,64 @@ +var _ = require('lodash'); +var stylelint = require('stylelint'); +var STYLELINT_CONFIG = require('./stylelint_config'); +var glob = require('glob'); +var path = require('path'); + +var customRules = {}; + +var reactRules = require('eslint-plugin-react').rules; + +_.defaults(customRules, reactRules); + +var convertNameToRuleId = function(item) { + var baseName = path.basename(item, '.js'); + + return 'csf-' + baseName.replace(/_/g, '-'); +}; + +var runLinter = function(contents, file, customRules, config) { + if (_.isObject(config)) { + config = _.merge({}, STYLELINT_CONFIG, config); + } + else { + config = STYLELINT_CONFIG; + } + + console.log('====',config, file, contents); + + return stylelint.lint( + { + code: contents, + codeFileName: file, + config: config, + formatter: 'json', + syntax: 'scss' + } + ); +}; + +var globOptions = { + cwd: __dirname +}; + +module.exports = function(contents, file, config) { + glob.sync( + './lint_css_rules/*.js', + globOptions + ).forEach( + function(item, index) { + var id = convertNameToRuleId(item); + + customRules[id] = require(item); + } + ); + + // stylelint.linter.defineRules(customRules); + + return runLinter(contents, file, customRules, config); +}; + +module.exports.convertNameToRuleId = convertNameToRuleId; +module.exports.stylelint = stylelint; +module.exports.linter = stylelint.linter; +module.exports.runLinter = runLinter; \ No newline at end of file diff --git a/lib/stylelint_config.js b/lib/stylelint_config.js new file mode 100644 index 0000000..28096a6 --- /dev/null +++ b/lib/stylelint_config.js @@ -0,0 +1,14 @@ +module.exports = { + + // 'plugins': [ + // 'react' + // ], + + 'globals': { + + }, + + 'rules': { + 'color-hex-case': 'upper' + } +}; \ No newline at end of file diff --git a/package.json b/package.json index c80d0f6..cf9def6 100644 --- a/package.json +++ b/package.json @@ -67,4 +67,4 @@ "sinon": "^2.2.0", "xsd-schema-validator": "^0.5.0" } -} +} \ No newline at end of file diff --git a/test/css.js b/test/css.js index e40b6aa..f4f0dca 100644 --- a/test/css.js +++ b/test/css.js @@ -37,18 +37,18 @@ describe( ); }; - it( - 'should detect lower case hex codes', - function() { - return testFile(getFilePath('hex_lower_case.css')).spread( - function(errors) { - assert.equal(errors.length, 1); - - assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); - } - ); - } - ); + // it( + // 'should detect lower case hex codes', + // function() { + // return testFile(getFilePath('hex_lower_case.css')).spread( + // function(errors) { + // assert.equal(errors.length, 1); + + // assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); + // } + // ); + // } + // ); it( 'should detect redundant hex codes', diff --git a/test/engine_rules/css.js b/test/engine_rules/css.js index 3a162f0..f541ee5 100644 --- a/test/engine_rules/css.js +++ b/test/engine_rules/css.js @@ -21,7 +21,7 @@ describe( var input = '#fff'; var output = '#FFF'; - var expectedWarning = 'Hex code should be all uppercase'; + // var expectedWarning = 'Hex code should be all uppercase'; var context = { content: input, @@ -32,7 +32,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); diff --git a/test/html.js b/test/html.js index 8b08254..745c704 100644 --- a/test/html.js +++ b/test/html.js @@ -2,6 +2,7 @@ var _ = require('lodash'); var chai = require('chai'); var fs = require('fs'); var path = require('path'); +var Promise = require('bluebird'); var Formatter = require('../lib/formatter'); var Logger = require('../lib/logger'); @@ -94,12 +95,20 @@ describe( it( 'should parse script blocks correctly', - function() { + function(done) { var scriptBlocks = htmlFormatter.parseJs(source); assert.isArray(scriptBlocks); + assert.equal(scriptBlocks.length, 6); - scriptBlocks.forEach(assert.isString); + + Promise.all(scriptBlocks).then( + function(scriptBlocks) { + scriptBlocks.forEach(assert.isString); + + done(); + } + ); } ); @@ -140,12 +149,19 @@ describe( it( 'should parse style blocks correctly', - function() { + function(done) { var styleBlocks = htmlFormatter.parseCSS(source); assert.isArray(styleBlocks); assert.equal(styleBlocks.length, 2); - styleBlocks.forEach(assert.isString); + + Promise.all(styleBlocks).then( + function(styleBlocks) { + styleBlocks.forEach(assert.isString); + + done(); + } + ); } ); From 4e46190c3abfb412f26ba5ea0867ccedd8998ca6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 18 Mar 2016 13:27:23 -0700 Subject: [PATCH 115/153] Seems to be working --- lib/css.js | 37 ++----------- lib/lint_css.js | 2 - lib/stylelint_config.js | 118 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 36 deletions(-) diff --git a/lib/css.js b/lib/css.js index 71e102f..ac5e31f 100644 --- a/lib/css.js +++ b/lib/css.js @@ -10,6 +10,8 @@ var Formatter = require('content-formatter'); var iterateLines = base.iterateLines; var sub = require('string-sub'); +var REGEX_STYLELINT_POSTFIX = / \(.+?\)$/ + Formatter.CSS = Formatter.create( { excludes: /[_.-](soy|min|nocsf)\.[^.]+$/, @@ -155,14 +157,6 @@ Formatter.CSS = Formatter.create( var results = linter(contents, this.file, lint); return results; - - // results.then(function(results) { - // console.log('promise', results); - // }) - - // if (results.length) { - // this._logLintResults(results); - // } }, _logLintResults: function(results) { @@ -176,34 +170,11 @@ Formatter.CSS = Formatter.create( results[0].warnings.forEach( function(item, index) { + item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); + if (lintLogFilter) { item = lintLogFilter(item); } -/*{ - source: "path/to/file.css", // The filepath or PostCSS identifier like - errored: true, // This is `true` if at least one rule with an "error"-level severity triggered a warning - warnings: [ // Array of rule violation warning objects, each like the following ... - { - line: 3, - column: 12, - rule: "block-no-empty", - severity: "error", - text: "You should not have an empty block (block-no-empty)" - }, - .. - ], - deprecations: [ // Array of deprecation warning objects, each like the following ... - { - text: "Feature X has been deprecated and will be removed in the next major version.", - reference: "http://stylelint.io/feature-x.md" - } - ], - invalidOptionWarnings: [ // Array of invalid option warning objects, each like the following ... - { - text: "Invalid option X for rule Y", - } - ] -}*/ instance.log( item.line, diff --git a/lib/lint_css.js b/lib/lint_css.js index 4732b9e..dad6591 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -24,8 +24,6 @@ var runLinter = function(contents, file, customRules, config) { config = STYLELINT_CONFIG; } - console.log('====',config, file, contents); - return stylelint.lint( { code: contents, diff --git a/lib/stylelint_config.js b/lib/stylelint_config.js index 28096a6..16e77b1 100644 --- a/lib/stylelint_config.js +++ b/lib/stylelint_config.js @@ -9,6 +9,122 @@ module.exports = { }, 'rules': { - 'color-hex-case': 'upper' + 'color-hex-case': 'upper', + 'color-hex-length': 'short', + // 'at-rule-empty-line-before': 'always'|'never', + // 'at-rule-no-vendor-prefix': true, + // 'block-closing-brace-newline-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-closing-brace-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'block-closing-brace-space-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-closing-brace-space-before': 'always'|'never'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-no-empty': true, + // 'block-no-single-line': true, + // 'block-opening-brace-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'block-opening-brace-newline-before': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-opening-brace-space-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-opening-brace-space-before': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'color-hex-case': 'lower'|'upper', + // 'color-hex-length': 'short'|'long', + // 'color-named': 'always-where-possible'|'never', + // 'color-no-hex': true, + // 'color-no-invalid-hex': true, + // 'comment-empty-line-before': 'always'|'never', + // 'comment-whitespace-inside': 'always'|'never', + // 'custom-media-pattern': string, + // 'custom-property-no-outside-root': true, + // 'custom-property-pattern': string, + // 'declaration-bang-space-after': 'always'|'never', + // 'declaration-bang-space-before': 'always'|'never', + // 'declaration-block-no-duplicate-properties': true, + // 'declaration-block-no-shorthand-property-overrides': true, + // 'declaration-block-properties-order': 'alphabetical'|[], + // 'declaration-block-semicolon-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'declaration-block-semicolon-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'declaration-block-semicolon-space-after': 'always'|'never'|'always-single-line'|'never-single-line', + // 'declaration-block-semicolon-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + // 'declaration-block-single-line-max-declarations': int, + // 'declaration-block-trailing-semicolon': 'always'|'never', + // 'declaration-colon-newline-after': 'always'|'always-multi-line', + // 'declaration-colon-space-after': 'always'|'never'|'always-single-line', + // 'declaration-colon-space-before': 'always'|'never', + // 'declaration-no-important': true, + // 'font-family-name-quotes': 'single-where-required'|'single-where-recommended'|'single-unless-keyword'|'double-where-required'|'double-where-recommended'|'double-unless-keyword', + // 'font-weight-notation': 'numeric'|'named', + // 'function-blacklist': string|[], + // 'function-calc-no-unspaced-operator': true, + // 'function-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'function-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'function-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', + // 'function-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + // 'function-linear-gradient-no-nonstandard-direction': true, + // 'function-parentheses-newline-inside': 'always'|'always-multi-line'|'never-multi-line', + // 'function-parentheses-space-inside': 'always'|'never'|'always-single-line'|'never-single-line', + // 'function-url-quotes': 'single'|'double'|'none', + // 'function-whitelist': string|[], + // 'function-whitespace-after': 'always'|'never', + // 'indentation': int|'tab', + // 'max-empty-lines': int, + // 'max-line-length': int, + // 'max-nesting-depth': int, + // 'media-feature-colon-space-after': 'always'|'never', + // 'media-feature-colon-space-before': 'always'|'never', + // 'media-feature-name-no-vendor-prefix': true, + // 'media-feature-no-missing-punctuation': true, + // 'media-feature-range-operator-space-after': 'always'|'never', + // 'media-feature-range-operator-space-before': 'always'|'never', + // 'media-query-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'media-query-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'media-query-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', + // 'media-query-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + // 'media-query-parentheses-space-inside': 'always'|'never', + // 'no-browser-hacks': true, + // 'no-descending-specificity': true, + // 'no-duplicate-selectors': true, + // 'no-eol-whitespace': true, + // 'no-invalid-double-slash-comments': true, + // 'no-missing-eof-newline': true, + // 'no-unknown-animations': true, + // 'no-unsupported-browser-features': true, + // 'number-leading-zero': 'always'|'never', + // 'number-max-precision': int, + // 'number-no-trailing-zeros': true, + // 'number-zero-length-no-unit': true, + // 'property-blacklist': string|[], + // 'property-no-vendor-prefix': true, + // 'property-unit-blacklist': {}, + // 'property-unit-whitelist': {}, + // 'property-value-blacklist': {}, + // 'property-whitelist': string|[], + // 'root-no-standard-properties': true, + // 'rule-nested-empty-line-before': 'always'|'never', + // 'rule-non-nested-empty-line-before': 'always'|'never', + // 'selector-class-pattern': string, + // 'selector-combinator-space-after': 'always'|'never', + // 'selector-combinator-space-before': 'always'|'never', + // 'selector-id-pattern': string, + // 'selector-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'selector-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'selector-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', + // 'selector-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + // 'selector-max-specificity': string, + // 'selector-no-attribute': true, + // 'selector-no-combinator': true, + // 'selector-no-id': true, + // 'selector-no-type': true, + // 'selector-no-universal': true, + // 'selector-no-vendor-prefix': true, + // 'selector-pseudo-element-colon-notation': 'single'|'double', + // 'selector-root-no-composition': true, + // 'selector-type-case': 'lower'|'upper', + // 'string-no-newline': true, + // 'string-quotes': 'single'|'double', + // 'time-no-imperceptible': true, + // 'unit-blacklist': string|[], + // 'unit-whitelist': string|[], + // 'value-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', + // 'value-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', + // 'value-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', + // 'value-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + // 'value-no-vendor-prefix': true } }; \ No newline at end of file From 496466776d031d3501ed9c82af1f1cf012f2e929 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 22 Mar 2016 14:02:20 -0700 Subject: [PATCH 116/153] Interim commit, need to come back to this --- lib/css.js | 28 ++-- lib/engine_rules/css.js | 56 ++++---- lib/lint_css.js | 23 +-- lib/lint_css_rules/at_rule_empty_line.js | 175 +++++++++++++++++++++++ lib/lint_js.js | 5 +- lib/rule_utils.js | 7 + lib/stylelint_config.js | 147 ++++++++++--------- package.json | 1 + test/fixture/css/needless_unit.css | 34 +++++ test/fixture/css/trailing_comma.css | 5 + 10 files changed, 353 insertions(+), 128 deletions(-) create mode 100644 lib/lint_css_rules/at_rule_empty_line.js diff --git a/lib/css.js b/lib/css.js index ac5e31f..1584862 100644 --- a/lib/css.js +++ b/lib/css.js @@ -49,19 +49,27 @@ Formatter.CSS = Formatter.create( } ); - return this._lint(contents).then(function(results) { - instance._logLintResults(results.results); + return this._lint(contents).then( + function(results) { + instance._logLintResults(results.results); - return newContents; - }).catch( + return newContents; + } + ).catch( function(err) { - done(err, null); + instance.log( + 'N/A', + 'Could not parse the file because of ' + err, + 'stylelint-error', + { + column: 0, + ruleId: 'stylelint-error' + } + ); + + return newContents; } ); - - return contents; - - return ; }, formatPropertyItem: function(content) { @@ -170,7 +178,7 @@ Formatter.CSS = Formatter.create( results[0].warnings.forEach( function(item, index) { - item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); + // item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); if (lintLogFilter) { item = lintLogFilter(item); diff --git a/lib/engine_rules/css.js b/lib/engine_rules/css.js index d059a68..2fe6599 100644 --- a/lib/engine_rules/css.js +++ b/lib/engine_rules/css.js @@ -28,13 +28,14 @@ module.exports = { }, hexRedundant: { - message: function(result, rule, context) { - var match = this.hasHex(context.content); + // message: function(result, rule, context) { + // var match = this.hasHex(context.content); - var message = 'Hex code can be reduced to ' + rule._reduceHex(match) + ': {1}'; + // var message = 'Hex code can be reduced to ' + rule._reduceHex(match) + ': {1}'; - return this.message(message, result, rule, context); - }, + // return this.message(message, result, rule, context); + // }, + message: false, regex: /#([0-9A-Fa-f])\1([0-9A-Fa-f])\2([0-9A-Fa-f])\3/, replacer: function(result, rule, context) { var rawContent = context.rawContent; @@ -56,13 +57,15 @@ module.exports = { }, missingInteger: { - message: 'Missing integer: {1}', + // message: 'Missing integer: {1}', + message: false, regex: /([^0-9])(\.\d+)/g, replacer: '$10$2' }, missingListValuesSpace: { - message: 'Needs space between comma-separated values: {1}', + // message: 'Needs space between comma-separated values: {1}', + message: false, regex: /,(?=[^\s])/g, replacer: ', ', test: function(content, regex) { @@ -79,19 +82,20 @@ module.exports = { }, missingNewlines: { - message: function(result, rule, context) { - var message = 'There should be a newline between "{prevRule}" and "{rule}"'; - - message = this.message(message, result, rule, context); - - return sub( - message, - { - rule: context.nextItem.trim(), - prevRule: context.previousItem.trim() - } - ); - }, + // message: function(result, rule, context) { + // var message = 'There should be a newline between "{prevRule}" and "{rule}"'; + + // message = this.message(message, result, rule, context); + + // return sub( + // message, + // { + // rule: context.nextItem.trim(), + // prevRule: context.previousItem.trim() + // } + // ); + // }, + message: false, regex: /.*?(\}|\{)/, replacer: function(result, rule, context) { var rawContent = context.rawContent; @@ -134,12 +138,14 @@ module.exports = { }, missingSelectorSpace: { - message: 'Missing space between selector and bracket: {1}', + // message: 'Missing space between selector and bracket: {1}', + message: false, regex: /([^ ])\{\s*$/ }, missingInternalSelectorSpace: { - message: 'Missing space around combinator: {1}', + // message: 'Missing space around combinator: {1}', + message: false, regex: /(.)?([>~+])(.)?/g, replacer: function(result, rule, context) { var item = context.rawContent; @@ -187,13 +193,15 @@ module.exports = { }, needlessQuotes: { - message: 'Needless quotes: {1}', + // message: 'Needless quotes: {1}', + message: false, regex: /url\((["'])(.*?)\1\)/, replacer: 'url($2)' }, needlessUnit: { - message: 'Needless unit: {1}', + // message: 'Needless unit: {1}', + message: false, regex: /(#?)(\b0(?!s\b)[a-zA-Z]{1,}\b)/, replacer: '0', test: function(content, regex) { diff --git a/lib/lint_css.js b/lib/lint_css.js index dad6591..0747d83 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -4,19 +4,9 @@ var STYLELINT_CONFIG = require('./stylelint_config'); var glob = require('glob'); var path = require('path'); -var customRules = {}; +var ruleUtils = require('./rule_utils'); -var reactRules = require('eslint-plugin-react').rules; - -_.defaults(customRules, reactRules); - -var convertNameToRuleId = function(item) { - var baseName = path.basename(item, '.js'); - - return 'csf-' + baseName.replace(/_/g, '-'); -}; - -var runLinter = function(contents, file, customRules, config) { +var runLinter = function(contents, file, config) { if (_.isObject(config)) { config = _.merge({}, STYLELINT_CONFIG, config); } @@ -45,18 +35,15 @@ module.exports = function(contents, file, config) { globOptions ).forEach( function(item, index) { - var id = convertNameToRuleId(item); + var id = ruleUtils.getRuleId(item); - customRules[id] = require(item); + stylelint.rules[id] = require(item); } ); - // stylelint.linter.defineRules(customRules); - - return runLinter(contents, file, customRules, config); + return runLinter(contents, file, config); }; -module.exports.convertNameToRuleId = convertNameToRuleId; module.exports.stylelint = stylelint; module.exports.linter = stylelint.linter; module.exports.runLinter = runLinter; \ No newline at end of file diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js new file mode 100644 index 0000000..22a669d --- /dev/null +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -0,0 +1,175 @@ +var stylelint = require('stylelint'); +var sub = require('string-sub'); + +var REGEX_NEWLINE = require('../regex').NEWLINE; + +var ruleUtils = require('../rule_utils'); + +var slUtils = stylelint.utils; +/* istanbul ignore next */ +var jsonf = require('lodash').bindKeyRight( + JSON, + 'stringify', + function(key, value) { + if (key === 'start' || key === 'end') { + return value.line; + } + if (['parent', 'range'].indexOf(key) === -1) { + return value; + } + }, + 4 +); + +module.exports = function(expectation, options) { + var atRuleFn = stylelint.rules['at-rule-empty-line-before'](expectation, options); + + return function(root, result) { + var otherResults = atRuleFn(root, result); + var ruleName = ruleUtils.getRuleId(__filename); + + var messages = slUtils.ruleMessages( + ruleName, + { + expected: 'Expected a newline {0} at-rule', + rejected: 'Unexpected newline {0} at-rule' + } + ); + + var validOptions = slUtils.validateOptions( + result, + ruleName, + { + actual: expectation, + possible: ['always', 'never'] + }, + { + actual: options, + possible: { + except: ['first-nested'], + ignore: ['between-nested'] + }, + optional: true + } + ); + + if (!validOptions) { + return; + } + + // var get + + // console.log(result); + + root.walkAtRules( + function(node) { + if (node.first !== root.first) { + if (node.name === 'include') { + if (/*node.source.start.line === node.source.end.line && */node.prev()) { + // console.log(jsonf(node)); + } + + var prev = node.prev(); + var next = node.next(); + + if (prev && prev.type === 'decl' && node.source.start.line - prev.source.end.line === 1) { + // node.raws.before = '\n' + node.raws.before; + } + else if (!prev && node.raws.before.split(REGEX_NEWLINE).length > 1) { + + } + + if (next && next.type === 'decl' && next.source.start.line - node.source.end.line < 2) { + // next.raws.before = '\n' + next.raws.before; + } + else if (!next && node.raws.after.split(REGEX_NEWLINE).length > 1) { + + } + } + } + } + ); + + return otherResults; + }; +}; + +// exports.default = function (expectation, options) { +// return function (root, result) { +// var validOptions = (0, _utils.validateOptions)(result, ruleName, { +// actual: expectation, +// possible: ["always", "never"] +// }, { +// actual: options, +// possible: { +// except: ["blockless-group", "first-nested", "all-nested"], +// ignore: ["after-comment", "all-nested"] +// }, +// optional: true +// }); +// if (!validOptions) { +// return; +// } + +// root.walkAtRules(function (atRule) { + +// // Ignore the first node +// if (atRule === root.first) { +// return; +// } + +// var isNested = atRule.parent !== root; +// if ((0, _utils.optionsHaveIgnored)(options, "all-nested") && isNested) { +// return; +// } + +// // Optionally ignore the expectation if a comment precedes this node +// if ((0, _utils.optionsHaveIgnored)(options, "after-comment") && atRule.prev() && atRule.prev().type === "comment") { +// return; +// } + +// var before = atRule.raw("before"); +// var emptyLineBefore = before && (before.indexOf("\n\n") !== -1 || before.indexOf("\r\n\r\n") !== -1 || before.indexOf("\n\r\n") !== -1); + +// var expectEmptyLineBefore = expectation === "always" ? true : false; + +// var previousNode = atRule.prev(); + +// // Reverse the expectation if any exceptions apply +// if ((0, _utils.optionsHaveException)(options, "all-nested") && isNested || getsFirstNestedException() || getsBlocklessGroupException()) { +// expectEmptyLineBefore = !expectEmptyLineBefore; +// } + +// // Return if the exceptation is met +// if (expectEmptyLineBefore === emptyLineBefore) { +// return; +// } + +// var message = expectEmptyLineBefore ? messages.expected : messages.rejected; + +// (0, _utils.report)({ +// message: message, +// node: atRule, +// result: result, +// ruleName: ruleName +// }); + +// function getsBlocklessGroupException() { +// return (0, _utils.optionsHaveException)(options, "blockless-group") && previousNode && previousNode.type === "atrule" && !(0, _utils.cssStatementHasBlock)(previousNode) && !(0, _utils.cssStatementHasBlock)(atRule); +// } + +// function getsFirstNestedException() { +// return (0, _utils.optionsHaveException)(options, "first-nested") && isNested && atRule === atRule.parent.first; +// } +// }); +// }; +// }; + +// var _utils = require("../../utils"); + +// var ruleName = exports.ruleName = "at-rule-empty-line-before"; + +// var messages = exports.messages = (0, _utils.ruleMessages)(ruleName, { +// expected: "Expected empty line before at-rule", +// rejected: "Unexpected empty line before at-rule" +// }); \ No newline at end of file diff --git a/lib/lint_js.js b/lib/lint_js.js index 061744c..f0fe54b 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -5,6 +5,8 @@ var ESLINT_CONFIG = require('./config/eslint'); var glob = require('glob'); var path = require('path'); +var ruleUtils = require('./rule_utils'); + var customRules = {}; var reactRules = require('eslint-plugin-react').rules; @@ -139,7 +141,7 @@ module.exports = function(contents, file, context) { globOptions ).forEach( function(item, index) { - var id = convertNameToRuleId(item); + var id = ruleUtils.getRuleId(item); customRules[id] = require(item); } @@ -150,7 +152,6 @@ module.exports = function(contents, file, context) { return runLinter(contents, file, context); }; -module.exports.convertNameToRuleId = convertNameToRuleId; module.exports.eslint = eslint; module.exports.linter = eslint.linter; module.exports.runLinter = runLinter; \ No newline at end of file diff --git a/lib/rule_utils.js b/lib/rule_utils.js index 0a17545..9f2ce2a 100644 --- a/lib/rule_utils.js +++ b/lib/rule_utils.js @@ -1,4 +1,5 @@ var _ = require('lodash'); +var path = require('path'); var REGEX = require('./regex'); @@ -84,4 +85,10 @@ exports.naturalCompare = function(a, b, caseInsensitive) { } return result; +}; + +exports.getRuleId = function(filePath) { + var baseName = path.basename(filePath, '.js'); + + return 'csf-' + _.kebabCase(baseName); }; \ No newline at end of file diff --git a/lib/stylelint_config.js b/lib/stylelint_config.js index 16e77b1..c1ba219 100644 --- a/lib/stylelint_config.js +++ b/lib/stylelint_config.js @@ -9,103 +9,102 @@ module.exports = { }, 'rules': { - 'color-hex-case': 'upper', - 'color-hex-length': 'short', - // 'at-rule-empty-line-before': 'always'|'never', - // 'at-rule-no-vendor-prefix': true, - // 'block-closing-brace-newline-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', - // 'block-closing-brace-newline-before': 'always'|'always-multi-line'|'never-multi-line', - // 'block-closing-brace-space-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', - // 'block-closing-brace-space-before': 'always'|'never'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'csf-at-rule-empty-line': ['always', {except: ['first-nested']}], + 'at-rule-empty-line-before': ['always', {except: ['first-nested']}], + 'at-rule-no-vendor-prefix': true, + 'block-closing-brace-newline-after': 'always', + 'block-closing-brace-newline-before': 'always', + // 'block-closing-brace-space-after': 'never', + // 'block-closing-brace-space-before': 'never', // 'block-no-empty': true, - // 'block-no-single-line': true, - // 'block-opening-brace-newline-after': 'always'|'always-multi-line'|'never-multi-line', + 'block-no-single-line': true, + 'block-opening-brace-newline-after': 'always', // 'block-opening-brace-newline-before': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', - // 'block-opening-brace-space-after': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', - // 'block-opening-brace-space-before': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', - // 'color-hex-case': 'lower'|'upper', - // 'color-hex-length': 'short'|'long', - // 'color-named': 'always-where-possible'|'never', + // 'block-opening-brace-space-after': 'never', + 'block-opening-brace-space-before': 'always', + 'color-hex-case': 'upper', + 'color-hex-length': 'short', + 'color-named': 'never', // 'color-no-hex': true, - // 'color-no-invalid-hex': true, - // 'comment-empty-line-before': 'always'|'never', - // 'comment-whitespace-inside': 'always'|'never', + 'color-no-invalid-hex': true, + 'comment-empty-line-before': ['always', {except: ['first-nested']}], + 'comment-whitespace-inside': 'always', // 'custom-media-pattern': string, // 'custom-property-no-outside-root': true, // 'custom-property-pattern': string, - // 'declaration-bang-space-after': 'always'|'never', - // 'declaration-bang-space-before': 'always'|'never', - // 'declaration-block-no-duplicate-properties': true, - // 'declaration-block-no-shorthand-property-overrides': true, - // 'declaration-block-properties-order': 'alphabetical'|[], - // 'declaration-block-semicolon-newline-after': 'always'|'always-multi-line'|'never-multi-line', - // 'declaration-block-semicolon-newline-before': 'always'|'always-multi-line'|'never-multi-line', + 'declaration-bang-space-after': 'never', + 'declaration-bang-space-before': 'always', + 'declaration-block-no-duplicate-properties': true, + 'declaration-block-no-shorthand-property-overrides': true, + 'declaration-block-properties-order': 'alphabetical', + 'declaration-block-semicolon-newline-after': 'always', + 'declaration-block-semicolon-newline-before': 'never', // 'declaration-block-semicolon-space-after': 'always'|'never'|'always-single-line'|'never-single-line', - // 'declaration-block-semicolon-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + 'declaration-block-semicolon-space-before': 'never', // 'declaration-block-single-line-max-declarations': int, - // 'declaration-block-trailing-semicolon': 'always'|'never', + 'declaration-block-trailing-semicolon': 'always', // 'declaration-colon-newline-after': 'always'|'always-multi-line', - // 'declaration-colon-space-after': 'always'|'never'|'always-single-line', - // 'declaration-colon-space-before': 'always'|'never', + 'declaration-colon-space-after': 'always', + 'declaration-colon-space-before': 'never', // 'declaration-no-important': true, - // 'font-family-name-quotes': 'single-where-required'|'single-where-recommended'|'single-unless-keyword'|'double-where-required'|'double-where-recommended'|'double-unless-keyword', - // 'font-weight-notation': 'numeric'|'named', - // 'function-blacklist': string|[], - // 'function-calc-no-unspaced-operator': true, - // 'function-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', - // 'function-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', - // 'function-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', - // 'function-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + 'font-family-name-quotes': 'single-where-recommended', + 'font-weight-notation': 'named-where-possible', + // 'function-blacklist': 'rgba', + 'function-calc-no-unspaced-operator': true, + 'function-comma-newline-after': 'never', + 'function-comma-newline-before': 'never', + 'function-comma-space-after': 'always', + 'function-comma-space-before': 'never', // 'function-linear-gradient-no-nonstandard-direction': true, // 'function-parentheses-newline-inside': 'always'|'always-multi-line'|'never-multi-line', - // 'function-parentheses-space-inside': 'always'|'never'|'always-single-line'|'never-single-line', - // 'function-url-quotes': 'single'|'double'|'none', + 'function-parentheses-space-inside': 'never', + 'function-url-quotes': 'none', // 'function-whitelist': string|[], - // 'function-whitespace-after': 'always'|'never', - // 'indentation': int|'tab', - // 'max-empty-lines': int, + 'function-whitespace-after': 'always', + 'indentation': 'tab', + 'max-empty-lines': 1, // 'max-line-length': int, // 'max-nesting-depth': int, - // 'media-feature-colon-space-after': 'always'|'never', - // 'media-feature-colon-space-before': 'always'|'never', + 'media-feature-colon-space-after': 'always', + 'media-feature-colon-space-before': 'never', // 'media-feature-name-no-vendor-prefix': true, - // 'media-feature-no-missing-punctuation': true, - // 'media-feature-range-operator-space-after': 'always'|'never', - // 'media-feature-range-operator-space-before': 'always'|'never', + 'media-feature-no-missing-punctuation': true, + 'media-feature-range-operator-space-after': 'always', + 'media-feature-range-operator-space-before': 'always', // 'media-query-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', // 'media-query-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', // 'media-query-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', // 'media-query-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', - // 'media-query-parentheses-space-inside': 'always'|'never', + 'media-query-parentheses-space-inside': 'never', // 'no-browser-hacks': true, - // 'no-descending-specificity': true, - // 'no-duplicate-selectors': true, - // 'no-eol-whitespace': true, + // 'no-descending-specificity': true, // Maybe + 'no-duplicate-selectors': true, // Maybe + 'no-eol-whitespace': true, // 'no-invalid-double-slash-comments': true, // 'no-missing-eof-newline': true, // 'no-unknown-animations': true, // 'no-unsupported-browser-features': true, - // 'number-leading-zero': 'always'|'never', - // 'number-max-precision': int, - // 'number-no-trailing-zeros': true, - // 'number-zero-length-no-unit': true, + 'number-leading-zero': 'always', + 'number-max-precision': 3, + 'number-no-trailing-zeros': true, + 'number-zero-length-no-unit': true, // 'property-blacklist': string|[], - // 'property-no-vendor-prefix': true, + 'property-no-vendor-prefix': true, // 'property-unit-blacklist': {}, // 'property-unit-whitelist': {}, // 'property-value-blacklist': {}, // 'property-whitelist': string|[], // 'root-no-standard-properties': true, - // 'rule-nested-empty-line-before': 'always'|'never', - // 'rule-non-nested-empty-line-before': 'always'|'never', - // 'selector-class-pattern': string, - // 'selector-combinator-space-after': 'always'|'never', - // 'selector-combinator-space-before': 'always'|'never', + 'rule-nested-empty-line-before': ['always', {except: ['first-nested']}], + 'rule-non-nested-empty-line-before': 'always', + 'selector-class-pattern': '^[a-z0-9]+(-[a-z0-9]+)*$', // Maybe + 'selector-combinator-space-after': 'always', + 'selector-combinator-space-before': 'always', // 'selector-id-pattern': string, - // 'selector-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', - // 'selector-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', - // 'selector-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', - // 'selector-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + 'selector-list-comma-newline-after': 'always-multi-line', // Maybe + 'selector-list-comma-newline-before': 'never-multi-line', + 'selector-list-comma-space-after': 'always-single-line', + 'selector-list-comma-space-before': 'never', // 'selector-max-specificity': string, // 'selector-no-attribute': true, // 'selector-no-combinator': true, @@ -113,18 +112,18 @@ module.exports = { // 'selector-no-type': true, // 'selector-no-universal': true, // 'selector-no-vendor-prefix': true, - // 'selector-pseudo-element-colon-notation': 'single'|'double', + 'selector-pseudo-element-colon-notation': 'single', // 'selector-root-no-composition': true, - // 'selector-type-case': 'lower'|'upper', - // 'string-no-newline': true, - // 'string-quotes': 'single'|'double', - // 'time-no-imperceptible': true, + 'selector-type-case': 'lower', + 'string-no-newline': true, + 'string-quotes': 'single', + 'time-no-imperceptible': true, // 'unit-blacklist': string|[], // 'unit-whitelist': string|[], - // 'value-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', - // 'value-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', - // 'value-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', - // 'value-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', + 'value-list-comma-newline-after': 'always-multi-line', + 'value-list-comma-newline-before': 'never-multi-line', + 'value-list-comma-space-after': 'always-single-line', + 'value-list-comma-space-before': 'never', // 'value-no-vendor-prefix': true } }; \ No newline at end of file diff --git a/package.json b/package.json index cf9def6..efd1188 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", + "stylelint": "^5.1.0", "update-notifier": "^2.1.0" }, "devDependencies": { diff --git a/test/fixture/css/needless_unit.css b/test/fixture/css/needless_unit.css index 1ac4ccb..0493c41 100644 --- a/test/fixture/css/needless_unit.css +++ b/test/fixture/css/needless_unit.css @@ -1,5 +1,39 @@ +@charset "UTF-8"; + .needless-unit { padding: 0px; + padding: 0; + @include test; + +} + +.needless-unit-2 { + @include foo(1, 3); + content: ''; + @include foo(1, 3); + @include test(2, 3); + @include ml(3, 3) { + content: ''; + }; + @include xs { + content: ''; + }; + + @media print { + .foo { + border: 1px solid black; + } + } + + @keyframes foo { + 0% { + border: 1px solid red; + } + to { + border: 1px solid green; + } + } + padding: 0; } \ No newline at end of file diff --git a/test/fixture/css/trailing_comma.css b/test/fixture/css/trailing_comma.css index 8efb674..033937d 100644 --- a/test/fixture/css/trailing_comma.css +++ b/test/fixture/css/trailing_comma.css @@ -1,3 +1,8 @@ +.trailing-comma5 { + padding: 1px; + color: #FFF; +} + .trailing-comma1, { color: #FFF; } From cebee3b7a0ca57f9c59f0dd5187b8b1c7db473e6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 23 Mar 2016 07:55:58 -0700 Subject: [PATCH 117/153] When a file is skipped (due to not matching, or being explicitly ignored), it will use the super's format method, which will not return a promise. --- lib/cli.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cli.js b/lib/cli.js index c4d5f2c..096230b 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -5,6 +5,7 @@ var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var util = require('util'); +var Promise = require('bluebird'); var _ = require('lodash'); From 0de89633766238cb2c43a6b1347314bd4e03a04b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 23 Mar 2016 08:28:05 -0700 Subject: [PATCH 118/153] Commenting out a few rules until I have it sorted which we should standardize on --- lib/stylelint_config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/stylelint_config.js b/lib/stylelint_config.js index c1ba219..be2dba0 100644 --- a/lib/stylelint_config.js +++ b/lib/stylelint_config.js @@ -9,8 +9,8 @@ module.exports = { }, 'rules': { - // 'csf-at-rule-empty-line': ['always', {except: ['first-nested']}], - 'at-rule-empty-line-before': ['always', {except: ['first-nested']}], + 'csf-at-rule-empty-line': ['always', {except: ['first-nested']}], + // 'at-rule-empty-line-before': ['always', {except: ['first-nested']}], 'at-rule-no-vendor-prefix': true, 'block-closing-brace-newline-after': 'always', 'block-closing-brace-newline-before': 'always', @@ -78,7 +78,7 @@ module.exports = { 'media-query-parentheses-space-inside': 'never', // 'no-browser-hacks': true, // 'no-descending-specificity': true, // Maybe - 'no-duplicate-selectors': true, // Maybe + // 'no-duplicate-selectors': true, // Maybe 'no-eol-whitespace': true, // 'no-invalid-double-slash-comments': true, // 'no-missing-eof-newline': true, @@ -116,7 +116,7 @@ module.exports = { // 'selector-root-no-composition': true, 'selector-type-case': 'lower', 'string-no-newline': true, - 'string-quotes': 'single', + // 'string-quotes': 'single', 'time-no-imperceptible': true, // 'unit-blacklist': string|[], // 'unit-whitelist': string|[], From 1f9525a4d7987cbbade66b5ebd5ab810a6a5082b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 23 Mar 2016 08:29:26 -0700 Subject: [PATCH 119/153] Making this rule invoke the default at-rule-empty-line-before, but removing messages that point to @includes and @imports --- lib/lint_css_rules/at_rule_empty_line.js | 42 +++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 22a669d..8bf2a00 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var stylelint = require('stylelint'); var sub = require('string-sub'); @@ -7,7 +8,7 @@ var ruleUtils = require('../rule_utils'); var slUtils = stylelint.utils; /* istanbul ignore next */ -var jsonf = require('lodash').bindKeyRight( +var jsonf = _.bindKeyRight( JSON, 'stringify', function(key, value) { @@ -57,14 +58,20 @@ module.exports = function(expectation, options) { return; } + var isSingleLineRule = function(node) { + return node.source.start.line === node.source.end.line; + }; + // var get // console.log(result); + var validLines = []; + root.walkAtRules( function(node) { if (node.first !== root.first) { - if (node.name === 'include') { + if (node.name === 'include' || node.name === 'import') { if (/*node.source.start.line === node.source.end.line && */node.prev()) { // console.log(jsonf(node)); } @@ -72,24 +79,37 @@ module.exports = function(expectation, options) { var prev = node.prev(); var next = node.next(); - if (prev && prev.type === 'decl' && node.source.start.line - prev.source.end.line === 1) { - // node.raws.before = '\n' + node.raws.before; - } - else if (!prev && node.raws.before.split(REGEX_NEWLINE).length > 1) { + // if (prev && prev.type === 'decl' && node.source.start.line - prev.source.end.line === 1) { + // // node.raws.before = '\n' + node.raws.before; + // } + // else if (!prev && node.raws.before.split(REGEX_NEWLINE).length > 1) { - } + // } - if (next && next.type === 'decl' && next.source.start.line - node.source.end.line < 2) { - // next.raws.before = '\n' + next.raws.before; + if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && node.source.start.line - prev.source.end.line === 1) { + validLines.push(node.source.start.line); } - else if (!next && node.raws.after.split(REGEX_NEWLINE).length > 1) { - } + // if (next && next.type === 'decl' && next.source.start.line - node.source.end.line < 2) { + // // next.raws.before = '\n' + next.raws.before; + // } + // else if (!next && node.raws.after.split(REGEX_NEWLINE).length > 1) { + + // } } } } ); + result.messages = _.reject( + result.messages, + function(item, index) { + return item.rule === 'at-rule-empty-line-before' && _.includes(validLines, item.line); + } + ); + + // console.log(foo); + return otherResults; }; }; From 7da8d9d373c62e5a67985a2302e64e9b06dbb0f4 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 23 Mar 2016 14:50:34 -0700 Subject: [PATCH 120/153] More rule handling --- lib/lint_css_rules/at_rule_empty_line.js | 30 ++++-------------------- test/fixture/css/needless_unit.css | 2 +- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 8bf2a00..3bb445d 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -58,44 +58,26 @@ module.exports = function(expectation, options) { return; } + var getLineDistance = function(left, right) { + return right.source.start.line - left.source.end.line; + }; + var isSingleLineRule = function(node) { return node.source.start.line === node.source.end.line; }; - // var get - - // console.log(result); - var validLines = []; root.walkAtRules( function(node) { if (node.first !== root.first) { if (node.name === 'include' || node.name === 'import') { - if (/*node.source.start.line === node.source.end.line && */node.prev()) { - // console.log(jsonf(node)); - } - var prev = node.prev(); var next = node.next(); - // if (prev && prev.type === 'decl' && node.source.start.line - prev.source.end.line === 1) { - // // node.raws.before = '\n' + node.raws.before; - // } - // else if (!prev && node.raws.before.split(REGEX_NEWLINE).length > 1) { - - // } - - if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && node.source.start.line - prev.source.end.line === 1) { + if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && getLineDistance(prev, node) === 1) { validLines.push(node.source.start.line); } - - // if (next && next.type === 'decl' && next.source.start.line - node.source.end.line < 2) { - // // next.raws.before = '\n' + next.raws.before; - // } - // else if (!next && node.raws.after.split(REGEX_NEWLINE).length > 1) { - - // } } } } @@ -108,8 +90,6 @@ module.exports = function(expectation, options) { } ); - // console.log(foo); - return otherResults; }; }; diff --git a/test/fixture/css/needless_unit.css b/test/fixture/css/needless_unit.css index 0493c41..2d6b292 100644 --- a/test/fixture/css/needless_unit.css +++ b/test/fixture/css/needless_unit.css @@ -10,9 +10,9 @@ .needless-unit-2 { @include foo(1, 3); - content: ''; @include foo(1, 3); @include test(2, 3); + @include ml(3, 3) { content: ''; }; From ae47f68602a187b9223c4ba399c69dcc574f208f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 5 Apr 2016 14:34:49 -0700 Subject: [PATCH 121/153] Moving the stylelint config file to config/ --- lib/{stylelint_config.js => config/stylelint.js} | 0 lib/lint_css.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/{stylelint_config.js => config/stylelint.js} (100%) diff --git a/lib/stylelint_config.js b/lib/config/stylelint.js similarity index 100% rename from lib/stylelint_config.js rename to lib/config/stylelint.js diff --git a/lib/lint_css.js b/lib/lint_css.js index 0747d83..1c2a725 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -1,6 +1,6 @@ var _ = require('lodash'); var stylelint = require('stylelint'); -var STYLELINT_CONFIG = require('./stylelint_config'); +var STYLELINT_CONFIG = require('./config/stylelint'); var glob = require('glob'); var path = require('path'); From cbf6e8b22af050f2d1328fc4e1ab1d3096852a4f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 5 Apr 2016 14:35:01 -0700 Subject: [PATCH 122/153] Temporarily updating tests --- test/css.js | 24 ++++++++++++------------ test/engine_rules/css.js | 18 +++++++++--------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/css.js b/test/css.js index f4f0dca..e40b6aa 100644 --- a/test/css.js +++ b/test/css.js @@ -37,18 +37,18 @@ describe( ); }; - // it( - // 'should detect lower case hex codes', - // function() { - // return testFile(getFilePath('hex_lower_case.css')).spread( - // function(errors) { - // assert.equal(errors.length, 1); - - // assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); - // } - // ); - // } - // ); + it( + 'should detect lower case hex codes', + function() { + return testFile(getFilePath('hex_lower_case.css')).spread( + function(errors) { + assert.equal(errors.length, 1); + + assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); + } + ); + } + ); it( 'should detect redundant hex codes', diff --git a/test/engine_rules/css.js b/test/engine_rules/css.js index f541ee5..9e93084 100644 --- a/test/engine_rules/css.js +++ b/test/engine_rules/css.js @@ -55,7 +55,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -77,7 +77,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -99,7 +99,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -146,7 +146,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -174,7 +174,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -218,7 +218,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -253,7 +253,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -297,7 +297,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -319,7 +319,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); + // assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); From 438588554445a015fce9d6e2362d5661d41e005f Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 5 Apr 2016 15:00:59 -0700 Subject: [PATCH 123/153] Expand selector rule definition --- lib/config/stylelint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index be2dba0..9489594 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -97,7 +97,7 @@ module.exports = { // 'root-no-standard-properties': true, 'rule-nested-empty-line-before': ['always', {except: ['first-nested']}], 'rule-non-nested-empty-line-before': 'always', - 'selector-class-pattern': '^[a-z0-9]+(-[a-z0-9]+)*$', // Maybe + 'selector-class-pattern': [/(#\{\$.*?\}|[a-z0-9]+)(-#\{\$.*?\}|-[a-z0-9]+)*$/, {resolveNestedSelectors: true}], // Maybe 'selector-combinator-space-after': 'always', 'selector-combinator-space-before': 'always', // 'selector-id-pattern': string, From f93fb466b5267a3a1933df8e58aaf98abdc76c83 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Wed, 13 Apr 2016 14:27:58 -0700 Subject: [PATCH 124/153] Remove unused variable --- lib/lint_css.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/lint_css.js b/lib/lint_css.js index 1c2a725..200e8d7 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -2,7 +2,6 @@ var _ = require('lodash'); var stylelint = require('stylelint'); var STYLELINT_CONFIG = require('./config/stylelint'); var glob = require('glob'); -var path = require('path'); var ruleUtils = require('./rule_utils'); From 348977e8b92c9ca9a248f51344da5e4ab70cf577 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 18 Apr 2016 11:20:49 -0700 Subject: [PATCH 125/153] Use the callback form as it displays better in the CLI --- test/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli.js b/test/cli.js index a181f8d..dd502ce 100644 --- a/test/cli.js +++ b/test/cli.js @@ -212,7 +212,7 @@ describe( function() { assert.isTrue(checkMeta.called, 'metaChecker.check should have been called, it was instead called ' + checkMeta.callCount + ' times'); } - ) + ); } ); From 2f670b5dd174eeab1e994b58828b449a48af39f0 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Mon, 18 Apr 2016 11:21:17 -0700 Subject: [PATCH 126/153] Allow formatters to return any content type to the CLI, and resolve it at the CLI level --- lib/html.js | 3 +-- lib/js.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/html.js b/lib/html.js index 1768989..22ad0f5 100644 --- a/lib/html.js +++ b/lib/html.js @@ -1,5 +1,4 @@ var _ = require('lodash'); -var Promise = require('bluebird'); var base = require('./base'); @@ -175,7 +174,7 @@ Formatter.HTML = Formatter.create( } ); - return Promise.resolve(newContents); + return newContents; }, formatCSS: function(styleBlocks) { diff --git a/lib/js.js b/lib/js.js index c40a80b..18a7606 100644 --- a/lib/js.js +++ b/lib/js.js @@ -1,5 +1,4 @@ var _ = require('lodash'); -var Promise = require('bluebird'); var base = require('./base'); var re = require('./re'); @@ -99,7 +98,7 @@ Formatter.JS = Formatter.create( } ); - return Promise.resolve(newContents); + return newContents; }, _hasSheBang: function(contents) { From 195ff81cd440d2470e613a7d645b1da49054e488 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 26 Apr 2016 14:54:04 -0700 Subject: [PATCH 127/153] Updating test since stylelint tries to find stylelintignore --- lib/cli.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/cli.js b/lib/cli.js index 096230b..c4d5f2c 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -5,7 +5,6 @@ var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var util = require('util'); -var Promise = require('bluebird'); var _ = require('lodash'); From 249d4e65b73e3ca9c9e57172cf996db696b0a890 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 26 May 2016 09:15:42 -0700 Subject: [PATCH 128/153] Rebase accidentally left this in --- lib/lint_js.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/lint_js.js b/lib/lint_js.js index f0fe54b..dbe9ce0 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -13,12 +13,6 @@ var reactRules = require('eslint-plugin-react').rules; _.defaults(customRules, reactRules); -var convertNameToRuleId = function(item) { - var baseName = path.basename(item, '.js'); - - return 'csf-' + baseName.replace(/_/g, '-'); -}; - var loadPlugin = function(pluginName, configPath) { var rules; From 5c8b78d0cd6eff5ade0051a960b1c08679be7c67 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 26 May 2016 09:16:40 -0700 Subject: [PATCH 129/153] Use the same custom config logic for CSS files as we do for JS --- lib/css.js | 9 +- lib/lint_css.js | 27 +++-- test/css.js | 130 ++++++++++++++++++++++++ test/fixture/css/at_rule_empty_line.css | 5 + test/js.js | 4 +- 5 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 test/fixture/css/at_rule_empty_line.css diff --git a/lib/css.js b/lib/css.js index 1584862..63077bb 100644 --- a/lib/css.js +++ b/lib/css.js @@ -37,7 +37,7 @@ Formatter.CSS = Formatter.create( return content; }, - format: function(contents) { + format: function(contents, lint) { var instance = this; var logger = this.log.bind(this); @@ -49,7 +49,12 @@ Formatter.CSS = Formatter.create( } ); - return this._lint(contents).then( + var context = { + file: this.file, + lintConfig: this.flags.lint !== false && lint + }; + + return this._lint(contents, context).then( function(results) { instance._logLintResults(results.results); diff --git a/lib/lint_css.js b/lib/lint_css.js index 200e8d7..f53dc69 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -5,14 +5,23 @@ var glob = require('glob'); var ruleUtils = require('./rule_utils'); -var runLinter = function(contents, file, config) { +var customRules = {}; + +var runLinter = function(contents, file, context) { + var customRules = context.customRules || {}; + + _.merge(stylelint.rules, customRules); + + var config = context.lintConfig; + + var configs = [{}, STYLELINT_CONFIG]; + if (_.isObject(config)) { - config = _.merge({}, STYLELINT_CONFIG, config); - } - else { - config = STYLELINT_CONFIG; + configs.push(config); } + config = _.merge.apply(_, configs); + return stylelint.lint( { code: contents, @@ -28,7 +37,9 @@ var globOptions = { cwd: __dirname }; -module.exports = function(contents, file, config) { +module.exports = function(contents, file, context) { + context.customRules = customRules; + glob.sync( './lint_css_rules/*.js', globOptions @@ -36,11 +47,11 @@ module.exports = function(contents, file, config) { function(item, index) { var id = ruleUtils.getRuleId(item); - stylelint.rules[id] = require(item); + customRules[id] = require(item); } ); - return runLinter(contents, file, config); + return runLinter(contents, file, context); }; module.exports.stylelint = stylelint; diff --git a/test/css.js b/test/css.js index e40b6aa..e896c9d 100644 --- a/test/css.js +++ b/test/css.js @@ -2,6 +2,9 @@ var _ = require('lodash'); var chai = require('chai'); var fs = require('fs'); var path = require('path'); +var sinon = require('sinon'); + +var Promise = require('bluebird'); var Promise = require('bluebird'); @@ -256,4 +259,131 @@ describe( } ); } +); + +describe( + 'Formatter.CSS Lint', + function() { + 'use strict'; + + var sandbox; + + beforeEach( + function() { + sandbox = sinon.sandbox.create(); + } + ); + + afterEach( + function() { + sandbox.restore(); + } + ); + + var lintConfig = require('../lib/config/stylelint'); + + var testFilePath = path.join(__dirname, 'fixture', 'css', 'at_rule_empty_line.css'); + + var cssLogger = new Logger.constructor(); + var cssFormatter = new Formatter.CSS(testFilePath, cssLogger); + var source = fs.readFileSync(testFilePath, 'utf-8'); + + var lint = require('../lib/lint_css'); + + it( + 'should find at least one lint error', + function(done) { + var response = cssFormatter.format(source, true); + + Promise.resolve(response).then( + function(results) { + var cssErrors = cssLogger.getErrors(testFilePath); + + var foundLintErrors = _.reduce( + cssErrors, + function(res, item, index) { + if (item.type) { + res[item.type] = true; + } + + return res; + }, + {} + ); + + var hasLintError = _.some( + lintConfig.rules, + function(item, index) { + var val = _.isArray(item) ? item[0] : item; + + return val !== false && foundLintErrors[index]; + } + ); + + assert.isTrue(hasLintError); + } + ).done(done); + } + ); + + it( + 'should use default configuration properties', + function() { + var stylelint = lint.stylelint; + + var cssLint = function(contents, config, file) { + return Promise.resolve( + { + line: 1, + message: '', + column: 0, + ruleId: '' + } + ); + }; + + sandbox.stub(stylelint, 'lint', cssLint); + + lint.runLinter(source, testFilePath, {}); + + var args = stylelint.lint.args[0]; + + assert.equal(args[0].config.rules['at-rule-no-vendor-prefix'], true); + } + ); + + it( + 'should merge configuration properties', + function() { + + var stylelint = lint.stylelint; + + var cssLint = function(contents, config, file) { + return Promise.resolve( + { + line: 1, + message: '', + column: 0, + ruleId: '' + } + ); + }; + + sandbox.stub(stylelint, 'lint', cssLint); + + cssFormatter.format( + source, + { + rules: { + 'at-rule-no-vendor-prefix': false + } + } + ); + + var args = stylelint.lint.args[0]; + + assert.equal(args[0].config.rules['at-rule-no-vendor-prefix'], false); + } + ); + } ); \ No newline at end of file diff --git a/test/fixture/css/at_rule_empty_line.css b/test/fixture/css/at_rule_empty_line.css new file mode 100644 index 0000000..48060b3 --- /dev/null +++ b/test/fixture/css/at_rule_empty_line.css @@ -0,0 +1,5 @@ +.at-rules { + background: red; + @include fakemixin(); + color: white; +} \ No newline at end of file diff --git a/test/js.js b/test/js.js index a985852..fc4f67a 100644 --- a/test/js.js +++ b/test/js.js @@ -257,7 +257,7 @@ describe( } ); - var esLintConfig = require('../lib/config/eslint'); + var lintConfig = require('../lib/config/eslint'); var testFilePath = path.join(__dirname, 'fixture', 'test.js'); @@ -287,7 +287,7 @@ describe( ); var hasLintError = _.some( - esLintConfig.rules, + lintConfig.rules, function(item, index) { var val = _.isArray(item) ? item[0] : item; From 2e66db089fe741b95ccb698cbffb65aa09aa0532 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 31 May 2016 12:38:45 -0700 Subject: [PATCH 130/153] Updating deps and adding more tests --- lib/config/stylelint.js | 2 +- lib/lint_css_rules/at_rule_empty_line.js | 5 ++- package.json | 2 +- test/css.js | 24 +++++++++++++ test/lint_css_rules/at_rule_empty_line.js | 31 ++++++++++++++++ test/stylelint_rule_tester.js | 44 +++++++++++++++++++++++ 6 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 test/lint_css_rules/at_rule_empty_line.js create mode 100644 test/stylelint_rule_tester.js diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index 9489594..a1d9a6c 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -120,7 +120,7 @@ module.exports = { 'time-no-imperceptible': true, // 'unit-blacklist': string|[], // 'unit-whitelist': string|[], - 'value-list-comma-newline-after': 'always-multi-line', + 'value-list-comma-newline-after': false, 'value-list-comma-newline-before': 'never-multi-line', 'value-list-comma-space-after': 'always-single-line', 'value-list-comma-space-before': 'never', diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 3bb445d..98a20e8 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -6,6 +6,8 @@ var REGEX_NEWLINE = require('../regex').NEWLINE; var ruleUtils = require('../rule_utils'); +var ruleName = ruleUtils.getRuleId(__filename); + var slUtils = stylelint.utils; /* istanbul ignore next */ var jsonf = _.bindKeyRight( @@ -27,7 +29,6 @@ module.exports = function(expectation, options) { return function(root, result) { var otherResults = atRuleFn(root, result); - var ruleName = ruleUtils.getRuleId(__filename); var messages = slUtils.ruleMessages( ruleName, @@ -94,6 +95,8 @@ module.exports = function(expectation, options) { }; }; +module.exports.ruleName = ruleName; + // exports.default = function (expectation, options) { // return function (root, result) { // var validOptions = (0, _utils.validateOptions)(result, ruleName, { diff --git a/package.json b/package.json index efd1188..c0bc570 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "stylelint": "^5.1.0", + "stylelint": "^6.5.1", "update-notifier": "^2.1.0" }, "devDependencies": { diff --git a/test/css.js b/test/css.js index e896c9d..06ce2f0 100644 --- a/test/css.js +++ b/test/css.js @@ -221,6 +221,30 @@ describe( ); } ); + + it( + 'should use a custom lint log filter', + function(done) { + var testFilePath = path.join(__dirname, 'fixture', 'css', 'at_rule_empty_line.css'); + + var source = fs.readFileSync(testFilePath, 'utf-8'); + + var cssLoggerFilter = new Logger.constructor(); + var cssFormatterFilter = new Formatter.CSS(testFilePath, cssLoggerFilter); + + var lintLogFilter = sinon.stub().returnsArg(0); + + cssFormatterFilter.lintLogFilter = lintLogFilter; + + var result = cssFormatterFilter.format(source); + + Promise.resolve(result).then( + function(result) { + assert.isTrue(lintLogFilter.called); + } + ).done(done); + } + ); } ); diff --git a/test/lint_css_rules/at_rule_empty_line.js b/test/lint_css_rules/at_rule_empty_line.js new file mode 100644 index 0000000..5c41dcd --- /dev/null +++ b/test/lint_css_rules/at_rule_empty_line.js @@ -0,0 +1,31 @@ +var path = require('path'); +var ruleUtils = require('../../lib/rule_utils'); +var testRule = require('../stylelint_rule_tester'); + +var stylelint = testRule.stylelint; + +var rule = require('../../lib/lint_css_rules/' + path.basename(__filename)); +var sub = require('string-sub'); + +var stylelintRule = require('stylelint/dist/rules/at-rule-empty-line-before'); + +testRule( + rule, + { + ruleName: rule.ruleName, + config: ['always', {except: ['first-nested']}], + accept: [ + { + code: 'a {\n @include foo;\n color: pink;\n}', + description: 'always at rule empty line no first-nested' + } + ], + reject: [ + { + code: 'a {\n color: blue;\n @include foo;\n}', + message: stylelintRule.messages.expected + } + ], + syntax: 'scss', + } +); \ No newline at end of file diff --git a/test/stylelint_rule_tester.js b/test/stylelint_rule_tester.js new file mode 100644 index 0000000..0413d97 --- /dev/null +++ b/test/stylelint_rule_tester.js @@ -0,0 +1,44 @@ +var stylelint = require('stylelint'); +var chai = require('chai'); + +chai.use(require('chai-string')); + +var assert = chai.assert; +var sinon = require('sinon'); +function assertEquality(processCss, context) { + const describeFn = (context.only) ? describe.only : describe; + + sinon.spy(it); + + describeFn( + context.caseDescription, + function() { + it( + context.completeAssertionDescription, + function(done) { + processCss.then( + function(comparisons) { + comparisons.forEach( + function(item, index) { + var actual = item.actual; + var expected = item.expected; + var description = item.description; + + assert.equal(actual, expected, description); + } + ); + + done(); + } + ).catch(done) + } + ); + + console.log(it.called); + } + ); +} + +module.exports = stylelint.createRuleTester(assertEquality); + +module.exports.stylelint = stylelint; \ No newline at end of file From 0dd7e425f0b62401b7add6fa5c30eb47ea7e762d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 Aug 2016 06:13:47 -0700 Subject: [PATCH 131/153] Updating stylelint --- lib/config/stylelint.js | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index a1d9a6c..b07b7e8 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -75,7 +75,7 @@ module.exports = { // 'media-query-list-comma-newline-before': 'always'|'always-multi-line'|'never-multi-line', // 'media-query-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', // 'media-query-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', - 'media-query-parentheses-space-inside': 'never', + 'media-feature-parentheses-space-inside': 'never', // 'no-browser-hacks': true, // 'no-descending-specificity': true, // Maybe // 'no-duplicate-selectors': true, // Maybe @@ -87,7 +87,7 @@ module.exports = { 'number-leading-zero': 'always', 'number-max-precision': 3, 'number-no-trailing-zeros': true, - 'number-zero-length-no-unit': true, + 'length-zero-no-unit': true, // 'property-blacklist': string|[], 'property-no-vendor-prefix': true, // 'property-unit-blacklist': {}, diff --git a/package.json b/package.json index c0bc570..3ccd778 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "stylelint": "^6.5.1", + "stylelint": "^7.0.3", "update-notifier": "^2.1.0" }, "devDependencies": { @@ -68,4 +68,4 @@ "sinon": "^2.2.0", "xsd-schema-validator": "^0.5.0" } -} \ No newline at end of file +} From e371fad569b4bd39d992d4a91adffbf3f5a44a5a Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 30 Aug 2016 12:27:16 -0700 Subject: [PATCH 132/153] Respect css config for linting --- lib/css.js | 16 +++++++++++++--- lib/html.js | 7 ++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/css.js b/lib/css.js index 63077bb..ef0072f 100644 --- a/lib/css.js +++ b/lib/css.js @@ -164,10 +164,20 @@ Formatter.CSS = Formatter.create( return context; }, - _lint: function(contents, lint) { - var linter = require('./lint_css'); + _lint: function(contents, context) { + var lint = context.lintConfig; - var results = linter(contents, this.file, lint); + var results = ''; + + if (lint !== false) { + var linter = require('./lint_css'); + + lint = _.isObjectLike(lint) ? lint : {}; + + context.lintConfig = _.merge(lint, this.config('css.lint')); + + results = linter(contents, this.file, context); + } return results; }, diff --git a/lib/html.js b/lib/html.js index 22ad0f5..b3bbc4e 100644 --- a/lib/html.js +++ b/lib/html.js @@ -180,11 +180,16 @@ Formatter.HTML = Formatter.create( formatCSS: function(styleBlocks) { var cssFormatter = new Formatter.CSS(this.file, this.logger, this.flags, this._config); + cssFormatter._config = this._config; cssFormatter._abspath = this._abspath; + var lintConfig = require('./config/stylelint'); + + var lint = _.merge({}, lintConfig, this.config('css.lint'), this.config('html.lint.css')); + return styleBlocks.map( function(item, index) { - return cssFormatter.format(item.contents); + return cssFormatter.format(item.contents, lint); } ); }, From dcf84a6ddb80b21208563abb5a40744b8b13c9ed Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 12 Jan 2017 09:40:57 -0800 Subject: [PATCH 133/153] Testing the rule tester --- package.json | 2 +- test/lint_css_rules/at_rule_empty_line.js | 9 +++++++++ test/stylelint_rule_tester.js | 6 +----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3ccd778..014cf31 100644 --- a/package.json +++ b/package.json @@ -68,4 +68,4 @@ "sinon": "^2.2.0", "xsd-schema-validator": "^0.5.0" } -} +} \ No newline at end of file diff --git a/test/lint_css_rules/at_rule_empty_line.js b/test/lint_css_rules/at_rule_empty_line.js index 5c41dcd..174919e 100644 --- a/test/lint_css_rules/at_rule_empty_line.js +++ b/test/lint_css_rules/at_rule_empty_line.js @@ -9,6 +9,15 @@ var sub = require('string-sub'); var stylelintRule = require('stylelint/dist/rules/at-rule-empty-line-before'); +var path = require('path'); +var fs = require('fs'); +var chai = require('chai'); +var _ = require('lodash'); + +chai.use(require('chai-string')); + +var assert = chai.assert; + testRule( rule, { diff --git a/test/stylelint_rule_tester.js b/test/stylelint_rule_tester.js index 0413d97..43cfa04 100644 --- a/test/stylelint_rule_tester.js +++ b/test/stylelint_rule_tester.js @@ -4,12 +4,10 @@ var chai = require('chai'); chai.use(require('chai-string')); var assert = chai.assert; -var sinon = require('sinon'); + function assertEquality(processCss, context) { const describeFn = (context.only) ? describe.only : describe; - sinon.spy(it); - describeFn( context.caseDescription, function() { @@ -33,8 +31,6 @@ function assertEquality(processCss, context) { ).catch(done) } ); - - console.log(it.called); } ); } From 0c634676d116182b6ae73eed6f4ee684d66d3fa5 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 17 Jan 2017 09:50:21 -0800 Subject: [PATCH 134/153] Fixing stylelint rule --- test/lint_css_rules/at_rule_empty_line.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lint_css_rules/at_rule_empty_line.js b/test/lint_css_rules/at_rule_empty_line.js index 174919e..fd479a7 100644 --- a/test/lint_css_rules/at_rule_empty_line.js +++ b/test/lint_css_rules/at_rule_empty_line.js @@ -7,7 +7,7 @@ var stylelint = testRule.stylelint; var rule = require('../../lib/lint_css_rules/' + path.basename(__filename)); var sub = require('string-sub'); -var stylelintRule = require('stylelint/dist/rules/at-rule-empty-line-before'); +var stylelintRule = require('stylelint/lib/rules/at-rule-empty-line-before'); var path = require('path'); var fs = require('fs'); From be1a8b572fb6af2a773c8f5b02298e7febc361f2 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 2 May 2017 11:50:00 -0700 Subject: [PATCH 135/153] Fixing the resolving of promises returned from formatters (was broken during rebase) --- lib/cli.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index c4d5f2c..e9cd14c 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -92,7 +92,8 @@ class CLI extends EventEmitter { var series = []; if (instance.flags.inlineEdit) { - series = results.reduce( + series = Promise.reduce( + results, function(prev, item, index) { if (item && !item.err && item.contents !== item.data) { prev.push(instance.writeFile(item.file, item.contents)); @@ -239,15 +240,19 @@ class CLI extends EventEmitter { processFileData(data, formatter) { var file = formatter.file; - var contents = formatter.format(data); + var res = Promise.resolve(formatter.format(data)); - this.logResults(this.renderOutput(file), file); + return res.bind(this).then( + function(contents) { + this.logResults(this.renderOutput(file), file); - return { - file: file, - contents: contents, - data: data - }; + return { + file: file, + contents: contents, + data: data + }; + } + ); } renderOutput(file) { From 0aaf686ea94b0ae5d5d5baf2601f72aaa45c6dce Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 2 May 2017 13:29:14 -0700 Subject: [PATCH 136/153] Increasing coverage, and fixing what the lint logging expects (instead of an empty string, it needs to be an object) --- lib/css.js | 10 +++++++- test/css.js | 74 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/lib/css.js b/lib/css.js index ef0072f..b4e810b 100644 --- a/lib/css.js +++ b/lib/css.js @@ -167,7 +167,15 @@ Formatter.CSS = Formatter.create( _lint: function(contents, context) { var lint = context.lintConfig; - var results = ''; + var results = Promise.resolve( + { + results: [ + { + warnings: [] + } + ] + } + ); if (lint !== false) { var linter = require('./lint_css'); diff --git a/test/css.js b/test/css.js index 06ce2f0..fffa824 100644 --- a/test/css.js +++ b/test/css.js @@ -312,6 +312,25 @@ describe( var cssFormatter = new Formatter.CSS(testFilePath, cssLogger); var source = fs.readFileSync(testFilePath, 'utf-8'); + var cssLint = function(contents, config, file) { + return Promise.resolve( + { + results: [ + { + warnings: [ + { + line: 1, + message: '', + column: 0, + ruleId: '' + } + ] + } + ] + } + ); + }; + var lint = require('../lib/lint_css'); it( @@ -350,23 +369,41 @@ describe( } ); + it( + 'should be able to disable linting', + function(done) { + var testFilePath = path.join(__dirname, 'fixture', 'css', 'at_rule_empty_line.css'); + + var source = fs.readFileSync(testFilePath, 'utf-8'); + + var cssLoggerFilter = new Logger.constructor(); + var cssFormatterFilter = new Formatter.CSS(testFilePath, cssLoggerFilter); + + var result = cssFormatterFilter.format(source, false); + + Promise.resolve(result).then( + function(result) { + var errors = cssLoggerFilter.getErrors()[testFilePath]; + + var hasRuleId = errors.some( + function(item, index) { + return !!item.ruleId; + } + ); + + assert.isFalse(hasRuleId); + assert.equal(errors.length, 1); + } + ).done(done); + } + ); + it( 'should use default configuration properties', function() { var stylelint = lint.stylelint; - var cssLint = function(contents, config, file) { - return Promise.resolve( - { - line: 1, - message: '', - column: 0, - ruleId: '' - } - ); - }; - - sandbox.stub(stylelint, 'lint', cssLint); + sandbox.stub(stylelint, 'lint').callsFake(cssLint); lint.runLinter(source, testFilePath, {}); @@ -382,18 +419,7 @@ describe( var stylelint = lint.stylelint; - var cssLint = function(contents, config, file) { - return Promise.resolve( - { - line: 1, - message: '', - column: 0, - ruleId: '' - } - ); - }; - - sandbox.stub(stylelint, 'lint', cssLint); + sandbox.stub(stylelint, 'lint').callsFake(cssLint); cssFormatter.format( source, From f0a6641798aa4ce5fb5b422c5983779ff03d6da7 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 4 May 2017 13:30:37 -0700 Subject: [PATCH 137/153] Increase coverage for stylelint rules to 100% --- lib/css.js | 21 ---- lib/lint_css_rules/at_rule_empty_line.js | 114 +++------------------- test/css.js | 4 +- test/lint_css_rules/at_rule_empty_line.js | 15 +++ test/stylelint_rule_tester.js | 8 +- 5 files changed, 36 insertions(+), 126 deletions(-) diff --git a/lib/css.js b/lib/css.js index b4e810b..6967550 100644 --- a/lib/css.js +++ b/lib/css.js @@ -18,25 +18,6 @@ Formatter.CSS = Formatter.create( id: 'css', includes: /\.s?css$/, prototype: { - comparePropertySort: function(content, nextItem, context) { - var re = this._re; - - var nextItemMatch; - - var contentMatch = content.match(REGEX.PROP_KEY); - - if (nextItem && re.hasProperty(nextItem)) { - nextItem = nextItem.replace(REGEX.LEADING_SPACE, ''); - nextItemMatch = nextItem && re.hasProperty(nextItem) && nextItem.match(REGEX.PROP_KEY); - } - - if (contentMatch && nextItemMatch && contentMatch[1] > nextItemMatch[1]) { - this.log(context.lineNum, sub('Sort: {0} {1}', content, nextItem)); - } - - return content; - }, - format: function(contents, lint) { var instance = this; @@ -130,8 +111,6 @@ Formatter.CSS = Formatter.create( rawContent = re.iterateRules('css._properties', propertyContext); - content = this.comparePropertySort(content, nextItem, context); - return { content: content, rawContent: rawContent diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 98a20e8..a423ec4 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -28,8 +28,6 @@ module.exports = function(expectation, options) { var atRuleFn = stylelint.rules['at-rule-empty-line-before'](expectation, options); return function(root, result) { - var otherResults = atRuleFn(root, result); - var messages = slUtils.ruleMessages( ruleName, { @@ -55,10 +53,6 @@ module.exports = function(expectation, options) { } ); - if (!validOptions) { - return; - } - var getLineDistance = function(left, right) { return right.source.start.line - left.source.end.line; }; @@ -69,20 +63,24 @@ module.exports = function(expectation, options) { var validLines = []; - root.walkAtRules( - function(node) { - if (node.first !== root.first) { - if (node.name === 'include' || node.name === 'import') { - var prev = node.prev(); - var next = node.next(); + if (validOptions) { + var otherResults = atRuleFn(root, result); + + root.walkAtRules( + function(node) { + if (node !== root.first) { + if (node.name === 'include' || node.name === 'import') { + var prev = node.prev(); + var next = node.next(); - if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && getLineDistance(prev, node) === 1) { - validLines.push(node.source.start.line); + if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && getLineDistance(prev, node) === 1) { + validLines.push(node.source.start.line); + } } } } - } - ); + ); + } result.messages = _.reject( result.messages, @@ -91,88 +89,8 @@ module.exports = function(expectation, options) { } ); - return otherResults; + return result; }; }; -module.exports.ruleName = ruleName; - -// exports.default = function (expectation, options) { -// return function (root, result) { -// var validOptions = (0, _utils.validateOptions)(result, ruleName, { -// actual: expectation, -// possible: ["always", "never"] -// }, { -// actual: options, -// possible: { -// except: ["blockless-group", "first-nested", "all-nested"], -// ignore: ["after-comment", "all-nested"] -// }, -// optional: true -// }); -// if (!validOptions) { -// return; -// } - -// root.walkAtRules(function (atRule) { - -// // Ignore the first node -// if (atRule === root.first) { -// return; -// } - -// var isNested = atRule.parent !== root; -// if ((0, _utils.optionsHaveIgnored)(options, "all-nested") && isNested) { -// return; -// } - -// // Optionally ignore the expectation if a comment precedes this node -// if ((0, _utils.optionsHaveIgnored)(options, "after-comment") && atRule.prev() && atRule.prev().type === "comment") { -// return; -// } - -// var before = atRule.raw("before"); -// var emptyLineBefore = before && (before.indexOf("\n\n") !== -1 || before.indexOf("\r\n\r\n") !== -1 || before.indexOf("\n\r\n") !== -1); - -// var expectEmptyLineBefore = expectation === "always" ? true : false; - -// var previousNode = atRule.prev(); - -// // Reverse the expectation if any exceptions apply -// if ((0, _utils.optionsHaveException)(options, "all-nested") && isNested || getsFirstNestedException() || getsBlocklessGroupException()) { -// expectEmptyLineBefore = !expectEmptyLineBefore; -// } - -// // Return if the exceptation is met -// if (expectEmptyLineBefore === emptyLineBefore) { -// return; -// } - -// var message = expectEmptyLineBefore ? messages.expected : messages.rejected; - -// (0, _utils.report)({ -// message: message, -// node: atRule, -// result: result, -// ruleName: ruleName -// }); - -// function getsBlocklessGroupException() { -// return (0, _utils.optionsHaveException)(options, "blockless-group") && previousNode && previousNode.type === "atrule" && !(0, _utils.cssStatementHasBlock)(previousNode) && !(0, _utils.cssStatementHasBlock)(atRule); -// } - -// function getsFirstNestedException() { -// return (0, _utils.optionsHaveException)(options, "first-nested") && isNested && atRule === atRule.parent.first; -// } -// }); -// }; -// }; - -// var _utils = require("../../utils"); - -// var ruleName = exports.ruleName = "at-rule-empty-line-before"; - -// var messages = exports.messages = (0, _utils.ruleMessages)(ruleName, { -// expected: "Expected empty line before at-rule", -// rejected: "Unexpected empty line before at-rule" -// }); \ No newline at end of file +module.exports.ruleName = ruleName; \ No newline at end of file diff --git a/test/css.js b/test/css.js index fffa824..e78c7ff 100644 --- a/test/css.js +++ b/test/css.js @@ -383,7 +383,7 @@ describe( Promise.resolve(result).then( function(result) { - var errors = cssLoggerFilter.getErrors()[testFilePath]; + var errors = cssLoggerFilter.getErrors()[testFilePath] || []; var hasRuleId = errors.some( function(item, index) { @@ -392,7 +392,7 @@ describe( ); assert.isFalse(hasRuleId); - assert.equal(errors.length, 1); + assert.equal(errors.length, 0); } ).done(done); } diff --git a/test/lint_css_rules/at_rule_empty_line.js b/test/lint_css_rules/at_rule_empty_line.js index fd479a7..0289461 100644 --- a/test/lint_css_rules/at_rule_empty_line.js +++ b/test/lint_css_rules/at_rule_empty_line.js @@ -37,4 +37,19 @@ testRule( ], syntax: 'scss', } +); + +testRule( + rule, + { + description: 'should handle invalid options', + config: [], + skipBasicChecks: true, + reject: [ + { + code: 'a {\n}', + message: 'Expected option value for rule "' + rule.ruleName + '"' + } + ], + } ); \ No newline at end of file diff --git a/test/stylelint_rule_tester.js b/test/stylelint_rule_tester.js index 43cfa04..9c421b6 100644 --- a/test/stylelint_rule_tester.js +++ b/test/stylelint_rule_tester.js @@ -13,8 +13,8 @@ function assertEquality(processCss, context) { function() { it( context.completeAssertionDescription, - function(done) { - processCss.then( + function() { + return processCss.then( function(comparisons) { comparisons.forEach( function(item, index) { @@ -25,10 +25,8 @@ function assertEquality(processCss, context) { assert.equal(actual, expected, description); } ); - - done(); } - ).catch(done) + ); } ); } From 5a695d9e91ba8783e6fe9cbe48ed7544f6642a94 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 5 May 2017 10:23:35 -0700 Subject: [PATCH 138/153] Add configBasedir to properly look up the plugins --- lib/lint_css.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/lint_css.js b/lib/lint_css.js index f53dc69..ff82df3 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -1,4 +1,5 @@ var _ = require('lodash'); +var path = require('path'); var stylelint = require('stylelint'); var STYLELINT_CONFIG = require('./config/stylelint'); var glob = require('glob'); @@ -27,6 +28,7 @@ var runLinter = function(contents, file, context) { code: contents, codeFileName: file, config: config, + configBasedir: path.resolve(__dirname, '..'), formatter: 'json', syntax: 'scss' } From 81c5d3803b605ba5eec3cdcf7dfd69eed38a2417 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 5 May 2017 10:24:24 -0700 Subject: [PATCH 139/153] Add new rules and add the stylelint-order plugin --- lib/config/stylelint.js | 93 +++++++++++++++++++++++++++++++++-------- package.json | 3 +- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index b07b7e8..93a2e29 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -1,25 +1,87 @@ module.exports = { - // 'plugins': [ - // 'react' - // ], + 'plugins': [ + 'stylelint-order' + ], 'globals': { }, 'rules': { + // 'at-rule-blacklist': 'string|[]', + // 'at-rule-empty-line-before': 'alwaysd|never', + 'at-rule-name-case': 'lower', + // 'at-rule-name-newline-after': 'alwaysd|always-multi-line', + 'at-rule-name-space-after': 'always', + // 'at-rule-no-unknown': true, + 'at-rule-semicolon-newline-after': 'always', + 'at-rule-semicolon-space-before': 'never', + // 'at-rule-whitelist': 'string|[]', + 'block-closing-brace-empty-line-before': 'never', + 'comment-no-empty': true, + // 'comment-word-blacklist': 'string|[]', + // 'custom-property-empty-line-before': 'alwaysd|never', + 'declaration-block-no-redundant-longhand-properties': true, + // 'declaration-empty-line-before': 'alwaysd|never', + // 'declaration-property-unit-blacklist': {}, + // 'declaration-property-unit-whitelist': {}, + // 'declaration-property-value-blacklist': {}, + // 'declaration-property-value-whitelist': {}, + 'font-family-no-duplicate-names': true, + 'function-max-empty-lines': 0, + 'function-name-case': 'lower', + // 'function-url-data-uris': 'alwaysd|never', + // 'function-url-no-scheme-relative': true, + // 'function-url-scheme-whitelist': 'string|[]', + // 'keyframe-declaration-no-important': true, + // 'media-feature-name-blacklist': 'string|[]', + 'media-feature-name-case': 'lower', + // 'media-feature-name-no-unknown': true, + // 'media-feature-name-whitelist': 'string|[]', + 'no-empty-source': true, + 'no-extra-semicolons': true, + // 'no-missing-end-of-source-newline': true, + 'property-case': 'lower', + // 'property-no-unknown': true, + 'rule-empty-line-before': ['always', {except: 'first-nested'}], + 'selector-attribute-brackets-space-inside': 'never', + // 'selector-attribute-operator-blacklist': 'string|[]', + 'selector-attribute-operator-space-after': 'never', + 'selector-attribute-operator-space-before': 'never', + // 'selector-attribute-operator-whitelist': 'string|[]', + // 'selector-attribute-quotes': 'alwaysd|never', + 'selector-descendant-combinator-no-non-space': true, + 'selector-max-empty-lines': 0, + // 'selector-max-compound-selectors': 'int', + // 'selector-nested-pattern': 'string', + // 'selector-no-qualifying-type': true, + // 'selector-pseudo-class-blacklist': 'string|[]', + 'selector-pseudo-class-case': 'lower', + 'selector-pseudo-class-no-unknown': true, + 'selector-pseudo-class-parentheses-space-inside': 'never', + // 'selector-pseudo-class-whitelist': 'string|[]', + 'selector-pseudo-element-case': 'lower', + 'selector-pseudo-element-no-unknown': true, + // 'selector-type-no-unknown': true, + 'shorthand-property-no-redundant-values': true, + // 'time-min-milliseconds': 'int', + 'unit-case': 'lower', + 'unit-no-unknown': true, + 'value-keyword-case': 'lower', + 'value-list-max-empty-lines': 0, + 'csf-at-rule-empty-line': ['always', {except: ['first-nested']}], - // 'at-rule-empty-line-before': ['always', {except: ['first-nested']}], + "order/properties-alphabetical-order": true, 'at-rule-no-vendor-prefix': true, 'block-closing-brace-newline-after': 'always', 'block-closing-brace-newline-before': 'always', // 'block-closing-brace-space-after': 'never', // 'block-closing-brace-space-before': 'never', // 'block-no-empty': true, - 'block-no-single-line': true, + // 'block-no-single-line': true, 'block-opening-brace-newline-after': 'always', - // 'block-opening-brace-newline-before': 'always'|'always-single-line'|'never-single-line'|'always-multi-line'|'never-multi-line', + // 'block-opening-brace-newline-before': 'always', // 'block-opening-brace-space-after': 'never', 'block-opening-brace-space-before': 'always', 'color-hex-case': 'upper', @@ -30,18 +92,16 @@ module.exports = { 'comment-empty-line-before': ['always', {except: ['first-nested']}], 'comment-whitespace-inside': 'always', // 'custom-media-pattern': string, - // 'custom-property-no-outside-root': true, // 'custom-property-pattern': string, 'declaration-bang-space-after': 'never', 'declaration-bang-space-before': 'always', 'declaration-block-no-duplicate-properties': true, 'declaration-block-no-shorthand-property-overrides': true, - 'declaration-block-properties-order': 'alphabetical', 'declaration-block-semicolon-newline-after': 'always', 'declaration-block-semicolon-newline-before': 'never', // 'declaration-block-semicolon-space-after': 'always'|'never'|'always-single-line'|'never-single-line', 'declaration-block-semicolon-space-before': 'never', - // 'declaration-block-single-line-max-declarations': int, + 'declaration-block-single-line-max-declarations': 1, 'declaration-block-trailing-semicolon': 'always', // 'declaration-colon-newline-after': 'always'|'always-multi-line', 'declaration-colon-space-after': 'always', @@ -58,7 +118,7 @@ module.exports = { // 'function-linear-gradient-no-nonstandard-direction': true, // 'function-parentheses-newline-inside': 'always'|'always-multi-line'|'never-multi-line', 'function-parentheses-space-inside': 'never', - 'function-url-quotes': 'none', + 'function-url-quotes': 'never', // 'function-whitelist': string|[], 'function-whitespace-after': 'always', 'indentation': 'tab', @@ -68,7 +128,7 @@ module.exports = { 'media-feature-colon-space-after': 'always', 'media-feature-colon-space-before': 'never', // 'media-feature-name-no-vendor-prefix': true, - 'media-feature-no-missing-punctuation': true, + // 'media-feature-no-missing-punctuation': true, 'media-feature-range-operator-space-after': 'always', 'media-feature-range-operator-space-before': 'always', // 'media-query-list-comma-newline-after': 'always'|'always-multi-line'|'never-multi-line', @@ -76,14 +136,12 @@ module.exports = { // 'media-query-list-comma-space-after': 'always'|'never'|'always-single-line'|'never-single-line', // 'media-query-list-comma-space-before': 'always'|'never'|'always-single-line'|'never-single-line', 'media-feature-parentheses-space-inside': 'never', - // 'no-browser-hacks': true, // 'no-descending-specificity': true, // Maybe // 'no-duplicate-selectors': true, // Maybe 'no-eol-whitespace': true, // 'no-invalid-double-slash-comments': true, - // 'no-missing-eof-newline': true, + // 'no-missing-end-of-source-newline': true, // 'no-unknown-animations': true, - // 'no-unsupported-browser-features': true, 'number-leading-zero': 'always', 'number-max-precision': 3, 'number-no-trailing-zeros': true, @@ -95,8 +153,8 @@ module.exports = { // 'property-value-blacklist': {}, // 'property-whitelist': string|[], // 'root-no-standard-properties': true, - 'rule-nested-empty-line-before': ['always', {except: ['first-nested']}], - 'rule-non-nested-empty-line-before': 'always', + 'rule-empty-line-before': ['always', {except: ['first-nested']}], + // 'rule-non-nested-empty-line-before': 'always', 'selector-class-pattern': [/(#\{\$.*?\}|[a-z0-9]+)(-#\{\$.*?\}|-[a-z0-9]+)*$/, {resolveNestedSelectors: true}], // Maybe 'selector-combinator-space-after': 'always', 'selector-combinator-space-before': 'always', @@ -113,11 +171,10 @@ module.exports = { // 'selector-no-universal': true, // 'selector-no-vendor-prefix': true, 'selector-pseudo-element-colon-notation': 'single', - // 'selector-root-no-composition': true, 'selector-type-case': 'lower', 'string-no-newline': true, // 'string-quotes': 'single', - 'time-no-imperceptible': true, + // 'time-no-imperceptible': true, // 'unit-blacklist': string|[], // 'unit-whitelist': string|[], 'value-list-comma-newline-after': false, diff --git a/package.json b/package.json index 014cf31..2eb2da0 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "roolz": "^1.0.2", "string-sub": "0.0.1", "stylelint": "^7.0.3", + "stylelint-order": "^0.4.4", "update-notifier": "^2.1.0" }, "devDependencies": { @@ -68,4 +69,4 @@ "sinon": "^2.2.0", "xsd-schema-validator": "^0.5.0" } -} \ No newline at end of file +} From 099702a4c0a3e509acf475cb71f0ba373d55d17d Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 5 May 2017 10:24:43 -0700 Subject: [PATCH 140/153] Exclude @else blocks from triggering an error --- lib/lint_css_rules/at_rule_empty_line.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index a423ec4..65a9d7b 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -69,14 +69,19 @@ module.exports = function(expectation, options) { root.walkAtRules( function(node) { if (node !== root.first) { + var startLine = node.source.start.line; + if (node.name === 'include' || node.name === 'import') { var prev = node.prev(); var next = node.next(); if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && getLineDistance(prev, node) === 1) { - validLines.push(node.source.start.line); + validLines.push(startLine); } } + else if (node.name === 'else') { + validLines.push(startLine); + } } } ); From cbeb3ab56980074adc209094f6e6dddd74923a8b Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 11:56:59 -0700 Subject: [PATCH 141/153] Update test coverage for scss rule --- test/lint_css_rules/at_rule_empty_line.js | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/lint_css_rules/at_rule_empty_line.js b/test/lint_css_rules/at_rule_empty_line.js index 0289461..2615f6a 100644 --- a/test/lint_css_rules/at_rule_empty_line.js +++ b/test/lint_css_rules/at_rule_empty_line.js @@ -25,13 +25,34 @@ testRule( config: ['always', {except: ['first-nested']}], accept: [ { - code: 'a {\n @include foo;\n color: pink;\n}', + code: `a { + @include foo; + color: pink; + }`, description: 'always at rule empty line no first-nested' + }, + { + code: ` + @if $foo != null { + div { + color: blue; + } + } + @else { + div { + color: red; + } + } + `, + description: 'ignore @else blocks' } ], reject: [ { - code: 'a {\n color: blue;\n @include foo;\n}', + code: `a { + color: blue; + @include foo; + }`, message: stylelintRule.messages.expected } ], From 1232cea4bde169686f8e751eae92be484ecb9850 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Thu, 11 May 2017 14:33:52 -0700 Subject: [PATCH 142/153] Update certain engine rules to only be replacers if we already have a valid stylelint rule --- lib/engine_rules/css.js | 10 ++---- test/css.js | 67 ++++++++++++++-------------------------- test/engine_rules/css.js | 2 -- test/html.js | 2 +- 4 files changed, 26 insertions(+), 55 deletions(-) diff --git a/lib/engine_rules/css.js b/lib/engine_rules/css.js index 2fe6599..41519d3 100644 --- a/lib/engine_rules/css.js +++ b/lib/engine_rules/css.js @@ -257,13 +257,7 @@ module.exports = { _properties: { invalidBorderReset: { - message: function(result, rule, context) { - var borderReplacement = rule._getValidReplacement(result); - - var message = sub('You should use "{1}": {0}', context.content, colors.error(borderReplacement)); - - return this.message(message, result, rule, context); - }, + message: false, regex: /(border(-(?:right|left|top|bottom))?):\s?(none|0)(\s?(none|0))?;/, replacer: function(result, rule, context) { var rawContent = context.rawContent; @@ -277,7 +271,7 @@ module.exports = { }, invalidFormat: { - message: 'There should be one space after ":": {1}', + message: false, regex: /^\t*([^:]+:(?:(?! )|(?= {2,})))[^;]+;$/, replacer: function(result, rule, context) { var rawContent = context.rawContent; diff --git a/test/css.js b/test/css.js index e78c7ff..8ab3e52 100644 --- a/test/css.js +++ b/test/css.js @@ -35,7 +35,12 @@ describe( function(contents) { var newContents = cssFormatter.format(contents); - return [cssLogger.fileErrors[filePath], contents, newContents]; + return Promise.all([contents, newContents]); + } + ) + .then( + function(arr) { + return [cssLogger.fileErrors[filePath]].concat(arr); } ); }; @@ -47,7 +52,7 @@ describe( function(errors) { assert.equal(errors.length, 1); - assert.startsWith(errors[0].msg, 'Hex code should be all uppercase'); + assert.startsWith(errors[0].msg, 'Expected "#fff" to be "#FFF"'); } ); } @@ -60,7 +65,7 @@ describe( function(errors) { assert.equal(errors.length, 1); - assert.startsWith(errors[0].msg, 'Hex code can be reduced to'); + assert.startsWith(errors[0].msg, 'Expected "#FFFFFF" to be "#FFF"'); } ); } @@ -73,14 +78,6 @@ describe( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); - var borderErrors = errors.filter( - function(item, index) { - return item.line <= 11 && item.msg.indexOf('You should use "border-') === 0; - } - ); - - assert.equal(borderErrors.length, errors.length); - assert.notEqual(contents, newContents); } ); @@ -94,13 +91,7 @@ describe( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); - var formatErrors = errors.filter( - function(item, index) { - return item.line <= 3 && item.msg.indexOf('There should be one space after ":"') === 0; - } - ); - - assert.equal(formatErrors.length, errors.length); + assert.notEqual(contents, newContents); } ); } @@ -111,9 +102,9 @@ describe( function() { return testFile(getFilePath('missing_integer.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); + assert.isAbove(errors.length, 0); - assert.startsWith(errors[0].msg, 'Missing integer'); + assert.notEqual(contents, newContents); } ); } @@ -124,9 +115,9 @@ describe( function() { return testFile(getFilePath('missing_list_values_space.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); + assert.isAbove(errors.length, 0); - assert.startsWith(errors[0].msg, 'Needs space between comma-separated values'); + assert.notEqual(contents, newContents); } ); } @@ -139,13 +130,7 @@ describe( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); - var formatErrors = errors.filter( - function(item, index) { - return item.msg.indexOf('There should be a newline between') === 0; - } - ); - - assert.equal(formatErrors.length, errors.length); + assert.notEqual(contents, newContents); } ); } @@ -156,9 +141,9 @@ describe( function() { return testFile(getFilePath('missing_selector_space.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); + assert.isAbove(errors.length, 0); - assert.startsWith(errors[0].msg, 'Missing space between selector and bracket'); + assert.startsWith(errors[0].msg, 'Expected single space before "{"'); } ); } @@ -171,13 +156,7 @@ describe( function(errors, contents, newContents) { assert.isAbove(errors.length, 0); - var formatErrors = errors.filter( - function(item, index) { - return item.msg.indexOf('Needless quotes') === 0; - } - ); - - assert.equal(formatErrors.length, errors.length); + assert.notEqual(contents, newContents); } ); } @@ -188,9 +167,9 @@ describe( function() { return testFile(getFilePath('needless_unit.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); + assert.isAbove(errors.length, 0); - assert.startsWith(errors[0].msg, 'Needless unit'); + assert.notEqual(contents, newContents); } ); } @@ -201,9 +180,7 @@ describe( function() { return testFile(getFilePath('property_sort.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); - - assert.startsWith(errors[0].msg, 'Sort'); + assert.startsWith(errors[0].msg, 'Expected background to come before padding'); } ); } @@ -214,9 +191,11 @@ describe( function() { return testFile(getFilePath('trailing_comma.css')).spread( function(errors, contents, newContents) { - assert.equal(errors.length, 1); + assert.isAbove(errors.length, 0); assert.startsWith(errors[0].msg, 'Trailing comma in selector'); + + assert.notEqual(contents, newContents); } ); } diff --git a/test/engine_rules/css.js b/test/engine_rules/css.js index 9e93084..740bb67 100644 --- a/test/engine_rules/css.js +++ b/test/engine_rules/css.js @@ -442,7 +442,6 @@ describe( var lineNum = 1; assert.isArray(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); @@ -474,7 +473,6 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), expectedWarning); assert.equal(output, re.replaceItem(result, rule, context)); } ); diff --git a/test/html.js b/test/html.js index 745c704..86197b2 100644 --- a/test/html.js +++ b/test/html.js @@ -196,7 +196,7 @@ describe( function() { var msg = getErrorMsgByLine(64, htmlErrors); - assert.startsWith(msg, 'You should use "border-width: 0;": border: none;'); + assert.startsWith(msg, 'Expected indentation of 1 tab'); } ); From f97fad4ffbe614aa9ce629c87cdf27f20ae660b5 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 12 May 2017 12:24:59 -0700 Subject: [PATCH 143/153] Remove the no-empty-source rule --- lib/config/stylelint.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index 93a2e29..6929b1d 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -39,7 +39,7 @@ module.exports = { 'media-feature-name-case': 'lower', // 'media-feature-name-no-unknown': true, // 'media-feature-name-whitelist': 'string|[]', - 'no-empty-source': true, + 'no-empty-source': false, 'no-extra-semicolons': true, // 'no-missing-end-of-source-newline': true, 'property-case': 'lower', @@ -118,8 +118,11 @@ module.exports = { // 'function-linear-gradient-no-nonstandard-direction': true, // 'function-parentheses-newline-inside': 'always'|'always-multi-line'|'never-multi-line', 'function-parentheses-space-inside': 'never', - 'function-url-quotes': 'never', - // 'function-whitelist': string|[], + + //Will probably need to reimplement this one to ignore strings with quotes + // 'function-url-quotes': 'never', + + // 'function-whitelist': '', 'function-whitespace-after': 'always', 'indentation': 'tab', 'max-empty-lines': 1, From 365537205cac369c461425e1d7f2c4f75fa61a87 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 12 May 2017 12:25:08 -0700 Subject: [PATCH 144/153] Remove the stylelint postfix --- lib/css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/css.js b/lib/css.js index 6967550..48bf1dd 100644 --- a/lib/css.js +++ b/lib/css.js @@ -180,7 +180,7 @@ Formatter.CSS = Formatter.create( results[0].warnings.forEach( function(item, index) { - // item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); + item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); if (lintLogFilter) { item = lintLogFilter(item); From 7bc0005f95fbc68d0c8dfc73a4d3e7b188c33593 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 12 May 2017 12:59:04 -0700 Subject: [PATCH 145/153] Updating code to es6 syntax (at least what's available on node >= 4.x) --- gulpfile.js | 48 +++--- lib/argv.js | 152 +++++++++--------- lib/base.js | 12 +- lib/cli.js | 32 ++-- lib/css.js | 34 ++-- lib/engine_rules/common.js | 20 ++- lib/engine_rules/css.js | 52 +++--- lib/engine_rules/html_js.js | 2 +- lib/engine_rules/js.js | 12 +- lib/file.js | 4 +- lib/formatter.js | 8 +- lib/html.js | 168 +++++++++----------- lib/js.js | 30 ++-- lib/lint_css.js | 10 +- lib/lint_css_rules/at_rule_empty_line.js | 20 +-- lib/lint_js.js | 24 ++- lib/lint_js_rules/array_spacing.js | 82 +++++----- lib/lint_js_rules/array_spacing_chars.js | 40 +++-- lib/lint_js_rules/catch_arg_name.js | 18 +-- lib/lint_js_rules/catch_format.js | 22 ++- lib/lint_js_rules/dot_notation.js | 20 ++- lib/lint_js_rules/format_args.js | 34 ++-- lib/lint_js_rules/format_constants.js | 6 +- lib/lint_js_rules/format_multiline_vars.js | 18 +-- lib/lint_js_rules/function_spacing.js | 10 +- lib/lint_js_rules/liferay_language_get.js | 8 +- lib/lint_js_rules/liferay_provide_format.js | 80 +++++----- lib/lint_js_rules/multiple_vars.js | 26 ++- lib/lint_js_rules/no_extra_semi.js | 16 +- lib/lint_js_rules/no_is_prefix.js | 16 +- lib/lint_js_rules/no_multiple_return.js | 20 +-- lib/lint_js_rules/no_undef.js | 6 +- lib/lint_js_rules/no_unused_vars.js | 10 +- lib/lint_js_rules/no_use_before_define.js | 8 +- lib/lint_js_rules/sort_constants.js | 12 +- lib/lint_js_rules/sort_props.js | 44 ++--- lib/lint_js_rules/sort_requires.js | 74 +++++---- lib/lint_js_rules/sort_vars.js | 24 ++- lib/logger.js | 4 +- lib/meta.js | 82 +++++----- lib/re.js | 8 +- lib/regex.js | 4 +- lib/rule_utils.js | 20 ++- lib/tpl/lint_rules/js/rule.js | 4 +- lib/tpl/lint_rules/js/test.js | 2 +- 45 files changed, 625 insertions(+), 721 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 6fba2f8..c2146ea 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -6,30 +6,26 @@ var plugins = require('gulp-load-plugins')(); var runSequence = require('run-sequence'); var inquirer = require('inquirer'); -gulp.task('coveralls', function () { +gulp.task('coveralls', () => { gulp.src('coverage/**/lcov.info') .pipe(plugins.coveralls()); }); -gulp.task('test', function(done) { - return runSequence('test-unit', done); -}); +gulp.task('test', done => runSequence('test-unit', done)); -gulp.task('test-complexity', function() { - return gulp.src(['lib/**/*.js']) - .pipe(plugins.complexity({ - cyclomatic: [4, 7, 12], - halstead: [15, 15, 20] - })); -}); +gulp.task('test-complexity', () => gulp.src(['lib/**/*.js']) + .pipe(plugins.complexity({ + cyclomatic: [4, 7, 12], + halstead: [15, 15, 20] + }))); -gulp.task('test-file', function() { +gulp.task('test-file', () => { var file = process.argv.slice(3).pop(); if (file) { file = file.slice(2); - file = !_.startsWith(file, 'test/') ? 'test/' + file : file; - file = !_.endsWith(file, '.js') ? file + '.js' : file; + file = !_.startsWith(file, 'test/') ? `test/${file}` : file; + file = !_.endsWith(file, '.js') ? `${file}.js` : file; file = [file]; } @@ -44,20 +40,18 @@ gulp.task('test-file', function() { .pipe(plugins.mocha()); }); -gulp.task('test-unit', function() { +gulp.task('test-unit', () => { process.argv.push('--display-raw'); return gulp.src(['test/**/*.js', '!test/fixture/*.js']) .pipe(plugins.mocha()); }); -gulp.task('test-cover', function() { - return gulp.src(['lib/**/*.js']) - .pipe(plugins.istanbul()) - .pipe(plugins.istanbul.hookRequire()); -}); +gulp.task('test-cover', () => gulp.src(['lib/**/*.js']) + .pipe(plugins.istanbul()) + .pipe(plugins.istanbul.hookRequire())); -gulp.task('test-coverage', ['test-cover'], function() { +gulp.task('test-coverage', ['test-cover'], () => { process.argv.push('--display-raw'); return gulp.src(['test/**/*.js', '!test/fixture/*.js']) @@ -65,7 +59,7 @@ gulp.task('test-coverage', ['test-cover'], function() { .pipe(plugins.istanbul.writeReports()); }); -gulp.task('toc', function(done) { +gulp.task('toc', done => { gulp.src('./README.md') .pipe( plugins.doctoc( @@ -80,7 +74,7 @@ gulp.task('toc', function(done) { gulp.task( 'new-rule', - function(done) { + done => { inquirer.prompt( [ { @@ -105,7 +99,7 @@ gulp.task( ] ) .then( - function(res) { + res => { var srcDir = 'js'; var destDir = 'lint_js_rules'; @@ -114,14 +108,14 @@ gulp.task( destDir = 'lint_css_rules'; } - gulp.src('./lib/tpl/lint_rules/' + srcDir + '/*.js') + gulp.src(`./lib/tpl/lint_rules/${srcDir}/*.js`) // .pipe(plugins.debug()) .pipe( plugins.rename( - function(path) { + path => { var baseDir = path.basename === 'rule' ? 'lib' : 'test'; - path.dirname = './' + baseDir + '/lint_' + srcDir + '_rules'; + path.dirname = `./${baseDir}/lint_${srcDir}_rules`; path.basename = res.name; } diff --git a/lib/argv.js b/lib/argv.js index d8dd06d..bb1867b 100644 --- a/lib/argv.js +++ b/lib/argv.js @@ -1,84 +1,86 @@ var optimist = require('optimist') - .usage('Usage: $0 -qo') - .options( - { - config: { - default: true, - string: true - }, - 'display-raw': { - boolean: true, - default: false - }, - f: { - alias: 'force', - boolean: true, - default: false - }, - filenames: { - boolean: true, - default: false - }, - h: { - alias: 'help', - boolean: true, - default: false - }, - i: { - alias: 'inline-edit', - boolean: true, - default: false - }, - l: { - alias: 'lint', - boolean: true, - default: true - }, - 'lint-ids': { - boolean: true, - default: false - }, - m: { - alias: 'check-metadata', - boolean: true, - default: false - }, - o: { - alias: 'open', - boolean: true, - default: false - }, - q: { - alias: 'quiet', - boolean: true, - default: false - }, - r: { - alias: 'relative', - boolean: true, - default: false - }, - 'show-columns': { - boolean: true, - default: false - }, - v: { - alias: 'verbose', - boolean: true, - default: false - }, - V: { - alias: 'version', - boolean: true, - default: false - } - } - ); +.usage('Usage: $0 -qo') +.options( + { + config: { + default: true, + string: true + }, + 'display-raw': { + boolean: true, + default: false + }, + f: { + alias: 'force', + boolean: true, + default: false + }, + filenames: { + boolean: true, + default: false + }, + h: { + alias: 'help', + boolean: true, + default: false + }, + i: { + alias: 'inline-edit', + boolean: true, + default: false + }, + l: { + alias: 'lint', + boolean: true, + default: true + }, + 'lint-ids': { + boolean: true, + default: false + }, + m: { + alias: 'check-metadata', + boolean: true, + default: false + }, + o: { + alias: 'open', + boolean: true, + default: false + }, + q: { + alias: 'quiet', + boolean: true, + default: false + }, + r: { + alias: 'relative', + boolean: true, + default: false + }, + 'show-columns': { + boolean: true, + default: false + }, + v: { + alias: 'verbose', + boolean: true, + default: false + }, + V: { + alias: 'version', + boolean: true, + default: false + } + } +); var argv = optimist.argv; /* istanbul ignore next */ if (argv.h || argv.V) { + /* eslint-disable */ + if (argv.h) { optimist.showHelp(); } diff --git a/lib/base.js b/lib/base.js index e2fed6f..c0df11b 100644 --- a/lib/base.js +++ b/lib/base.js @@ -5,7 +5,7 @@ require('lodash-bindright')(_); var REGEX_NEWLINE = /\r?\n/; -var iterateLines = function(contents, iterator) { +var iterateLines = (contents, iterator) => { var lines = contents.split(REGEX_NEWLINE); return lines.map(iterator).join('\n'); @@ -20,7 +20,7 @@ var jspLintStubs = { var stubs = _.transform( jspLintStubs, - function(result, item, index) { + (result, item, index) => { result[item] = true; }, {} @@ -28,9 +28,9 @@ var stubs = _.transform( module.exports = { INDENT: ' ', - REGEX_NEWLINE: REGEX_NEWLINE, + REGEX_NEWLINE, - iterateLines: iterateLines, - jspLintStubs: jspLintStubs, - stubs: stubs + iterateLines, + jspLintStubs, + stubs }; \ No newline at end of file diff --git a/lib/cli.js b/lib/cli.js index e9cd14c..27a3618 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -29,7 +29,7 @@ var MAP_OMIT = { var flags = _.reduce( argv, - function(res, item, index) { + (res, item, index) => { if (index.length > 1 && !MAP_OMIT[index]) { index = _.camelCase(index); @@ -41,9 +41,7 @@ var flags = _.reduce( {} ); -var filterFileErrors = function(errors) { - return _.reject(errors, ['type', 'ignored']); -}; +var filterFileErrors = errors => _.reject(errors, ['type', 'ignored']); class CLI extends EventEmitter { constructor(config) { @@ -76,7 +74,7 @@ class CLI extends EventEmitter { ); return this._loadConfigs().then( - function(configs) { + configs => { instance._configs = configs; return configs; @@ -94,7 +92,7 @@ class CLI extends EventEmitter { if (instance.flags.inlineEdit) { series = Promise.reduce( results, - function(prev, item, index) { + (prev, item, index) => { if (item && !item.err && item.contents !== item.data) { prev.push(instance.writeFile(item.file, item.contents)); } @@ -167,7 +165,7 @@ class CLI extends EventEmitter { } logGeneralError(err) { - var msg = util.format(colors.error('Something went wrong.\nDetails below:') + '\n%s', err.stack); + var msg = util.format(`${colors.error('Something went wrong.\nDetails below:')}\n%s`, err.stack); this._log(msg); @@ -209,8 +207,8 @@ class CLI extends EventEmitter { return { contents: '', - err: err, - file: file + err, + file }; } @@ -222,9 +220,9 @@ class CLI extends EventEmitter { if (errorFiles.length) { instance._exec( 'git config --get user.editor', - function(res) { + res => { instance._exec( - 'open -a "' + res[0] + '" "' + errorFiles.join('" "') + '"' + `open -a "${res[0]}" "${errorFiles.join('" "')}"` ); } ); @@ -247,9 +245,9 @@ class CLI extends EventEmitter { this.logResults(this.renderOutput(file), file); return { - file: file, - contents: contents, - data: data + file, + contents, + data }; } ); @@ -300,7 +298,7 @@ class CLI extends EventEmitter { return Promise.reduce( instance._args, - function(prev, item, index) { + (prev, item, index) => { var filePath = path.resolve(instance._cwd, path.dirname(item)); var res; @@ -317,7 +315,7 @@ class CLI extends EventEmitter { } return res.then( - function(config) { + config => { prev[item] = config; var obj = config._paths.obj; @@ -347,7 +345,7 @@ class CLI extends EventEmitter { msg = `Using local config from ${configFiles[0]}`; } else if (this.flags.verbose) { - msg = 'Using local config from: \n' + configFiles.join('\n'); + msg = `Using local config from: \n${configFiles.join('\n')}`; } else { msg = `Using local config from ${configSize} files. Pass -v to see all locations`; diff --git a/lib/css.js b/lib/css.js index 48bf1dd..e119f9f 100644 --- a/lib/css.js +++ b/lib/css.js @@ -18,16 +18,14 @@ Formatter.CSS = Formatter.create( id: 'css', includes: /\.s?css$/, prototype: { - format: function(contents, lint) { + format(contents, lint) { var instance = this; var logger = this.log.bind(this); var newContents = iterateLines( contents, - function(item, index, collection) { - return instance.processFile(item, index, collection, logger); - } + (item, index, collection) => instance.processFile(item, index, collection, logger) ); var context = { @@ -36,16 +34,16 @@ Formatter.CSS = Formatter.create( }; return this._lint(contents, context).then( - function(results) { + results => { instance._logLintResults(results.results); return newContents; } ).catch( - function(err) { + err => { instance.log( 'N/A', - 'Could not parse the file because of ' + err, + `Could not parse the file because of ${err}`, 'stylelint-error', { column: 0, @@ -58,11 +56,11 @@ Formatter.CSS = Formatter.create( ); }, - formatPropertyItem: function(content) { + formatPropertyItem(content) { return content.replace(REGEX.LEADING_SPACE, '').replace(REGEX.LEADING_INCLUDE, ''); }, - processFile: function(content, index, collection, logger) { + processFile(content, index, collection, logger) { var re = this._re; var rawContent = content; @@ -96,7 +94,7 @@ Formatter.CSS = Formatter.create( return rawContent; }, - processProperty: function(rawContent, content, nextItem, context) { + processProperty(rawContent, content, nextItem, context) { var re = this._re; content = this.formatPropertyItem(content); @@ -105,21 +103,21 @@ Formatter.CSS = Formatter.create( {}, context, { - content: content + content } ); rawContent = re.iterateRules('css._properties', propertyContext); return { - content: content, - rawContent: rawContent + content, + rawContent }; }, - _getContext: function(content, index, collection, logger) { + _getContext(content, index, collection, logger) { var context = { - collection: collection, + collection, file: this.file }; @@ -143,7 +141,7 @@ Formatter.CSS = Formatter.create( return context; }, - _lint: function(contents, context) { + _lint(contents, context) { var lint = context.lintConfig; var results = Promise.resolve( @@ -169,7 +167,7 @@ Formatter.CSS = Formatter.create( return results; }, - _logLintResults: function(results) { + _logLintResults(results) { var instance = this; var lintLogFilter = instance.lintLogFilter; @@ -179,7 +177,7 @@ Formatter.CSS = Formatter.create( } results[0].warnings.forEach( - function(item, index) { + (item, index) => { item.text = item.text.replace(REGEX_STYLELINT_POSTFIX, ''); if (lintLogFilter) { diff --git a/lib/engine_rules/common.js b/lib/engine_rules/common.js index dd38455..94cd4c2 100644 --- a/lib/engine_rules/common.js +++ b/lib/engine_rules/common.js @@ -6,16 +6,16 @@ var MAP_WHITESPACE = { '\x99': '' }; -var REGEX_WHITESPACE_CHARS = new RegExp('(' + Object.keys(MAP_WHITESPACE).join('|') + ')', 'g'); +var REGEX_WHITESPACE_CHARS = new RegExp(`(${Object.keys(MAP_WHITESPACE).join('|')})`, 'g'); module.exports = { extraneousSpaces: { message: 'Extraneous whitespace at the end of the line', regex: /\s+$/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { return ''; }, - test: function(content, regex) { + test(content, regex) { var invalid = this.test(content, regex); return invalid; @@ -26,12 +26,12 @@ module.exports = { mixedSpaces: { message: 'Mixed spaces and tabs: {1}', regex: /^.*( \t|\t ).*$/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; rawContent = rawContent.replace( /(.*)( +\t|\t +)(.*)/g, - function(str, prefix, problem, suffix) { + (str, prefix, problem, suffix) => { problem = problem.replace(/ {4}| {2}/g, '\t').replace(/ /g, ''); return prefix + problem + suffix; @@ -45,7 +45,7 @@ module.exports = { invalidWhiteSpace: { MSG: 'Invalid whitespace characters', - message: function(result, rule, context) { + message(result, rule, context) { var content = context.content; var displayedContent = content.replace( @@ -55,17 +55,15 @@ module.exports = { context.content = displayedContent; - return this.message(rule.MSG + ': {1}', result, rule, context); + return this.message(`${rule.MSG}: {1}`, result, rule, context); }, regex: REGEX_WHITESPACE_CHARS, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; return rawContent.replace( rule.regex, - function(str, m) { - return MAP_WHITESPACE[m]; - } + (str, m) => MAP_WHITESPACE[m] ); }, testProp: 'rawContent' diff --git a/lib/engine_rules/css.js b/lib/engine_rules/css.js index 41519d3..40f62ba 100644 --- a/lib/engine_rules/css.js +++ b/lib/engine_rules/css.js @@ -11,7 +11,7 @@ module.exports = { message: false, // message: 'Hex code should be all uppercase: {1}', regex: /[a-f]/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; var hexMatch = this.hasHex(rawContent); @@ -20,7 +20,7 @@ module.exports = { return rawContent; }, - test: function(content, regex) { + test(content, regex) { var match = this.hasHex(content); return match && this.test(match, regex); @@ -37,7 +37,7 @@ module.exports = { // }, message: false, regex: /#([0-9A-Fa-f])\1([0-9A-Fa-f])\2([0-9A-Fa-f])\3/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; var hexMatch = this.hasHex(rawContent); @@ -46,12 +46,12 @@ module.exports = { return rawContent; }, - test: function(content, regex) { + test(content, regex) { var match = this.hasHex(content); return match && this.test(match, regex); }, - _reduceHex: function(hex) { + _reduceHex(hex) { return hex.replace(REGEX.HEX_REDUNDANT, REGEX.REPLACE_HEX_REDUNDANT); } }, @@ -68,7 +68,7 @@ module.exports = { message: false, regex: /,(?=[^\s])/g, replacer: ', ', - test: function(content, regex) { + test(content, regex) { var needsSpace = this.test(content, regex); if (this.hasProperty(content)) { @@ -97,21 +97,21 @@ module.exports = { // }, message: false, regex: /.*?(\}|\{)/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; return rawContent.replace( rule.regex, - function(m, bracket) { + (m, bracket) => { if (bracket == '{') { - m = '\n' + m; + m = `\n${m}`; } return m; } ); }, - test: function(content, regex, rule, context) { + test(content, regex, rule, context) { var missingNewlines = false; var hasCloser = REGEX.BRACE_CLOSING.test(content); @@ -128,11 +128,11 @@ module.exports = { return missingNewlines; }, - _isNextLineInvalid: function(content) { + _isNextLineInvalid(content) { return (content !== '' && !REGEX.BRACE_CLOSING.test(content) && content.indexOf('@') !== 0); }, - _isPrevLineInvalid: function(content) { + _isPrevLineInvalid(content) { return (content !== '' && !REGEX.BRACE_OPENING.test(content) && !REGEX.CSS_COMMA_END.test(content)); } }, @@ -147,20 +147,20 @@ module.exports = { // message: 'Missing space around combinator: {1}', message: false, regex: /(.)?([>~+])(.)?/g, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var item = context.rawContent; if (!this.hasProperty(item)) { item = context.rawContent.replace( rule.regex, - function(m, before, combinator, after) { + (m, before, combinator, after) => { if (rule._hasCombinator(before, after)) { if (before && !REGEX_WHITESPACE.test(before)) { before += ' '; } if (!REGEX_WHITESPACE.test(after)) { - after = ' ' + after; + after = ` ${after}`; } } @@ -171,13 +171,13 @@ module.exports = { return item; }, - test: function(item, regex, rule, context) { + test(item, regex, rule, context) { var hasCombinator = false; if (!this.hasProperty(item) && regex.test(item)) { item.replace( regex, - function(m, before, combinator, after) { + (m, before, combinator, after) => { if (!hasCombinator) { hasCombinator = rule._hasCombinator(before, after); } @@ -187,7 +187,7 @@ module.exports = { return hasCombinator; }, - _hasCombinator: function(before, after) { + _hasCombinator(before, after) { return after !== '=' && ((before && !REGEX_WHITESPACE.test(before)) || !REGEX_WHITESPACE.test(after)); } }, @@ -204,7 +204,7 @@ module.exports = { message: false, regex: /(#?)(\b0(?!s\b)[a-zA-Z]{1,}\b)/, replacer: '0', - test: function(content, regex) { + test(content, regex) { var m = content.match(regex); return m && !m[1]; @@ -214,7 +214,7 @@ module.exports = { trailingNewlines: { PRECEDING: 1, TRAILING: 2, - message: function(result, rule, context) { + message(result, rule, context) { var offset = 1; if (result == rule.PRECEDING) { @@ -225,7 +225,7 @@ module.exports = { return this.message('Needless new line', result, rule, context); }, - test: function(content, regex, rule, context) { + test(content, regex, rule, context) { var hasCloser = REGEX.BRACE_CLOSING.test(content); var hasOpener = REGEX.BRACE_OPENING.test(content); @@ -259,26 +259,26 @@ module.exports = { invalidBorderReset: { message: false, regex: /(border(-(?:right|left|top|bottom))?):\s?(none|0)(\s?(none|0))?;/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; return rawContent.replace(result[0], rule._getValidReplacement(result)); }, test: 'match', - _getValidReplacement: function(result) { - return '' + result[1] + '-width: 0;'; + _getValidReplacement(result) { + return `${result[1]}-width: 0;`; } }, invalidFormat: { message: false, regex: /^\t*([^:]+:(?:(?! )|(?= {2,})))[^;]+;$/, - replacer: function(result, rule, context) { + replacer(result, rule, context) { var rawContent = context.rawContent; return rawContent.replace(/:\s*/, ': '); }, - test: function(content, regex) { + test(content, regex) { return content.indexOf(':') > -1 && regex.test(content); } } diff --git a/lib/engine_rules/html_js.js b/lib/engine_rules/html_js.js index 9a494aa..3e24604 100644 --- a/lib/engine_rules/html_js.js +++ b/lib/engine_rules/html_js.js @@ -6,7 +6,7 @@ module.exports = { liferayProvide: { message: 'You can\'t have a Liferay.provide call in a script taglib that has a "use" attribute', regex: /Liferay\.provide/, - test: function(content, regex, rule, context) { + test(content, regex, rule, context) { return context.asyncAUIScript && this.test(content, regex); } } diff --git a/lib/engine_rules/js.js b/lib/engine_rules/js.js index ce66b08..1992e72 100644 --- a/lib/engine_rules/js.js +++ b/lib/engine_rules/js.js @@ -16,12 +16,12 @@ module.exports = { invalidArgumentFormat: { message: 'These arguments should each be on their own line: {1}', regex: /(\w+)\((?!(?:$|.*?\);?))/, - test: function(content, regex) { + test(content, regex) { var invalid = false; content.replace( regex, - function(str, fnName) { + (str, fnName) => { if (fnName !== 'function') { invalid = true; } @@ -33,14 +33,14 @@ module.exports = { }, invalidConditional: { - message: function(result, rule, context) { + message(result, rule, context) { var message = 'Needs a space between ")" and "{bracket}": {1}'; return sub(this.message(message, result, rule, context), rule._bracket); }, regex: /\)\{(?!\})/, replacer: ') {', - test: function(content, regex) { + test(content, regex) { content = content.replace(REGEX.REGEX, ''); return regex.test(content); @@ -66,7 +66,7 @@ module.exports = { logging: { message: 'Debugging statement: {1}', regex: /\bconsole\.[^\(]+?\(/, - valid: function(rule, context) { + valid(rule, context) { return !context.hasSheBang; } }, @@ -74,7 +74,7 @@ module.exports = { varLineSpacing: { message: 'Variable declaration needs a new line after it: {1}', regex: /^(\s*?)?var\b\s/, - test: function(content, regex, rule, context) { + test(content, regex, rule, context) { var nextLineEmpty = context.nextItem == ''; var nextLineHasVar = this.test(context.nextItem, regex); diff --git a/lib/file.js b/lib/file.js index 1d8aa6c..04df3a4 100644 --- a/lib/file.js +++ b/lib/file.js @@ -4,7 +4,7 @@ var util = require('util'); var colors = require('cli-color-keywords')(); -exports.handleFileReadError = function(err, file) { +exports.handleFileReadError = (err, file) => { var errMsg = 'Could not open file'; if (err.code === 'ENOENT') { @@ -21,7 +21,7 @@ exports.handleFileReadError = function(err, file) { return errMsg; }; -exports.handleFileWriteError = function(err, file) { +exports.handleFileWriteError = (err, file) => { var errMsg = 'Could not write to file'; if (file == '') { diff --git a/lib/formatter.js b/lib/formatter.js index ae1acec..33a96a1 100644 --- a/lib/formatter.js +++ b/lib/formatter.js @@ -35,7 +35,7 @@ Formatter.prototype.config = function(key) { var filteredConfigs = _.reduce( paths.keys, - function(prev, item, index) { + (prev, item, index) => { if (minimatch(abspath, item)) { prev.push(configs[index]); } @@ -48,7 +48,7 @@ Formatter.prototype.config = function(key) { if (filteredConfigs.length) { filteredConfigs.unshift(new Config(), config); - configObj = _.merge.apply(_, filteredConfigs); + configObj = _.merge(...filteredConfigs); delete configObj._paths; } @@ -64,7 +64,7 @@ Formatter.prototype.config = function(key) { Formatter.on( 'init', - function(instance) { + instance => { instance._config = new Config(); var ruleInstance = new re(RULES); @@ -75,7 +75,7 @@ Formatter.on( instance.on( 're:message', - function(data) { + data => { instance.log(data.context.lineNum, data.message); } ); diff --git a/lib/html.js b/lib/html.js index b3bbc4e..d296f34 100644 --- a/lib/html.js +++ b/lib/html.js @@ -34,11 +34,11 @@ Formatter.HTML = Formatter.create( id: 'html', includes: /\.(jsp.*|htm.*|vm|ftl|tag|tpl|tmpl|hbs|soy)$/, prototype: { - init: function(file, logger, flags) { + init(file, logger, flags) { this._attrMap = {}; }, - extractCSS: function(contents) { + extractCSS(contents) { var filePath = this.file; var styleBlocks = []; @@ -56,7 +56,7 @@ Formatter.HTML = Formatter.create( newContents.replace( reStyleGlobal, - function(m, tagName, styleAttrs, body, index) { + (m, tagName, styleAttrs, body, index) => { if (!body) { return; } @@ -68,7 +68,7 @@ Formatter.HTML = Formatter.create( contents: body, file: filePath, match: m, - styleAttrs: styleAttrs, + styleAttrs, startLine: lines } ); @@ -79,7 +79,7 @@ Formatter.HTML = Formatter.create( return styleBlocks; }, - extractJs: function(contents) { + extractJs(contents) { var filePath = this.file; var scriptBlocks = []; @@ -97,7 +97,7 @@ Formatter.HTML = Formatter.create( newContents.replace( reAUIScriptGlobal, - function(m, tagNamespace, scriptAttrs, body, index) { + (m, tagNamespace, scriptAttrs, body, index) => { if (!body) { return; } @@ -109,9 +109,9 @@ Formatter.HTML = Formatter.create( contents: body, file: filePath, match: m, - scriptAttrs: scriptAttrs, + scriptAttrs, startLine: lines, - tagNamespace: tagNamespace + tagNamespace } ); } @@ -121,7 +121,7 @@ Formatter.HTML = Formatter.create( return scriptBlocks; }, - format: function(contents) { + format(contents) { var instance = this; instance.parseCSS(contents); @@ -139,7 +139,7 @@ Formatter.HTML = Formatter.create( var newContents = iterateLines( contents, - function(content, index, collection) { + (content, index, collection) => { var rawContent = content; content = content.trim(); @@ -177,7 +177,7 @@ Formatter.HTML = Formatter.create( return newContents; }, - formatCSS: function(styleBlocks) { + formatCSS(styleBlocks) { var cssFormatter = new Formatter.CSS(this.file, this.logger, this.flags, this._config); cssFormatter._config = this._config; @@ -188,13 +188,11 @@ Formatter.HTML = Formatter.create( var lint = _.merge({}, lintConfig, this.config('css.lint'), this.config('html.lint.css')); return styleBlocks.map( - function(item, index) { - return cssFormatter.format(item.contents, lint); - } + (item, index) => cssFormatter.format(item.contents, lint) ); }, - formatJs: function(scriptBlocks) { + formatJs(scriptBlocks) { var jsFormatter = new Formatter.JS(this.file, this.logger, this.flags, this._config); jsFormatter._config = this._config; @@ -206,13 +204,11 @@ Formatter.HTML = Formatter.create( jsFormatter.lintLogFilter = this._jsLogFilter.bind(this); return scriptBlocks.map( - function(item, index) { - return jsFormatter.format(item.contents, lint); - } + (item, index) => jsFormatter.format(item.contents, lint) ); }, - parseCSS: function(contents) { + parseCSS(contents) { var styleBlocks = this.extractCSS(contents); styleBlocks = this.sanitizeStyleBlocks(styleBlocks); @@ -221,7 +217,7 @@ Formatter.HTML = Formatter.create( return styleBlocks; }, - parseJs: function(contents) { + parseJs(contents) { var scriptBlocks = this.extractJs(contents); scriptBlocks = this.sanitizeScriptBlocks(scriptBlocks); @@ -230,13 +226,13 @@ Formatter.HTML = Formatter.create( return scriptBlocks; }, - sanitizeScriptBlocks: function(scriptBlocks) { + sanitizeScriptBlocks(scriptBlocks) { var instance = this; var token = 'void 0;'; scriptBlocks = scriptBlocks.map( - function(item, index) { + (item, index) => { item = instance._jsIterateRules(item); item = instance._jsRemoveScriptletBlocks(item); @@ -251,7 +247,7 @@ Formatter.HTML = Formatter.create( contents = contents.substr(0, lastIndex); } - item.contents = contents; + item.contents = contents; return item; } @@ -260,13 +256,13 @@ Formatter.HTML = Formatter.create( return scriptBlocks; }, - sanitizeStyleBlocks: function(styleBlocks) { + sanitizeStyleBlocks(styleBlocks) { var instance = this; var token = 'void: 0;'; styleBlocks = styleBlocks.map( - function(item, index) { + (item, index) => { item = instance._jsRemoveScriptletBlocks(item); item = instance._jsHandleScriptletWhitespace(item); item = instance._jsPadLines(item, token); @@ -279,7 +275,7 @@ Formatter.HTML = Formatter.create( contents = contents.substr(0, lastIndex); } - item.contents = contents; + item.contents = contents; return item; } @@ -288,13 +284,13 @@ Formatter.HTML = Formatter.create( return styleBlocks; }, - _attrCheckOrder: function(attrName, lastAttr, line, lineNum) { + _attrCheckOrder(attrName, lastAttr, line, lineNum) { var needsSort = false; if (lastAttr > attrName) { var filePath = this.file; - var regex = new RegExp('\\b' + lastAttr + '\\b.*?> ?<.*?' + attrName); + var regex = new RegExp(`\\b${lastAttr}\\b.*?> ?<.*?${attrName}`); var note = ''; @@ -312,17 +308,17 @@ Formatter.HTML = Formatter.create( return needsSort; }, - _attrCleanTokens: function(value) { + _attrCleanTokens(value) { var token = this._TOKEN; var nsToken = this._NS_TOKEN; - value = value.replace(new RegExp(token + '(\\d+)' + token, 'g'), '<%...%>'); - value = value.replace(new RegExp(nsToken + '(\\d+)' + nsToken, 'g'), ''); + value = value.replace(new RegExp(`${token}(\\d+)${token}`, 'g'), '<%...%>'); + value = value.replace(new RegExp(`${nsToken}(\\d+)${nsToken}`, 'g'), ''); return value; }, - _attrGetMapEntry: function(lineNum) { + _attrGetMapEntry(lineNum) { var attrMapEntry = this._attrMap[lineNum]; if (!attrMapEntry) { @@ -334,12 +330,12 @@ Formatter.HTML = Formatter.create( return attrMapEntry; }, - _attrRemoveScriptlets: function(line, lineNum) { + _attrRemoveScriptlets(line, lineNum) { var token = this._TOKEN; var index = 0; - var mapTokens = function(item) { + var mapTokens = item => { line = line.replace(item, token + (index++) + token); return item; @@ -350,7 +346,7 @@ Formatter.HTML = Formatter.create( /\$\{.*?\}/g, /\{{1,3}[^}]+\}{1,3}/g ].reduce( - function(prev, item, index) { + (prev, item, index) => { var m = line.match(item); var matches = m && m.map(mapTokens); @@ -373,13 +369,13 @@ Formatter.HTML = Formatter.create( return line; }, - _attrRemoveTags: function(line, lineNum) { + _attrRemoveTags(line, lineNum) { var nsm = line.match(new RegExp(REGEX_JSP_PORTLET_NAMESPACE.source)); var nsToken = this._NS_TOKEN; var nsMatches = nsm && nsm.map( - function(item, index) { + (item, index) => { line = line.replace(item, nsToken + index + nsToken); return item; @@ -393,7 +389,7 @@ Formatter.HTML = Formatter.create( return line; }, - _attrRestoreScriptlets: function(line, lineNum) { + _attrRestoreScriptlets(line, lineNum) { var attrMapEntry = this._attrGetMapEntry(lineNum); var matches = attrMapEntry.matches; @@ -402,17 +398,15 @@ Formatter.HTML = Formatter.create( var token = this._TOKEN; line = line.replace( - new RegExp(token + '(\\d+)' + token, 'g'), - function(str, id) { - return matches[id]; - } + new RegExp(`${token}(\\d+)${token}`, 'g'), + (str, id) => matches[id] ); } return line; }, - _attrRestoreTags: function(line, lineNum) { + _attrRestoreTags(line, lineNum) { var attrMapEntry = this._attrGetMapEntry(lineNum); var nsMatches = attrMapEntry.nsMatches; @@ -421,17 +415,15 @@ Formatter.HTML = Formatter.create( var nsToken = this._NS_TOKEN; line = line.replace( - new RegExp(nsToken + '(\\d+)' + nsToken, 'g'), - function(str, id) { - return nsMatches[id]; - } + new RegExp(`${nsToken}(\\d+)${nsToken}`, 'g'), + (str, id) => nsMatches[id] ); } return line; }, - _attrSortValues: function(attrName, attrValue, item, line, lineNum) { + _attrSortValues(attrName, attrValue, item, line, lineNum) { var instance = this; if (!MAP_IGNORE_ATTR_VALUES.hasOwnProperty(attrName)) { @@ -455,7 +447,7 @@ Formatter.HTML = Formatter.create( var filePath = this.file; attrValuePieces.forEach( - function(item, index, collection) { + (item, index, collection) => { item = item.trim(); if (/^[A-Za-z]/.test(item)) { // Skip event handlers like onClick, labels, or any attr value @@ -465,7 +457,7 @@ Formatter.HTML = Formatter.create( var tmpLastAttrPiece = instance._attrCleanTokens(lastAttrPiece); var tmpItem = instance._attrCleanTokens(item); - instance.log(lineNum, sub('Sort attribute values: {0} {1}', tmpLastAttrPiece, tmpItem)); + instance.log(lineNum, sub('Sort attribute values: {0} {1}', tmpLastAttrPiece, tmpItem)); sort = true; } @@ -479,15 +471,13 @@ Formatter.HTML = Formatter.create( if (sort) { attrValuePieces = attrValuePieces.filter( - function(item, index, collection) { - return !!item.trim(); - } + (item, index, collection) => !!item.trim() ); attrValuePieces.sort(); if (styleAttr) { - newAttrValue = attrValuePieces.join('; ') + ';'; + newAttrValue = `${attrValuePieces.join('; ')};`; } else { newAttrValue = attrValuePieces.join(' '); @@ -500,17 +490,17 @@ Formatter.HTML = Formatter.create( return item; }, - _getScriptletBlockReplacement: function(length) { + _getScriptletBlockReplacement(length) { return scriptletBlockOpen + (new Array(length).join('\nvoid 0;')) + scriptletBlockClose; }, - _jsCommentSingleLineScriptlets: function(lines) { + _jsCommentSingleLineScriptlets(lines) { var re = this._re; return lines.map( - function(item, index) { + (item, index) => { if (REGEX.SCRIPTLET_STUB.test(item)) { - item = '//' + item; + item = `//${item}`; } return item; @@ -518,7 +508,7 @@ Formatter.HTML = Formatter.create( ); }, - _jsFindScriptletBlock: function(contents) { + _jsFindScriptletBlock(contents) { var scriptBlockRe = /<%/g; var match; @@ -533,7 +523,7 @@ Formatter.HTML = Formatter.create( return contents; }, - _jsFindScriptletClose: function(contents, matchIndex) { + _jsFindScriptletClose(contents, matchIndex) { for (var i = matchIndex; i < contents.length; i++) { var item = contents.charAt(i); @@ -549,7 +539,7 @@ Formatter.HTML = Formatter.create( return contents; }, - _jsIgnoreEndNewlines: function(lines) { + _jsIgnoreEndNewlines(lines) { var numLines = lines.length; if (lines[numLines - 2] === '' && lines[numLines - 3].indexOf('void 0; */') > -1) { @@ -559,7 +549,7 @@ Formatter.HTML = Formatter.create( return lines; }, - _jsIgnoreStartNewlines: function(lines) { + _jsIgnoreStartNewlines(lines) { var numLines = lines.length; if (lines[1] === '' && lines[2].indexOf(scriptletBlockOpen) > -1) { @@ -569,18 +559,18 @@ Formatter.HTML = Formatter.create( return lines; }, - _jsIsScriptletCloseToken: function(item, prev) { + _jsIsScriptletCloseToken(item, prev) { return item && item == '>' && prev == '%'; }, - _jsHandleScriptletWhitespace: function(scriptBlock) { + _jsHandleScriptletWhitespace(scriptBlock) { var contents = scriptBlock.contents; // Let's check to see if we have new new lines at the start // or end of a script block due to scriptlet blocks, ie: // // - // <% if() { %> + // <% if() { %> // ... // <% } %> // @@ -609,7 +599,7 @@ Formatter.HTML = Formatter.create( return scriptBlock; }, - _jsIterateRules: function(scriptBlock) { + _jsIterateRules(scriptBlock) { var instance = this; var contents = scriptBlock.contents; @@ -627,22 +617,22 @@ Formatter.HTML = Formatter.create( iterateLines( contents, - function(content, index) { + (content, index) => { var rawContent = content; var lineNum = startLine + index; content = content.trim(); var context = { - asyncAUIScript: asyncAUIScript, + asyncAUIScript, body: contents, - content: content, - file: file, + content, + file, fullMatch: match, - lineNum: lineNum, - rawContent: rawContent, - scriptAttrs: scriptAttrs, - tagNamespace: tagNamespace + lineNum, + rawContent, + scriptAttrs, + tagNamespace }; rawContent = re.iterateRules('htmlJS', context); @@ -652,7 +642,7 @@ Formatter.HTML = Formatter.create( return scriptBlock; }, - _jsLogFilter: function(item) { + _jsLogFilter(item) { var message = item.message; item.message = item.message.replace(/\b_PN_(\w+)\b/g, '$1'); @@ -660,15 +650,15 @@ Formatter.HTML = Formatter.create( return item; }, - _jsPadLines: function(scriptBlock, token) { - var prefix = new Array(scriptBlock.startLine).join(token + '\n'); + _jsPadLines(scriptBlock, token) { + var prefix = new Array(scriptBlock.startLine).join(`${token}\n`); scriptBlock.contents = prefix + scriptBlock.contents; return scriptBlock; }, - _jsRemoveScriptletBlocks: function(scriptBlock) { + _jsRemoveScriptletBlocks(scriptBlock) { var instance = this; var rescanBlocks = []; @@ -677,13 +667,11 @@ Formatter.HTML = Formatter.create( contents = contents.replace( /\$\{.*?\}/g, - function(m, index, str) { - return jspLintStubs.elExpression + index; - } + (m, index, str) => jspLintStubs.elExpression + index ) .replace( /<%[^>]+>/g, - function(m, index) { + (m, index) => { var len = m.length; var retVal = m; @@ -713,7 +701,7 @@ Formatter.HTML = Formatter.create( return scriptBlock; }, - _processAttrs: function(line, lineNum) { + _processAttrs(line, lineNum) { var instance = this; var filePath = this.file; @@ -722,7 +710,7 @@ Formatter.HTML = Formatter.create( line = line.replace( /<[^>]+>/g, - function(m, mi, str) { + (m, mi, str) => { var attrs = m.match(/(?: )?([A-Za-z0-9-]+=(["']).*?\2)/g); if (attrs) { @@ -731,7 +719,7 @@ Formatter.HTML = Formatter.create( var trackSort = {}; attrs = attrs.map( - function(item, index, collection) { + (item, index, collection) => { var oldItem = item; var pieces = item.trim().match(/^([^=]+)=(["'])(.*)\2$/); @@ -765,24 +753,24 @@ Formatter.HTML = Formatter.create( return line; }, - _sortAttrs: function(line, attrs) { + _sortAttrs(line, attrs) { var instance = this; var sortedAttrs = []; attrs.forEach( - function(item, index) { + (item, index) => { sortedAttrs.push(item); - line = line.replace(item, '__' + index + '__'); + line = line.replace(item, `__${index}__`); } ); sortedAttrs.sort(); sortedAttrs.forEach( - function(item, index) { - line = line.replace('__' + index + '__', item); + (item, index) => { + line = line.replace(`__${index}__`, item); } ); diff --git a/lib/js.js b/lib/js.js index 18a7606..3278c37 100644 --- a/lib/js.js +++ b/lib/js.js @@ -14,7 +14,7 @@ var sub = require('string-sub'); var jsonf = _.bindKeyRight( JSON, 'stringify', - function(key, value) { + (key, value) => { if (key === 'start' || key === 'end') { return value.line; } @@ -31,17 +31,17 @@ Formatter.JS = Formatter.create( id: 'js', includes: /\.js$/, prototype: { - init: function() { + init() { this.processor = {}; }, - format: function(contents, lint) { + format(contents, lint) { var hasSheBang = this._hasSheBang(contents); var rawContents = contents; if (hasSheBang) { - contents = '//' + contents; + contents = `//${contents}`; } var filePath = this.file; @@ -52,7 +52,7 @@ Formatter.JS = Formatter.create( customIgnore: re.rules.js.IGNORE, file: filePath, fileConfig: this._config, - hasSheBang: hasSheBang, + hasSheBang, lintConfig: this.flags.lint !== false && lint }; @@ -70,7 +70,7 @@ Formatter.JS = Formatter.create( var newContents = iterateLines( contents, - function(content, index, collection) { + (content, index, collection) => { var rawContent = content; content = content.trim(); @@ -101,11 +101,11 @@ Formatter.JS = Formatter.create( return newContents; }, - _hasSheBang: function(contents) { + _hasSheBang(contents) { return contents && contents[0] === '#' && contents[1] === '!'; }, - _lint: function(contents, context) { + _lint(contents, context) { var lint = context.lintConfig; if (lint !== false) { @@ -129,7 +129,7 @@ Formatter.JS = Formatter.create( return contents; }, - _logLintResults: function(results) { + _logLintResults(results) { var instance = this; var lintLogFilter = instance.lintLogFilter; @@ -139,7 +139,7 @@ Formatter.JS = Formatter.create( } results.forEach( - function(item, index) { + (item, index) => { if (lintLogFilter) { item = lintLogFilter(item); } @@ -157,15 +157,13 @@ Formatter.JS = Formatter.create( ); }, - _printAsSource: function(contents) { + _printAsSource(contents) { return contents.split(REGEX.NEWLINE).map( - function(item, index) { - return (index + 1) + ' ' + item; - } + (item, index) => `${index + 1} ${item}` ).join('\n'); }, - _processSyntax: function(contents) { + _processSyntax(contents) { var instance = this; try { @@ -177,7 +175,7 @@ Formatter.JS = Formatter.create( loc: true, tolerant: true }, - function(node) { + node => { var parent = node.parent; var type = node.type; diff --git a/lib/lint_css.js b/lib/lint_css.js index ff82df3..629802c 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -8,7 +8,7 @@ var ruleUtils = require('./rule_utils'); var customRules = {}; -var runLinter = function(contents, file, context) { +var runLinter = (contents, file, context) => { var customRules = context.customRules || {}; _.merge(stylelint.rules, customRules); @@ -21,13 +21,13 @@ var runLinter = function(contents, file, context) { configs.push(config); } - config = _.merge.apply(_, configs); + config = _.merge(...configs); return stylelint.lint( { code: contents, codeFileName: file, - config: config, + config, configBasedir: path.resolve(__dirname, '..'), formatter: 'json', syntax: 'scss' @@ -39,14 +39,14 @@ var globOptions = { cwd: __dirname }; -module.exports = function(contents, file, context) { +module.exports = (contents, file, context) => { context.customRules = customRules; glob.sync( './lint_css_rules/*.js', globOptions ).forEach( - function(item, index) { + (item, index) => { var id = ruleUtils.getRuleId(item); customRules[id] = require(item); diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 65a9d7b..3a1e995 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -13,7 +13,7 @@ var slUtils = stylelint.utils; var jsonf = _.bindKeyRight( JSON, 'stringify', - function(key, value) { + (key, value) => { if (key === 'start' || key === 'end') { return value.line; } @@ -24,10 +24,10 @@ var jsonf = _.bindKeyRight( 4 ); -module.exports = function(expectation, options) { +module.exports = (expectation, options) => { var atRuleFn = stylelint.rules['at-rule-empty-line-before'](expectation, options); - return function(root, result) { + return (root, result) => { var messages = slUtils.ruleMessages( ruleName, { @@ -53,13 +53,9 @@ module.exports = function(expectation, options) { } ); - var getLineDistance = function(left, right) { - return right.source.start.line - left.source.end.line; - }; + var getLineDistance = (left, right) => right.source.start.line - left.source.end.line; - var isSingleLineRule = function(node) { - return node.source.start.line === node.source.end.line; - }; + var isSingleLineRule = node => node.source.start.line === node.source.end.line; var validLines = []; @@ -67,7 +63,7 @@ module.exports = function(expectation, options) { var otherResults = atRuleFn(root, result); root.walkAtRules( - function(node) { + node => { if (node !== root.first) { var startLine = node.source.start.line; @@ -89,9 +85,7 @@ module.exports = function(expectation, options) { result.messages = _.reject( result.messages, - function(item, index) { - return item.rule === 'at-rule-empty-line-before' && _.includes(validLines, item.line); - } + (item, index) => item.rule === 'at-rule-empty-line-before' && _.includes(validLines, item.line) ); return result; diff --git a/lib/lint_js.js b/lib/lint_js.js index dbe9ce0..daa73f0 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -13,12 +13,12 @@ var reactRules = require('eslint-plugin-react').rules; _.defaults(customRules, reactRules); -var loadPlugin = function(pluginName, configPath) { +var loadPlugin = (pluginName, configPath) => { var rules; if (pluginName !== 'react') { if (pluginName.indexOf('eslint-plugin-') === -1) { - pluginName = 'eslint-plugin-' + pluginName; + pluginName = `eslint-plugin-${pluginName}`; } var baseName = pluginName.replace('eslint-plugin-', ''); @@ -40,9 +40,7 @@ var loadPlugin = function(pluginName, configPath) { if (rules) { rules = _.mapKeys( rules, - function(item, index) { - return baseName + '/' + index; - } + (item, index) => `${baseName}/${index}` ); eslint.linter.defineRules(rules); @@ -52,7 +50,7 @@ var loadPlugin = function(pluginName, configPath) { return rules; }; -var runLinter = function(contents, file, context) { +var runLinter = (contents, file, context) => { var customRules = context.customRules || {}; eslint.linter.defineRules(customRules); @@ -80,7 +78,7 @@ var runLinter = function(contents, file, context) { } configs.push( - function(objValue, srcValue, key) { + (objValue, srcValue, key) => { var retVal; if (key === 'plugins' && _.isArray(objValue) && _.isArray(srcValue)) { @@ -91,7 +89,7 @@ var runLinter = function(contents, file, context) { } ); - config = _.mergeWith.apply(_, configs); + config = _.mergeWith(...configs); if (config.plugins) { var configPath = _.get(context, 'fileConfig._paths.obj.filepath'); @@ -101,7 +99,7 @@ var runLinter = function(contents, file, context) { } config.plugins.forEach( - function(item, index) { + (item, index) => { loadPlugin(item, configPath); } ); @@ -118,8 +116,8 @@ var runLinter = function(contents, file, context) { } return { - contents: contents, - results: results + contents, + results }; }; @@ -127,14 +125,14 @@ var globOptions = { cwd: __dirname }; -module.exports = function(contents, file, context) { +module.exports = (contents, file, context) => { context.customRules = customRules; glob.sync( './lint_js_rules/*.js', globOptions ).forEach( - function(item, index) { + (item, index) => { var id = ruleUtils.getRuleId(item); customRules[id] = require(item); diff --git a/lib/lint_js_rules/array_spacing.js b/lib/lint_js_rules/array_spacing.js index e8b46f2..9399098 100644 --- a/lib/lint_js_rules/array_spacing.js +++ b/lib/lint_js_rules/array_spacing.js @@ -5,51 +5,47 @@ var REGEX = require('../regex'); var sub = require('string-sub'); -var isSingleLine = function(node) { - return node.loc.start.line === node.loc.end.line; -}; - -module.exports = function(context) { - return { - ArrayExpression: function(node) { - var source = context.getSource(node); - - if (isSingleLine(node) && REGEX.ARRAY_SURROUNDING_SPACE.test(source)) { - var brackets = []; - var surroundingSpaceTypes = []; - - source.replace( - REGEX.ARRAY_SURROUNDING_SPACE, - function(item, index, str) { - var startIndex = 0; - var endIndex = str.length; - - var leadingSpace = item.indexOf('[') > -1; - - if (leadingSpace) { - endIndex = index + 1; - surroundingSpaceTypes.push('leading'); - } - else { - startIndex = index + 1; - surroundingSpaceTypes.push('trailing'); - brackets.push('...'); - } - - brackets.push(str.substring(startIndex, endIndex)); - - if (leadingSpace) { - brackets.push('...'); - } +var isSingleLine = node => node.loc.start.line === node.loc.end.line; + +module.exports = context => ({ + ArrayExpression(node) { + var source = context.getSource(node); + + if (isSingleLine(node) && REGEX.ARRAY_SURROUNDING_SPACE.test(source)) { + var brackets = []; + var surroundingSpaceTypes = []; + + source.replace( + REGEX.ARRAY_SURROUNDING_SPACE, + (item, index, str) => { + var startIndex = 0; + var endIndex = str.length; + + var leadingSpace = item.indexOf('[') > -1; + + if (leadingSpace) { + endIndex = index + 1; + surroundingSpaceTypes.push('leading'); + } + else { + startIndex = index + 1; + surroundingSpaceTypes.push('trailing'); + brackets.push('...'); + } + + brackets.push(str.substring(startIndex, endIndex)); + + if (leadingSpace) { + brackets.push('...'); } - ); + } + ); - brackets = _.uniq(brackets); + brackets = _.uniq(brackets); - var message = sub('Remove {0} spaces: {1}', surroundingSpaceTypes.join(' and '), brackets.join(' ')); + var message = sub('Remove {0} spaces: {1}', surroundingSpaceTypes.join(' and '), brackets.join(' ')); - context.report(node, message); - } + context.report(node, message); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/array_spacing_chars.js b/lib/lint_js_rules/array_spacing_chars.js index b1af72e..6d3f733 100644 --- a/lib/lint_js_rules/array_spacing_chars.js +++ b/lib/lint_js_rules/array_spacing_chars.js @@ -2,33 +2,29 @@ var sub = require('string-sub'); var REGEX = require('../regex'); -var isSingleLine = function(node) { - return node.loc.start.line === node.loc.end.line; -}; +var isSingleLine = node => node.loc.start.line === node.loc.end.line; -module.exports = function(context) { - return { - ArrayExpression: function(node) { - if (isSingleLine(node)) { - var source = context.getSource(node); +module.exports = context => ({ + ArrayExpression(node) { + if (isSingleLine(node)) { + var source = context.getSource(node); - var tmpSource = source.replace(/(['"]).*?\1/g, '$1$1'); + var tmpSource = source.replace(/(['"]).*?\1/g, '$1$1'); - if (REGEX.ARRAY_INTERNAL_SPACE.test(tmpSource)) { - var missingSpaces = []; + if (REGEX.ARRAY_INTERNAL_SPACE.test(tmpSource)) { + var missingSpaces = []; - source.replace( - REGEX.ARRAY_INTERNAL_SPACE, - function(item, index, str) { - missingSpaces.push(item.replace('\t', '\\t')); - } - ); + source.replace( + REGEX.ARRAY_INTERNAL_SPACE, + (item, index, str) => { + missingSpaces.push(item.replace('\t', '\\t')); + } + ); - var message = sub('Array items should be separated by exactly one space:{0}', missingSpaces.join('')); + var message = sub('Array items should be separated by exactly one space:{0}', missingSpaces.join('')); - context.report(node, message); - } + context.report(node, message); } } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/catch_arg_name.js b/lib/lint_js_rules/catch_arg_name.js index 4365d85..4d708a0 100644 --- a/lib/lint_js_rules/catch_arg_name.js +++ b/lib/lint_js_rules/catch_arg_name.js @@ -2,16 +2,14 @@ var base = require('../base'); var sub = require('string-sub'); -module.exports = function(context) { - return { - CatchClause: function(node) { - var paramName = node.param.name; +module.exports = context => ({ + CatchClause(node) { + var paramName = node.param.name; - if (paramName != 'e') { - var message = sub('Catch statement param should be "e", not "{0}"', paramName); + if (paramName != 'e') { + var message = sub('Catch statement param should be "e", not "{0}"', paramName); - context.report(node, message); - } + context.report(node, message); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/catch_format.js b/lib/lint_js_rules/catch_format.js index f192021..4a1d7cb 100644 --- a/lib/lint_js_rules/catch_format.js +++ b/lib/lint_js_rules/catch_format.js @@ -2,18 +2,16 @@ var base = require('../base'); var sub = require('string-sub'); -module.exports = function(context) { - return { - CatchClause: function(node) { - var start = node.loc.start.line; - var shouldEnd = start + 1; - var end = node.loc.end.line; +module.exports = context => ({ + CatchClause(node) { + var start = node.loc.start.line; + var shouldEnd = start + 1; + var end = node.loc.end.line; - if (!node.body.body.length && end != shouldEnd) { - var message = sub('Empty catch statement should be closed on line {0}', shouldEnd); + if (!node.body.body.length && end != shouldEnd) { + var message = sub('Empty catch statement should be closed on line {0}', shouldEnd); - context.report(node, message); - } + context.report(node, message); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/dot_notation.js b/lib/lint_js_rules/dot_notation.js index 452bbdb..4cf5ea3 100644 --- a/lib/lint_js_rules/dot_notation.js +++ b/lib/lint_js_rules/dot_notation.js @@ -1,16 +1,14 @@ var REGEX = require('../regex'); -module.exports = function(context) { - return { - MemberExpression: function(node) { - var propertyValue = node.property.value; - var propertyType = node.property.type; +module.exports = context => ({ + MemberExpression(node) { + var propertyValue = node.property.value; + var propertyType = node.property.type; - if (propertyType === 'Literal' && !REGEX.STUBS.test(propertyValue)) { - var dotNotation = require('eslint/lib/rules/dot-notation'); + if (propertyType === 'Literal' && !REGEX.STUBS.test(propertyValue)) { + var dotNotation = require('eslint/lib/rules/dot-notation'); - dotNotation.create(context).MemberExpression(node); - } + dotNotation.create(context).MemberExpression(node); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/format_args.js b/lib/lint_js_rules/format_args.js index db86a7d..0a7fa7c 100644 --- a/lib/lint_js_rules/format_args.js +++ b/lib/lint_js_rules/format_args.js @@ -3,16 +3,12 @@ var base = require('../base'); var sub = require('string-sub'); -module.exports = function(context) { - var isFunctionExpression = function(type) { - return _.endsWith(type, 'FunctionExpression'); - }; +module.exports = context => { + var isFunctionExpression = type => _.endsWith(type, 'FunctionExpression'); - var isCallable = function(type) { - return isFunctionExpression(type) || type === 'CallExpression'; - }; + var isCallable = type => isFunctionExpression(type) || type === 'CallExpression'; - var getAnonymousFnName = function(fnName) { + var getAnonymousFnName = fnName => { if (!fnName) { fnName = ''; } @@ -22,7 +18,7 @@ module.exports = function(context) { var sc = context.getSourceCode(); - var getFnExpLines = function(lineBounds, node) { + var getFnExpLines = (lineBounds, node) => { var end = lineBounds.end; var start = lineBounds.start; @@ -32,7 +28,7 @@ module.exports = function(context) { if (node.arguments && node.arguments.length) { node.arguments.forEach( - function(item, index) { + (item, index) => { var type = item.type; if (isCallable(type)) { @@ -55,7 +51,7 @@ module.exports = function(context) { return lineBounds; }; - var getFnLines = function(node) { + var getFnLines = node => { var lineBounds = getLineBounds(node); var callee = node.callee; @@ -80,7 +76,7 @@ module.exports = function(context) { return lineBounds; }; - var getFnName = function(callee) { + var getFnName = callee => { var fnName = callee.name; if (!fnName && callee.id) { @@ -102,7 +98,7 @@ module.exports = function(context) { return fnName; }; - var getLineBounds = function(loc, prop) { + var getLineBounds = (loc, prop) => { var val = {}; loc = loc.loc || loc; @@ -117,7 +113,7 @@ module.exports = function(context) { return val; }; - var getMethodName = function(callee) { + var getMethodName = callee => { var fnName = callee.property.name; if (!fnName && callee.object.callee) { @@ -127,7 +123,7 @@ module.exports = function(context) { return fnName; }; - var getMultiLineError = function(error, loc, options) { + var getMultiLineError = (error, loc, options) => { var argStart = loc.start; var argEnd = loc.end; var fnStart = options.start; @@ -145,7 +141,7 @@ module.exports = function(context) { return error; }; - var logArgError = function(fnLines, fnName, node) { + var logArgError = (fnLines, fnName, node) => { var message; var obj = processArgs(node.arguments, fnLines, node); @@ -159,7 +155,7 @@ module.exports = function(context) { } }; - var processArgs = function(args, options, node) { + var processArgs = (args, options, node) => { var obj = {}; var fnStart = options.start; @@ -180,7 +176,7 @@ module.exports = function(context) { var error = ''; args.forEach( - function(item, index) { + (item, index) => { var type = item.type; var loc = getLineBounds(item.loc); @@ -226,7 +222,7 @@ module.exports = function(context) { }; return { - CallExpression: function(node) { + CallExpression(node) { var callee = node.callee; var fnName = getFnName(callee); diff --git a/lib/lint_js_rules/format_constants.js b/lib/lint_js_rules/format_constants.js index 799d1fa..fbca457 100644 --- a/lib/lint_js_rules/format_constants.js +++ b/lib/lint_js_rules/format_constants.js @@ -1,12 +1,12 @@ var base = require('../base'); var utils = require('../rule_utils'); -module.exports = function(context) { - var checkDistance = function(node) { +module.exports = context => { + var checkDistance = node => { var constants = utils.getConstants(node); constants.forEach( - function(item, index, coll) { + (item, index, coll) => { var prev = coll[index - 1]; if (prev) { diff --git a/lib/lint_js_rules/format_multiline_vars.js b/lib/lint_js_rules/format_multiline_vars.js index e7a9b86..7e8a997 100644 --- a/lib/lint_js_rules/format_multiline_vars.js +++ b/lib/lint_js_rules/format_multiline_vars.js @@ -1,4 +1,4 @@ -var findFirstofLastLine = function(tokens, line) { +var findFirstofLastLine = (tokens, line) => { var firstOfLast = null; for (var i = 0, len = tokens.length; i < len; i++) { @@ -14,18 +14,16 @@ var findFirstofLastLine = function(tokens, line) { return firstOfLast; }; -var isSameColumn = function(a, b, requireKeyword) { +var isSameColumn = (a, b, requireKeyword) => { var inc = requireKeyword ? 3 : 0; return a.loc.start.column === (b.loc.start.column + inc); }; -var isSameLine = function(a, b) { - return a.loc.start.line === b.loc.start.line; -}; +var isSameLine = (a, b) => a.loc.start.line === b.loc.start.line; -module.exports = function(context) { - var checkEndColumn = function(declaration, init, node) { +module.exports = context => { + var checkEndColumn = (declaration, init, node) => { var decLoc = declaration.loc; var decStart = decLoc.start; @@ -54,7 +52,7 @@ module.exports = function(context) { } }; - var checkStartLine = function(id, init, node) { + var checkStartLine = (id, init, node) => { var allowedFormat = isSameLine(id, init); if (!allowedFormat) { @@ -109,12 +107,12 @@ module.exports = function(context) { }; return { - AssignmentExpression: function(node) { + AssignmentExpression(node) { checkStartLine(node.left, node.right, node); checkEndColumn(node, node.right, node); }, - VariableDeclaration: function(node) { + VariableDeclaration(node) { var declarations = node.declarations; var dec = declarations[0]; diff --git a/lib/lint_js_rules/function_spacing.js b/lib/lint_js_rules/function_spacing.js index c380f0a..57e566a 100644 --- a/lib/lint_js_rules/function_spacing.js +++ b/lib/lint_js_rules/function_spacing.js @@ -3,8 +3,8 @@ var utils = require('../rule_utils'); var sub = require('string-sub'); module.exports = { - create: function(context) { - var testFunctionSpacing = function(node) { + create(context) { + var testFunctionSpacing = node => { var nodeBody = node.body; var fnBody = nodeBody.body; @@ -42,9 +42,9 @@ module.exports = { context.report( { - fix: fix, + fix, message: sub('There should be exactly one line between the start of the function and the first statement, not {0} lines', startLineDistance), - node: node + node } ); } @@ -67,7 +67,7 @@ module.exports = { context.report( { - fix: fix, + fix, message: sub('There should be exactly one line between the last statement and the end of the function, not {0} lines', endLineDistance), node: lastStatement } diff --git a/lib/lint_js_rules/liferay_language_get.js b/lib/lint_js_rules/liferay_language_get.js index 989308f..8f3b966 100644 --- a/lib/lint_js_rules/liferay_language_get.js +++ b/lib/lint_js_rules/liferay_language_get.js @@ -1,12 +1,10 @@ -module.exports = function(context) { +module.exports = context => { var REGEX_STRING = /^(['"]).*\1$/; - var isMemberExpression = function(obj) { - return obj.type === 'MemberExpression'; - }; + var isMemberExpression = obj => obj.type === 'MemberExpression'; return { - CallExpression: function(node) { + CallExpression(node) { var callee = node.callee; if (isMemberExpression(callee) && isMemberExpression(callee.object) && callee.object.object.name === 'Liferay' && callee.object.property.name === 'Language' && callee.property.name === 'get') { diff --git a/lib/lint_js_rules/liferay_provide_format.js b/lib/lint_js_rules/liferay_provide_format.js index 64d2a9e..c6075d2 100644 --- a/lib/lint_js_rules/liferay_provide_format.js +++ b/lib/lint_js_rules/liferay_provide_format.js @@ -1,47 +1,45 @@ -module.exports = function(context) { - return { - CallExpression: function(node) { - var callee = node.callee; +module.exports = context => ({ + CallExpression(node) { + var callee = node.callee; - if (callee.type === 'MemberExpression' && callee.object.name === 'Liferay' && callee.property.name === 'provide') { - var args = node.arguments; + if (callee.type === 'MemberExpression' && callee.object.name === 'Liferay' && callee.property.name === 'provide') { + var args = node.arguments; - if (args.length < 4) { - context.report(node, 'Missing dependencies (don\'t use Liferay.provide to create regular functions).'); + if (args.length < 4) { + context.report(node, 'Missing dependencies (don\'t use Liferay.provide to create regular functions).'); + } + else { + var arg0 = args[0]; + var arg1 = args[1]; + var arg2 = args[2]; + var arg3 = args[3]; + + var arg0Type = arg0.type; + var arg1Type = arg1.type; + var arg2Type = arg2.type; + var arg3Type = arg3.type; + + if (arg0Type !== 'Identifier' && arg0Type !== 'MemberExpression') { + context.report(arg0, 'Liferay.provide expects an object as the first argument.'); + } + + if (arg1Type !== 'Identifier' && typeof arg1.value !== 'string') { + context.report(arg1, 'Liferay.provide expects a string as the second argument.'); + } + + if (arg2Type !== 'Identifier' && arg2Type !== 'FunctionExpression') { + context.report(arg2, 'Liferay.provide expects a function as the third argument.'); + } + + var arg3TypeExpression = arg3Type === 'CallExpression'; + + if (arg3Type !== 'Identifier' && arg3Type !== 'ArrayExpression' && !arg3TypeExpression || arg3TypeExpression && arg3.callee.object.type !== 'ArrayExpression') { + context.report(arg3, 'Liferay.provide expects an array as the last argument.'); } - else { - var arg0 = args[0]; - var arg1 = args[1]; - var arg2 = args[2]; - var arg3 = args[3]; - - var arg0Type = arg0.type; - var arg1Type = arg1.type; - var arg2Type = arg2.type; - var arg3Type = arg3.type; - - if (arg0Type !== 'Identifier' && arg0Type !== 'MemberExpression') { - context.report(arg0, 'Liferay.provide expects an object as the first argument.'); - } - - if (arg1Type !== 'Identifier' && typeof arg1.value !== 'string') { - context.report(arg1, 'Liferay.provide expects a string as the second argument.'); - } - - if (arg2Type !== 'Identifier' && arg2Type !== 'FunctionExpression') { - context.report(arg2, 'Liferay.provide expects a function as the third argument.'); - } - - var arg3TypeExpression = arg3Type === 'CallExpression'; - - if (arg3Type !== 'Identifier' && arg3Type !== 'ArrayExpression' && !arg3TypeExpression || arg3TypeExpression && arg3.callee.object.type !== 'ArrayExpression') { - context.report(arg3, 'Liferay.provide expects an array as the last argument.'); - } - else if (arg3Type === 'ArrayExpression' && !arg3.elements.length) { - context.report(arg3, 'Liferay.provide dependencies should have at least one dependency.'); - } + else if (arg3Type === 'ArrayExpression' && !arg3.elements.length) { + context.report(arg3, 'Liferay.provide dependencies should have at least one dependency.'); } } } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/multiple_vars.js b/lib/lint_js_rules/multiple_vars.js index 751e023..af0af3d 100644 --- a/lib/lint_js_rules/multiple_vars.js +++ b/lib/lint_js_rules/multiple_vars.js @@ -2,22 +2,18 @@ var base = require('../base'); var sub = require('string-sub'); -module.exports = function(context) { - return { - VariableDeclaration: function(node) { - var declarations = node.declarations; +module.exports = context => ({ + VariableDeclaration(node) { + var declarations = node.declarations; - if (declarations.length > 1) { - var vars = declarations.map( - function(item, index) { - return item.id.name; - } - ); + if (declarations.length > 1) { + var vars = declarations.map( + (item, index) => item.id.name + ); - var message = sub('Each variable should have it\'s own var statement: {0}', vars.join(', ')); + var message = sub('Each variable should have it\'s own var statement: {0}', vars.join(', ')); - context.report(node, message); - } + context.report(node, message); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/no_extra_semi.js b/lib/lint_js_rules/no_extra_semi.js index 3aedbf0..a5b77aa 100644 --- a/lib/lint_js_rules/no_extra_semi.js +++ b/lib/lint_js_rules/no_extra_semi.js @@ -1,11 +1,9 @@ -module.exports = function(context) { - return { - EmptyStatement: function(node) { - var afterText = context.getSource(node, 0, 10); +module.exports = context => ({ + EmptyStatement(node) { + var afterText = context.getSource(node, 0, 10); - if (afterText !== ';(function(') { - context.report(node, 'Unnecessary semicolon.'); - } + if (afterText !== ';(function(') { + context.report(node, 'Unnecessary semicolon.'); } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/no_is_prefix.js b/lib/lint_js_rules/no_is_prefix.js index 71f6d3c..a2d67fd 100644 --- a/lib/lint_js_rules/no_is_prefix.js +++ b/lib/lint_js_rules/no_is_prefix.js @@ -4,8 +4,8 @@ var REGEX = require('../regex'); var sub = require('string-sub'); -module.exports = function(context) { - var checkProcessVars = function(node) { +module.exports = context => { + var checkProcessVars = node => { var value = node.value; var valueType = value.type; @@ -27,7 +27,7 @@ module.exports = function(context) { return processVars; }; - var testVarNames = function(varName, node) { + var testVarNames = (varName, node) => { var pass = true; if (REGEX.VAR_IS.test(varName)) { @@ -38,11 +38,11 @@ module.exports = function(context) { return pass; }; - var testFunctionParams = function(node) { + var testFunctionParams = node => { var params = node.params; params.forEach( - function(item, index) { + (item, index) => { testVarNames(item.name, node); } ); @@ -53,7 +53,7 @@ module.exports = function(context) { FunctionDeclaration: testFunctionParams, - Property: function(node) { + Property(node) { if (node.value.type !== 'FunctionExpression') { var processVars = checkProcessVars(node); @@ -63,9 +63,9 @@ module.exports = function(context) { } }, - VariableDeclaration: function(node) { + VariableDeclaration(node) { node.declarations.forEach( - function(item, index) { + (item, index) => { var process = true; var varName = item.id.name; diff --git a/lib/lint_js_rules/no_multiple_return.js b/lib/lint_js_rules/no_multiple_return.js index bb45c22..be654ff 100644 --- a/lib/lint_js_rules/no_multiple_return.js +++ b/lib/lint_js_rules/no_multiple_return.js @@ -11,45 +11,45 @@ module.exports = { category: 'Fill me in', recommended: false }, - fixable: null, // or "code" or "whitespace" + fixable: null, // or "code" or "whitespace" schema: [ // fill in your schema ] }, - create: function(context) { + create(context) { var funcInfo = null; - var checkReturns = function(node) { + var checkReturns = node => { if (funcInfo.returnCount > 1) { context.report( { message: 'Functions should only have one return statement', - node: node + node } ); } }; return { - onCodePathStart: function(codePath) { + onCodePathStart(codePath) { funcInfo = { upper: funcInfo, returnCount: 0 }; }, - onCodePathEnd: function() { + onCodePathEnd() { funcInfo = funcInfo.upper; }, - ReturnStatement: function(node) { + ReturnStatement(node) { funcInfo.returnCount += 1; }, 'Program:exit': checkReturns, - 'FunctionDeclaration:exit': checkReturns, - 'FunctionExpression:exit': checkReturns, - 'ArrowFunctionExpression:exit': checkReturns + 'FunctionDeclaration:exit': checkReturns, + 'FunctionExpression:exit': checkReturns, + 'ArrowFunctionExpression:exit': checkReturns }; } }; \ No newline at end of file diff --git a/lib/lint_js_rules/no_undef.js b/lib/lint_js_rules/no_undef.js index c8c7089..1907a5d 100644 --- a/lib/lint_js_rules/no_undef.js +++ b/lib/lint_js_rules/no_undef.js @@ -3,13 +3,13 @@ var _ = require('lodash'); var base = require('../base'); var stubs = base.stubs; -module.exports = function(context) { +module.exports = context => { var noUndef = require('eslint/lib/rules/no-undef').create; var collectedReport = []; var mockContext = { - report: function(obj) { + report(obj) { collectedReport.push(obj); } }; @@ -21,7 +21,7 @@ module.exports = function(context) { noUndef(mockContext)['Program:exit'](node); collectedReport.forEach( - function(item, index) { + (item, index) => { var name = item.node.name; if (/_EL_EXPRESSION_\d+/.test(name)) { diff --git a/lib/lint_js_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js index 4b2a205..44548cf 100644 --- a/lib/lint_js_rules/no_unused_vars.js +++ b/lib/lint_js_rules/no_unused_vars.js @@ -4,10 +4,10 @@ var base = require('../base'); var stubs = base.stubs; var portletNS = base.jspLintStubs.namespace; -var STUB_RE = new RegExp('^' + Object.keys(stubs).join('|')); +var STUB_RE = new RegExp(`^${Object.keys(stubs).join('|')}`); module.exports = { - create: function(context) { + create(context) { function useInstance(node) { context.markVariableAsUsed('instance'); } @@ -25,7 +25,7 @@ module.exports = { var collectedReport = []; var mockContext = { - report: function(obj) { + report(obj) { collectedReport.push(obj); }, options: [{'vars': 'local', 'args': 'none'}] @@ -35,13 +35,13 @@ module.exports = { mockContext.getSourceCode = context.getSourceCode; - lintRules['Program:exit'] = function(node) { + lintRules['Program:exit'] = node => { noUnused(mockContext)['Program:exit'](node); // console.log(collectedReport); collectedReport.forEach( - function(item, index) { + (item, index) => { var declaration = item.node; var name = declaration.name; diff --git a/lib/lint_js_rules/no_use_before_define.js b/lib/lint_js_rules/no_use_before_define.js index 4f2c0ac..40fca9a 100644 --- a/lib/lint_js_rules/no_use_before_define.js +++ b/lib/lint_js_rules/no_use_before_define.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var base = require('../base'); var stubs = base.stubs; -module.exports = function(context) { +module.exports = context => { var noUse = require('eslint/lib/rules/no-use-before-define').create; var collectedReport = []; @@ -19,14 +19,14 @@ module.exports = function(context) { } var mockContext = { - report: function(obj) { + report(obj) { var report = true; if (sameScope) { var scope = mockContext.getScope(); scope.references.forEach( - function(reference) { + reference => { if (reference.identifier !== obj.node) { return; } @@ -54,7 +54,7 @@ module.exports = function(context) { defaultRule['Program:exit'](node); collectedReport.forEach( - function(item, index) { + (item, index) => { context.report(item); } ); diff --git a/lib/lint_js_rules/sort_constants.js b/lib/lint_js_rules/sort_constants.js index 3c78a8a..67029e6 100644 --- a/lib/lint_js_rules/sort_constants.js +++ b/lib/lint_js_rules/sort_constants.js @@ -6,9 +6,9 @@ var sub = require('string-sub'); var REGEX_UNDERSCORE = /_/g; -module.exports = function(context) { +module.exports = context => { // Recursive function for collecting identifiers from node - var getIdentifiers = function(node, obj) { + var getIdentifiers = (node, obj) => { obj = obj || {}; if (node) { @@ -45,13 +45,13 @@ module.exports = function(context) { return obj; }; - var checkSort = function(node) { + var checkSort = node => { var constants = utils.getConstants(node); var prevConstants = []; constants.forEach( - function(item, index, coll) { + (item, index, coll) => { var prev = coll[index - 1]; var itemName = item.id.name; @@ -65,9 +65,7 @@ module.exports = function(context) { var identifiers = getIdentifiers(item.init); var hasReference = prevConstants.some( - function(item, index) { - return identifiers[item]; - } + (item, index) => identifiers[item] ); if (!hasReference) { diff --git a/lib/lint_js_rules/sort_props.js b/lib/lint_js_rules/sort_props.js index 9d559ac..67ad549 100644 --- a/lib/lint_js_rules/sort_props.js +++ b/lib/lint_js_rules/sort_props.js @@ -6,7 +6,7 @@ var sub = require('string-sub'); var ruleUtils = require('../rule_utils'); -module.exports = function(context) { +module.exports = context => { var LIFECYCLE_METHODS = { init: -1100, initializer: -1000, @@ -62,7 +62,7 @@ module.exports = function(context) { // return names; // }; - var getPropName = function(obj) { + var getPropName = obj => { var propName = ''; // propName = getVals(obj, []).join(''); @@ -100,11 +100,9 @@ module.exports = function(context) { var sourceCode = context.getSourceCode(); - var getComputedPropertyName = function(obj) { - return sourceCode.getTokenBefore(obj).value + sourceCode.getText(obj) + sourceCode.getTokenAfter(obj).value; - }; + var getComputedPropertyName = obj => sourceCode.getTokenBefore(obj).value + sourceCode.getText(obj) + sourceCode.getTokenAfter(obj).value; - var inAttrs = function(parent) { + var inAttrs = parent => { var insideAttrs = false; var grandParent = parent && parent.parent; @@ -116,40 +114,28 @@ module.exports = function(context) { return insideAttrs; }; - var isFunctionExpression = function(obj) { - return obj.type === 'FunctionExpression' || obj.type === 'ArrowFunctionExpression'; - }; + var isFunctionExpression = obj => obj.type === 'FunctionExpression' || obj.type === 'ArrowFunctionExpression'; var isLifecycle = _.memoize( - function(propName, prevPropName) { - return (LIFECYCLE_METHODS.hasOwnProperty(propName) || LIFECYCLE_METHODS.hasOwnProperty(prevPropName)); - }, + (propName, prevPropName) => LIFECYCLE_METHODS.hasOwnProperty(propName) || LIFECYCLE_METHODS.hasOwnProperty(prevPropName), getCacheKey ); var isMatchingCase = _.memoize( - function(propName, prevPropName) { - return isUpper(propName) === isUpper(prevPropName); - }, + (propName, prevPropName) => isUpper(propName) === isUpper(prevPropName), getCacheKey ); - var isMatchingType = function(item, prev) { - return isFunctionExpression(prev.value) === isFunctionExpression(item.value); - }; + var isMatchingType = (item, prev) => isFunctionExpression(prev.value) === isFunctionExpression(item.value); var isPrivate = _.memoize( - function(str) { - return _.isString(str) && str.charAt(0) === '_'; - } + str => _.isString(str) && str.charAt(0) === '_' ); var RE_UPPER = /^[^a-z]+$/; var isUpper = _.memoize( - function(str) { - return RE_UPPER.test(str); - } + str => RE_UPPER.test(str) ); var naturalCompare = ruleUtils.naturalCompare; @@ -157,7 +143,7 @@ module.exports = function(context) { var configuration = context.options[0] || {}; var caseSensitive = configuration.casesensitive; - var checkLifecyleSort = function(needsSort, propName, prevPropName, item, prev, parent) { + var checkLifecyleSort = (needsSort, propName, prevPropName, item, prev, parent) => { var customPropName = LIFECYCLE_METHODS[propName]; var customPrevPropName = LIFECYCLE_METHODS[prevPropName]; @@ -173,7 +159,7 @@ module.exports = function(context) { return needsSort; }; - var checkRegPropSort = function(needsSort, propName, prevPropName, item, prev, caseSensitive, parent) { + var checkRegPropSort = (needsSort, propName, prevPropName, item, prev, caseSensitive, parent) => { var privateProp = isPrivate(propName); var privatePrevProp = isPrivate(prevPropName); @@ -191,7 +177,7 @@ module.exports = function(context) { return needsSort; }; - var checkSort = function(propName, prevPropName, item, prev, caseSensitive, parent) { + var checkSort = (propName, prevPropName, item, prev, caseSensitive, parent) => { var needsSort = false; if (isLifecycle(propName, prevPropName)) { @@ -209,11 +195,11 @@ module.exports = function(context) { }; return { - ObjectExpression: function(node) { + ObjectExpression(node) { var prev = null; node.properties.forEach( - function(item, index, collection) { + (item, index, collection) => { if (index > 0 && item.type !== 'ExperimentalSpreadProperty' && prev.type !== 'ExperimentalSpreadProperty') { var key = item.key; var prevKey = prev.key; diff --git a/lib/lint_js_rules/sort_requires.js b/lib/lint_js_rules/sort_requires.js index fb8cf94..12bf987 100644 --- a/lib/lint_js_rules/sort_requires.js +++ b/lib/lint_js_rules/sort_requires.js @@ -1,48 +1,46 @@ -module.exports = function(context) { - return { - Property: function(node) { - var nodeValue = node.value; - - if (node.key.name == 'requires' && nodeValue.type == 'ArrayExpression') { - var elements = nodeValue.elements; - - if (elements.length > 1) { - // I really, really hate having two loops here, - // but I can't think of any way to check only strings - // in an array, allowing for the off chance of non-string values - // ie. if the previous N items are not strings, you'll have to loop - // backwards anyways, but I would like to find a way to do - // this check all in one iteration - - var modules = []; - - elements.forEach( - function(item, index) { - if (item.type == 'Literal' && typeof item.value === 'string') { - modules.push(item.value); - } +module.exports = context => ({ + Property(node) { + var nodeValue = node.value; + + if (node.key.name == 'requires' && nodeValue.type == 'ArrayExpression') { + var elements = nodeValue.elements; + + if (elements.length > 1) { + // I really, really hate having two loops here, + // but I can't think of any way to check only strings + // in an array, allowing for the off chance of non-string values + // ie. if the previous N items are not strings, you'll have to loop + // backwards anyways, but I would like to find a way to do + // this check all in one iteration + + var modules = []; + + elements.forEach( + (item, index) => { + if (item.type == 'Literal' && typeof item.value === 'string') { + modules.push(item.value); } - ); + } + ); - var needsSort = []; + var needsSort = []; - modules.forEach( - function(item, index, collection) { - if (index > 0) { - var prevValue = collection[index - 1]; + modules.forEach( + (item, index, collection) => { + if (index > 0) { + var prevValue = collection[index - 1]; - if (item < prevValue) { - needsSort.push(prevValue + ' > ' + item); - } + if (item < prevValue) { + needsSort.push(`${prevValue} > ${item}`); } } - ); - - if (needsSort.length) { - context.report(node, 'Sort modules in "requires" array: ' + needsSort.join(', ')); } + ); + + if (needsSort.length) { + context.report(node, `Sort modules in "requires" array: ${needsSort.join(', ')}`); } } } - }; -}; \ No newline at end of file + } +}); \ No newline at end of file diff --git a/lib/lint_js_rules/sort_vars.js b/lib/lint_js_rules/sort_vars.js index da84821..ddfa860 100644 --- a/lib/lint_js_rules/sort_vars.js +++ b/lib/lint_js_rules/sort_vars.js @@ -10,7 +10,7 @@ var REGEX_FOR = /For.*Statement/; var REGEX_ASSIGNMENT_PATTERNS = /(Object|Array)Pattern/; -module.exports = function(context) { +module.exports = context => { var configuration = context.options[0] || {}; var caseSensitive = configuration.casesensitive; @@ -18,14 +18,14 @@ module.exports = function(context) { var destructuredVars = []; var imports = []; - var findVars = function(node) { + var findVars = node => { if (!REGEX_FOR.test(node.parent.type)) { var declarations = node.declarations; var specifiers = node.specifiers; if (declarations) { declarations.forEach( - function(val, key) { + (val, key) => { var varType = val.id.type; var destructuredVar = REGEX_ASSIGNMENT_PATTERNS.test(varType); @@ -35,9 +35,7 @@ module.exports = function(context) { } else if (destructuredVar && varType === 'ObjectPattern') { var props = val.id.properties.filter( - function(item, index) { - return item.key; - } + (item, index) => item.key ); destructuredVars.push(props); @@ -47,9 +45,7 @@ module.exports = function(context) { } else { specifiers = specifiers.filter( - function(item, index) { - return item.type !== 'ImportDefaultSpecifier'; - } + (item, index) => item.type !== 'ImportDefaultSpecifier' ); if (specifiers.length > 1) { @@ -62,7 +58,7 @@ module.exports = function(context) { return { 'Program:exit': function(){ var varGroups = variables.reduce( - function(prev, item, index) { + (prev, item, index) => { var lineDistance = getLineDistance(prev, item); if (lineDistance === 1 || lineDistance === 0) { @@ -84,9 +80,9 @@ module.exports = function(context) { ); destructuredVars.forEach( - function(item, index) { + (item, index) => { var destructuredVarGroups = item.reduce( - function(prev, item, index) { + (prev, item, index) => { var prevName = prev.key.name; var curName = item.key.name; @@ -106,9 +102,9 @@ module.exports = function(context) { ); imports.forEach( - function(item, index) { + (item, index) => { var importGroups = item.reduce( - function(prev, item, index) { + (prev, item, index) => { var prevName = prev.local.name; var curName = item.local.name; diff --git a/lib/logger.js b/lib/logger.js index 506af33..7fb6a21 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -4,7 +4,7 @@ var Logger = require('content-logger'); var contentLogger = Logger.create( { prototype: { - init: function() { + init() { this.testStats = { failures: 0 }; @@ -21,7 +21,7 @@ var contentLogger = Logger.create( ); }, - filterFileErrors: function(file, fn) { + filterFileErrors(file, fn) { var fileErrors; var errors = this.getErrors(file); diff --git a/lib/meta.js b/lib/meta.js index 3ecc61b..37da3ab 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -11,12 +11,12 @@ var INDENT = base.INDENT; var VERBOSE = argv.v; -var extractRequires = function(node) { +var extractRequires = node => { var requires = []; if (node && node.type == 'Property' && node.key.name == 'requires' && node.value && node.value.elements) { node.value.elements.forEach( - function(item, index) { + (item, index) => { requires.push(item.value); } ); @@ -25,7 +25,7 @@ var extractRequires = function(node) { return requires; }; -var extractModuleMetaData = function(node, metaDataObj) { +var extractModuleMetaData = (node, metaDataObj) => { if (node.type == 'Property' && node.key.name == 'modules' && node.parent.parent.type == 'Property' && node.parent.parent.key.name == 'liferay' && node.value.type == 'ObjectExpression' @@ -33,13 +33,13 @@ var extractModuleMetaData = function(node, metaDataObj) { var objSource = node.value.source(); node.value.properties.forEach( - function(item, index) { + (item, index) => { var val = item.value; var metaDataItem = {}; if (val.type == 'ObjectExpression') { val.properties.forEach( - function(valItem, valIndex) { + (valItem, valIndex) => { var propName = valItem.key.name; var propValue = valItem.value; @@ -71,7 +71,7 @@ var extractModuleMetaData = function(node, metaDataObj) { return metaDataObj; }; -var extractFileMetaData = function(node, moduleInfo, fileName) { +var extractFileMetaData = (node, moduleInfo, fileName) => { if (node.type == 'Property' && node.key.name == 'requires') { if (node.parent.parent.type == 'CallExpression') { var moduleDef = node.parent.parent; @@ -95,20 +95,18 @@ var extractFileMetaData = function(node, moduleInfo, fileName) { return moduleInfo; }; -var readFile = function(filePath, fileName, moduleInfo) { - return fs.readFileAsync(filePath).then( - function(contents) { - contents = falafel( - contents.toString(), - function(node) { - moduleInfo = extractFileMetaData(node, moduleInfo, fileName); - } - ); - } - ).catch(_.noop); -}; +var readFile = (filePath, fileName, moduleInfo) => fs.readFileAsync(filePath).then( + contents => { + contents = falafel( + contents.toString(), + node => { + moduleInfo = extractFileMetaData(node, moduleInfo, fileName); + } + ); + } +).catch(_.noop); -var checkMissingModuleInfo = function(files, metaDataObj) { +var checkMissingModuleInfo = (files, metaDataObj) => { var missingModules = metaDataObj.missing; var moduleFiles = metaDataObj.files; @@ -122,7 +120,7 @@ var checkMissingModuleInfo = function(files, metaDataObj) { } missingModules = largest.reduce( - function(prev, item, index) { + (prev, item, index) => { if (smallest.indexOf(item) === -1) { prev.push(item); } @@ -136,15 +134,11 @@ var checkMissingModuleInfo = function(files, metaDataObj) { return metaDataObj; }; -var diffArray = function(array, values) { - return array.filter( - function(item, index) { - return values.indexOf(item) == -1; - } - ); -}; +var diffArray = (array, values) => array.filter( + (item, index) => values.indexOf(item) == -1 +); -var checkMetaData = function(config) { +var checkMetaData = config => { var done = config.done; var liferayModuleDir = config.liferayModuleDir; @@ -167,7 +161,7 @@ var checkMetaData = function(config) { loc: true, tolerant: true }, - function(node) { + node => { moduleInfo = extractModuleMetaData(node, moduleInfo); } ); @@ -175,11 +169,9 @@ var checkMetaData = function(config) { var fileSeries = []; fs.readdirAsync(liferayModuleDir).then( - function(files) { + files => { files = files.filter( - function(item, index) { - return path.extname(item) == '.js' && item !== 'modules.js'; - } + (item, index) => path.extname(item) == '.js' && item !== 'modules.js' ); checkMissingModuleInfo(files, moduleInfo); @@ -187,13 +179,13 @@ var checkMetaData = function(config) { var updateModules = []; files.forEach( - function(item, index) { + (item, index) => { fileSeries.push(readFile(path.join(liferayModuleDir, item), item, moduleInfo)); } ); return Promsie.all(fileSeries).then( - function(results) { + results => { var moduleKeys = Object.keys(moduleInfo.meta); var fileModuleKeys = Object.keys(moduleInfo.fileMeta); @@ -212,14 +204,14 @@ var checkMetaData = function(config) { var needsFileData = []; combined.forEach( - function(item, index) { + (item, index) => { var moduleMeta = moduleInfo.meta[item]; var fileMeta = moduleInfo.fileMeta[item]; var hasModuleMeta = !!moduleMeta; var hasFileMeta = !!fileMeta; - var modFileIdentifier = item + ': ' + (hasFileMeta ? fileMeta.path : moduleMeta.path); + var modFileIdentifier = `${item}: ${hasFileMeta ? fileMeta.path : moduleMeta.path}`; if (!hasModuleMeta && hasFileMeta) { needsModuleData.push(modFileIdentifier); @@ -232,16 +224,16 @@ var checkMetaData = function(config) { needsMetaSync.push(modFileIdentifier); if (VERBOSE) { - needsMetaSync.push(INDENT + 'modules.js: ' + moduleMeta.requires); - needsMetaSync.push(INDENT + fileMeta.path + ': ' + fileMeta.requires.join(', ')); + needsMetaSync.push(`${INDENT}modules.js: ${moduleMeta.requires}`); + needsMetaSync.push(`${INDENT + fileMeta.path}: ${fileMeta.requires.join(', ')}`); } } else if (moduleMeta.requires && !fileMeta.requires) { needsMetaSync.push(modFileIdentifier); if (VERBOSE) { - needsMetaSync.push(INDENT + 'modules.js: ' + moduleMeta.requires.join(', ')); - needsMetaSync.push(INDENT + fileMeta.path + ': ' + fileMeta.requires); + needsMetaSync.push(`${INDENT}modules.js: ${moduleMeta.requires.join(', ')}`); + needsMetaSync.push(`${INDENT + fileMeta.path}: ${fileMeta.requires}`); } } else { @@ -260,14 +252,14 @@ var checkMetaData = function(config) { needsMetaSync.push(modFileIdentifier); if (VERBOSE) { - needsMetaSync.push(INDENT + 'modules.js: ' + moduleMeta.requires.join(', ')); - needsMetaSync.push(INDENT + fileMeta.path + ': ' + fileMeta.requires.join(', ')); + needsMetaSync.push(`${INDENT}modules.js: ${moduleMeta.requires.join(', ')}`); + needsMetaSync.push(`${INDENT + fileMeta.path}: ${fileMeta.requires.join(', ')}`); var merged = fileMeta.requires.concat(moduleMeta.requires); merged = _.uniq(merged).sort(); - needsMetaSync.push(INDENT + 'merged: \'' + merged.join('\', \'') + '\''); + needsMetaSync.push(`${INDENT}merged: '${merged.join('\', \'')}'`); needsMetaSync.push('---'); } } @@ -314,7 +306,7 @@ var checkMetaData = function(config) { }; module.exports = { - check: function(config) { + check(config) { return checkMetaData(config); } }; \ No newline at end of file diff --git a/lib/re.js b/lib/re.js index 948a0c5..947d538 100644 --- a/lib/re.js +++ b/lib/re.js @@ -21,7 +21,7 @@ re.prototype.hasExtraNewLines = function(item, index, collection) { { context: { rawContent: item, - item: item, + item, lineNum: index + 1 }, message: 'Extra new line' @@ -32,14 +32,12 @@ re.prototype.hasExtraNewLines = function(item, index, collection) { return extraNewLines; }; -re.prototype.hasHex = function(item) { +re.prototype.hasHex = item => { var match = item.match(REGEX.HEX); return match && match[0]; }; -re.prototype.hasProperty = function(item) { - return REGEX.PROPERTY.test(item); -}; +re.prototype.hasProperty = item => REGEX.PROPERTY.test(item); module.exports = re; \ No newline at end of file diff --git a/lib/regex.js b/lib/regex.js index 4c918b3..4f23dd6 100644 --- a/lib/regex.js +++ b/lib/regex.js @@ -28,11 +28,11 @@ var REGEX = { REGEX: /\/.*\/([gim]{1,3})?/g, - SCRIPTLET_STUB: new RegExp('^\\s*' + base.jspLintStubs.scriptlet + '$'), + SCRIPTLET_STUB: new RegExp(`^\\s*${base.jspLintStubs.scriptlet}$`), SERVICE_PROPS: /(^@)|((.*?) = (.*?))/, - STUBS: new RegExp('^_*(' + Object.keys(base.stubs).join('|') + ')_*'), + STUBS: new RegExp(`^_*(${Object.keys(base.stubs).join('|')})_*`), STYLE: /<(style)(.*?)>([\s\S]*?)<\/\1>/, diff --git a/lib/rule_utils.js b/lib/rule_utils.js index 9f2ce2a..98758eb 100644 --- a/lib/rule_utils.js +++ b/lib/rule_utils.js @@ -3,14 +3,14 @@ var path = require('path'); var REGEX = require('./regex'); -exports.getConstants = function(node) { +exports.getConstants = node => { var constants = []; node.body.forEach( - function(item, index) { + (item, index) => { if (item.type == 'VariableDeclaration' && item.declarations) { item.declarations.forEach( - function(val, key) { + (val, key) => { if (/^[A-Z0-9_]+$/.test(val.id.name)) { constants.push(val); } @@ -27,11 +27,9 @@ exports.getConstants = function(node) { // Or, pass in leftEnd or rightStart to define whether // it's the end or start of a line -exports.getLineDistance = function(left, right, leftEnd, rightStart) { - return right.loc[rightStart || 'start'].line - left.loc[leftEnd || 'end'].line; -}; +exports.getLineDistance = (left, right, leftEnd, rightStart) => right.loc[rightStart || 'start'].line - left.loc[leftEnd || 'end'].line; -var compare = function(a, b) { +var compare = (a, b) => { var retVal = 0; if (a < b) { @@ -44,7 +42,7 @@ var compare = function(a, b) { return retVal; }; -var compareAlpha = function(a, b, caseInsensitive, result) { +var compareAlpha = (a, b, caseInsensitive, result) => { if (caseInsensitive === true) { a = a.toLowerCase(); b = b.toLowerCase(); @@ -74,7 +72,7 @@ var compareAlpha = function(a, b, caseInsensitive, result) { var isFinite = _.isFinite; -exports.naturalCompare = function(a, b, caseInsensitive) { +exports.naturalCompare = (a, b, caseInsensitive) => { var result = 0; if ((isFinite(a) && isFinite(b)) || (isFinite(+a) && isFinite(+b))) { @@ -87,8 +85,8 @@ exports.naturalCompare = function(a, b, caseInsensitive) { return result; }; -exports.getRuleId = function(filePath) { +exports.getRuleId = filePath => { var baseName = path.basename(filePath, '.js'); - return 'csf-' + _.kebabCase(baseName); + return `csf-${_.kebabCase(baseName)}`; }; \ No newline at end of file diff --git a/lib/tpl/lint_rules/js/rule.js b/lib/tpl/lint_rules/js/rule.js index f985997..8ddb4be 100644 --- a/lib/tpl/lint_rules/js/rule.js +++ b/lib/tpl/lint_rules/js/rule.js @@ -11,13 +11,13 @@ module.exports = { category: 'Fill me in', recommended: false }, - fixable: null, // or "code" or "whitespace" + fixable: null, // or "code" or "whitespace" schema: [ // fill in your schema ] }, - create: function(context) { + create(context) { return { // ReturnStatement: function(node) { diff --git a/lib/tpl/lint_rules/js/test.js b/lib/tpl/lint_rules/js/test.js index c8e7059..9e0f6e4 100644 --- a/lib/tpl/lint_rules/js/test.js +++ b/lib/tpl/lint_rules/js/test.js @@ -9,7 +9,7 @@ var ruleTester = new RuleTester(); ruleTester.run( path.basename(__filename, '.js'), - require('../../lib/lint_js_rules/' + path.basename(__filename)), + require(`../../lib/lint_js_rules/${path.basename(__filename)}`), { valid: [ // Code that won't give a warning From e3ba7b05ed6448de692f5b9d4fcd0894e59be1b6 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 12 May 2017 14:21:20 -0700 Subject: [PATCH 146/153] Source formatting --- lib/cli.js | 10 +- lib/config/eslint.js | 125 ++++++++++++++++----- lib/config/eslint_es6.js | 116 ++++++++++--------- lib/config/eslint_jsp.js | 12 +- lib/config/stylelint.js | 35 ++++-- lib/css.js | 9 +- lib/engine_rules/common.js | 4 +- lib/engine_rules/css.js | 37 +----- lib/engine_rules/html.js | 4 +- lib/file.js | 1 - lib/formatter.js | 1 + lib/html.js | 87 ++++++-------- lib/js.js | 15 ++- lib/junit.js | 17 +-- lib/lint_css.js | 3 +- lib/lint_css_rules/at_rule_empty_line.js | 26 ++--- lib/lint_js.js | 6 +- lib/lint_js_rules/array_spacing.js | 3 +- lib/lint_js_rules/catch_arg_name.js | 2 - lib/lint_js_rules/catch_format.js | 5 +- lib/lint_js_rules/dot_notation.js | 2 +- lib/lint_js_rules/format_args.js | 26 ++--- lib/lint_js_rules/format_constants.js | 1 - lib/lint_js_rules/format_multiline_vars.js | 16 ++- lib/lint_js_rules/function_spacing.js | 2 +- lib/lint_js_rules/multiple_vars.js | 2 - lib/lint_js_rules/no_is_prefix.js | 4 +- lib/lint_js_rules/no_multiple_return.js | 32 +++--- lib/lint_js_rules/no_undef.js | 8 +- lib/lint_js_rules/no_unused_vars.js | 19 ++-- lib/lint_js_rules/no_use_before_define.js | 3 - lib/lint_js_rules/sort_constants.js | 3 +- lib/lint_js_rules/sort_props.js | 78 ++----------- lib/lint_js_rules/sort_requires.js | 1 + lib/lint_js_rules/sort_vars.js | 22 ++-- lib/logger.js | 1 - 36 files changed, 362 insertions(+), 376 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 27a3618..14dc60d 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -2,6 +2,7 @@ var cli = require('cli'); var Promise = require('bluebird'); + var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var util = require('util'); @@ -9,10 +10,9 @@ var util = require('util'); var _ = require('lodash'); var argv = require('./argv'); -var base = require('./base'); + var colors = require('cli-color-keywords')(); var junit = require('./junit'); -var re = require('./re'); var Config = require('./config'); var File = require('./file'); @@ -245,9 +245,9 @@ class CLI extends EventEmitter { this.logResults(this.renderOutput(file), file); return { - file, contents, - data + data, + file }; } ); @@ -370,7 +370,7 @@ class CLI extends EventEmitter { .then(this.createReport) .then(this.afterFormat); } -}; +} CLI.prototype._metaCheckerPath = './meta'; diff --git a/lib/config/eslint.js b/lib/config/eslint.js index 19a04ae..f58f500 100644 --- a/lib/config/eslint.js +++ b/lib/config/eslint.js @@ -10,12 +10,12 @@ module.exports = { 'parser': 'babel-eslint', 'parserOptions': { - 'sourceType': 'module', - 'ecmaVersion': 7, 'ecmaFeatures': { 'experimentalObjectRestSpread': true, 'jsx': true - } + }, + 'ecmaVersion': 7, + 'sourceType': 'module' }, 'globals': { @@ -31,12 +31,7 @@ module.exports = { }, 'rules': { - 'object-property-newline': 2, - 'csf-no-multiple-return': 2, - // 'csf-no-lonely-if': 2, - 'csf-function-spacing': 2, - 'csf-liferay-language-get': 2, - 'csf-liferay-provide-format': 2, + 'array-bracket-spacing': [2, 'never'], 'block-scoped-var': 2, 'brace-style': [2, 'stroustrup'], 'camelcase': 0, @@ -46,18 +41,33 @@ module.exports = { 'complexity': [0, 11], 'consistent-return': 2, 'consistent-this': [1, 'instance'], + + // 'csf-no-lonely-if': 2, + 'csf-array-spacing': 2, 'csf-array-spacing-chars': 2, 'csf-catch-arg-name': 2, 'csf-catch-format': 2, 'csf-format-args': 2, 'csf-format-constants': 2, + + 'csf-function-spacing': 2, 'csf-format-multiline-vars': 2, + 'csf-liferay-language-get': 2, + 'csf-liferay-provide-format': 2, 'csf-multiple-vars': 2, 'csf-no-extra-semi': 2, 'csf-no-is-prefix': 2, + 'csf-no-multiple-return': 2, 'csf-no-unused-vars': 2, - 'csf-no-use-before-define': [2, {'functions': true, 'classes': true, 'samescope': true}], + 'csf-no-use-before-define': [ + 2, + { + 'classes': true, + 'functions': true, + 'samescope': true + } + ], 'csf-sort-constants': 2, 'csf-sort-props': 2, 'csf-sort-requires': 2, @@ -75,6 +85,13 @@ module.exports = { 'handle-callback-err': 0, 'indent': [2, 'tab'], 'key-spacing': 2, + 'keyword-spacing': [ + 2, + { + after: true, + before: true + } + ], 'max-depth': [0, 4], 'max-len': [0, 80, 4], 'max-nested-callbacks': [0, 2], @@ -101,7 +118,6 @@ module.exports = { 'no-else-return': 2, 'no-empty': 0, 'no-empty-character-class': 2, - 'no-labels': 2, 'no-eq-null': 0, 'no-eval': 2, 'no-ex-assign': 2, @@ -128,7 +144,12 @@ module.exports = { 'no-mixed-spaces-and-tabs': [0, false], 'no-multi-spaces': 2, 'no-multi-str': 2, - 'no-multiple-empty-lines': [2, {max: 2}], + 'no-multiple-empty-lines': [ + 2, + { + max: 2 + } + ], 'no-native-reassign': 2, 'no-negated-in-lhs': 2, 'no-nested-ternary': 2, @@ -148,7 +169,6 @@ module.exports = { 'no-proto': 2, 'no-redeclare': 2, 'no-regex-spaces': 2, - 'quote-props': 0, 'no-restricted-modules': 0, 'no-return-assign': 2, 'no-script-url': 0, @@ -168,13 +188,27 @@ module.exports = { 'no-underscore-dangle': 0, 'no-unreachable': 2, 'no-unused-expressions': 2, - 'no-unused-vars': [2, {'vars': 'local', 'args': 'none'}], + 'no-unused-vars': [ + 2, + { + 'args': 'none', + 'vars': 'local' + } + ], 'no-use-before-define': [0], 'no-var': 0, 'no-void': 0, - 'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }], + 'no-warning-comments': [ + 0, + { + 'location': 'start', + 'terms': ['todo', 'fixme', 'xxx'] + } + ], 'no-with': 2, + // 'no-extra-parens': 2, + 'one-var': 0, 'operator-assignment': [2, 'always'], 'padded-blocks': 0, @@ -182,16 +216,30 @@ module.exports = { 'quotes': [2, 'single'], 'radix': 2, 'semi': [2, 'always'], - 'semi-spacing': [2, {before: false, after: true}], - 'sort-vars': [2, {ignoreCase: true}], - 'keyword-spacing': [2, {before: true, after: true}], + 'semi-spacing': [ + 2, + { + after: true, + before: false + } + ], + 'sort-vars': [ + 2, + { + ignoreCase: true + } + ], 'space-before-blocks': [2, 'always'], 'space-before-function-paren': [2, 'never'], - 'object-curly-spacing': [2, 'never'], - 'array-bracket-spacing': [2, 'never'], 'space-in-parens': [2, 'never'], 'space-infix-ops': 2, - 'space-unary-ops': [1, {'words': true, 'nonwords': false}], + 'space-unary-ops': [ + 1, + { + 'nonwords': false, + 'words': true + } + ], 'spaced-comment': [2, 'always'], 'template-curly-spacing': [2, 'never'], 'no-self-assign': 2, @@ -205,6 +253,7 @@ module.exports = { 'yoda': 2, // Investigate + 'jsx-quotes': 0, 'no-continue': 0, 'no-invalid-this': 0, @@ -215,7 +264,13 @@ module.exports = { 'accessor-pairs': 0, 'array-callback-return': 2, - 'arrow-spacing': [2, {before: true, after: true}], + 'arrow-spacing': [ + 2, + { + after: true, + before: true + } + ], 'block-spacing': 0, 'callback-return': 0, 'computed-property-spacing': [2, 'never'], @@ -226,7 +281,15 @@ module.exports = { 'id-match': 0, 'init-declarations': 0, 'linebreak-style': [2, 'unix'], - 'lines-around-comment': [2, { 'beforeBlockComment': true, 'afterBlockComment': true, 'beforeLineComment': true, 'afterLineComment': true }], + 'lines-around-comment': [ + 2, + { + 'afterBlockComment': true, + 'afterLineComment': true, + 'beforeBlockComment': true, + 'beforeLineComment': true + } + ], 'newline-per-chained-call': 0, 'no-case-declarations': 2, 'no-class-assign': 2, @@ -236,7 +299,12 @@ module.exports = { 'no-empty-function': 0, 'no-empty-pattern': 2, 'no-extra-label': 2, - 'no-implicit-coercion': [2, {allow: ['!!', '*', '+']}], + 'no-implicit-coercion': [ + 2, + { + allow: ['!!', '*', '+'] + } + ], 'no-restricted-imports': 0, 'no-this-before-super': 2, 'no-unexpected-multiline': 2, @@ -248,12 +316,19 @@ module.exports = { 'no-useless-constructor': 2, 'no-whitespace-before-property': 2, 'object-curly-spacing': [2, 'never'], + 'object-property-newline': 2, 'one-var-declaration-per-line': 0, 'operator-linebreak': [2, 'after'], 'prefer-reflect': 0, 'require-jsdoc': 0, 'require-yield': 0, - 'sort-imports': [0, { ignoreCase: true, memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'] }], + 'sort-imports': [ + 0, + { + ignoreCase: true, + memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'] + } + ], 'yield-star-spacing': 0 } }; \ No newline at end of file diff --git a/lib/config/eslint_es6.js b/lib/config/eslint_es6.js index 4989594..6ccf988 100644 --- a/lib/config/eslint_es6.js +++ b/lib/config/eslint_es6.js @@ -1,24 +1,9 @@ module.exports = { - // 'env': { - // 'es6': true - // }, - - // 'parser': 'babel-eslint', - - // 'parserOptions': { - // 'sourceType': 'module', - // 'ecmaFeatures': { - // 'experimentalObjectRestSpread': true, - // 'jsx': true - // } - // }, - 'plugins': [ 'react' ], 'rules': { - 'object-property-newline': 0, 'jsx-quotes': [2, 'prefer-double'], 'jsx-uses-react': 2, 'jsx-uses-vars': 2, @@ -33,42 +18,54 @@ module.exports = { 'jsx-closing-bracket-location': 2, 'jsx-pascal-case': 2, 'jsx-tag-spacing': [2], - 'jsx-sort-props': [2, {'ignoreCase': true}], - 'no-multi-comp': [0, {'ignoreStateless': true}], - 'jsx-wrap-multilines': [2/*, {'ignoreStateless': true}*/], + 'jsx-sort-props': [ + 2, + { + 'ignoreCase': true + } + ], + 'no-multi-comp': [ + 0, + { + 'ignoreStateless': true + } + ], + 'jsx-wrap-multilines': [2/* , {'ignoreStateless': true} */], 'no-unknown-property': 2, - 'sort-comp': [0, { - order: [ - 'static-methods', - 'lifecycle', - 'everything-else', - 'render' - ], - groups: { - lifecycle: [ - 'constructor', - 'displayName', - 'mixins', - 'propTypes', - 'statics', - 'defaultProps', - 'getDefaultProps', - 'getInitialState', - 'state', - 'componentWillMount', - 'componentDidMount', - 'componentWillReceiveProps', - 'componentWillUpdate', - 'componentDidUpdate', - 'componentWillUnmount', - 'shouldComponentUpdate', - 'getChildContext', - 'childContextTypes', - 'contextTypes', + 'sort-comp': [ + 0, + { + groups: { + lifecycle: [ + 'constructor', + 'displayName', + 'mixins', + 'propTypes', + 'statics', + 'defaultProps', + 'getDefaultProps', + 'getInitialState', + 'state', + 'componentWillMount', + 'componentDidMount', + 'componentWillReceiveProps', + 'componentWillUpdate', + 'componentDidUpdate', + 'componentWillUnmount', + 'shouldComponentUpdate', + 'getChildContext', + 'childContextTypes', + 'contextTypes' + ] + }, + order: [ + 'static-methods', + 'lifecycle', + 'everything-else', + 'render' ] } - }], - + ], 'prop-types': 0, 'display-name': 0, 'no-danger': 0, @@ -88,7 +85,12 @@ module.exports = { 'require-render-return': 2, 'jsx-first-prop-new-line': [2, 'multiline'], 'self-closing-comp': 2, - 'sort-prop-types': [2, {'ignoreCase': true}], + 'sort-prop-types': [ + 2, + { + 'ignoreCase': true + } + ], 'no-direct-mutation-state': 2, 'forbid-prop-types': 0, @@ -97,8 +99,20 @@ module.exports = { 'arrow-body-style': [0, 'as-needed'], 'arrow-parens': [2, 'as-needed'], - 'object-shorthand': [2, 'always', {'ignoreConstructors': true}], - 'prefer-arrow-callback': [2, {'allowNamedFunctions': true}], + 'object-property-newline': 0, + 'object-shorthand': [ + 2, + 'always', + { + 'ignoreConstructors': true + } + ], + 'prefer-arrow-callback': [ + 2, + { + 'allowNamedFunctions': true + } + ], 'no-new-symbol': 2, 'prefer-const': 2, 'prefer-rest-params': 2, diff --git a/lib/config/eslint_jsp.js b/lib/config/eslint_jsp.js index 9e32622..c56595f 100644 --- a/lib/config/eslint_jsp.js +++ b/lib/config/eslint_jsp.js @@ -8,8 +8,16 @@ module.exports = { 'rules': { 'block-scoped-var': 0, 'csf-dot-notation': 2, - 'csf-no-undef': [2, {}], - 'csf-no-unused-vars': [2, {'jsp': true}], + 'csf-no-undef': [ + 2, + {} + ], + 'csf-no-unused-vars': [ + 2, + { + 'jsp': true + } + ], 'indent': [0, 'tab'], 'dot-notation': 0, 'no-trailing-spaces': 0, diff --git a/lib/config/stylelint.js b/lib/config/stylelint.js index 6929b1d..224ff17 100644 --- a/lib/config/stylelint.js +++ b/lib/config/stylelint.js @@ -44,7 +44,6 @@ module.exports = { // 'no-missing-end-of-source-newline': true, 'property-case': 'lower', // 'property-no-unknown': true, - 'rule-empty-line-before': ['always', {except: 'first-nested'}], 'selector-attribute-brackets-space-inside': 'never', // 'selector-attribute-operator-blacklist': 'string|[]', 'selector-attribute-operator-space-after': 'never', @@ -71,8 +70,13 @@ module.exports = { 'value-keyword-case': 'lower', 'value-list-max-empty-lines': 0, - 'csf-at-rule-empty-line': ['always', {except: ['first-nested']}], - "order/properties-alphabetical-order": true, + 'csf-at-rule-empty-line': [ + 'always', + { + except: ['first-nested'] + } + ], + 'order/properties-alphabetical-order': true, 'at-rule-no-vendor-prefix': true, 'block-closing-brace-newline-after': 'always', 'block-closing-brace-newline-before': 'always', @@ -89,7 +93,12 @@ module.exports = { 'color-named': 'never', // 'color-no-hex': true, 'color-no-invalid-hex': true, - 'comment-empty-line-before': ['always', {except: ['first-nested']}], + 'comment-empty-line-before': [ + 'always', + { + except: ['first-nested'] + } + ], 'comment-whitespace-inside': 'always', // 'custom-media-pattern': string, // 'custom-property-pattern': string, @@ -119,7 +128,7 @@ module.exports = { // 'function-parentheses-newline-inside': 'always'|'always-multi-line'|'never-multi-line', 'function-parentheses-space-inside': 'never', - //Will probably need to reimplement this one to ignore strings with quotes + // Will probably need to reimplement this one to ignore strings with quotes // 'function-url-quotes': 'never', // 'function-whitelist': '', @@ -156,9 +165,19 @@ module.exports = { // 'property-value-blacklist': {}, // 'property-whitelist': string|[], // 'root-no-standard-properties': true, - 'rule-empty-line-before': ['always', {except: ['first-nested']}], + 'rule-empty-line-before': [ + 'always', + { + except: ['first-nested'] + } + ], // 'rule-non-nested-empty-line-before': 'always', - 'selector-class-pattern': [/(#\{\$.*?\}|[a-z0-9]+)(-#\{\$.*?\}|-[a-z0-9]+)*$/, {resolveNestedSelectors: true}], // Maybe + 'selector-class-pattern': [ + /(#\{\$.*?\}|[a-z0-9]+)(-#\{\$.*?\}|-[a-z0-9]+)*$/, + { + resolveNestedSelectors: true + } + ], // Maybe 'selector-combinator-space-after': 'always', 'selector-combinator-space-before': 'always', // 'selector-id-pattern': string, @@ -183,7 +202,7 @@ module.exports = { 'value-list-comma-newline-after': false, 'value-list-comma-newline-before': 'never-multi-line', 'value-list-comma-space-after': 'always-single-line', - 'value-list-comma-space-before': 'never', + 'value-list-comma-space-before': 'never' // 'value-no-vendor-prefix': true } }; \ No newline at end of file diff --git a/lib/css.js b/lib/css.js index e119f9f..1407d10 100644 --- a/lib/css.js +++ b/lib/css.js @@ -1,16 +1,15 @@ var _ = require('lodash'); -var base = require('./base'); -var re = require('./re'); var Promise = require('bluebird'); +var base = require('./base'); + var REGEX = require('./regex'); var Formatter = require('content-formatter'); var iterateLines = base.iterateLines; -var sub = require('string-sub'); -var REGEX_STYLELINT_POSTFIX = / \(.+?\)$/ +var REGEX_STYLELINT_POSTFIX = / \(.+?\)$/; Formatter.CSS = Formatter.create( { @@ -130,8 +129,6 @@ Formatter.CSS = Formatter.create( previousItem = previousItem && previousItem.trim(); } - var propertyRules = this._re.rules.css._properties; - context.content = content; context.index = index; context.lineNum = lineNum; diff --git a/lib/engine_rules/common.js b/lib/engine_rules/common.js index 94cd4c2..1dbea26 100644 --- a/lib/engine_rules/common.js +++ b/lib/engine_rules/common.js @@ -1,9 +1,9 @@ var colors = require('cli-color-keywords')(); var MAP_WHITESPACE = { - '\xa0': ' ', '\x95': '', - '\x99': '' + '\x99': '', + '\xa0': ' ' }; var REGEX_WHITESPACE_CHARS = new RegExp(`(${Object.keys(MAP_WHITESPACE).join('|')})`, 'g'); diff --git a/lib/engine_rules/css.js b/lib/engine_rules/css.js index 40f62ba..424db6d 100644 --- a/lib/engine_rules/css.js +++ b/lib/engine_rules/css.js @@ -1,15 +1,10 @@ -var colors = require('cli-color-keywords')(); - -var sub = require('string-sub'); +var REGEX = require('../regex'); var REGEX_WHITESPACE = /\s/; -var REGEX = require('../regex'); - module.exports = { hexLowerCase: { message: false, - // message: 'Hex code should be all uppercase: {1}', regex: /[a-f]/, replacer(result, rule, context) { var rawContent = context.rawContent; @@ -28,13 +23,6 @@ module.exports = { }, hexRedundant: { - // message: function(result, rule, context) { - // var match = this.hasHex(context.content); - - // var message = 'Hex code can be reduced to ' + rule._reduceHex(match) + ': {1}'; - - // return this.message(message, result, rule, context); - // }, message: false, regex: /#([0-9A-Fa-f])\1([0-9A-Fa-f])\2([0-9A-Fa-f])\3/, replacer(result, rule, context) { @@ -57,14 +45,12 @@ module.exports = { }, missingInteger: { - // message: 'Missing integer: {1}', message: false, regex: /([^0-9])(\.\d+)/g, replacer: '$10$2' }, missingListValuesSpace: { - // message: 'Needs space between comma-separated values: {1}', message: false, regex: /,(?=[^\s])/g, replacer: ', ', @@ -82,19 +68,6 @@ module.exports = { }, missingNewlines: { - // message: function(result, rule, context) { - // var message = 'There should be a newline between "{prevRule}" and "{rule}"'; - - // message = this.message(message, result, rule, context); - - // return sub( - // message, - // { - // rule: context.nextItem.trim(), - // prevRule: context.previousItem.trim() - // } - // ); - // }, message: false, regex: /.*?(\}|\{)/, replacer(result, rule, context) { @@ -117,8 +90,8 @@ module.exports = { var hasCloser = REGEX.BRACE_CLOSING.test(content); var hasOpener = REGEX.BRACE_OPENING.test(content); - var previousItem = (context.previousItem || '').trim(); var nextItem = (context.nextItem || '').trim(); + var previousItem = (context.previousItem || '').trim(); if ((hasCloser && rule._isNextLineInvalid.call(this, nextItem)) || (hasOpener && rule._isPrevLineInvalid.call(this, previousItem) && content.indexOf('@else') !== 0)) { @@ -138,13 +111,11 @@ module.exports = { }, missingSelectorSpace: { - // message: 'Missing space between selector and bracket: {1}', message: false, regex: /([^ ])\{\s*$/ }, missingInternalSelectorSpace: { - // message: 'Missing space around combinator: {1}', message: false, regex: /(.)?([>~+])(.)?/g, replacer(result, rule, context) { @@ -193,14 +164,12 @@ module.exports = { }, needlessQuotes: { - // message: 'Needless quotes: {1}', message: false, regex: /url\((["'])(.*?)\1\)/, replacer: 'url($2)' }, needlessUnit: { - // message: 'Needless unit: {1}', message: false, regex: /(#?)(\b0(?!s\b)[a-zA-Z]{1,}\b)/, replacer: '0', @@ -229,8 +198,8 @@ module.exports = { var hasCloser = REGEX.BRACE_CLOSING.test(content); var hasOpener = REGEX.BRACE_OPENING.test(content); - var previousItem = context.previousItem; var nextItem = context.nextItem; + var previousItem = context.previousItem; var trailingNewlines = false; diff --git a/lib/engine_rules/html.js b/lib/engine_rules/html.js index c06144c..0016f03 100644 --- a/lib/engine_rules/html.js +++ b/lib/engine_rules/html.js @@ -1,6 +1,6 @@ module.exports = { anonymousBlockContainers: { - regex: //, - message: 'Block level containers need either a class or id: {1}' + message: 'Block level containers need either a class or id: {1}', + regex: // } }; \ No newline at end of file diff --git a/lib/file.js b/lib/file.js index 04df3a4..2c5de0d 100644 --- a/lib/file.js +++ b/lib/file.js @@ -1,4 +1,3 @@ -var fs = require('fs'); var path = require('path'); var util = require('util'); diff --git a/lib/formatter.js b/lib/formatter.js index 33a96a1..fb0215b 100644 --- a/lib/formatter.js +++ b/lib/formatter.js @@ -31,6 +31,7 @@ Formatter.prototype.config = function(key) { var config = this._config; var paths = config._paths; + var configs = paths.configs; var filteredConfigs = _.reduce( diff --git a/lib/html.js b/lib/html.js index d296f34..da675e0 100644 --- a/lib/html.js +++ b/lib/html.js @@ -12,6 +12,7 @@ var sub = require('string-sub'); var jspLintStubs = base.jspLintStubs; var scriptletBlockOpen = '/* scriptlet block'; + var scriptletBlockClose = ' */'; require('./js'); @@ -24,9 +25,11 @@ var MAP_IGNORE_ATTR_VALUES = { 'title': true }; +var REGEX_JSP_PORTLET_NAMESPACE = //g; + var REGEX_JSP_SCRIPT_BLOCK = /<%.*?%>/gim; + var REGEX_JSP_SCRIPTLET_BLOCK = /<%=[^>]+>/g; -var REGEX_JSP_PORTLET_NAMESPACE = //g; Formatter.HTML = Formatter.create( { @@ -43,8 +46,6 @@ Formatter.HTML = Formatter.create( var styleBlocks = []; - var re = this._re; - var hasCSS = (REGEX.STYLE).test(contents); if (hasCSS) { @@ -68,8 +69,8 @@ Formatter.HTML = Formatter.create( contents: body, file: filePath, match: m, - styleAttrs, - startLine: lines + startLine: lines, + styleAttrs } ); } @@ -84,8 +85,6 @@ Formatter.HTML = Formatter.create( var scriptBlocks = []; - var re = this._re; - var hasJs = (REGEX.AUI_SCRIPT).test(contents); if (hasJs) { @@ -129,8 +128,6 @@ Formatter.HTML = Formatter.create( var filePath = instance.file; - var logger = instance.log.bind(instance); - var re = instance._re; var context = { @@ -288,8 +285,6 @@ Formatter.HTML = Formatter.create( var needsSort = false; if (lastAttr > attrName) { - var filePath = this.file; - var regex = new RegExp(`\\b${lastAttr}\\b.*?> ?<.*?${attrName}`); var note = ''; @@ -309,8 +304,8 @@ Formatter.HTML = Formatter.create( }, _attrCleanTokens(value) { - var token = this._TOKEN; var nsToken = this._NS_TOKEN; + var token = this._TOKEN; value = value.replace(new RegExp(`${token}(\\d+)${token}`, 'g'), '<%...%>'); value = value.replace(new RegExp(`${nsToken}(\\d+)${nsToken}`, 'g'), ''); @@ -427,8 +422,8 @@ Formatter.HTML = Formatter.create( var instance = this; if (!MAP_IGNORE_ATTR_VALUES.hasOwnProperty(attrName)) { - var styleAttr = (attrName == 'style'); var onAttr = (attrName.indexOf('on') === 0); + var styleAttr = (attrName == 'style'); var hasScript = (attrValue.indexOf('javascript:') === 0); @@ -444,18 +439,18 @@ Formatter.HTML = Formatter.create( var sort = false; - var filePath = this.file; - attrValuePieces.forEach( (item, index, collection) => { item = item.trim(); if (/^[A-Za-z]/.test(item)) { + // Skip event handlers like onClick, labels, or any attr value // starting with javascript:;, etc since they will have // complex values that probably shouldn't be sorted + if (!hasScript && !onAttr && lastAttrPiece > item) { - var tmpLastAttrPiece = instance._attrCleanTokens(lastAttrPiece); var tmpItem = instance._attrCleanTokens(item); + var tmpLastAttrPiece = instance._attrCleanTokens(lastAttrPiece); instance.log(lineNum, sub('Sort attribute values: {0} {1}', tmpLastAttrPiece, tmpItem)); @@ -495,8 +490,6 @@ Formatter.HTML = Formatter.create( }, _jsCommentSingleLineScriptlets(lines) { - var re = this._re; - return lines.map( (item, index) => { if (REGEX.SCRIPTLET_STUB.test(item)) { @@ -539,30 +532,6 @@ Formatter.HTML = Formatter.create( return contents; }, - _jsIgnoreEndNewlines(lines) { - var numLines = lines.length; - - if (lines[numLines - 2] === '' && lines[numLines - 3].indexOf('void 0; */') > -1) { - lines[numLines - 2] = 'void 0;'; - } - - return lines; - }, - - _jsIgnoreStartNewlines(lines) { - var numLines = lines.length; - - if (lines[1] === '' && lines[2].indexOf(scriptletBlockOpen) > -1) { - lines[1] = 'void 0;'; - } - - return lines; - }, - - _jsIsScriptletCloseToken(item, prev) { - return item && item == '>' && prev == '%'; - }, - _jsHandleScriptletWhitespace(scriptBlock) { var contents = scriptBlock.contents; @@ -599,6 +568,28 @@ Formatter.HTML = Formatter.create( return scriptBlock; }, + _jsIgnoreEndNewlines(lines) { + var numLines = lines.length; + + if (lines[numLines - 2] === '' && lines[numLines - 3].indexOf('void 0; */') > -1) { + lines[numLines - 2] = 'void 0;'; + } + + return lines; + }, + + _jsIgnoreStartNewlines(lines) { + if (lines[1] === '' && lines[2].indexOf(scriptletBlockOpen) > -1) { + lines[1] = 'void 0;'; + } + + return lines; + }, + + _jsIsScriptletCloseToken(item, prev) { + return item && item == '>' && prev == '%'; + }, + _jsIterateRules(scriptBlock) { var instance = this; @@ -611,15 +602,13 @@ Formatter.HTML = Formatter.create( var asyncAUIScript = tagNamespace && tagNamespace.indexOf('aui:') === 0 && scriptAttrs.indexOf('use="') > -1; - var logger = instance.log.bind(instance); - var re = instance._re; iterateLines( contents, (content, index) => { - var rawContent = content; var lineNum = startLine + index; + var rawContent = content; content = content.trim(); @@ -643,8 +632,6 @@ Formatter.HTML = Formatter.create( }, _jsLogFilter(item) { - var message = item.message; - item.message = item.message.replace(/\b_PN_(\w+)\b/g, '$1'); return item; @@ -704,10 +691,6 @@ Formatter.HTML = Formatter.create( _processAttrs(line, lineNum) { var instance = this; - var filePath = this.file; - - var prevLine = line; - line = line.replace( /<[^>]+>/g, (m, mi, str) => { @@ -741,7 +724,7 @@ Formatter.HTML = Formatter.create( } ); - if (trackSort[true]) { + if (trackSort.true) { m = instance._sortAttrs(m, attrs); } } diff --git a/lib/js.js b/lib/js.js index 3278c37..26836a0 100644 --- a/lib/js.js +++ b/lib/js.js @@ -1,7 +1,6 @@ var _ = require('lodash'); var base = require('./base'); -var re = require('./re'); var REGEX = require('./regex'); @@ -15,12 +14,16 @@ var jsonf = _.bindKeyRight( JSON, 'stringify', (key, value) => { + var retVal; + if (key === 'start' || key === 'end') { - return value.line; + retVal = value.line; } - if (['parent', 'range'].indexOf(key) === -1) { - return value; + else if (['parent', 'range'].indexOf(key) === -1) { + retVal = value; } + + return retVal; }, 4 ); @@ -38,8 +41,6 @@ Formatter.JS = Formatter.create( format(contents, lint) { var hasSheBang = this._hasSheBang(contents); - var rawContents = contents; - if (hasSheBang) { contents = `//${contents}`; } @@ -66,8 +67,6 @@ Formatter.JS = Formatter.create( contents = contents.substr(2, contents.length); } - var logger = this.log.bind(this); - var newContents = iterateLines( contents, (content, index, collection) => { diff --git a/lib/junit.js b/lib/junit.js index ad1f844..f402783 100644 --- a/lib/junit.js +++ b/lib/junit.js @@ -1,15 +1,13 @@ 'use strict'; var _ = require('lodash'); -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs')); var Handlebars = require('content-logger-handlebars-helpers')(); var path = require('path'); +var Promise = require('bluebird'); -var base = require('./base'); -var Logger = require('./logger'); +var fs = Promise.promisifyAll(require('fs')); -var A = base.A; +var Logger = require('./logger'); class JUnitReporter { constructor(config) { @@ -41,7 +39,12 @@ class JUnitReporter { (fileErrors, fileName) => { const errors = []; - fileErrors = _.reject(fileErrors, {type: 'ignored'}); + fileErrors = _.reject( + fileErrors, + { + type: 'ignored' + } + ); _.forEach( _.groupBy(fileErrors, 'type'), @@ -97,7 +100,7 @@ class JUnitReporter { return xmlTpl(context); } -}; +} JUnitReporter.prototype.TPL_PATH = path.join(__dirname, 'tpl', 'junit_report.tpl'); diff --git a/lib/lint_css.js b/lib/lint_css.js index 629802c..e1ed69f 100644 --- a/lib/lint_css.js +++ b/lib/lint_css.js @@ -1,8 +1,9 @@ var _ = require('lodash'); +var glob = require('glob'); var path = require('path'); var stylelint = require('stylelint'); + var STYLELINT_CONFIG = require('./config/stylelint'); -var glob = require('glob'); var ruleUtils = require('./rule_utils'); diff --git a/lib/lint_css_rules/at_rule_empty_line.js b/lib/lint_css_rules/at_rule_empty_line.js index 3a1e995..d742f65 100644 --- a/lib/lint_css_rules/at_rule_empty_line.js +++ b/lib/lint_css_rules/at_rule_empty_line.js @@ -1,25 +1,27 @@ var _ = require('lodash'); var stylelint = require('stylelint'); -var sub = require('string-sub'); - -var REGEX_NEWLINE = require('../regex').NEWLINE; var ruleUtils = require('../rule_utils'); var ruleName = ruleUtils.getRuleId(__filename); var slUtils = stylelint.utils; + /* istanbul ignore next */ var jsonf = _.bindKeyRight( JSON, 'stringify', (key, value) => { + var retVal; + if (key === 'start' || key === 'end') { - return value.line; + retVal = value.line; } - if (['parent', 'range'].indexOf(key) === -1) { - return value; + else if (['parent', 'range'].indexOf(key) === -1) { + retVal = value; } + + return retVal; }, 4 ); @@ -28,14 +30,6 @@ module.exports = (expectation, options) => { var atRuleFn = stylelint.rules['at-rule-empty-line-before'](expectation, options); return (root, result) => { - var messages = slUtils.ruleMessages( - ruleName, - { - expected: 'Expected a newline {0} at-rule', - rejected: 'Unexpected newline {0} at-rule' - } - ); - var validOptions = slUtils.validateOptions( result, ruleName, @@ -49,6 +43,7 @@ module.exports = (expectation, options) => { except: ['first-nested'], ignore: ['between-nested'] }, + optional: true } ); @@ -60,7 +55,7 @@ module.exports = (expectation, options) => { var validLines = []; if (validOptions) { - var otherResults = atRuleFn(root, result); + atRuleFn(root, result); root.walkAtRules( node => { @@ -69,7 +64,6 @@ module.exports = (expectation, options) => { if (node.name === 'include' || node.name === 'import') { var prev = node.prev(); - var next = node.next(); if (prev && prev.type === 'atrule' && isSingleLineRule(node) && isSingleLineRule(prev) && getLineDistance(prev, node) === 1) { validLines.push(startLine); diff --git a/lib/lint_js.js b/lib/lint_js.js index daa73f0..ccc64e6 100644 --- a/lib/lint_js.js +++ b/lib/lint_js.js @@ -1,12 +1,14 @@ var _ = require('lodash'); var eslint = require('eslint'); -var SourceCodeFixer = require('eslint/lib/util/source-code-fixer'); -var ESLINT_CONFIG = require('./config/eslint'); var glob = require('glob'); var path = require('path'); +var SourceCodeFixer = require('eslint/lib/util/source-code-fixer'); + var ruleUtils = require('./rule_utils'); +var ESLINT_CONFIG = require('./config/eslint'); + var customRules = {}; var reactRules = require('eslint-plugin-react').rules; diff --git a/lib/lint_js_rules/array_spacing.js b/lib/lint_js_rules/array_spacing.js index 9399098..fd20af0 100644 --- a/lib/lint_js_rules/array_spacing.js +++ b/lib/lint_js_rules/array_spacing.js @@ -1,5 +1,4 @@ var _ = require('lodash'); -var base = require('../base'); var REGEX = require('../regex'); @@ -18,8 +17,8 @@ module.exports = context => ({ source.replace( REGEX.ARRAY_SURROUNDING_SPACE, (item, index, str) => { - var startIndex = 0; var endIndex = str.length; + var startIndex = 0; var leadingSpace = item.indexOf('[') > -1; diff --git a/lib/lint_js_rules/catch_arg_name.js b/lib/lint_js_rules/catch_arg_name.js index 4d708a0..bc424bc 100644 --- a/lib/lint_js_rules/catch_arg_name.js +++ b/lib/lint_js_rules/catch_arg_name.js @@ -1,5 +1,3 @@ -var base = require('../base'); - var sub = require('string-sub'); module.exports = context => ({ diff --git a/lib/lint_js_rules/catch_format.js b/lib/lint_js_rules/catch_format.js index 4a1d7cb..bbd3392 100644 --- a/lib/lint_js_rules/catch_format.js +++ b/lib/lint_js_rules/catch_format.js @@ -1,12 +1,11 @@ -var base = require('../base'); - var sub = require('string-sub'); module.exports = context => ({ CatchClause(node) { + var end = node.loc.end.line; var start = node.loc.start.line; + var shouldEnd = start + 1; - var end = node.loc.end.line; if (!node.body.body.length && end != shouldEnd) { var message = sub('Empty catch statement should be closed on line {0}', shouldEnd); diff --git a/lib/lint_js_rules/dot_notation.js b/lib/lint_js_rules/dot_notation.js index 4cf5ea3..d3a4f62 100644 --- a/lib/lint_js_rules/dot_notation.js +++ b/lib/lint_js_rules/dot_notation.js @@ -2,8 +2,8 @@ var REGEX = require('../regex'); module.exports = context => ({ MemberExpression(node) { - var propertyValue = node.property.value; var propertyType = node.property.type; + var propertyValue = node.property.value; if (propertyType === 'Literal' && !REGEX.STUBS.test(propertyValue)) { var dotNotation = require('eslint/lib/rules/dot-notation'); diff --git a/lib/lint_js_rules/format_args.js b/lib/lint_js_rules/format_args.js index 0a7fa7c..8da42dc 100644 --- a/lib/lint_js_rules/format_args.js +++ b/lib/lint_js_rules/format_args.js @@ -1,5 +1,4 @@ var _ = require('lodash'); -var base = require('../base'); var sub = require('string-sub'); @@ -16,8 +15,6 @@ module.exports = context => { return fnName; }; - var sc = context.getSourceCode(); - var getFnExpLines = (lineBounds, node) => { var end = lineBounds.end; var start = lineBounds.start; @@ -67,9 +64,6 @@ module.exports = context => { lineBounds.start = getLineBounds(callee, 'end'); } } - // else if (isFunctionExpression(node.type)) { - // lineBounds = getFnExpLines(lineBounds, node); - // } lineBounds.multi = (lineBounds.end > lineBounds.start); @@ -124,10 +118,10 @@ module.exports = context => { }; var getMultiLineError = (error, loc, options) => { - var argStart = loc.start; var argEnd = loc.end; - var fnStart = options.start; + var argStart = loc.start; var fnEnd = options.end; + var fnStart = options.start; if (options.multi) { if (argStart === fnStart) { @@ -158,20 +152,18 @@ module.exports = context => { var processArgs = (args, options, node) => { var obj = {}; - var fnStart = options.start; - var fnEnd = options.end; - var multiLineFn = options.multi; - var lastArgStartLine = 0; var lastArgEndLine = 0; + var lastArgStartLine = 0; var hasNonEmptyFunctionArg = false; var hasNonEmptyObjectArg = false; - var testLineEndings = false; - var argLineStarts = []; var argLineEnds = []; + var argLineStarts = []; + + var testLineEndings = false; var error = ''; @@ -184,8 +176,8 @@ module.exports = context => { var argStart = loc.start; var argEnd = loc.end; - argLineStarts.push(argStart); argLineEnds.push(argEnd); + argLineStarts.push(argStart); if (type === 'FunctionExpression' && item.body.body.length) { hasNonEmptyFunctionArg = true; @@ -200,8 +192,8 @@ module.exports = context => { testLineEndings = true; } - lastArgStartLine = argStart; lastArgEndLine = argEnd; + lastArgStartLine = argStart; } ); @@ -225,8 +217,8 @@ module.exports = context => { CallExpression(node) { var callee = node.callee; - var fnName = getFnName(callee); var fnLines = getFnLines(node); + var fnName = getFnName(callee); if (node.arguments.length) { logArgError(fnLines, fnName, node); diff --git a/lib/lint_js_rules/format_constants.js b/lib/lint_js_rules/format_constants.js index fbca457..a45100a 100644 --- a/lib/lint_js_rules/format_constants.js +++ b/lib/lint_js_rules/format_constants.js @@ -1,4 +1,3 @@ -var base = require('../base'); var utils = require('../rule_utils'); module.exports = context => { diff --git a/lib/lint_js_rules/format_multiline_vars.js b/lib/lint_js_rules/format_multiline_vars.js index 7e8a997..faef4ae 100644 --- a/lib/lint_js_rules/format_multiline_vars.js +++ b/lib/lint_js_rules/format_multiline_vars.js @@ -1,7 +1,9 @@ var findFirstofLastLine = (tokens, line) => { var firstOfLast = null; - for (var i = 0, len = tokens.length; i < len; i++) { + var len = tokens.length; + + for (var i = 0; i < len; i++) { var token = tokens[i]; if (token.loc.start.line === line) { @@ -56,32 +58,34 @@ module.exports = context => { var allowedFormat = isSameLine(id, init); if (!allowedFormat) { - var message = 'Variable values should start on the same line as the variable name "{{identifier}}"'; var info = { identifier: id.name }; + var message = 'Variable values should start on the same line as the variable name "{{identifier}}"'; + if (init.type === 'LogicalExpression' || init.type === 'JSXElement') { var token = context.getTokenBefore(init); allowedFormat = (token.value === '(' && isSameLine(id, token)); } else if (id.type === 'ObjectPattern' || id.type === 'ArrayPattern') { - var startToken = context.getFirstToken(id); var endToken = context.getLastToken(id); + var startToken = context.getFirstToken(id); + var keywordToken = context.getTokenBefore(id); - var startOnSameLineAsKeyword = isSameLine(keywordToken, startToken); var endOnSameLineAsInit = isSameLine(init, endToken); + var startOnSameLineAsKeyword = isSameLine(keywordToken, startToken); allowedFormat = startOnSameLineAsKeyword && endOnSameLineAsInit; if (!allowedFormat) { info = { - startToken: startToken.value, endToken: endToken.value, + initName: init.name || context.getSourceCode().getText(init), keywordToken: keywordToken.value, - initName: init.name || context.getSourceCode().getText(init) + startToken: startToken.value }; if (!startOnSameLineAsKeyword && !endOnSameLineAsInit) { diff --git a/lib/lint_js_rules/function_spacing.js b/lib/lint_js_rules/function_spacing.js index 57e566a..8574db9 100644 --- a/lib/lint_js_rules/function_spacing.js +++ b/lib/lint_js_rules/function_spacing.js @@ -27,8 +27,8 @@ module.exports = { var startLineDistance = utils.getLineDistance(nodeBody, firstStatement, 'start'); if (leadingComments.length) { - var lastLeadingComment = leadingComments[leadingComments.length - 1]; var firstLeadingComment = leadingComments[0]; + var lastLeadingComment = leadingComments[leadingComments.length - 1]; var startCommentAfterDistance = utils.getLineDistance(lastLeadingComment, firstStatement, 'start'); var startCommentBeforeDistance = utils.getLineDistance(nodeBody, firstLeadingComment, 'start'); diff --git a/lib/lint_js_rules/multiple_vars.js b/lib/lint_js_rules/multiple_vars.js index af0af3d..012c063 100644 --- a/lib/lint_js_rules/multiple_vars.js +++ b/lib/lint_js_rules/multiple_vars.js @@ -1,5 +1,3 @@ -var base = require('../base'); - var sub = require('string-sub'); module.exports = context => ({ diff --git a/lib/lint_js_rules/no_is_prefix.js b/lib/lint_js_rules/no_is_prefix.js index a2d67fd..b7043a7 100644 --- a/lib/lint_js_rules/no_is_prefix.js +++ b/lib/lint_js_rules/no_is_prefix.js @@ -1,5 +1,3 @@ -var base = require('../base'); - var REGEX = require('../regex'); var sub = require('string-sub'); @@ -9,8 +7,8 @@ module.exports = context => { var value = node.value; var valueType = value.type; - var propValueMemberExp = (valueType === 'MemberExpression'); var propValueIdentifier = (valueType === 'Identifier'); + var propValueMemberExp = (valueType === 'MemberExpression'); var processVars = true; diff --git a/lib/lint_js_rules/no_multiple_return.js b/lib/lint_js_rules/no_multiple_return.js index be654ff..0aa8db8 100644 --- a/lib/lint_js_rules/no_multiple_return.js +++ b/lib/lint_js_rules/no_multiple_return.js @@ -1,20 +1,12 @@ -var _ = require('lodash'); -var sub = require('string-sub'); - -var base = require('../base'); -var utils = require('../rule_utils'); - module.exports = { meta: { docs: { - description: 'Enforces keeping a single return within a function', category: 'Fill me in', + description: 'Enforces keeping a single return within a function', recommended: false }, - fixable: null, // or "code" or "whitespace" - schema: [ - // fill in your schema - ] + fixable: null, + schema: [] }, create(context) { @@ -32,24 +24,26 @@ module.exports = { }; return { + 'ArrowFunctionExpression:exit': checkReturns, + 'FunctionDeclaration:exit': checkReturns, + 'FunctionExpression:exit': checkReturns, + onCodePathStart(codePath) { funcInfo = { - upper: funcInfo, - returnCount: 0 + returnCount: 0, + upper: funcInfo }; }, + onCodePathEnd() { funcInfo = funcInfo.upper; }, + 'Program:exit': checkReturns, + ReturnStatement(node) { funcInfo.returnCount += 1; - }, - - 'Program:exit': checkReturns, - 'FunctionDeclaration:exit': checkReturns, - 'FunctionExpression:exit': checkReturns, - 'ArrowFunctionExpression:exit': checkReturns + } }; } }; \ No newline at end of file diff --git a/lib/lint_js_rules/no_undef.js b/lib/lint_js_rules/no_undef.js index 1907a5d..e67f46f 100644 --- a/lib/lint_js_rules/no_undef.js +++ b/lib/lint_js_rules/no_undef.js @@ -14,7 +14,13 @@ module.exports = context => { } }; - _.defaults(mockContext, context, {options: context.options}); + _.defaults( + mockContext, + context, + { + options: context.options + } + ); return { 'Program:exit': function(node) { diff --git a/lib/lint_js_rules/no_unused_vars.js b/lib/lint_js_rules/no_unused_vars.js index 44548cf..d162cad 100644 --- a/lib/lint_js_rules/no_unused_vars.js +++ b/lib/lint_js_rules/no_unused_vars.js @@ -2,7 +2,6 @@ var _ = require('lodash'); var base = require('../base'); var stubs = base.stubs; -var portletNS = base.jspLintStubs.namespace; var STUB_RE = new RegExp(`^${Object.keys(stubs).join('|')}`); @@ -13,8 +12,8 @@ module.exports = { } var lintRules = { - 'VariableDeclaration': useInstance, - 'ReturnStatement': useInstance + 'ReturnStatement': useInstance, + 'VariableDeclaration': useInstance }; var options = context.options; @@ -28,7 +27,12 @@ module.exports = { report(obj) { collectedReport.push(obj); }, - options: [{'vars': 'local', 'args': 'none'}] + options: [ + { + 'args': 'none', + 'vars': 'local' + } + ] }; _.defaults(mockContext, context); @@ -38,8 +42,6 @@ module.exports = { lintRules['Program:exit'] = node => { noUnused(mockContext)['Program:exit'](node); - // console.log(collectedReport); - collectedReport.forEach( (item, index) => { var declaration = item.node; @@ -50,9 +52,6 @@ module.exports = { var namespacedFn = false; if (namespacedVar) { - // item[0].name = name.replace(portletNS, ''); - // item[2].name = name.replace(portletNS, ''); - var parentType = declaration.parent.type; if (parentType === 'FunctionDeclaration' || @@ -67,7 +66,7 @@ module.exports = { } } ); - } + }; } return lintRules; diff --git a/lib/lint_js_rules/no_use_before_define.js b/lib/lint_js_rules/no_use_before_define.js index 40fca9a..7ec71b5 100644 --- a/lib/lint_js_rules/no_use_before_define.js +++ b/lib/lint_js_rules/no_use_before_define.js @@ -1,8 +1,5 @@ var _ = require('lodash'); -var base = require('../base'); -var stubs = base.stubs; - module.exports = context => { var noUse = require('eslint/lib/rules/no-use-before-define').create; diff --git a/lib/lint_js_rules/sort_constants.js b/lib/lint_js_rules/sort_constants.js index 67029e6..319f973 100644 --- a/lib/lint_js_rules/sort_constants.js +++ b/lib/lint_js_rules/sort_constants.js @@ -1,5 +1,4 @@ var _ = require('lodash'); -var base = require('../base'); var utils = require('../rule_utils'); var sub = require('string-sub'); @@ -7,7 +6,9 @@ var sub = require('string-sub'); var REGEX_UNDERSCORE = /_/g; module.exports = context => { + // Recursive function for collecting identifiers from node + var getIdentifiers = (node, obj) => { obj = obj || {}; diff --git a/lib/lint_js_rules/sort_props.js b/lib/lint_js_rules/sort_props.js index 67ad549..72a3d68 100644 --- a/lib/lint_js_rules/sort_props.js +++ b/lib/lint_js_rules/sort_props.js @@ -18,55 +18,9 @@ module.exports = context => { var getCacheKey = (...args) => args.join('_'); - // Recursive function for collection node values - // var getVals = function(obj, arr) { - // var type = obj.type; - - // if (type === 'BinaryExpression') { - // arr = getVals(obj.left, arr); - // arr = getVals(obj.right, arr); - // } - // else if (type === 'Literal') { - // arr.push(obj.value); - // } - // else if (type === 'Identifier') { - // arr.push(obj.name); - // } - // else if (type === 'CallExpression') { - // arr = getVals(obj.callee, arr); - // } - // else if (type === 'MemberExpression') { - // arr = getVals(obj.object, arr); - // arr = getVals(obj.property, arr); - // } - - // return arr; - // }; - - // var getPropertyNames = function(node, names) { - // names = names || []; - - // if (node.type === 'MemberExpression') { - // var obj = node.object; - - // if (obj.type === 'Identifier') { - // names.push(obj.name); - // } - // else if (obj.type === 'MemberExpression') { - // names = getPropertyNames(obj, names); - // } - - // names.push(node.property.name); - // } - - // return names; - // }; - var getPropName = obj => { var propName = ''; - // propName = getVals(obj, []).join(''); - var type = obj.type; if (type === 'Literal' || type === 'Identifier') { @@ -76,25 +30,6 @@ module.exports = context => { propName = context.getSourceCode().getText(obj); } - // if (type === 'Literal' || type === 'Identifier') { - // propName = obj.name || obj.value; - // } - // if (type === 'CallExpression') { - // if (obj.callee.type === 'Identifier') { - // propName = obj.callee.name; - // } - // else if (obj.callee.type === 'MemberExpression') { - // propName = getPropertyNames(obj.callee).join('.'); - // } - // } - // else if (type === 'MemberExpression') { - // propName = getPropertyNames(obj).join('.'); - // } - // else if (type === 'BinaryExpression') { - - // console.log(context.getSourceCode().getText(obj)); - // } - return propName; }; @@ -141,11 +76,12 @@ module.exports = context => { var naturalCompare = ruleUtils.naturalCompare; var configuration = context.options[0] || {}; + var caseSensitive = configuration.casesensitive; var checkLifecyleSort = (needsSort, propName, prevPropName, item, prev, parent) => { - var customPropName = LIFECYCLE_METHODS[propName]; var customPrevPropName = LIFECYCLE_METHODS[prevPropName]; + var customPropName = LIFECYCLE_METHODS[propName]; if (customPropName) { if (customPrevPropName) { @@ -160,8 +96,8 @@ module.exports = context => { }; var checkRegPropSort = (needsSort, propName, prevPropName, item, prev, caseSensitive, parent) => { - var privateProp = isPrivate(propName); var privatePrevProp = isPrivate(prevPropName); + var privateProp = isPrivate(propName); needsSort = (privateProp === privatePrevProp) && isMatchingCase(propName, prevPropName) && naturalCompare(propName, prevPropName, !caseSensitive) === -1 && isMatchingType(item, prev); @@ -170,7 +106,9 @@ module.exports = context => { } if (needsSort && !isFunctionExpression(item.value) && !inAttrs(parent)) { + // Allow a set of properties to be grouped with an extra newline + needsSort = (item.loc.start.line - prev.loc.end.line) < 2; } @@ -204,20 +142,20 @@ module.exports = context => { var key = item.key; var prevKey = prev.key; - var propName = getPropName(key); var prevPropName = getPropName(prevKey); + var propName = getPropName(key); var needsSort = checkSort(propName, prevPropName, item, prev, caseSensitive, node); if (needsSort) { var note = isLifecycle(propName, prevPropName) ? ' (Lifecycle methods should come first)' : ''; - var displayPropName = propName; var displayPrevPropName = prevPropName; + var displayPropName = propName; if (item.computed) { - displayPropName = getComputedPropertyName(key); displayPrevPropName = getComputedPropertyName(prevKey); + displayPropName = getComputedPropertyName(key); } var message = sub('Sort properties: {0} {1}{2}', displayPrevPropName, displayPropName, note); diff --git a/lib/lint_js_rules/sort_requires.js b/lib/lint_js_rules/sort_requires.js index 12bf987..f90c6e1 100644 --- a/lib/lint_js_rules/sort_requires.js +++ b/lib/lint_js_rules/sort_requires.js @@ -6,6 +6,7 @@ module.exports = context => ({ var elements = nodeValue.elements; if (elements.length > 1) { + // I really, really hate having two loops here, // but I can't think of any way to check only strings // in an array, allowing for the off chance of non-string values diff --git a/lib/lint_js_rules/sort_vars.js b/lib/lint_js_rules/sort_vars.js index ddfa860..dc950e0 100644 --- a/lib/lint_js_rules/sort_vars.js +++ b/lib/lint_js_rules/sort_vars.js @@ -1,4 +1,3 @@ -var base = require('../base'); var utils = require('../rule_utils'); var getLineDistance = utils.getLineDistance; @@ -6,17 +5,18 @@ var naturalCompare = utils.naturalCompare; var sub = require('string-sub'); -var REGEX_FOR = /For.*Statement/; - var REGEX_ASSIGNMENT_PATTERNS = /(Object|Array)Pattern/; +var REGEX_FOR = /For.*Statement/; + module.exports = context => { var configuration = context.options[0] || {}; + var caseSensitive = configuration.casesensitive; - var variables = []; var destructuredVars = []; var imports = []; + var variables = []; var findVars = node => { if (!REGEX_FOR.test(node.parent.type)) { @@ -56,14 +56,14 @@ module.exports = context => { }; return { - 'Program:exit': function(){ - var varGroups = variables.reduce( + 'Program:exit': function() { + variables.reduce( (prev, item, index) => { var lineDistance = getLineDistance(prev, item); if (lineDistance === 1 || lineDistance === 0) { - var prevName = prev.id.name; var curName = item.id.name; + var prevName = prev.id.name; var result = naturalCompare(curName, prevName, !caseSensitive); @@ -81,10 +81,10 @@ module.exports = context => { destructuredVars.forEach( (item, index) => { - var destructuredVarGroups = item.reduce( + item.reduce( (prev, item, index) => { - var prevName = prev.key.name; var curName = item.key.name; + var prevName = prev.key.name; var result = naturalCompare(curName, prevName, !caseSensitive); @@ -103,10 +103,10 @@ module.exports = context => { imports.forEach( (item, index) => { - var importGroups = item.reduce( + item.reduce( (prev, item, index) => { - var prevName = prev.local.name; var curName = item.local.name; + var prevName = prev.local.name; if (prevName === prev.imported.name && curName === item.imported.name) { var result = naturalCompare(curName, prevName, !caseSensitive); diff --git a/lib/logger.js b/lib/logger.js index 7fb6a21..343aae9 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -1,4 +1,3 @@ -var _ = require('lodash'); var Logger = require('content-logger'); var contentLogger = Logger.create( From c29a3c53e1bb797a81a1542ea7b6f37699e4fe0a Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 19 May 2017 12:21:19 -0700 Subject: [PATCH 147/153] Deprecating check_sf command name to use csf instead, as well as adding a deprecation warning so people can switch --- bin/index.js | 49 +++++++++++++++++++++++++++++++++++++++++++------ package.json | 4 +++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/bin/index.js b/bin/index.js index fcc462c..2124c62 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,16 +1,53 @@ #!/bin/sh ":" //# http://sambal.org/?p=1014 ; exec /usr/bin/env node --harmony "$0" "$@" +var _ = require('lodash'); +var colors = require('cli-color-keywords')(); +var ConfigStore = require('configstore'); +var path = require('path'); var updateNotifier = require('update-notifier'); +var fs = require('fs'); -var notifier = updateNotifier( - { - pkg: require('../package.json') - } -); +const ONE_DAY = 1000 * 60 * 60 * 24; + +var pkg = require('../package.json'); + +var notifier = updateNotifier({pkg}); if (notifier.update) { notifier.notify(); } -require('../lib/cli').init(); \ No newline at end of file +var cli = require('../lib/cli').init(); + +var config = new ConfigStore( + pkg.name, + { + lastPackageVersion: pkg.version, + lastUpdateCheck: Date.now() + } +); + +var lastUpdateCheck = config.get('lastUpdateCheck'); + +if (path.basename(process.argv[1]) === 'check_sf' && (Date.now() - lastUpdateCheck > ONE_DAY)) { + var unindent = (strings, ...keys) => _.zipWith(strings, keys, _.add).join('').replace(/^\s+/gm, ' '); + + cli.then( + function() { + var header = `Using the ${colors.inverse('check_sf')} form of this module is deprecated.`; + + var footer = `Please use the ${colors.inverse('csf')} command instead. It's easier to type too!`; + + var maxLineLength = Math.max(header.length, footer.length); + + var bar = new Array(maxLineLength).join('-'); + + console.log(unindent`${bar} + ${colors.error(header)} + ${colors.green(footer)}`); + + config.set('lastUpdateCheck', Date.now()); + } + ); +} \ No newline at end of file diff --git a/package.json b/package.json index 2eb2da0..596aa89 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Check the source formatting of HTML/JS/CSS", "main": "lib/cli.js", "bin": { - "check_sf": "./bin/index.js" + "check_sf": "./bin/index.js", + "csf": "./bin/index.js" }, "scripts": { "coveralls": "gulp coveralls", @@ -25,6 +26,7 @@ "bluebird": "^3.4.1", "cli": "^1.0.0", "cli-color-keywords": "0.0.1", + "configstore": "^3.1.0", "content-formatter": "^2.0.2", "content-logger": "^1.0.1", "content-logger-handlebars-helpers": "0.0.1", From b08b38c47574be5075cb032837e368545dd6e423 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 19 May 2017 13:38:37 -0700 Subject: [PATCH 148/153] Moving deprecation checking into it's own module with tests --- bin/index.js | 44 ++++++++++----------------- lib/deprecation.js | 38 ++++++++++++++++++++++++ test/deprecation.js | 72 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 29 deletions(-) create mode 100644 lib/deprecation.js create mode 100644 test/deprecation.js diff --git a/bin/index.js b/bin/index.js index 2124c62..d05bf39 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,14 +1,10 @@ #!/bin/sh ":" //# http://sambal.org/?p=1014 ; exec /usr/bin/env node --harmony "$0" "$@" -var _ = require('lodash'); -var colors = require('cli-color-keywords')(); var ConfigStore = require('configstore'); -var path = require('path'); var updateNotifier = require('update-notifier'); -var fs = require('fs'); -const ONE_DAY = 1000 * 60 * 60 * 24; +var deprecationCheck = require('../lib/deprecation'); var pkg = require('../package.json'); @@ -18,8 +14,6 @@ if (notifier.update) { notifier.notify(); } -var cli = require('../lib/cli').init(); - var config = new ConfigStore( pkg.name, { @@ -28,26 +22,18 @@ var config = new ConfigStore( } ); -var lastUpdateCheck = config.get('lastUpdateCheck'); - -if (path.basename(process.argv[1]) === 'check_sf' && (Date.now() - lastUpdateCheck > ONE_DAY)) { - var unindent = (strings, ...keys) => _.zipWith(strings, keys, _.add).join('').replace(/^\s+/gm, ' '); - - cli.then( - function() { - var header = `Using the ${colors.inverse('check_sf')} form of this module is deprecated.`; - - var footer = `Please use the ${colors.inverse('csf')} command instead. It's easier to type too!`; - - var maxLineLength = Math.max(header.length, footer.length); - - var bar = new Array(maxLineLength).join('-'); - - console.log(unindent`${bar} - ${colors.error(header)} - ${colors.green(footer)}`); - - config.set('lastUpdateCheck', Date.now()); +var cli = require('../lib/cli').init().then( + function() { + var deprecated = deprecationCheck( + { + config, + pkg, + scriptName: process.argv[1] + } + ); + + if (deprecated) { + console.log(deprecated); } - ); -} \ No newline at end of file + } +); \ No newline at end of file diff --git a/lib/deprecation.js b/lib/deprecation.js new file mode 100644 index 0000000..2323d09 --- /dev/null +++ b/lib/deprecation.js @@ -0,0 +1,38 @@ +var _ = require('lodash'); +var colors = require('cli-color-keywords')(); +var path = require('path'); + +var unindent = (strings, ...keys) => _.zipWith(strings, keys, _.add).join('').replace(/^\s+/gm, ' '); + +function deprecationCheck(params) { + var config = params.config; + var scriptName = params.scriptName; + + var checkInterval = params.interval || deprecationCheck.INTERVAL; + + var lastDeprecationCheck = config.get('lastDeprecationCheck'); + + var retVal = ''; + + if (path.basename(scriptName) === 'check_sf' && (Date.now() - lastDeprecationCheck >= checkInterval)) { + var header = `Using the ${colors.inverse('check_sf')} form of this module is deprecated.`; + + var footer = `Please use the ${colors.inverse('csf')} command instead. It's easier to type too!`; + + var maxLineLength = Math.max(header.length, footer.length); + + var bar = new Array(maxLineLength).join('-'); + + config.set('lastDeprecationCheck', Date.now()); + + retVal = unindent`${bar} + ${colors.error(header)} + ${colors.green(footer)}`; + } + + return retVal; +} + +deprecationCheck.INTERVAL = 1000 * 60 * 60 * 24; + +module.exports = deprecationCheck; \ No newline at end of file diff --git a/test/deprecation.js b/test/deprecation.js new file mode 100644 index 0000000..62cde33 --- /dev/null +++ b/test/deprecation.js @@ -0,0 +1,72 @@ +var path = require('path'); +var fs = require('fs'); +var chai = require('chai'); +var _ = require('lodash'); + +var deprecationCheck = require('../lib/deprecation'); + +chai.use(require('chai-string')); + +var assert = chai.assert; + +var INTERVAL = deprecationCheck.INTERVAL; + +var configStore = { + get(key) { + return this[key]; + }, + + set(key, value) { + this[key] = value; + } +}; + +var expectedMessage = `----------------------------------------------------------- + Using the check_sf form of this module is deprecated. + Please use the csf command instead. It's easier to type too!`; + +describe( + 'deprecation checking', + function () { + 'use strict'; + + it( + 'should return a deprecation message', + function() { + var config = Object.create(configStore); + + config.set('lastDeprecationCheck', Date.now() - INTERVAL); + + var message = deprecationCheck( + { + config, + scriptName: 'check_sf' + } + ); + + assert.isString(message); + assert.isAbove(message.length, 0); + assert.equal(message, expectedMessage); + } + ); + + it( + 'should not return a deprecation message', + function() { + var config = Object.create(configStore); + + config.set('lastDeprecationCheck', Date.now()); + + var message = deprecationCheck( + { + config, + scriptName: 'check_sf' + } + ); + + assert.isString(message); + assert.equal(message.length, 0); + } + ); + } +); \ No newline at end of file From 5872c7721a253fdfb540cb95bf5a7500ee479e23 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 19 May 2017 13:45:23 -0700 Subject: [PATCH 149/153] Remove duplicate message logging for console.log warnings (eslint is already doing the checking) --- lib/engine_rules/js.js | 2 +- test/engine_rules/js.js | 2 +- test/js.js | 7 ------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/engine_rules/js.js b/lib/engine_rules/js.js index 1992e72..cd7b80d 100644 --- a/lib/engine_rules/js.js +++ b/lib/engine_rules/js.js @@ -64,7 +64,7 @@ module.exports = { }, logging: { - message: 'Debugging statement: {1}', + message: false, regex: /\bconsole\.[^\(]+?\(/, valid(rule, context) { return !context.hasSheBang; diff --git a/test/engine_rules/js.js b/test/engine_rules/js.js index ea75796..ade7e02 100644 --- a/test/engine_rules/js.js +++ b/test/engine_rules/js.js @@ -155,7 +155,7 @@ describe( var lineNum = 1; assert.isTrue(result); - assert.startsWith(re.getMessage(result, rule, context), 'Debugging statement'); + assert.isUndefined(re.getMessage(result, rule, context)); assert.equal(content, re.replaceItem(result, rule, context)); } ); diff --git a/test/js.js b/test/js.js index fc4f67a..ec050cb 100644 --- a/test/js.js +++ b/test/js.js @@ -76,13 +76,6 @@ describe( } ); - it( - 'should recognize debugging statements', - function() { - assert.startsWith(getErrorMsgByLine(21, jsErrors), 'Debugging statement:'); - } - ); - it( 'should recognize variable line spacing', function() { From 1a9be5026373b658059531f568822f0626778883 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Fri, 19 May 2017 15:16:03 -0700 Subject: [PATCH 150/153] Updating README --- README.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5403610..a1f95e5 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,12 @@ check-source-formatting ### Jump to Section - [Description](#description) +- [What's new](#whats-new) - [Installation](#installation) - [Usage](#usage) - [Options](#options) - [Sublime Text Integration](#sublime-text-integration) +- [Custom configuration](#custom-configuration) - [Known issues](#known-issues) @@ -54,6 +56,19 @@ This will scan through HTML(-like) files, JS files, and CSS files and detect man - Variable names starting with `is` (it ignores methods, which is valid, but properties and variables should not have a prefix of `is`) - **Experimental** Will try to parse JavaScript inside of blocks +## What's new +As of v2, there are a few new features: + +- [Custom configuration](#custom-configuration) +- Custom configuration on a per file basis or using globs +- New, [shorter command](#v2-deprecation-notice): `csf` +- Now able to check on both ES6+ and JSX syntaxes +- Uses stylelint for CSS checking, which should reduce false positives +- Now requires Node 4+ + +### API Changes +For any consumers of the API, there was previously no way to know when the CLI object had finished reading the files and reporting the errors, whereas now, `cli.init()` returns a promise so you can run anything you want to after everything has been processed. + ## Installation ``` @@ -62,33 +77,39 @@ This will scan through HTML(-like) files, JS files, and CSS files and detect man ## Usage +### V2 Deprecation notice: +> The `check_sf` command is now deprecated in favor of the new `csf` command. +> They're identical (though `check_sf` will periodically warn you that it's deprecated), but `check_sf` will be removed in the next major version. + The simplest way to run it is: ``` -check_sf path/to/file +csf path/to/file ``` However, you can also check multiple files at once: ``` -find . -name '*.css' | xargs check_sf +find . -name '*.css' | xargs csf ``` I find it easier to use it with pull requests and check the files that were changed on the branch. In my .gitconfig I have: ``` -sfm = "!f() { git diff --stat --name-only master.. | grep -E '.(jsp.?|vm|ftl|tag|tpl|tmpl|js|soy|hbs|(s)?css)$' | tr \"\\n\" \"\\0\" | xargs -0 -J{} check_sf {} $@; }; f" +sfm = "!f() { git diff --stat --name-only master.. | tr \"\\n\" \"\\0\" | xargs -0 -J{} csf {} $@; }; f" ``` -(You could get rid of the grep portion, but I find it easier to just filter them out on this level). - When someone sends me a pull request, I check out the branch and run `git sfm` and it scans the changed files and reports any issues. ## Options There are some options that you can pass to the command: +`--config` If you pass this flag with a path to a configuration file, it will use that one instead of looking up one. + +If you pass `--no-config`, it will disable any custom configuration look ups, and only use the defaults. + `-q, --quiet` will set it so that it only shows files that have errors. By default it will log out all files and report 'clear' if there are no errors. `-o, --open` If you have an editor specified in your gitconfig (under user.editor), this will open all of the files that have errors in your editor. @@ -112,7 +133,7 @@ If you pass `--no-lint` it will overwrite the default and disable linting. This is mainly useful when you want to show the file name relative to your current working directory. I use it mainly when I'm running this on a git branch. In order for it to work from your alias, you would need to change the above alias to be: ``` -sfm = "!f() { export GIT_PWD=\"$GIT_PREFIX\"; git diff --stat --name-only master.. | grep -E '.(jsp.?|vm|ftl|tag|tpl|tmpl|js|(s)?css)$' | xargs check_sf $@; }; f" +sfm = "!f() { export GIT_PWD=\"$GIT_PREFIX\"; git diff --stat --name-only master.. | tr \"\\n\" \"\\0\" | xargs csf $@; }; f" ``` `-v, --verbose` This will log out any possible error, even ones that are probably a false positive. @@ -128,7 +149,7 @@ However, passing -v will show these errors (marked with a **). If you pass `--no-color` it will overwrite the default and give you plain text. -`--lint-ids` Previously, all errors that were generated by ESLint included their rule ID in the error message. This is no longer true by default (as it adds a lot of noise), but you can turn it on by adding this option. +`--lint-ids` Previously, all errors that were generated by ESLint or stylelint included their rule ID in the error message. This is no longer true by default (as it adds a lot of noise), but you can turn it on by adding this option. `-m`, `--check-metadata` If we're inside of a portal repository, and one of the files is in the /html/js/liferay/ directory, check all of the modules in that directory, and see if the requires metadata in the files matches the metadata in the modules.js file. @@ -142,11 +163,12 @@ There are now two ways you can integrate this module with Sublime Text: ### As a build system You can setup a build system in Sublime Text to run the formatter on the file you are working in, and this is the simplest of the options. You can set up your build system using the following steps: + - Go to the menu labeled Tools > Build System > New Build System -- Use the following code for the new build system and save the file +- Use the following code for the new build system and save the file
``` { - "shell_cmd": "check_sf $file" + "shell_cmd": "csf $file" } ``` - Go to Tools > Build System and select the system you created @@ -159,6 +181,7 @@ You can also use [Sublime Linter](http://www.sublimelinter.com/en/latest/) to vi [![Sublime Linter](/../screenshots/images/sublime_linter.png?raw=true "Sublime Linter")](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting) You can install it via a couple of steps: + - Install [Sublime Linter](http://www.sublimelinter.com/en/latest/) via Package Control - Install the [SublimeLinter-contrib-check-source-formatting](https://packagecontrol.io/packages/SublimeLinter-contrib-check-source-formatting) package via Package Control - In order to get it to lint, you may need to either manually lint it (in the Command Palette, type "Lint this view" and select it), or you may wish to change when it lints (in the Command Palette again, type "Choose Lint Mode", and select when you want it to lint the file). @@ -167,6 +190,7 @@ You can read more on [the project page](https://packagecontrol.io/packages/Subli Thanks to [Drew Brokke](https://github.com/drewbrokke) for writing the plugin and publishing it. ### As an Atom Linter plugin + - Install [liferay-linter](https://atom.io/packages/linter-liferay) via `apm install linter linter-liferay` You can read more on [the github page](https://github.com/mthadley/linter-liferay). @@ -175,35 +199,42 @@ Thanks to [Michael Hadley](https://github.com/mthadley) for writing the plugin a ## Custom configuration Starting in version 2, you can now customize the configuration of the engine in a few different ways. Here are the items you can currently customize: - - CLI Flags + - ESLint rules + - stylelint rules I'm planning on expanding this into more areas, but currently those are the two sections that can be modified. How do you define a custom configuration? We are currently using [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to look for configuration files, which means you can define custom configuration by adding any one of the following files somewhere in the current working directory or one of the parent directories: + - Inside of `package.json`, using a custom key of `csfConfig` - `csf.config.js` - `.csfrc` in JSON or YAML format -Also note, the configuration will stop searching after it finds the first file it can find and that configurations are *NOT* merged (I may change this in the future). - What does the structure of the configuration look like? Let's say we create a `.csf.config.js` file, our configuration, at the very least, should export a JSON object like so: + ``` module.exports = {}; ``` Here is an example of a config with all keys defined: + ``` module.exports = { - flags: {}, + css: { + lint: {} + }, js: { lint: {} }, html: { + css: { + lint: {} + }, js: { lint: {} } @@ -217,21 +248,74 @@ Here is an example of a config with all keys defined: ``` (please note, if using one of the JSON files, you'll need to quote the Object keys, however, there are some benefits to using a plain JS file, which I'll mention below). + And here are the descriptions of what they do: -- `flags` - This will default any of the flags listed above to whatever option you specify (.e.g. `quiet`). You *must* use the long form the flag, however. -- `lint` - These accept any option that can be passed to [ESLint](http://eslint.org/docs/user-guide/configuring), you can set here. This includes any environment or globals you wish to define, rules you wish to define, etc.
-This means anywhere the lint object is called, you can set the rules. +- `css.lint` - These accept any option that can be passed to [stylelint](https://stylelint.io/user-guide/configuration/#rules), which is really just the rule configuration.
+This means anywhere the lint object is called, you can set the rules. +- `lint` - These accept any option that can be passed to [ESLint](http://eslint.org/docs/user-guide/configuring), you can set here. This includes any environment or globals you wish to define, rules you wish to define, etc.
+This means anywhere the lint object is called, you can set the rules.
+The `html.css.lint` property is only applied for style blocks inside of HTML-like files that go through the HTML formatter. This property is merged on top of anything specified in `css.lint`.
The `html.js.lint` property is only applied for script blocks inside of HTML-like files that go through the HTML formatter. This property is merged on top of anything specified in `js.lint`. -You'll also notice that a key there of `path:**/*.something.js`. This allows you to specify a configuration to a specific file path, or a glob referencing a file path. -Any files matching that glob will apply those rules on top of the ones inside of `js.lint`, and `html.js.lint`. +You'll also notice that a key there of `path:**/*.something.js`. This allows you to specify a configuration to a specific file path, or a glob referencing a file path.
+Any files matching that glob will apply those rules on top of the ones inside of `css.lint`, `js.lint`, `html.css.lint`, and `html.js.lint`. #### Benefits to using `.js` over `.json`? As I mentioned before, there are some benefits to using a `.js` file, but mainly is that it's less strict about what can go inside of the file, so you can use comments, and unquoted keys. But also, any configuration you define with a function as the value, that function will be executed, and anything you return from there will be used as the value. This means you can dynamically configure the script at runtime. +### Using ESlint plugins +You can configure ESLint to leverage specific plugins for your project. +The way you would do this is slightly hokey, but it's because ESLint only looks for plugins next to where eslint itself is installed. Because of this limitation, we need a path to the plugin you wish to use. + +Here's how you would set it up to use, let's say the [Lodash eslint plugin](https://www.npmjs.com/package/eslint-plugin-lodash): + +1. In your project, run the following command:
+``` + npm install --save-dev eslint-plugin-lodash +``` +2. In your configuration file, add the following: +``` +{ + "js": { + "lint": { + "plugins": ["./node_modules/eslint-plugin-lodash"] + } + } +} +``` +3. Then, in the same block, you can configure any rules from the plugin by adding a `rules` object, and configuring it like so: +``` +{ + "js": { + "lint": { + "plugins": ["./node_modules/eslint-plugin-lodash"], + "rules": { + "lodash/prefer-noop": 2 + } + } + } +} +``` + +Right now, it's not possible to use stylelint plugins, but I'll be adding support for that soon. +You can still, however, configure the rules included with stylelint. + +### JSX and ES6/7 +We include the [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) by default, but we only turn it on for projects that are using JSX syntax (whether it's React or [MetalJS](http://metaljs.com)), but you need to explicitly opt into ES6 or above in your configuration. +We currently handle es7 code, but we don't enable any of the future focused rules such as [prefer-template](http://eslint.org/docs/rules/prefer-template), unless you set your lint.parserOptions.ecmaVersion to 7 in your config file. +This is how you would do it: +``` + "lint": { + "parserOptions": { + "ecmaVersion": 7 + } + } +``` +Once you have that set, it will enable the react plugin rules for JSX syntax checking, and for upgrading your code to more future focused syntax. + ## Known issues The following are known issues where it will say there's an error, but there's not (or where there should be an error but there's not) From bfe8d7c69598d2e5c16d38f210e7c8e6d810ab6e Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 22 Aug 2017 09:53:37 -0700 Subject: [PATCH 151/153] Update deps --- package-lock.json | 14667 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 16 +- 2 files changed, 14675 insertions(+), 8 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2bb2faf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,14667 @@ +{ + "name": "check-source-formatting", + "version": "2.0.0-rc.7", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "2.1.1" + } + }, + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.0" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "requires": { + "sprintf-js": "1.0.3" + } + }, + "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-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.8.0" + } + }, + "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 + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "requires": { + "babel-code-frame": "6.22.0", + "babel-traverse": "6.24.1", + "babel-types": "6.24.1", + "babylon": "6.17.1" + }, + "dependencies": { + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "js-tokens": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=" + } + } + }, + "babel-traverse": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.24.1.tgz", + "integrity": "sha1-qzZnP9NW+aCUhlnnszjV/q2zFpU=", + "requires": { + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.24.1", + "babylon": "6.17.1", + "debug": "2.6.6", + "globals": "9.17.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + } + } + }, + "debug": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz", + "integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=", + "requires": { + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + } + } + }, + "globals": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", + "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=" + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "requires": { + "loose-envify": "1.3.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.1" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=" + } + } + } + } + } + } + }, + "babel-types": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.24.1.tgz", + "integrity": "sha1-oTaHncFbNga9oNkMH8dDBML/CXU=", + "requires": { + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + }, + "dependencies": { + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + } + } + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babylon": { + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.1.tgz", + "integrity": "sha1-F/FP3fNhtpWYH+Z5OF5PHAHr2G8=" + } + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "boxen": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.1.tgz", + "integrity": "sha1-DxHn/jRO25OXl3/BPt5/ZNlWSB0=", + "requires": { + "ansi-align": "2.0.0", + "camelcase": "4.1.0", + "chalk": "2.1.0", + "cli-boxes": "1.0.0", + "string-width": "2.1.1", + "term-size": "1.2.0", + "widest-line": "1.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + } + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + }, + "dependencies": { + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "file:node_shrinkwrap/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "file:node_shrinkwrap/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + } + } + }, + "chai-string": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.4.0.tgz", + "integrity": "sha1-NZFAwFHTak5LGl/GuRAVL0OKjUk=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "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=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "requires": { + "exit": "0.1.2", + "glob": "7.1.2" + }, + "dependencies": { + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "cli-color-keywords": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/cli-color-keywords/-/cli-color-keywords-0.0.1.tgz", + "integrity": "sha1-3eoJX653nJ5LT0FYHsenbbSOlLc=", + "requires": { + "chalk": "1.1.3", + "lodash": "3.10.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "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 + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "configstore": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", + "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", + "requires": { + "dot-prop": "4.2.0", + "graceful-fs": "4.1.11", + "make-dir": "1.0.0", + "unique-string": "1.0.0", + "write-file-atomic": "2.3.0", + "xdg-basedir": "3.0.0" + } + }, + "content-formatter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/content-formatter/-/content-formatter-2.0.2.tgz", + "integrity": "sha1-dqUrLiSQy1dLsEqeojZoypwiAqo=", + "requires": { + "drip": "1.4.0", + "lodash": "4.17.4" + } + }, + "content-logger": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-logger/-/content-logger-1.0.1.tgz", + "integrity": "sha1-dsobrEkqmKoL/xhIfkr2bHxvFlM=", + "requires": { + "content-logger-handlebars-helpers": "0.0.1", + "drip": "1.4.0", + "lodash": "4.17.4" + } + }, + "content-logger-handlebars-helpers": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/content-logger-handlebars-helpers/-/content-logger-handlebars-helpers-0.0.1.tgz", + "integrity": "sha1-V797IGgUio4PZItp+SnF0qUNQr0=", + "requires": { + "cli-color-keywords": "0.0.1", + "handlebars": "3.0.3", + "lodash": "3.10.1" + }, + "dependencies": { + "handlebars": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-3.0.3.tgz", + "integrity": "sha1-DgllGi8Ps8lJFgWDcQ1VH5Lm0q0=", + "requires": { + "optimist": "0.6.1", + "source-map": "0.1.43", + "uglify-js": "2.3.6" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": "1.0.1" + }, + "dependencies": { + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + } + } + }, + "uglify-js": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", + "integrity": "sha1-+gmEdwtCi3qbKoBY9GNV0U/vIRo=", + "optional": true, + "requires": { + "async": "0.2.10", + "optimist": "0.3.7", + "source-map": "0.1.43" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "optional": true + }, + "optimist": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", + "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", + "optional": true, + "requires": { + "wordwrap": "0.0.3" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "optional": true + } + } + } + } + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.9.1", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + } + }, + "coveralls": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.1.tgz", + "integrity": "sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg=", + "dev": true, + "requires": { + "js-yaml": "3.6.1", + "lcov-parse": "0.0.10", + "log-driver": "1.2.5", + "minimist": "1.2.0", + "request": "2.79.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + }, + "dependencies": { + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + } + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, + "log-driver": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", + "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.0.1" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + } + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + }, + "dependencies": { + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + } + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.9.0", + "is-my-json-valid": "2.16.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": "1.0.1" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + } + } + }, + "is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + }, + "dependencies": { + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + }, + "dependencies": { + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + } + } + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + } + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "jsprim": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "dev": true, + "requires": { + "extsprintf": "1.0.2" + } + } + } + }, + "sshpk": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", + "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "jodid25519": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true, + "requires": { + "mime-db": "1.27.0" + }, + "dependencies": { + "mime-db": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true, + "requires": { + "punycode": "1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + }, + "uuid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", + "dev": true + } + } + } + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "1.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "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=" + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "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==", + "requires": { + "is-obj": "1.0.1" + } + }, + "drip": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/drip/-/drip-1.4.0.tgz", + "integrity": "sha1-JDhhZq2QrsZ9aYYaGAieET7fJgI=", + "requires": { + "tea-concat": "0.1.0" + }, + "dependencies": { + "tea-concat": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tea-concat/-/tea-concat-0.1.0.tgz", + "integrity": "sha1-6i6QdAD914pjNM4CD6PGlQLZnoQ=" + } + } + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.18" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.8.0.tgz", + "integrity": "sha512-Cf9/h5MrXtExM20gSS55YFrGKCyPrRBjIVBtVyy8vmlsDfe0NPKMWj65tPLgzyfPuapWxh5whpXCtW4+AW5mRg==", + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.0", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "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": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "requires": { + "babel-code-frame": "6.22.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.6", + "doctrine": "2.0.0", + "escope": "3.6.0", + "espree": "3.4.3", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.17.0", + "ignore": "3.3.0", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.8.4", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.7", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.1" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=" + } + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.2.9", + "typedarray": "0.0.6" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + } + } + }, + "debug": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz", + "integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=", + "requires": { + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + } + } + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.1.0", + "estraverse": "4.2.0" + }, + "dependencies": { + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16", + "es6-iterator": "2.0.1", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.16" + } + }, + "es5-ext": { + "version": "0.10.16", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.16.tgz", + "integrity": "sha1-HvGwTz0J22pdYwIm1iIC8uQl5Fo=", + "requires": { + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16", + "es6-symbol": "3.1.1" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16" + } + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16" + } + } + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.16" + } + }, + "es5-ext": { + "version": "0.10.16", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.16.tgz", + "integrity": "sha1-HvGwTz0J22pdYwIm1iIC8uQl5Fo=", + "requires": { + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16", + "es6-symbol": "3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.16" + } + } + } + }, + "esrecurse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=", + "requires": { + "estraverse": "4.1.1", + "object-assign": "4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + } + } + }, + "espree": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", + "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", + "requires": { + "acorn": "5.0.3", + "acorn-jsx": "3.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=" + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + } + } + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "requires": { + "estraverse": "4.2.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "file:node_shrinkwrap/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "1.2.2", + "object-assign": "4.1.1" + }, + "dependencies": { + "flat-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "requires": { + "circular-json": "0.3.1", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + }, + "dependencies": { + "circular-json": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=" + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" + }, + "dependencies": { + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + }, + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + } + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + } + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "requires": { + "is-path-inside": "1.0.0" + }, + "dependencies": { + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "requires": { + "path-is-inside": "1.0.2" + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "requires": { + "glob": "7.1.2" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "0.5.1" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "globals": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", + "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=" + }, + "ignore": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.0.tgz", + "integrity": "sha1-OBLSLL6RJfLCtJFXVaG4q9dFoAE=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.1.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "1.0.1" + }, + "dependencies": { + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + }, + "dependencies": { + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + } + } + } + } + }, + "cli-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + }, + "dependencies": { + "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=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" + } + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "requires": { + "once": "1.4.0" + }, + "dependencies": { + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + } + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + } + } + }, + "is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + }, + "dependencies": { + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + }, + "dependencies": { + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + } + } + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "requires": { + "tryit": "1.0.3" + }, + "dependencies": { + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=" + } + } + }, + "js-yaml": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", + "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", + "requires": { + "argparse": "1.0.9", + "esprima": "3.1.3" + }, + "dependencies": { + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "requires": { + "sprintf-js": "1.0.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + } + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + } + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + }, + "dependencies": { + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + } + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + }, + "dependencies": { + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "1.1.2" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + }, + "dependencies": { + "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=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "1.1.2" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + } + } + }, + "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=" + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + }, + "dependencies": { + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "0.2.0" + }, + "dependencies": { + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + } + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + } + } + }, + "shelljs": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz", + "integrity": "sha1-svXHfvlxSPS09uImguELuoZnz/E=", + "requires": { + "glob": "7.1.2", + "interpret": "1.0.3", + "rechoir": "0.6.2" + }, + "dependencies": { + "interpret": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=" + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "1.3.3" + }, + "dependencies": { + "resolve": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "requires": { + "path-parse": "1.0.5" + }, + "dependencies": { + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + } + } + } + } + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "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=" + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.0.0" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + } + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "file:node_shrinkwrap/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + }, + "string-width": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + } + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "file:node_shrinkwrap/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + } + } + } + } + }, + "eslint-plugin-dollar-sign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-dollar-sign/-/eslint-plugin-dollar-sign-1.0.0.tgz", + "integrity": "sha1-r7pQRZ6d6XpfzXdjJ55MOp4ltaw=", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.3.0.tgz", + "integrity": "sha512-7L6QEOxm7XhcDoe+U9Qt7GJjU6KeQOX9jCLGE8EPGF6FQbwZ9LgcBzsjXIZv9oYvNQlvQZmLjJs76xEeWsI4QA==", + "requires": { + "doctrine": "2.0.0", + "has": "1.0.1", + "jsx-ast-utils": "2.0.0", + "prop-types": "15.5.10" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "external-editor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", + "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "dev": true, + "requires": { + "iconv-lite": "0.4.18", + "jschardet": "1.5.1", + "tmp": "0.0.31" + } + }, + "falafel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", + "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=", + "requires": { + "acorn": "1.2.2", + "foreach": "2.0.5", + "isarray": "0.0.1", + "object-keys": "1.0.11" + }, + "dependencies": { + "acorn": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", + "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + } + } + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "fbjs": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.14.tgz", + "integrity": "sha1-0dviviVMNakeCfMfnNUKQLKg7Rw=", + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.14" + } + }, + "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" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "dev": true, + "requires": { + "archy": "1.0.0", + "chalk": "1.1.3", + "deprecated": "0.0.1", + "gulp-util": "3.0.8", + "interpret": "1.0.3", + "liftoff": "2.3.0", + "minimist": "1.2.0", + "orchestrator": "0.3.8", + "pretty-hrtime": "1.0.3", + "semver": "4.3.6", + "tildify": "1.2.0", + "v8flags": "2.1.1", + "vinyl-fs": "0.3.14" + }, + "dependencies": { + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", + "dev": true + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "interpret": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "liftoff": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "dev": true, + "requires": { + "extend": "3.0.1", + "findup-sync": "0.4.3", + "fined": "1.0.2", + "flagged-respawn": "0.3.2", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.mapvalues": "4.6.0", + "rechoir": "0.6.2", + "resolve": "1.3.3" + }, + "dependencies": { + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "findup-sync": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "dev": true, + "requires": { + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" + }, + "dependencies": { + "detect-file": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "dev": true, + "requires": { + "fs-exists-sync": "0.1.0" + }, + "dependencies": { + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + } + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.0", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.0.3" + }, + "dependencies": { + "arr-flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", + "dev": true + } + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + }, + "dependencies": { + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.6", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + }, + "dependencies": { + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.0" + } + }, + "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" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "randomatic": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "kind-of": "3.2.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + } + } + } + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + }, + "dependencies": { + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "kind-of": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.1" + }, + "dependencies": { + "remove-trailing-separator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", + "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + }, + "dependencies": { + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "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 + } + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.2", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + } + } + }, + "is-dotfile": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=", + "dev": true + } + } + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + }, + "dependencies": { + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + } + } + } + } + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "requires": { + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" + }, + "dependencies": { + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + } + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "requires": { + "global-prefix": "0.1.5", + "is-windows": "0.2.0" + }, + "dependencies": { + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1", + "ini": "1.3.4", + "is-windows": "0.2.0", + "which": "1.2.14" + }, + "dependencies": { + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + }, + "dependencies": { + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + } + } + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + } + } + } + } + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + } + } + } + } + } + } + }, + "fined": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz", + "integrity": "sha1-WyhCS3YNdZiWC374SA3/itNmDpc=", + "dev": true, + "requires": { + "expand-tilde": "1.2.2", + "lodash.assignwith": "4.2.0", + "lodash.isempty": "4.4.0", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.pick": "4.4.0", + "parse-filepath": "1.0.1" + }, + "dependencies": { + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + } + } + }, + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", + "dev": true + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "parse-filepath": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "dev": true, + "requires": { + "is-absolute": "0.2.6", + "map-cache": "0.2.2", + "path-root": "0.1.1" + }, + "dependencies": { + "is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "dev": true, + "requires": { + "is-relative": "0.2.1", + "is-windows": "0.2.0" + }, + "dependencies": { + "is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "dev": true, + "requires": { + "is-unc-path": "0.1.2" + }, + "dependencies": { + "is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "dev": true, + "requires": { + "unc-path-regex": "0.1.2" + }, + "dependencies": { + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + } + } + } + } + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "0.1.2" + }, + "dependencies": { + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + } + } + } + } + } + } + }, + "flagged-respawn": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.3.3" + } + }, + "resolve": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "dev": true, + "requires": { + "path-parse": "1.0.5" + }, + "dependencies": { + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + } + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dev": true, + "requires": { + "end-of-stream": "0.1.5", + "sequencify": "0.0.7", + "stream-consume": "0.1.0" + }, + "dependencies": { + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "dev": true, + "requires": { + "once": "1.3.3" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + } + } + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "dev": true + }, + "stream-consume": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "dev": true + } + } + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + } + } + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "1.1.1" + }, + "dependencies": { + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + } + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "dev": true, + "requires": { + "defaults": "1.0.3", + "glob-stream": "3.1.18", + "glob-watcher": "0.0.6", + "graceful-fs": "3.0.11", + "mkdirp": "0.5.1", + "strip-bom": "1.0.0", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + } + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dev": true, + "requires": { + "glob": "4.5.3", + "glob2base": "0.0.12", + "minimatch": "2.0.10", + "ordered-read-streams": "0.1.0", + "through2": "0.6.5", + "unique-stream": "1.0.0" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" + }, + "dependencies": { + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + } + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true, + "requires": { + "find-index": "0.1.1" + }, + "dependencies": { + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "dev": true + } + } + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "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 + } + } + } + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", + "dev": true + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "dev": true + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "dev": true, + "requires": { + "gaze": "0.5.2" + }, + "dependencies": { + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "dev": true, + "requires": { + "globule": "0.1.0" + }, + "dependencies": { + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "dev": true, + "requires": { + "glob": "3.1.21", + "lodash": "1.0.2", + "minimatch": "0.2.14" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" + }, + "dependencies": { + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + } + } + }, + "lodash": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + } + } + } + } + } + } + } + } + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dev": true, + "requires": { + "natives": "1.1.0" + }, + "dependencies": { + "natives": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", + "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "is-utf8": "0.2.1" + }, + "dependencies": { + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + } + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + } + } + }, + "gulp-complexity": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/gulp-complexity/-/gulp-complexity-0.3.2.tgz", + "integrity": "sha1-yPn2L1WuqK8ROCK6gBkqwtTlMlI=", + "dev": true, + "requires": { + "chalk": "0.4.0", + "complexity-report": "0.6.2", + "gulp-util": "2.2.20", + "multiline": "0.2.0", + "string-interpolate": "0.1.1", + "through2": "0.4.2", + "util-extend": "1.0.3" + }, + "dependencies": { + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "complexity-report": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/complexity-report/-/complexity-report-0.6.2.tgz", + "integrity": "sha1-XgLgp2ZIKNDLWt/0PK0pd4RIIPw=", + "dev": true, + "requires": { + "check-types": "0.3.1", + "commander": "1.1.1", + "esprima": "1.0.4" + }, + "dependencies": { + "check-types": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-0.3.1.tgz", + "integrity": "sha1-DA1G8yq4mgHKq+AM0S4p+vJx89A=", + "dev": true + }, + "commander": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-1.1.1.tgz", + "integrity": "sha1-UNFlGGiuYOzP8KLZ80WVN2vGsEE=", + "dev": true, + "requires": { + "keypress": "0.1.0" + }, + "dependencies": { + "keypress": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", + "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=", + "dev": true + } + } + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "dev": true + } + } + }, + "gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "dateformat": "1.0.12", + "lodash._reinterpolate": "2.4.1", + "lodash.template": "2.4.1", + "minimist": "0.2.0", + "multipipe": "0.1.2", + "through2": "0.5.1", + "vinyl": "0.2.3" + }, + "dependencies": { + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "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 + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + } + } + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + } + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + } + } + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.8", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + }, + "dependencies": { + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + }, + "dependencies": { + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "normalize-package-data": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", + "dev": true, + "requires": { + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + } + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "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 + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" + }, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "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.3.1" + }, + "dependencies": { + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + }, + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + } + } + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + } + } + } + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + }, + "dependencies": { + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + }, + "dependencies": { + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + } + } + } + } + } + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + } + } + } + } + }, + "lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", + "dev": true + }, + "lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", + "dev": true, + "requires": { + "lodash._escapestringchar": "2.4.1", + "lodash._reinterpolate": "2.4.1", + "lodash.defaults": "2.4.1", + "lodash.escape": "2.4.1", + "lodash.keys": "2.4.1", + "lodash.templatesettings": "2.4.1", + "lodash.values": "2.4.1" + }, + "dependencies": { + "lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", + "dev": true + }, + "lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + }, + "lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", + "dev": true, + "requires": { + "lodash._escapehtmlchar": "2.4.1", + "lodash._reunescapedhtml": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1" + }, + "dependencies": { + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + } + } + }, + "lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + } + } + } + } + }, + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + }, + "dependencies": { + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", + "dev": true + }, + "lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + } + } + }, + "lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", + "dev": true, + "requires": { + "lodash._reinterpolate": "2.4.1", + "lodash.escape": "2.4.1" + } + }, + "lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", + "dev": true, + "requires": { + "lodash.keys": "2.4.1" + } + } + } + }, + "minimist": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", + "dev": true, + "requires": { + "clone-stats": "0.0.1" + }, + "dependencies": { + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "multiline": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/multiline/-/multiline-0.2.0.tgz", + "integrity": "sha1-fLSkvRW58jgAe/BbFjBtLRKriVg=", + "dev": true + }, + "string-interpolate": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/string-interpolate/-/string-interpolate-0.1.1.tgz", + "integrity": "sha1-Q2gxkDEgI7DsBx7EV5d9iomGdz0=", + "dev": true + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "2.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "0.4.0" + }, + "dependencies": { + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + } + } + } + } + }, + "util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", + "dev": true + } + } + }, + "gulp-coveralls": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/gulp-coveralls/-/gulp-coveralls-0.1.4.tgz", + "integrity": "sha1-L2IKyN9i0LhrS73mTaNnzEGhkMk=", + "dev": true, + "requires": { + "coveralls": "2.13.1", + "gulp-util": "3.0.8", + "through2": "1.1.1" + }, + "dependencies": { + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "through2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-1.1.1.tgz", + "integrity": "sha1-CEfLxESfNAVXTb3M2buEG4OsNUU=", + "dev": true, + "requires": { + "readable-stream": "1.1.14", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + } + } + }, + "gulp-debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-debug/-/gulp-debug-3.1.0.tgz", + "integrity": "sha1-TakVaLVJFb6ANpbKqsEMiVssCnE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "gulp-util": "3.0.8", + "plur": "2.1.2", + "stringify-object": "3.2.0", + "through2": "2.0.3", + "tildify": "1.2.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, + "requires": { + "irregular-plurals": "1.2.0" + }, + "dependencies": { + "irregular-plurals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", + "dev": true + } + } + }, + "stringify-object": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.0.tgz", + "integrity": "sha1-lDcKE15BvASDWIE7+ZSB8TFcaqY=", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "1.0.1", + "is-obj": "1.0.1", + "is-regexp": "1.0.0" + }, + "dependencies": { + "get-own-enumerable-property-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-1.0.1.tgz", + "integrity": "sha1-8dTjrRQC4DmJjlbR6bmqkkwm5IQ=", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + } + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + } + } + } + } + }, + "gulp-doctoc": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/gulp-doctoc/-/gulp-doctoc-0.1.4.tgz", + "integrity": "sha1-ChGZPyIMTPUJbbcBQo23ilW/tn8=", + "dev": true, + "requires": { + "doctoc": "1.3.0", + "gulp-util": "2.2.20", + "through2": "0.4.2" + }, + "dependencies": { + "doctoc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/doctoc/-/doctoc-1.3.0.tgz", + "integrity": "sha1-fwg5hR3VjICKLK5V2VBOAS0I7jA=", + "dev": true, + "requires": { + "anchor-markdown-header": "0.5.7", + "htmlparser2": "3.9.2", + "markdown-to-ast": "3.4.0", + "minimist": "1.2.0", + "underscore": "1.8.3", + "update-section": "0.3.3" + }, + "dependencies": { + "anchor-markdown-header": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.5.7.tgz", + "integrity": "sha1-BFBj125qH5zTJ6V6ASaqD97Dcac=", + "dev": true, + "requires": { + "emoji-regex": "6.1.3" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.3.tgz", + "integrity": "sha1-7HmjlpsC0uzytyJUJ5v5m8eoOTI=", + "dev": true + } + } + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.4.1", + "domutils": "1.6.2", + "entities": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.2.9" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.6.2.tgz", + "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + }, + "dependencies": { + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + } + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + } + } + }, + "markdown-to-ast": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/markdown-to-ast/-/markdown-to-ast-3.4.0.tgz", + "integrity": "sha1-Diy6gTkLBUmpFT7DsNkVthwWS+c=", + "dev": true, + "requires": { + "debug": "2.6.6", + "remark": "5.1.0", + "structured-source": "3.0.2", + "traverse": "0.6.6" + }, + "dependencies": { + "debug": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz", + "integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=", + "dev": true, + "requires": { + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "dev": true + } + } + }, + "remark": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-5.1.0.tgz", + "integrity": "sha1-y0Y709vLS5l5STXu4c9x16jjBow=", + "dev": true, + "requires": { + "remark-parse": "1.1.0", + "remark-stringify": "1.1.0", + "unified": "4.2.1" + }, + "dependencies": { + "remark-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-1.1.0.tgz", + "integrity": "sha1-w8oQ+ajaBGFcKPCapOMEUQUm7CE=", + "dev": true, + "requires": { + "collapse-white-space": "1.0.2", + "extend": "3.0.1", + "parse-entities": "1.1.0", + "repeat-string": "1.6.1", + "trim": "0.0.1", + "trim-trailing-lines": "1.1.0", + "unherit": "1.1.0", + "unist-util-remove-position": "1.1.0", + "vfile-location": "2.0.1" + }, + "dependencies": { + "collapse-white-space": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.2.tgz", + "integrity": "sha1-nEY/ucbRkNLcriGjVqAbyunu720=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "parse-entities": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.0.tgz", + "integrity": "sha1-S8WPNf3I5l3e01oS8uQCI8oko/c=", + "dev": true, + "requires": { + "character-entities": "1.2.0", + "character-entities-legacy": "1.1.0", + "character-reference-invalid": "1.1.0", + "has": "1.0.1", + "is-alphanumerical": "1.0.0", + "is-decimal": "1.0.0", + "is-hexadecimal": "1.0.0" + }, + "dependencies": { + "character-entities": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.0.tgz", + "integrity": "sha1-poPiz3Xb6LFxljUxNk5Y4YobFV8=", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.0.tgz", + "integrity": "sha1-sYqtmPa3vMZGweTIH58ZVjdqVho=", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.0.tgz", + "integrity": "sha1-3smtHfufjQa0/NqircPE/ZevHmg=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.0" + }, + "dependencies": { + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + } + } + }, + "is-alphanumerical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz", + "integrity": "sha1-4GSS5xnBvxXewjnk8a9fZ7TW578=", + "dev": true, + "requires": { + "is-alphabetical": "1.0.0", + "is-decimal": "1.0.0" + }, + "dependencies": { + "is-alphabetical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.0.tgz", + "integrity": "sha1-4lRMEwWCVfIUTLdXBmzTNCocjEY=", + "dev": true + } + } + }, + "is-decimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.0.tgz", + "integrity": "sha1-lAV5tupjxigICmnmK9qIyEcLT+A=", + "dev": true + }, + "is-hexadecimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz", + "integrity": "sha1-XEWXcdKvmi45Ungf1U/LG8/kETw=", + "dev": true + } + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz", + "integrity": "sha1-eu+7eAjfnWafbaLkOMrIxGradoQ=", + "dev": true + }, + "unherit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz", + "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "unist-util-remove-position": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.0.tgz", + "integrity": "sha1-JET+3DRLxfVA2rY1PgE7bXgQHcI=", + "dev": true, + "requires": { + "unist-util-visit": "1.1.1" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.1.1.tgz", + "integrity": "sha1-6RejsTdlizNctEIMfaLnTZKOTpQ=", + "dev": true + } + } + }, + "vfile-location": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.1.tgz", + "integrity": "sha1-C/iBb3MrD4vZAqVv2kxiyOk13FI=", + "dev": true + } + } + }, + "remark-stringify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-1.1.0.tgz", + "integrity": "sha1-pxBeJbnuK/mkm3XSxCPxGwauIJI=", + "dev": true, + "requires": { + "ccount": "1.0.1", + "extend": "3.0.1", + "longest-streak": "1.0.0", + "markdown-table": "0.4.0", + "parse-entities": "1.1.0", + "repeat-string": "1.6.1", + "stringify-entities": "1.3.0", + "unherit": "1.1.0" + }, + "dependencies": { + "ccount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.1.tgz", + "integrity": "sha1-ZlaHlFFowhjsd/9hpBVa4AInqWw=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "longest-streak": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-1.0.0.tgz", + "integrity": "sha1-0GWXxNTDG1LMsfXY+P5xSOr9aWU=", + "dev": true + }, + "markdown-table": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-0.4.0.tgz", + "integrity": "sha1-iQwsGzv+g/sA5BKbjkz+ZFJw+dE=", + "dev": true + }, + "parse-entities": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.0.tgz", + "integrity": "sha1-S8WPNf3I5l3e01oS8uQCI8oko/c=", + "dev": true, + "requires": { + "character-entities": "1.2.0", + "character-entities-legacy": "1.1.0", + "character-reference-invalid": "1.1.0", + "has": "1.0.1", + "is-alphanumerical": "1.0.0", + "is-decimal": "1.0.0", + "is-hexadecimal": "1.0.0" + }, + "dependencies": { + "character-entities": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.0.tgz", + "integrity": "sha1-poPiz3Xb6LFxljUxNk5Y4YobFV8=", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.0.tgz", + "integrity": "sha1-sYqtmPa3vMZGweTIH58ZVjdqVho=", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.0.tgz", + "integrity": "sha1-3smtHfufjQa0/NqircPE/ZevHmg=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.0" + }, + "dependencies": { + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + } + } + }, + "is-alphanumerical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz", + "integrity": "sha1-4GSS5xnBvxXewjnk8a9fZ7TW578=", + "dev": true, + "requires": { + "is-alphabetical": "1.0.0", + "is-decimal": "1.0.0" + }, + "dependencies": { + "is-alphabetical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.0.tgz", + "integrity": "sha1-4lRMEwWCVfIUTLdXBmzTNCocjEY=", + "dev": true + } + } + }, + "is-decimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.0.tgz", + "integrity": "sha1-lAV5tupjxigICmnmK9qIyEcLT+A=", + "dev": true + }, + "is-hexadecimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz", + "integrity": "sha1-XEWXcdKvmi45Ungf1U/LG8/kETw=", + "dev": true + } + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "stringify-entities": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.0.tgz", + "integrity": "sha1-IkSlFsTx6OAbc9rQECMBZ3ar2Rc=", + "dev": true, + "requires": { + "character-entities-html4": "1.1.0", + "character-entities-legacy": "1.1.0", + "has": "1.0.1", + "is-alphanumerical": "1.0.0", + "is-hexadecimal": "1.0.0" + }, + "dependencies": { + "character-entities-html4": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.0.tgz", + "integrity": "sha1-GrCFUdPOH6HfCNAPucod77FHoGw=", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.0.tgz", + "integrity": "sha1-sYqtmPa3vMZGweTIH58ZVjdqVho=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.0" + }, + "dependencies": { + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + } + } + }, + "is-alphanumerical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz", + "integrity": "sha1-4GSS5xnBvxXewjnk8a9fZ7TW578=", + "dev": true, + "requires": { + "is-alphabetical": "1.0.0", + "is-decimal": "1.0.0" + }, + "dependencies": { + "is-alphabetical": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.0.tgz", + "integrity": "sha1-4lRMEwWCVfIUTLdXBmzTNCocjEY=", + "dev": true + }, + "is-decimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.0.tgz", + "integrity": "sha1-lAV5tupjxigICmnmK9qIyEcLT+A=", + "dev": true + } + } + }, + "is-hexadecimal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz", + "integrity": "sha1-XEWXcdKvmi45Ungf1U/LG8/kETw=", + "dev": true + } + } + }, + "unherit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz", + "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + } + } + }, + "unified": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/unified/-/unified-4.2.1.tgz", + "integrity": "sha1-dv9Dqo2kMPbn5KVchOusKtLPzS4=", + "dev": true, + "requires": { + "bail": "1.0.1", + "extend": "3.0.1", + "has": "1.0.1", + "once": "1.4.0", + "trough": "1.0.0", + "vfile": "1.4.0" + }, + "dependencies": { + "bail": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.1.tgz", + "integrity": "sha1-kSV53os5Gq3zxf30zSoPwiXfO8I=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.0" + }, + "dependencies": { + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + }, + "trough": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.0.tgz", + "integrity": "sha1-a97f5/KqSabzxDIldodVWVfzQv0=", + "dev": true + }, + "vfile": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-1.4.0.tgz", + "integrity": "sha1-wP1vpIT43r23cfaMMe112I2pf+c=", + "dev": true + } + } + } + } + }, + "structured-source": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-3.0.2.tgz", + "integrity": "sha1-3YAkJeD1PcSm56yjdSkBoczaevU=", + "dev": true, + "requires": { + "boundary": "1.0.1" + }, + "dependencies": { + "boundary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/boundary/-/boundary-1.0.1.tgz", + "integrity": "sha1-TWfcJgLAzBbdm85+v4fpSCkPWBI=", + "dev": true + } + } + }, + "traverse": { + "version": "0.6.6", + "resolved": "file:node_shrinkwrap/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "update-section": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz", + "integrity": "sha1-RY8Xgg03gg3GDiC4bZQ5GwASMVg=", + "dev": true + } + } + }, + "gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "dateformat": "1.0.12", + "lodash._reinterpolate": "2.4.1", + "lodash.template": "2.4.1", + "minimist": "0.2.0", + "multipipe": "0.1.2", + "through2": "0.5.1", + "vinyl": "0.2.3" + }, + "dependencies": { + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "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 + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + } + } + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + } + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + } + } + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.8", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + }, + "dependencies": { + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + }, + "dependencies": { + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "normalize-package-data": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", + "dev": true, + "requires": { + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + } + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "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 + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" + }, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "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.3.1" + }, + "dependencies": { + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + }, + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + } + } + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + } + } + } + } + } + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + }, + "dependencies": { + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + }, + "dependencies": { + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + } + } + } + } + } + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + } + } + } + } + }, + "lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", + "dev": true + }, + "lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", + "dev": true, + "requires": { + "lodash._escapestringchar": "2.4.1", + "lodash._reinterpolate": "2.4.1", + "lodash.defaults": "2.4.1", + "lodash.escape": "2.4.1", + "lodash.keys": "2.4.1", + "lodash.templatesettings": "2.4.1", + "lodash.values": "2.4.1" + }, + "dependencies": { + "lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", + "dev": true + }, + "lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + }, + "lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", + "dev": true, + "requires": { + "lodash._escapehtmlchar": "2.4.1", + "lodash._reunescapedhtml": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1" + }, + "dependencies": { + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + } + } + }, + "lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + } + } + } + } + }, + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + }, + "dependencies": { + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", + "dev": true + }, + "lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + }, + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + } + } + } + } + }, + "lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", + "dev": true, + "requires": { + "lodash._reinterpolate": "2.4.1", + "lodash.escape": "2.4.1" + } + }, + "lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", + "dev": true, + "requires": { + "lodash.keys": "2.4.1" + } + } + } + }, + "minimist": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", + "dev": true, + "requires": { + "clone-stats": "0.0.1" + }, + "dependencies": { + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "2.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "0.4.0" + }, + "dependencies": { + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + } + } + } + } + } + } + }, + "gulp-istanbul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gulp-istanbul/-/gulp-istanbul-1.1.2.tgz", + "integrity": "sha512-53+BDhGlGNHYfeFh/mSXWhNu9wSFmE8qAEFj6ViMiWzTwI9pYxedUxMmGfigwaddsHHQxBl9TgnzUydrX84Kog==", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "istanbul": "0.4.5", + "istanbul-threshold-checker": "0.2.1", + "lodash": "4.17.4", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" + } + }, + "gulp-load-plugins": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-1.5.0.tgz", + "integrity": "sha1-TEGffldk2aDjMGG6uWGPgbc9QXE=", + "dev": true, + "requires": { + "array-unique": "0.2.1", + "fancy-log": "1.3.0", + "findup-sync": "0.4.3", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "micromatch": "2.3.11", + "resolve": "1.3.3" + }, + "dependencies": { + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "findup-sync": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "dev": true, + "requires": { + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" + }, + "dependencies": { + "detect-file": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "dev": true, + "requires": { + "fs-exists-sync": "0.1.0" + }, + "dependencies": { + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + } + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + } + } + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "requires": { + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" + }, + "dependencies": { + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + } + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "requires": { + "global-prefix": "0.1.5", + "is-windows": "0.2.0" + }, + "dependencies": { + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1", + "ini": "1.3.4", + "is-windows": "0.2.0", + "which": "1.2.14" + }, + "dependencies": { + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + }, + "dependencies": { + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + } + } + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + } + } + } + } + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + } + } + } + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.0", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.0.3" + }, + "dependencies": { + "arr-flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", + "dev": true + } + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + }, + "dependencies": { + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.6", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + }, + "dependencies": { + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.0" + } + }, + "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" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "randomatic": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "kind-of": "3.2.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + } + } + } + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + }, + "dependencies": { + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.1" + }, + "dependencies": { + "remove-trailing-separator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", + "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + }, + "dependencies": { + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "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 + } + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.2", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + } + } + }, + "is-dotfile": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=", + "dev": true + } + } + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + }, + "dependencies": { + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + } + } + } + } + }, + "resolve": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "dev": true, + "requires": { + "path-parse": "1.0.5" + }, + "dependencies": { + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + } + } + } + } + }, + "gulp-mocha": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-3.0.1.tgz", + "integrity": "sha1-qwyiw5QDcYF03drXUOY6Yb4X4EE=", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "mocha": "3.3.0", + "plur": "2.1.2", + "req-cwd": "1.0.1", + "temp": "0.8.3", + "through": "2.3.8" + }, + "dependencies": { + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, + "requires": { + "irregular-plurals": "1.2.0" + }, + "dependencies": { + "irregular-plurals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", + "dev": true + } + } + }, + "req-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", + "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", + "dev": true, + "requires": { + "req-from": "1.0.1" + }, + "dependencies": { + "req-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", + "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", + "dev": true, + "requires": { + "resolve-from": "2.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "file:node_shrinkwrap/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + } + } + } + } + }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + } + } + }, + "gulp-rename": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", + "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", + "dev": true + }, + "gulp-template": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/gulp-template/-/gulp-template-4.0.0.tgz", + "integrity": "sha1-Bd42gIxvuZZleNWpTucs7gjNxTs=", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "lodash": "4.17.4", + "through2": "2.0.3" + }, + "dependencies": { + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + } + }, + "harmonize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/harmonize/-/harmonize-2.0.0.tgz", + "integrity": "sha1-peMLabaNc+PsPAQYOR8RCoDo1Pc=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "inquirer": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.2.tgz", + "integrity": "sha512-bTKLzEHJVATimZO/YFdLrom0lRx1BHfRYskFHfIMVkGdp8+dIZaxuU+4yrsS1lcu6YWywVQVVsfvdwESzbeqHw==", + "dev": true, + "requires": { + "ansi-escapes": "2.0.0", + "chalk": "2.1.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.4", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.1" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "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=" + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "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-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "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=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.2", + "whatwg-fetch": "2.0.3" + } + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.8", + "js-yaml": "3.8.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.2.14", + "wordwrap": "1.0.0" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "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.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + }, + "dependencies": { + "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 + }, + "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 + }, + "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" + } + }, + "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 + }, + "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" + } + } + } + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + }, + "dependencies": { + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + } + } + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + }, + "dependencies": { + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + } + } + }, + "handlebars": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.8.tgz", + "integrity": "sha1-Irh1zT8ObL6jAxTxROgrx6cv9CA=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.23" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + }, + "dependencies": { + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + } + } + }, + "uglify-js": { + "version": "2.8.23", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.23.tgz", + "integrity": "sha1-gjDdl4M3EjLWKngh4s+agXJwqKA=", + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true, + "optional": true + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + }, + "dependencies": { + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "3.2.0", + "longest": "1.0.1", + "repeat-string": "1.6.1" + }, + "dependencies": { + "kind-of": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true, + "optional": true + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true, + "optional": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "optional": true + } + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + } + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + }, + "dependencies": { + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "3.2.0", + "longest": "1.0.1", + "repeat-string": "1.6.1" + }, + "dependencies": { + "kind-of": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true, + "optional": true + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true, + "optional": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "optional": true + } + } + } + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "optional": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + } + } + } + } + } + } + }, + "js-yaml": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", + "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "3.1.3" + }, + "dependencies": { + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + } + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + } + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "istanbul-threshold-checker": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/istanbul-threshold-checker/-/istanbul-threshold-checker-0.2.1.tgz", + "integrity": "sha1-xdyU6PLMXNP/0zVFL4S1U8QkgzE=", + "dev": true, + "requires": { + "istanbul": "0.4.5", + "lodash": "4.17.4" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", + "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jschardet": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", + "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", + "dev": true + }, + "jsx-ast-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.0.tgz", + "integrity": "sha1-7Aaj1gzzB+XhGdrHutgeifCW8Pg=", + "requires": { + "array-includes": "3.0.3" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "4.0.1" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash-bindright": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lodash-bindright/-/lodash-bindright-1.0.1.tgz", + "integrity": "sha1-VnyxrMnCvhAvA1Dpp9+oSGwY+z4=", + "requires": { + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "lodash-namespace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lodash-namespace/-/lodash-namespace-1.0.0.tgz", + "integrity": "sha1-i9rcy40a9sCWsCjLKMdvmbqt68I=", + "requires": { + "lodash": "3.10.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "make-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "requires": { + "pify": "2.3.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "requires": { + "brace-expansion": "1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mocha": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.3.0.tgz", + "integrity": "sha1-0pt0KNP1LILi5l3x7LcGThqrv7U=", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.0", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": "1.0.1" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + } + } + }, + "debug": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz", + "integrity": "sha1-vFlryr52F/Edn6FTYe3tVgi4SZs=", + "dev": true, + "requires": { + "ms": "0.7.2" + }, + "dependencies": { + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "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 + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "3.2.0", + "lodash._basecreate": "3.0.3", + "lodash._isiterateecall": "3.0.9" + }, + "dependencies": { + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash.keys": "3.1.2" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + } + } + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + } + } + } + } + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "node-fetch": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.2.tgz", + "integrity": "sha512-xZZUq2yDhKMIn/UgG5q//IZSNLJIwW2QxS14CNH5spuiXkITM2pUitjdq58yLSaU7m4M0wBNaM2Gh/ggY4YJig==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "6.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.4.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.5.10", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", + "integrity": "sha1-J5ffwxJhguOpXj37suiT3ddFYVQ=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "rc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "registry-auth-token": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "requires": { + "rc": "1.2.1", + "safe-buffer": "5.1.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "1.2.1" + } + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "roolz": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/roolz/-/roolz-1.0.2.tgz", + "integrity": "sha1-9GScCTA2bsSxs12cbFr9ofHpGM8=", + "requires": { + "drip": "1.4.0", + "lodash": "3.10.1", + "string-sub": "0.0.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + } + } + }, + "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" + } + }, + "run-sequence": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-1.2.2.tgz", + "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "gulp-util": "3.0.8" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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 + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "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 + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "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-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 + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.0.1" + }, + "dependencies": { + "time-stamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + }, + "dependencies": { + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + } + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + }, + "dependencies": { + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + }, + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + } + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + }, + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.2.9", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.0", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true, + "requires": { + "buffer-shims": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + } + } + } + } + } + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "5.4.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "sinon": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.2.0.tgz", + "integrity": "sha1-OxtC/13vy/UaUqYqym1hFxuf0mI=", + "dev": true, + "requires": { + "diff": "3.2.0", + "formatio": "1.2.0", + "lolex": "1.6.0", + "native-promise-only": "0.8.1", + "path-to-regexp": "1.7.0", + "samsam": "1.2.1", + "text-encoding": "0.6.4", + "type-detect": "4.0.3" + }, + "dependencies": { + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.2.1" + } + }, + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "samsam": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", + "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", + "dev": true + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "type-detect": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", + "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "string-sub": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/string-sub/-/string-sub-0.0.1.tgz", + "integrity": "sha1-Z8lZrDoU5c/igP7wi0IcJAUOqk0=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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=", + "requires": { + "ansi-regex": "3.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "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=" + }, + "stylelint": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-7.10.1.tgz", + "integrity": "sha1-IJp85eeB/CpiSJ+7MewCAexnXbI=", + "requires": { + "autoprefixer": "6.7.7", + "balanced-match": "0.4.2", + "chalk": "1.1.3", + "colorguard": "1.2.0", + "cosmiconfig": "2.2.2", + "debug": "2.6.6", + "doiuse": "2.6.0", + "execall": "1.0.0", + "file-entry-cache": "2.0.0", + "get-stdin": "5.0.1", + "globby": "6.1.0", + "globjoin": "0.1.4", + "html-tags": "1.1.1", + "ignore": "3.3.0", + "imurmurhash": "0.1.4", + "known-css-properties": "0.0.7", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "meow": "3.7.0", + "micromatch": "2.3.11", + "normalize-selector": "0.2.0", + "postcss": "5.2.17", + "postcss-less": "0.14.0", + "postcss-media-query-parser": "0.2.3", + "postcss-reporter": "3.0.0", + "postcss-resolve-nested-selector": "0.1.1", + "postcss-scss": "0.4.1", + "postcss-selector-parser": "2.2.3", + "postcss-value-parser": "3.3.0", + "resolve-from": "2.0.0", + "specificity": "0.3.0", + "string-width": "2.0.0", + "style-search": "0.1.0", + "stylehacks": "2.3.2", + "sugarss": "0.2.0", + "svg-tags": "1.0.0", + "table": "4.0.1" + }, + "dependencies": { + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000666", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000666", + "electron-to-chromium": "1.3.10" + }, + "dependencies": { + "electron-to-chromium": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.10.tgz", + "integrity": "sha1-Y9YreFRx8NjdqFGZ1kV53opEnwg=" + } + } + }, + "caniuse-db": { + "version": "1.0.30000666", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000666.tgz", + "integrity": "sha1-lR7Z89O/qgigba+7UImrB8zmq5A=" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + } + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "colorguard": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.0.tgz", + "integrity": "sha1-8/rK9cquuk71RlPZ+yW7cxd8DYQ=", + "requires": { + "chalk": "1.1.3", + "color-diff": "0.1.7", + "log-symbols": "1.0.2", + "object-assign": "4.1.1", + "pipetteur": "2.0.3", + "plur": "2.1.2", + "postcss": "5.2.17", + "postcss-reporter": "1.4.1", + "text-table": "0.2.0", + "yargs": "1.3.3" + }, + "dependencies": { + "color-diff": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz", + "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "pipetteur": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pipetteur/-/pipetteur-2.0.3.tgz", + "integrity": "sha1-GVV2CVno0aEcsqUOyD7sRwYz5J8=", + "requires": { + "onecolor": "3.0.4", + "synesthesia": "1.0.1" + }, + "dependencies": { + "onecolor": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.4.tgz", + "integrity": "sha1-daRvgNpseqpbTarhekcZi9llJJQ=" + }, + "synesthesia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/synesthesia/-/synesthesia-1.0.1.tgz", + "integrity": "sha1-XvlepUjA1cbm+btLDQcx3/hkp3c=", + "requires": { + "css-color-names": "0.0.3" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", + "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=" + } + } + } + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "requires": { + "irregular-plurals": "1.2.0" + }, + "dependencies": { + "irregular-plurals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=" + } + } + }, + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "file:node_shrinkwrap/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "yargs": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", + "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=" + } + } + }, + "debug": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz", + "integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=", + "requires": { + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + } + } + }, + "doiuse": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-2.6.0.tgz", + "integrity": "sha1-GJLRC2Gpo1at2/K2FJM+gfi7ODQ=", + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000666", + "css-rule-stream": "1.1.0", + "duplexer2": "0.0.2", + "jsonfilter": "1.1.2", + "ldjson-stream": "1.2.1", + "lodash": "4.17.4", + "multimatch": "2.1.0", + "postcss": "5.2.17", + "source-map": "0.4.4", + "through2": "0.6.5", + "yargs": "3.32.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000666", + "electron-to-chromium": "1.3.10" + }, + "dependencies": { + "electron-to-chromium": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.10.tgz", + "integrity": "sha1-Y9YreFRx8NjdqFGZ1kV53opEnwg=" + } + } + }, + "caniuse-db": { + "version": "1.0.30000666", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000666.tgz", + "integrity": "sha1-lR7Z89O/qgigba+7UImrB8zmq5A=" + }, + "css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "requires": { + "css-tokenize": "1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "1.2.1", + "through2": "0.6.5" + }, + "dependencies": { + "css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.1.14" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + } + } + } + } + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + } + } + }, + "jsonfilter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jsonfilter/-/jsonfilter-1.1.2.tgz", + "integrity": "sha1-Ie987cdRk4E8dZMulqmL4gW6WhE=", + "requires": { + "JSONStream": "0.8.4", + "minimist": "1.2.0", + "stream-combiner": "0.2.2", + "through2": "0.6.5" + }, + "dependencies": { + "JSONStream": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", + "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=", + "requires": { + "jsonparse": "0.0.5", + "through": "2.3.8" + }, + "dependencies": { + "jsonparse": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", + "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "requires": { + "duplexer": "0.1.1", + "through": "2.3.8" + }, + "dependencies": { + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + } + } + } + } + }, + "ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "requires": { + "split2": "0.2.1", + "through2": "0.6.5" + }, + "dependencies": { + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "requires": { + "through2": "0.6.5" + } + } + } + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + }, + "dependencies": { + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + }, + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + } + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + } + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + }, + "dependencies": { + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + } + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "2.1.1", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "os-locale": "1.4.0", + "string-width": "1.0.2", + "window-size": "0.1.4", + "y18n": "3.2.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.0.0" + }, + "dependencies": { + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "1.0.0" + }, + "dependencies": { + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + } + } + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + } + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + } + } + } + } + }, + "execall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", + "integrity": "sha1-c9CQTjlbPKsGWLCNCewlMH8pu3M=", + "requires": { + "clone-regexp": "1.0.0" + }, + "dependencies": { + "clone-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.0.tgz", + "integrity": "sha1-6uCiQT9VwJQvgYwin+/OhF1/Oxw=", + "requires": { + "is-regexp": "1.0.0", + "is-supported-regexp-flag": "1.0.0" + }, + "dependencies": { + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-supported-regexp-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz", + "integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=" + } + } + } + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "1.2.2", + "object-assign": "4.1.1" + }, + "dependencies": { + "flat-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "requires": { + "circular-json": "0.3.1", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + }, + "dependencies": { + "circular-json": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=" + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" + }, + "dependencies": { + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + }, + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + } + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + } + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "requires": { + "is-path-inside": "1.0.0" + }, + "dependencies": { + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "requires": { + "path-is-inside": "1.0.2" + }, + "dependencies": { + "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=" + } + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "requires": { + "glob": "7.1.2" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "0.5.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + } + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + }, + "dependencies": { + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=" + }, + "html-tags": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.1.1.tgz", + "integrity": "sha1-hp9DhZ8S2b3DiSQZ5JSmKKobIE4=" + }, + "ignore": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.0.tgz", + "integrity": "sha1-OBLSLL6RJfLCtJFXVaG4q9dFoAE=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "known-css-properties": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.0.7.tgz", + "integrity": "sha1-kQQ0Oirf2O87B73uejJeTUTtk3E=" + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "requires": { + "chalk": "1.1.3" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.8", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + }, + "dependencies": { + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.2" + }, + "dependencies": { + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "normalize-package-data": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", + "requires": { + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + } + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + } + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" + }, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + }, + "dependencies": { + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + } + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + }, + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + } + } + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + } + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + }, + "dependencies": { + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.2" + }, + "dependencies": { + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + } + } + } + } + } + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + } + } + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.0", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "1.0.3" + }, + "dependencies": { + "arr-flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=" + } + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + }, + "dependencies": { + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.6", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + }, + "dependencies": { + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "3.2.0" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "randomatic": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", + "requires": { + "is-number": "2.1.0", + "kind-of": "3.2.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + } + } + } + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "0.1.1" + }, + "dependencies": { + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "requires": { + "is-buffer": "1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.0.1" + }, + "dependencies": { + "remove-trailing-separator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", + "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=" + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "1.0.2" + }, + "dependencies": { + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + } + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.2", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "2.0.1" + } + } + } + }, + "is-dotfile": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=" + } + } + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + }, + "dependencies": { + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + } + } + } + } + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=" + }, + "postcss": { + "version": "5.2.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", + "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.1.9", + "source-map": "0.5.6", + "supports-color": "3.2.3" + }, + "dependencies": { + "js-base64": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", + "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=" + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + } + } + } + } + }, + "postcss-less": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz", + "integrity": "sha1-xjGwicbM5CK5oQ86lY0r7dOBkyQ=", + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=" + }, + "postcss-reporter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz", + "integrity": "sha1-CeoPN6RExWk4eGBuCbAY6+/3z48=", + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=" + }, + "postcss-scss": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-0.4.1.tgz", + "integrity": "sha1-rXcbgfD3L19IRdCKpg+TVXZT1Uw=", + "requires": { + "postcss": "5.2.17" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + }, + "dependencies": { + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + } + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "file:node_shrinkwrap/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "specificity": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.3.0.tgz", + "integrity": "sha1-MyRy1OXrWvIIIRcZM5mKa8Oxzm8=" + }, + "string-width": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + } + } + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=" + }, + "stylehacks": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-2.3.2.tgz", + "integrity": "sha1-ZMg+BDimjJ7fRJ6MVSp9mrYAmws=", + "requires": { + "browserslist": "1.7.7", + "chalk": "1.1.3", + "log-symbols": "1.0.2", + "minimist": "1.2.0", + "plur": "2.1.2", + "postcss": "5.2.17", + "postcss-reporter": "1.4.1", + "postcss-selector-parser": "2.2.3", + "read-file-stdin": "0.2.1", + "text-table": "0.2.0", + "write-file-stdout": "0.0.2" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "1.0.30000666", + "electron-to-chromium": "1.3.10" + }, + "dependencies": { + "caniuse-db": { + "version": "1.0.30000666", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000666.tgz", + "integrity": "sha1-lR7Z89O/qgigba+7UImrB8zmq5A=" + }, + "electron-to-chromium": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.10.tgz", + "integrity": "sha1-Y9YreFRx8NjdqFGZ1kV53opEnwg=" + } + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "requires": { + "irregular-plurals": "1.2.0" + }, + "dependencies": { + "irregular-plurals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=" + } + } + }, + "postcss-reporter": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz", + "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=", + "requires": { + "chalk": "1.1.3", + "lodash": "4.17.4", + "log-symbols": "1.0.2", + "postcss": "5.2.17" + } + }, + "read-file-stdin": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz", + "integrity": "sha1-JezP86FTtoCa+ssj7hU4fbng7mE=", + "requires": { + "gather-stream": "1.0.0" + }, + "dependencies": { + "gather-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz", + "integrity": "sha1-szmUr0V6gRVwDUEPMXczy+egkEs=" + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "file:node_shrinkwrap/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "write-file-stdout": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/write-file-stdout/-/write-file-stdout-0.0.2.tgz", + "integrity": "sha1-wlLXx8WxtAKJdjDjRTx7/mkNnKE=" + } + } + }, + "sugarss": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-0.2.0.tgz", + "integrity": "sha1-rDQjdWMyfG/4l7ZHQr9q7BkK054=", + "requires": { + "postcss": "5.2.17" + } + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" + }, + "table": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", + "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.0.0" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + }, + "dependencies": { + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + } + } + } + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "file:node_shrinkwrap/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + } + } + } + } + }, + "stylelint-order": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-0.4.4.tgz", + "integrity": "sha1-2338oFQbUGIBDH4uIedFeR/AiKw=", + "requires": { + "lodash": "4.17.4", + "postcss": "5.2.17", + "stylelint": "7.10.1" + }, + "dependencies": { + "postcss": { + "version": "5.2.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", + "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "requires": { + "chalk": "1.1.3", + "js-base64": "2.1.9", + "source-map": "0.5.6", + "supports-color": "3.2.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "js-base64": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", + "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=" + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + } + } + } + } + } + } + }, + "supports-color": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", + "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", + "requires": { + "has-flag": "2.0.0" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "0.7.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "ua-parser-js": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", + "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=" + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "1.0.0" + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, + "update-notifier": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz", + "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=", + "requires": { + "boxen": "1.2.1", + "chalk": "1.1.3", + "configstore": "3.1.1", + "import-lazy": "2.1.0", + "is-npm": "1.0.0", + "latest-version": "3.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "3.0.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "1.0.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "2.0.0" + } + }, + "widest-line": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "signal-exit": "3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, + "xsd-schema-validator": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xsd-schema-validator/-/xsd-schema-validator-0.5.0.tgz", + "integrity": "sha1-OjXEblIxV2bk1WjBmBi7kCp2lTE=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } +} diff --git a/package.json b/package.json index 596aa89..3840684 100644 --- a/package.json +++ b/package.json @@ -26,17 +26,17 @@ "bluebird": "^3.4.1", "cli": "^1.0.0", "cli-color-keywords": "0.0.1", - "configstore": "^3.1.0", + "configstore": "^3.1.1", "content-formatter": "^2.0.2", "content-logger": "^1.0.1", "content-logger-handlebars-helpers": "0.0.1", - "cosmiconfig": "^2.1.3", + "cosmiconfig": "^2.2.2", "drip": "^1.4.0", "eslint": "^3.3.1", - "eslint-plugin-react": "^7.0.0", + "eslint-plugin-react": "^7.3.0", "falafel": "^1.2.0", "getobject": "^0.1.0", - "glob": "^7.0.5", + "glob": "^7.1.2", "lodash": "^4.15.0", "lodash-bindright": "^1.0.1", "lodash-namespace": "^1.0.0", @@ -46,11 +46,11 @@ "string-sub": "0.0.1", "stylelint": "^7.0.3", "stylelint-order": "^0.4.4", - "update-notifier": "^2.1.0" + "update-notifier": "^2.2.0" }, "devDependencies": { "chai": "^3.5.0", - "chai-string": "^1.2.0", + "chai-string": "^1.4.0", "coveralls": "^2.13.1", "eslint-plugin-dollar-sign": "^1.0.0", "gulp": "^3.9.1", @@ -58,13 +58,13 @@ "gulp-coveralls": "^0.1.4", "gulp-debug": "^3.1.0", "gulp-doctoc": "^0.1.4", - "gulp-istanbul": "^1.1.0", + "gulp-istanbul": "^1.1.2", "gulp-load-plugins": "^1.2.4", "gulp-mocha": "^3.0.1", "gulp-rename": "^1.2.2", "gulp-template": "^4.0.0", "harmonize": "^2.0.0", - "inquirer": "^3.0.6", + "inquirer": "^3.2.2", "istanbul": "^0.4.4", "mocha": "^3.3.0", "run-sequence": "^1.2.2", From 85328e8cae6e2d203e933e164ab18054dce78dc8 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 22 Aug 2017 10:17:46 -0700 Subject: [PATCH 152/153] Add node 8 to testing version --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 34e7afb..342de8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - "8" - "7" - "6" - "5" From d1b13b3618852febc7d3ac3afa5b94fadd266655 Mon Sep 17 00:00:00 2001 From: Nate Cavanaugh Date: Tue, 22 Aug 2017 10:36:17 -0700 Subject: [PATCH 153/153] Pinning stylelint to 7.10.0, need to investigate why it's breaking on 7.13.0 as well as look into upgrading to 8 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3840684..1b3b33f 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "optimist": "^0.6.1", "roolz": "^1.0.2", "string-sub": "0.0.1", - "stylelint": "^7.0.3", + "stylelint": "7.10.0", "stylelint-order": "^0.4.4", "update-notifier": "^2.2.0" }, @@ -71,4 +71,4 @@ "sinon": "^2.2.0", "xsd-schema-validator": "^0.5.0" } -} +} \ No newline at end of file