Socket
Socket
Sign inDemoInstall

jscs

Package Overview
Dependencies
Maintainers
4
Versions
95
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jscs - npm Package Compare versions

Comparing version 1.7.3 to 1.8.0

lib/config/configuration.js

67

lib/checker.js

@@ -7,6 +7,3 @@ var vowFs = require('vow-fs');

var additionalRules = require('./options/additional-rules');
var excludeFiles = require('./options/exclude-files');
var fileExtensions = require('./options/file-extensions');
var esnext = require('./options/esnext');
var NodeConfiguration = require('./config/node-configuration');

@@ -30,10 +27,5 @@ /**

Checker.prototype.configure = function(config) {
var cwd = config.configPath ? path.dirname(config.configPath) : process.cwd();
StringChecker.prototype.configure.apply(this, arguments);
fileExtensions(config, this);
excludeFiles(config, this, cwd);
additionalRules(config, this, cwd);
esnext(config);
StringChecker.prototype.configure.apply(this, arguments);
this._fileExtensions = this._configuration.getFileExtensions();
};

@@ -48,14 +40,9 @@

Checker.prototype.checkFile = function(path) {
var _this = this;
if (!_this._isExcluded(path)) {
if (!this._configuration.isFileExcluded(path)) {
return vowFs.read(path, 'utf8').then(function(data) {
return _this.checkString(data, path);
});
return this.checkString(data, path);
}, this);
}
var defer = Vow.defer();
defer.resolve(null);
return defer.promise();
return Vow.resolve(null);
};

@@ -70,4 +57,2 @@

Checker.prototype.checkDirectory = function(path) {
var _this = this;
return vowFs.listDir(path).then(function(filenames) {

@@ -77,4 +62,3 @@ return Vow.all(filenames.map(function(filename) {

// check for exclude path
if (_this._isExcluded(fullname)) {
if (this._configuration.isFileExcluded(fullname)) {
return [];

@@ -85,10 +69,10 @@ }

if (stat.isDirectory()) {
return _this.checkDirectory(fullname);
return this.checkDirectory(fullname);
}
if (!_this._hasCorrectExtension(fullname)) {
if (!this._hasCorrectExtension(fullname)) {
return [];
}
return Vow.when(_this.checkFile(fullname)).then(function(errors) {
return Vow.when(this.checkFile(fullname)).then(function(errors) {
if (errors) {

@@ -100,7 +84,7 @@ return errors;

});
});
})).then(function(results) {
}, this);
}, this)).then(function(results) {
return [].concat.apply([], results);
});
});
}, this);
};

@@ -165,15 +149,2 @@

/**
* Returns true if specified path is in excluded list.
*
* @returns {Boolean}
*/
Checker.prototype._isExcluded = function(testPath) {
testPath = path.resolve(testPath);
return !this._excludes.every(function(exclude) {
return !exclude.match(testPath);
});
};
/**
* Returns true if the file extension matches a file extension to process.

@@ -194,2 +165,12 @@ *

/**
* Returns new configuration instance.
*
* @protected
* @returns {Configuration}
*/
Checker.prototype._createConfiguration = function() {
return new NodeConfiguration();
};
module.exports = Checker;

@@ -10,3 +10,2 @@ /**

var configFile = require('./cli-config');
var preset = require('./options/preset');

@@ -67,4 +66,4 @@ var Vow = require('vow');

if (program.preset && !preset.exists(program.preset)) {
console.error(preset.getDoesNotExistError(program.preset));
if (program.preset && !checker.getConfiguration().hasPreset(program.preset)) {
console.error('Preset "%s" does not exist', program.preset);
defer.reject(1);

@@ -87,9 +86,17 @@

if (program.preset) {
config.preset = program.preset;
checker.getConfiguration().override({preset: program.preset});
}
if (program.maxErrors) {
config.maxErrors = Number(program.maxErrors);
checker.getConfiguration().override({maxErrors: Number(program.maxErrors)});
}
if (program.errorFilter) {
checker.getConfiguration().override({errorFilter: program.errorFilter});
}
if (program.esprima) {
checker.getConfiguration().override({esprima: program.esprima});
}
if (program.reporter) {

@@ -119,3 +126,3 @@ reporterPath = path.resolve(process.cwd(), program.reporter);

checker.registerDefaultRules();
checker.getConfiguration().registerDefaultRules();
checker.configure(config);

@@ -122,0 +129,0 @@

@@ -0,2 +1,4 @@

var assert = require('assert');
var colors = require('colors');
var TokenAssert = require('./token-assert');

@@ -15,2 +17,9 @@ /**

this._verbose = verbose || false;
/**
* @type {TokenAssert}
* @public
*/
this.assert = new TokenAssert(file);
this.assert.on('error', this._addError.bind(this));
};

@@ -24,3 +33,3 @@

* @param {Number|Object} line
* @param {Number} [column]
* @param {Number} [column] optional if line is an object
*/

@@ -33,3 +42,23 @@ add: function(message, line, column) {

if (!this._file.isEnabledRule(this._currentRule, line)) {
// line and column numbers should be explicit
assert(typeof line === 'number' && line > 0,
'Unable to add an error, `line` should be a number greater than 0 but ' + line + ' given');
assert(typeof column === 'number' && column >= 0,
'Unable to add an error, `column` should be a positive number but ' + column + ' given');
this._addError({
message: message,
line: line,
column: column
});
},
/**
* Adds error to error list.
*
* @param {Object} errorInfo
* @private
*/
_addError: function(errorInfo) {
if (!this._file.isEnabledRule(this._currentRule, errorInfo.line)) {
return;

@@ -39,6 +68,7 @@ }

this._errorList.push({
filename: this._file.getFilename(),
rule: this._currentRule,
message: this._verbose ? this._currentRule + ': ' + message : message,
line: line,
column: column || 0
message: this._verbose ? this._currentRule + ': ' + errorInfo.message : errorInfo.message,
line: errorInfo.line,
column: errorInfo.column
});

@@ -93,2 +123,11 @@ },

/**
* Filters out errors based on the supplied filter function
*
* @param {Function} filter
*/
filter: function(filter) {
this._errorList = this._errorList.filter(filter);
},
/**
* Formats error for further output.

@@ -95,0 +134,0 @@ *

var treeIterator = require('./tree-iterator');
/**
* Operator list which are represented as keywords in token list.
*/
var KEYWORD_OPERATORS = {
'instanceof': true,
'in': true
};
/**
* File representation for JSCS.

@@ -13,3 +21,4 @@ *

this._lines = source.split(/\r\n|\r|\n/);
this._tokenIndex = null;
this._tokenRangeStartIndex = null;
this._tokenRangeEndIndex = null;
var index = this._index = {};

@@ -115,4 +124,2 @@ var _this = this;

rulesStr.split(',').forEach(function(rule) {
var ruleLength;
rule = rule.trim();

@@ -137,8 +144,11 @@

var tokens = this._tree.tokens;
var tokenIndex = {};
var tokenRangeStartIndex = {};
var tokenRangeEndIndex = {};
for (var i = 0, l = tokens.length; i < l; i++) {
tokenIndex[tokens[i].range[0]] = i;
tokenRangeStartIndex[tokens[i].range[0]] = i;
tokenRangeEndIndex[tokens[i].range[1]] = i;
tokens[i]._tokenIndex = i;
}
this._tokenIndex = tokenIndex;
this._tokenRangeStartIndex = tokenRangeStartIndex;
this._tokenRangeEndIndex = tokenRangeEndIndex;
},

@@ -151,3 +161,3 @@ /**

getTokenPosByRangeStart: function(start) {
return this._tokenIndex[start];
return this._tokenRangeStartIndex[start];
},

@@ -160,8 +170,17 @@ /**

getTokenByRangeStart: function(start) {
var tokenIndex = this._tokenIndex[start];
var tokenIndex = this._tokenRangeStartIndex[start];
return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex];
},
/**
* Returns first token for the node from the AST.
* Returns token using range end from the index.
*
* @returns {Object|undefined}
*/
getTokenByRangeEnd: function(end) {
var tokenIndex = this._tokenRangeEndIndex[end];
return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex];
},
/**
* Returns the first token for the node from the AST.
*
* @param {Object} node

@@ -174,2 +193,11 @@ * @returns {Object}

/**
* Returns the last token for the node from the AST.
*
* @param {Object} node
* @returns {Object}
*/
getLastNodeToken: function(node) {
return this.getTokenByRangeEnd(node.range[1]);
},
/**
* Returns the first token before the given.

@@ -231,2 +259,22 @@ *

/**
* Returns the first token before the given which matches type (and value).
*
* @param {Object} token
* @param {String} value
* @returns {Object|undefined}
*/
findPrevOperatorToken: function(token, value) {
return this.findPrevToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value);
},
/**
* Returns the first token after the given which matches type (and value).
*
* @param {Object} token
* @param {String} value
* @returns {Object|undefined}
*/
findNextOperatorToken: function(token, value) {
return this.findNextToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value);
},
/**
* Iterates through the token tree using tree iterator.

@@ -248,3 +296,2 @@ * Calls passed function for every token.

var result = {};
this.iterate(function(node) {

@@ -255,3 +302,2 @@ if (node && node.range) {

}
if (number < node.range[0]) {

@@ -262,3 +308,2 @@ return false;

});
return result;

@@ -265,0 +310,0 @@ },

@@ -23,12 +23,9 @@ var assert = require('assert');

check: function(file, errors) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
var nextToken = tokens[i + 1];
if (nextToken && nextToken.loc.start.line !== token.loc.end.line) {
errors.add(
'Commas should be placed on new line',
token.loc.end.line,
token.loc.end.column
);
}
errors.assert.sameLine({
token: token,
nextToken: file.getNextToken(token),
message: 'Commas should be placed on new line'
});
}

@@ -35,0 +32,0 @@ });

@@ -7,17 +7,37 @@ var assert = require('assert');

configure: function(disallowDanglingUnderscores) {
configure: function(identifiers) {
assert(
typeof disallowDanglingUnderscores === 'boolean',
'disallowDanglingUnderscores option requires boolean value'
identifiers === true ||
typeof identifiers === 'object',
this.getOptionName() + ' option requires the value `true` ' +
'or an object with String[] `allExcept` property'
);
// verify first item in `allExcept` property in object (if it's an object)
assert(
disallowDanglingUnderscores === true,
'disallowDanglingUnderscores option requires true value or should be removed'
typeof identifiers !== 'object' ||
Array.isArray(identifiers.allExcept) &&
typeof identifiers.allExcept[0] === 'string',
'Property `allExcept` in requireSpaceAfterLineComment should be an array of strings'
);
this._allowedIdentifiers = {
_: true,
__dirname: true,
__filename: true
};
var isTrue = identifiers === true;
var defaultIdentifiers = [
'__proto__',
'_',
'__dirname',
'__filename',
'super_'
];
if (isTrue) {
identifiers = defaultIdentifiers;
} else {
identifiers = (identifiers.allExcept).concat(defaultIdentifiers);
}
this._identifierIndex = {};
for (var i = 0, l = identifiers.length; i < l; i++) {
this._identifierIndex[identifiers[i]] = true;
}
},

@@ -30,3 +50,3 @@

check: function(file, errors) {
var allowedIdentifiers = this._allowedIdentifiers;
var allowedIdentifiers = this._identifierIndex;

@@ -33,0 +53,0 @@ file.iterateTokensByType('Identifier', function(token) {

@@ -54,3 +54,3 @@ var assert = require('assert');

if (line.match(test)) {
errors.add('Mixed spaces and tabs found', i + 1);
errors.add('Mixed spaces and tabs found', i + 1, 0);
}

@@ -57,0 +57,0 @@ });

@@ -9,7 +9,10 @@ var assert = require('assert');

assert(
disallowMultipleVarDecl === true || disallowMultipleVarDecl === 'strict',
'disallowMultipleVarDecl option requires true or "strict" value'
disallowMultipleVarDecl === true ||
disallowMultipleVarDecl === 'strict' ||
disallowMultipleVarDecl === 'exceptUndefined',
'disallowMultipleVarDecl option requires true, "strict", or "exceptUndefined" value'
);
this.strictMode = disallowMultipleVarDecl === 'strict';
this.exceptUndefined = disallowMultipleVarDecl === 'exceptUndefined';
},

@@ -23,9 +26,23 @@

var inStrictMode = this.strictMode;
var exceptUndefined = this.exceptUndefined;
file.iterateNodesByType('VariableDeclaration', function(node) {
// allow multiple var declarations in for statement unless we're in strict mode
// for (var i = 0, j = myArray.length; i < j; i++) {}
if (node.declarations.length > 1 && (inStrictMode || node.parentNode.type !== 'ForStatement')) {
errors.add('Multiple var declaration', node.loc.start);
var hasDefinedVariables = node.declarations.some(function(declaration) {
return !!declaration.init;
});
var isForStatement = node.parentNode.type === 'ForStatement';
// allow single var declarations
if (node.declarations.length === 1 ||
// allow multiple var declarations in for statement unless we're in strict mode
// for (var i = 0, j = myArray.length; i < j; i++) {}
!inStrictMode && isForStatement ||
// allow multiple var declarations with all undefined variables in exceptUndefined mode
// var a, b, c
exceptUndefined && !hasDefinedVariables) {
return;
}
errors.add('Multiple var declaration', node.loc.start);
});

@@ -32,0 +49,0 @@ }

var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../utils').binaryOperators;

@@ -33,25 +32,12 @@

function errorIfApplicable(token, i, tokens, operator) {
var nextToken = tokens[i + 1];
if (nextToken && nextToken.range[0] !== token.range[1]) {
var loc = token.loc.start;
errors.add(
'Operator ' + operator + ' should stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
}
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',') {
return;
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
errors.assert.noWhitespaceBetween({
token: token,
nextToken: file.getNextToken(token),
message: 'Operator , should stick to following expression'
});
}
errorIfApplicable(token, i, tokens, operator);
});

@@ -64,32 +50,30 @@ }

function(node) {
var isDec = node.type === 'VariableDeclarator';
var operator = isDec ? '=' : node.operator;
var operator;
var expression;
if (!operators[operator] || node.init === null) {
if (node.type === 'VariableDeclarator') {
expression = node.init;
operator = '=';
} else {
operator = node.operator;
expression = node.right;
}
if (expression === null) {
return;
}
var range = (isDec ? node.init : node.right).range[0];
var indent = tokenHelper.isTokenParenthesis(file, range - 1, true) ?
operator.length + 1 :
operator.length;
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
range - indent,
operator,
true
var operatorToken = file.findPrevOperatorToken(
file.getFirstNodeToken(expression),
operator
);
if (!part) {
var loc = tokenHelper.findOperatorByRangeStart(
file, range, operator, true
).loc.start;
var nextToken = file.getNextToken(operatorToken);
errors.add(
'Operator ' + operator + ' should stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, operator.length)
);
if (operators[operator]) {
errors.assert.noWhitespaceBetween({
token: operatorToken,
nextToken: nextToken,
message: 'Operator ' + node.operator + ' should stick to following expression'
});
}

@@ -96,0 +80,0 @@ }

var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../utils').binaryOperators;

@@ -34,30 +33,12 @@

function errorIfApplicable(token, i, tokens, operator) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] !== token.range[0]) {
var loc = token.loc.start;
errors.add(
'Operator ' + operator + ' should stick to preceding expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
}
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',') {
return;
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
errors.assert.noWhitespaceBetween({
token: file.getPrevToken(token),
nextToken: token,
message: 'Operator , should stick to previous expression'
});
}
var prevToken = tokens[i - 1];
// Do not report error if comma not on the same line with the first operand #467
if (token.loc.start.line === prevToken.loc.start.line) {
errorIfApplicable(token, i, tokens, operator);
}
});

@@ -70,20 +51,30 @@ }

function(node) {
var isDec = node.type === 'VariableDeclarator';
var operator = isDec ? '=' : node.operator;
var operator;
var expression;
// !node.init is it's an empty assignment
if (!operators[operator] || node.init === null) {
if (node.type === 'VariableDeclarator') {
expression = node.init;
operator = '=';
} else {
operator = node.operator;
expression = node.right;
}
if (expression === null) {
return;
}
var range = (isDec ? node.id : node.left).range;
var part = tokenHelper.getTokenByRangeStartIfPunctuator(file, range[1], operator);
var operatorToken = file.findPrevOperatorToken(
file.getFirstNodeToken(expression),
operator
);
if (!part) {
errors.add(
'Operator ' + node.operator + ' should stick to preceding expression',
tokenHelper.findOperatorByRangeStart(
file, range[0], operator
).loc.start
);
var prevToken = file.getPrevToken(operatorToken);
if (operators[operator]) {
errors.assert.noWhitespaceBetween({
token: prevToken,
nextToken: operatorToken,
message: 'Operator ' + node.operator + ' should stick to previous expression'
});
}

@@ -90,0 +81,0 @@ }

@@ -70,3 +70,3 @@ var assert = require('assert');

'Illegal space before opening round brace',
functionToken.loc.start
functionToken.loc.end
);

@@ -73,0 +73,0 @@ }

@@ -22,13 +22,10 @@ var assert = require('assert');

check: function(file, errors) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (token.value === ',') {
var nextToken = tokens[i + 1];
if (nextToken && nextToken.type === 'Punctuator' &&
(nextToken.value === '}' || nextToken.value === ']')) {
errors.add(
'Extra comma following the final element of an array or object literal',
token.loc.start
);
}
}
file.iterateNodesByType(['ObjectExpression', 'ArrayExpression'], function(node) {
var closingToken = file.getLastNodeToken(node);
errors.assert.noTokenBefore({
token: closingToken,
expectedTokenBefore: {type: 'Punctuator', value: ','},
message: 'Extra comma following the final element of an array or object literal'
});
});

@@ -35,0 +32,0 @@ }

var assert = require('assert');
var upperCasePattern = /[A-Z]/;
var alphabeticalPattern = /[a-z|A-Z]/;
module.exports = function() {};

@@ -18,4 +21,3 @@

check: function(file, errors) {
var upperCasePattern = /[A-Z]/;
var alphabeticalPattern = /[a-z|A-Z]/;
var inTextBlock = null;

@@ -25,11 +27,22 @@ file.getComments().forEach(function(comment) {

var firstChar = stripped[0];
var isLetter = firstChar && alphabeticalPattern.test(firstChar);
if (alphabeticalPattern.test(firstChar) && !upperCasePattern.test(firstChar)) {
if (!isLetter) {
inTextBlock = false;
return;
}
var isUpperCase = upperCasePattern.test(firstChar);
var isValid = isUpperCase || (inTextBlock && !isUpperCase);
if (!isValid) {
errors.add(
'Comments must start with an uppercase letter',
'Comments must start with an uppercase letter, unless it is part of a textblock',
comment.loc.start
);
}
inTextBlock = !inTextBlock ? isLetter && isUpperCase : isLetter;
});
}
};

@@ -23,12 +23,9 @@ var assert = require('assert');

check: function(file, errors) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) {
errors.add(
'Commas should not be placed on new line',
token.loc.start.line,
token.loc.start.column
);
}
errors.assert.sameLine({
token: file.getPrevToken(token),
nextToken: token,
message: 'Commas should not be placed on new line'
});
}

@@ -35,0 +32,0 @@ });

var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../utils').binaryOperators;

@@ -34,25 +33,12 @@

function errorIfApplicable(token, i, tokens, operator) {
var nextToken = tokens[i + 1];
if (token && nextToken && nextToken.range[0] === token.range[1]) {
var loc = token.loc.start;
errors.add(
'Operator ' + operator + ' should not stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
}
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',') {
return;
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
errors.assert.whitespaceBetween({
token: token,
nextToken: file.getNextToken(token),
message: 'Operator , should not stick to following expression'
});
}
errorIfApplicable(token, i, tokens, operator);
});

@@ -65,30 +51,30 @@ }

function(node) {
var isDec = node.type === 'VariableDeclarator';
var operator = isDec ? '=' : node.operator;
var operator;
var expression;
if (!operators[operator] || node.init === null) {
if (node.type === 'VariableDeclarator') {
expression = node.init;
operator = '=';
} else {
operator = node.operator;
expression = node.right;
}
if (expression === null) {
return;
}
var range = (isDec ? node.init : node.right).range[0];
var indent = tokenHelper.isTokenParenthesis(file, range - 1, true) ?
operator.length + 1 :
operator.length;
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
range - indent,
operator,
true
var operatorToken = file.findPrevOperatorToken(
file.getFirstNodeToken(expression),
operator
);
if (part) {
var loc = part.loc.start;
var nextToken = file.getNextToken(operatorToken);
errors.add(
'Operator ' + operator + ' should not stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, operator.length)
);
if (operators[operator]) {
errors.assert.whitespaceBetween({
token: operatorToken,
nextToken: nextToken,
message: 'Operator ' + node.operator + ' should not stick to following expression'
});
}

@@ -95,0 +81,0 @@ }

@@ -57,3 +57,3 @@ var assert = require('assert');

util.format.apply(null,
diff === 1 ?
diff === 0 ?
[texts[0], token.value] :

@@ -60,0 +60,0 @@ [texts[1], diff, token.value]

@@ -10,7 +10,21 @@ var assert = require('assert');

requireSpaceAfterLineComment === true ||
requireSpaceAfterLineComment === 'allowSlash',
'requireSpaceAfterLineComment option requires the value true or `allowSlash`'
requireSpaceAfterLineComment === 'allowSlash' ||
typeof requireSpaceAfterLineComment === 'object',
'requireSpaceAfterLineComment option requires the value `true` ' +
'or an object with String[] `allExcept` property'
);
this._allowSlash = requireSpaceAfterLineComment === 'allowSlash';
// verify first item in `allExcept` property in object (if it's an object)
assert(
typeof requireSpaceAfterLineComment !== 'object' ||
Array.isArray(requireSpaceAfterLineComment.allExcept) &&
typeof requireSpaceAfterLineComment.allExcept[0] === 'string',
'Property `allExcept` in requireSpaceAfterLineComment should be an array of strings'
);
// don't check triple slashed comments, microsoft js doc convention. see #593
// exceptions. see #592
// need to drop allowSlash support in 2.0. Fixes #697
this._allExcept = requireSpaceAfterLineComment === 'allowSlash' ? ['/'] :
requireSpaceAfterLineComment.allExcept || [];
},

@@ -24,3 +38,3 @@

var comments = file.getComments();
var allowSlash = this._allowSlash;
var allExcept = this._allExcept;

@@ -31,6 +45,8 @@ comments.forEach(function(comment) {

// don't check triple slashed comments, microsoft js doc convention. see #593
if (allowSlash && value[0] === '/') {
value = value.substr(1);
}
// cutout exceptions
allExcept.forEach(function(el) {
if (value.indexOf(el) === 0) {
value = value.substr(el.length);
}
});

@@ -37,0 +53,0 @@ if (value.length === 0) {

var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../../lib/utils').binaryOperators.filter(function(operator) {

@@ -36,25 +35,12 @@ return operator !== ',';

function errorIfApplicable(token, i, tokens, operator) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] === token.range[0]) {
var loc = token.loc.start;
errors.add(
'Operator ' + operator + ' should not stick to preceding expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
}
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',') {
return;
file.iterateTokensByType('Punctuator', function(token) {
if (token.value === ',') {
errors.assert.whitespaceBetween({
token: file.getPrevToken(token),
nextToken: token,
message: 'Operator , should not stick to preceding expression'
});
}
errorIfApplicable(token, i, tokens, operator);
});

@@ -67,19 +53,30 @@ }

function(node) {
var isDec = node.type === 'VariableDeclarator';
var operator = isDec ? '=' : node.operator;
var operator;
var expression;
if (!operators[operator]) {
if (node.type === 'VariableDeclarator') {
expression = node.init;
operator = '=';
} else {
operator = node.operator;
expression = node.right;
}
if (expression === null) {
return;
}
var range = (isDec ? node.id : node.left).range[1];
var part = tokenHelper.getTokenByRangeStartIfPunctuator(file, range, operator);
var operatorToken = file.findPrevOperatorToken(
file.getFirstNodeToken(expression),
operator
);
if (part) {
var loc = part.loc.start;
errors.add(
'Operator ' + operator + ' should not stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, operator.length)
);
var prevToken = file.getPrevToken(operatorToken);
if (operators[operator]) {
errors.assert.whitespaceBetween({
token: prevToken,
nextToken: operatorToken,
message: 'Operator ' + node.operator + ' should not stick to preceding expression'
});
}

@@ -86,0 +83,0 @@ }

var assert = require('assert');
var tokenHelper = require('../token-helper');

@@ -8,9 +7,18 @@ module.exports = function() {};

configure: function(requireTrailingComma) {
if (typeof requireTrailingComma === 'object') {
assert(
requireTrailingComma.ignoreSingleValue === true,
'requireTrailingComma option ignoreSingleValue requires true value or should be removed'
);
this._ignoreSingleValue = true;
if ('ignoreSingleValue' in requireTrailingComma) {
assert(
requireTrailingComma.ignoreSingleValue === true,
'requireTrailingComma option ignoreSingleValue requires true value or should be removed'
);
this._ignoreSingleValue = true;
}
if ('ignoreSingleLine' in requireTrailingComma) {
assert(
requireTrailingComma.ignoreSingleLine === true,
'requireTrailingComma option ignoreSingleLine requires true value or should be removed'
);
this._ignoreSingleLine = true;
}
} else {

@@ -33,19 +41,23 @@ assert(

var isObject = node.type === 'ObjectExpression';
var message = 'Missing comma before closing ' + (isObject ? ' curly brace' : ' bracket');
var entities = isObject ? node.properties : node.elements;
var last;
var hasTrailingComma;
if (entities.length) {
if (_this._ignoreSingleValue && entities.length === 1) {
return;
}
if (entities.length === 0) {
return;
}
last = entities[entities.length - 1];
hasTrailingComma = tokenHelper.getTokenByRangeStartIfPunctuator(file, last.range[1], ',');
if (_this._ignoreSingleValue && entities.length === 1) {
return;
}
if (!hasTrailingComma) {
errors.add(message, node.loc.end);
}
if (_this._ignoreSingleLine && node.loc.start.line === node.loc.end.line) {
return;
}
var closingToken = file.getLastNodeToken(node);
errors.assert.tokenBefore({
token: closingToken,
expectedTokenBefore: {type: 'Punctuator', value: ','},
message: 'Missing comma before closing ' + (isObject ? ' curly brace' : ' bracket')
});
});

@@ -52,0 +64,0 @@ }

@@ -22,46 +22,45 @@ var assert = require('assert');

var tokens = file.getTokens();
var validateTokens = this._separator.split('');
var separatorBefore = validateTokens[0];
var separatorAfter = validateTokens[validateTokens.length - 1];
var separators = this._separator.split(',');
var whitespaceBeforeComma = Boolean(separators.shift());
var whitespaceAfterComma = Boolean(separators.pop());
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) {
node.params.forEach(function(param) {
node.params.forEach(function(paramNode) {
var paramTokenPos = file.getTokenPosByRangeStart(param.range[0]);
var punctuatorToken = tokens[paramTokenPos + 1];
var prevParamToken = file.getFirstNodeToken(paramNode);
var punctuatorToken = file.getNextToken(prevParamToken);
if (punctuatorToken.value === ',') {
var nextParamToken = tokens[paramTokenPos + 2];
if (separatorBefore === ',' &&
punctuatorToken.range[0] !== param.range[1] &&
param.loc.start.line === nextParamToken.loc.start.line) {
errors.add(
'Unexpected space after function parameter \'' + param.name + '\'',
punctuatorToken.loc.start
);
} else if (separatorBefore === ' ' && punctuatorToken.range[0] === param.range[1]) {
errors.add(
'Missing space after function parameter \'' + param.name + '\'',
punctuatorToken.loc.start
);
if (whitespaceBeforeComma) {
errors.assert.whitespaceBetween({
token: prevParamToken,
nextToken: punctuatorToken,
spaces: 1,
message: 'Missing space after function parameter \'' + prevParamToken.value + '\''
});
} else {
errors.assert.noWhitespaceBetween({
token: prevParamToken,
nextToken: punctuatorToken,
message: 'Unexpected space after function parameter \'' + prevParamToken.value + '\''
});
}
if (separatorAfter === ',' &&
punctuatorToken.range[1] < nextParamToken.range[0] &&
param.loc.start.line === nextParamToken.loc.start.line) {
var nextParamToken = file.getNextToken(punctuatorToken);
errors.add(
'Unexpected space before function parameter \'' + nextParamToken.value + '\'',
nextParamToken.loc.start
);
} else if (separatorAfter === ' ' && punctuatorToken.range[1] === nextParamToken.range[0]) {
errors.add(
'Missing space before function parameter \'' + nextParamToken.value + '\'',
nextParamToken.loc.start
);
if (whitespaceAfterComma) {
errors.assert.whitespaceBetween({
token: punctuatorToken,
nextToken: nextParamToken,
spaces: 1,
message: 'Missing space before function parameter \'' + nextParamToken.value + '\''
});
} else {
errors.assert.noWhitespaceBetween({
token: punctuatorToken,
nextToken: nextParamToken,
message: 'Unexpected space before function parameter \'' + nextParamToken.value + '\''
});
}

@@ -68,0 +67,0 @@ }

@@ -5,4 +5,3 @@ var defaultEsprima = require('esprima');

var JsFile = require('./js-file');
var preset = require('./options/preset');
var maxErrors = require('./options/max-errors');
var Configuration = require('./config/configuration');

@@ -19,8 +18,10 @@ /**

var StringChecker = function(options) {
this._rules = [];
this._activeRules = [];
this._config = {};
this._configuredRules = [];
this._errorsFound = 0;
this._maxErrorsExceeded = false;
this._configuration = this._createConfiguration();
this._configuration.registerDefaultPresets();
if (typeof options === 'boolean') {

@@ -42,129 +43,19 @@ this._verbose = options;

registerRule: function(rule) {
this._rules.push(rule);
this._configuration.registerRule(rule);
},
/**
* Registers built-in Code Style cheking rules.
* Registers built-in Code Style checking rules.
*/
registerDefaultRules: function() {
this.registerRule(new (require('./rules/require-curly-braces'))());
this.registerRule(new (require('./rules/require-multiple-var-decl'))());
this.registerRule(new (require('./rules/disallow-multiple-var-decl'))());
this.registerRule(new (require('./rules/disallow-empty-blocks'))());
this.registerRule(new (require('./rules/require-space-after-keywords'))());
this.registerRule(new (require('./rules/disallow-space-after-keywords'))());
this.registerRule(new (require('./rules/require-parentheses-around-iife'))());
/* deprecated rules */
this.registerRule(new (require('./rules/require-left-sticked-operators'))());
this.registerRule(new (require('./rules/disallow-left-sticked-operators'))());
this.registerRule(new (require('./rules/require-right-sticked-operators'))());
this.registerRule(new (require('./rules/disallow-right-sticked-operators'))());
this.registerRule(new (require('./rules/validate-jsdoc'))());
/* deprecated rules (end) */
this.registerRule(new (require('./rules/require-operator-before-line-break'))());
this.registerRule(new (require('./rules/disallow-implicit-type-conversion'))());
this.registerRule(new (require('./rules/require-camelcase-or-uppercase-identifiers'))());
this.registerRule(new (require('./rules/disallow-keywords'))());
this.registerRule(new (require('./rules/disallow-multiple-line-breaks'))());
this.registerRule(new (require('./rules/disallow-multiple-line-strings'))());
this.registerRule(new (require('./rules/validate-line-breaks'))());
this.registerRule(new (require('./rules/validate-quote-marks'))());
this.registerRule(new (require('./rules/validate-indentation'))());
this.registerRule(new (require('./rules/disallow-trailing-whitespace'))());
this.registerRule(new (require('./rules/disallow-mixed-spaces-and-tabs'))());
this.registerRule(new (require('./rules/require-keywords-on-new-line'))());
this.registerRule(new (require('./rules/disallow-keywords-on-new-line'))());
this.registerRule(new (require('./rules/require-line-feed-at-file-end'))());
this.registerRule(new (require('./rules/maximum-line-length'))());
this.registerRule(new (require('./rules/require-yoda-conditions'))());
this.registerRule(new (require('./rules/disallow-yoda-conditions'))());
this.registerRule(new (require('./rules/require-spaces-inside-object-brackets'))());
this.registerRule(new (require('./rules/require-spaces-inside-array-brackets'))());
this.registerRule(new (require('./rules/require-spaces-inside-parentheses'))());
this.registerRule(new (require('./rules/disallow-spaces-inside-object-brackets'))());
this.registerRule(new (require('./rules/disallow-spaces-inside-array-brackets'))());
this.registerRule(new (require('./rules/disallow-spaces-inside-parentheses'))());
this.registerRule(new (require('./rules/require-blocks-on-newline'))());
this.registerRule(new (require('./rules/require-space-after-object-keys'))());
this.registerRule(new (require('./rules/require-space-before-object-values'))());
this.registerRule(new (require('./rules/disallow-space-after-object-keys'))());
this.registerRule(new (require('./rules/disallow-space-before-object-values'))());
this.registerRule(new (require('./rules/disallow-quoted-keys-in-objects'))());
this.registerRule(new (require('./rules/disallow-dangling-underscores'))());
this.registerRule(new (require('./rules/require-aligned-object-values'))());
this.registerRule(new (require('./rules/disallow-padding-newlines-in-blocks'))());
this.registerRule(new (require('./rules/require-padding-newlines-in-blocks'))());
this.registerRule(new (require('./rules/require-padding-newlines-in-objects'))());
this.registerRule(new (require('./rules/disallow-padding-newlines-in-objects'))());
this.registerRule(new (require('./rules/require-newline-before-block-statements'))());
this.registerRule(new (require('./rules/disallow-newline-before-block-statements'))());
this.registerRule(new (require('./rules/disallow-trailing-comma'))());
this.registerRule(new (require('./rules/require-trailing-comma'))());
this.registerRule(new (require('./rules/disallow-comma-before-line-break'))());
this.registerRule(new (require('./rules/require-comma-before-line-break'))());
this.registerRule(new (require('./rules/disallow-space-before-block-statements.js'))());
this.registerRule(new (require('./rules/require-space-before-block-statements.js'))());
this.registerRule(new (require('./rules/disallow-space-before-postfix-unary-operators.js'))());
this.registerRule(new (require('./rules/require-space-before-postfix-unary-operators.js'))());
this.registerRule(new (require('./rules/disallow-space-after-prefix-unary-operators.js'))());
this.registerRule(new (require('./rules/require-space-after-prefix-unary-operators.js'))());
this.registerRule(new (require('./rules/disallow-space-before-binary-operators'))());
this.registerRule(new (require('./rules/require-space-before-binary-operators'))());
this.registerRule(new (require('./rules/disallow-space-after-binary-operators'))());
this.registerRule(new (require('./rules/require-space-after-binary-operators'))());
this.registerRule(new (require('./rules/require-spaces-in-conditional-expression'))());
this.registerRule(new (require('./rules/disallow-spaces-in-conditional-expression'))());
this.registerRule(new (require('./rules/require-spaces-in-function'))());
this.registerRule(new (require('./rules/disallow-spaces-in-function'))());
this.registerRule(new (require('./rules/require-spaces-in-function-expression'))());
this.registerRule(new (require('./rules/disallow-spaces-in-function-expression'))());
this.registerRule(new (require('./rules/require-spaces-in-anonymous-function-expression'))());
this.registerRule(new (require('./rules/disallow-spaces-in-anonymous-function-expression'))());
this.registerRule(new (require('./rules/require-spaces-in-named-function-expression'))());
this.registerRule(new (require('./rules/disallow-spaces-in-named-function-expression'))());
this.registerRule(new (require('./rules/require-spaces-in-function-declaration'))());
this.registerRule(new (require('./rules/disallow-spaces-in-function-declaration'))());
this.registerRule(new (require('./rules/require-spaces-in-call-expression'))());
this.registerRule(new (require('./rules/disallow-spaces-in-call-expression'))());
this.registerRule(new (require('./rules/validate-parameter-separator'))());
this.registerRule(new (require('./rules/require-capitalized-constructors'))());
this.registerRule(new (require('./rules/safe-context-keyword'))());
this.registerRule(new (require('./rules/require-dot-notation'))());
this.registerRule(new (require('./rules/require-space-after-line-comment'))());
this.registerRule(new (require('./rules/disallow-space-after-line-comment'))());
this.registerRule(new (require('./rules/require-anonymous-functions'))());
this.registerRule(new (require('./rules/disallow-anonymous-functions'))());
this.registerRule(new (require('./rules/require-function-declarations'))());
this.registerRule(new (require('./rules/disallow-function-declarations'))());
this.registerRule(new (require('./rules/require-capitalized-comments'))());
this.registerRule(new (require('./rules/disallow-capitalized-comments'))());
this._configuration.registerDefaultRules();
},
/**
* Get processed config
* Get processed config.
*
* @return {Object}
*/
getProcessedConfig: function() {
return this._config;
return this._configuration.getProcessedConfig();
},

@@ -178,80 +69,15 @@

configure: function(config) {
maxErrors(config, this);
this._configuration.load(config);
this.throwNonCamelCaseErrorIfNeeded(config);
if (config.preset && !preset.exists(config.preset)) {
throw new Error(preset.getDoesNotExistError(config.preset));
}
preset.extend(config);
if (config.esnext) {
if (this._configuration.hasCustomEsprima()) {
this._esprima = this._configuration.getCustomEsprima();
} else if (this._configuration.isESNextEnabled()) {
this._esprima = harmonyEsprima;
}
var configRules = Object.keys(config);
var activeRules = this._activeRules;
this._config = config;
this._rules.forEach(function(rule) {
var ruleOptionName = rule.getOptionName();
if (config.hasOwnProperty(ruleOptionName)) {
// Do not configure the rule if it's equals to null (#203)
if (config[ruleOptionName] !== null) {
rule.configure(config[ruleOptionName]);
}
activeRules.push(rule);
configRules.splice(configRules.indexOf(ruleOptionName), 1);
}
});
if (configRules.length > 0) {
throw new Error('Unsupported rules: ' + configRules.join(', '));
}
this._configuredRules = this._configuration.getConfiguredRules();
this._maxErrors = this._configuration.getMaxErrors();
},
/**
* Throws error for non camel-case options.
*
* @param {Object} config
*/
throwNonCamelCaseErrorIfNeeded: function(config) {
function symbolToUpperCase(s, symbol) {
return symbol.toUpperCase();
}
function fixConfig(originConfig) {
var result = {};
for (var i in originConfig) {
if (originConfig.hasOwnProperty(i)) {
var camelCaseName = i.replace(/_([a-zA-Z])/g, symbolToUpperCase);
var value = originConfig[i];
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
value = fixConfig(value);
}
result[camelCaseName] = value;
}
}
return result;
}
var hasOldStyleConfigParams = false;
for (var i in config) {
if (config.hasOwnProperty(i)) {
if (i.indexOf('_') !== -1) {
hasOldStyleConfigParams = true;
break;
}
}
}
if (hasOldStyleConfigParams) {
throw new Error('JSCS now accepts configuration options in camel case. Sorry for inconvenience. ' +
'On the bright side, we tried to convert your jscs config to camel case.\n' +
'----------------------------------------\n' +
JSON.stringify(fixConfig(config), null, 4) +
'\n----------------------------------------\n');
}
},
/**
* Checks file provided with a string.

@@ -276,2 +102,3 @@ * @param {String} str

var errors = new Errors(file, this._verbose);
var errorFilter = this._configuration.getErrorFilter();

@@ -286,10 +113,11 @@ if (!this._maxErrorsExceeded) {

this._activeRules.forEach(function(rule) {
// Do not process the rule if it's equals to null (#203)
if (this._config[rule.getOptionName()] !== null) {
errors.setCurrentRule(rule.getOptionName());
rule.check(file, errors);
}
this._configuredRules.forEach(function(rule) {
errors.setCurrentRule(rule.getOptionName());
rule.check(file, errors);
}, this);
this._configuration.getUnsupportedRuleNames().forEach(function(rulename) {
errors.add('Unsupported rule: ' + rulename, 1, 0);
});
// sort errors list to show errors as they appear in source

@@ -300,3 +128,7 @@ errors.getErrorList().sort(function(a, b) {

if (!isNaN(this._maxErrors)) {
if (errorFilter) {
errors.filter(errorFilter);
}
if (this._maxErrors !== null && !isNaN(this._maxErrors)) {
if (!this._maxErrorsExceeded) {

@@ -321,2 +153,21 @@ this._maxErrorsExceeded = this._errorsFound + errors.getErrorCount() > this._maxErrors;

return this._maxErrorsExceeded;
},
/**
* Returns new configuration instance.
*
* @protected
* @returns {Configuration}
*/
_createConfiguration: function() {
return new Configuration();
},
/**
* Returns current configuration instance.
*
* @returns {Configuration}
*/
getConfiguration: function() {
return this._configuration;
}

@@ -323,0 +174,0 @@ };

@@ -55,2 +55,5 @@ module.exports = {

// export (ES6)
'declaration': true,
// xxx.yyy

@@ -57,0 +60,0 @@ 'property': true

@@ -81,2 +81,3 @@ // 7.5.2 Keywords

'catch',
'finally',
'void',

@@ -83,0 +84,0 @@ 'while',

@@ -5,3 +5,3 @@ {

"name": "jscs",
"version": "1.7.3",
"version": "1.8.0",
"main": "lib/checker",

@@ -30,4 +30,4 @@ "homepage": "https://github.com/jscs-dev/node-jscs",

"dependencies": {
"colors": "~0.6.2",
"commander": "~2.3.0",
"colors": "~1.0.3",
"commander": "~2.5.0",
"esprima": "~1.2.2",

@@ -42,6 +42,6 @@ "esprima-harmony-jscs": "1.1.0-dev-harmony",

"xmlbuilder": "~2.4.0",
"supports-color": "~1.1.0"
"supports-color": "~1.2.0"
},
"devDependencies": {
"browserify": "~5.10.0",
"browserify": "~6.2.0",
"coveralls": "~2.11.1",

@@ -51,6 +51,6 @@ "has-ansi": "~1.0.0",

"jshint": "~2.5.0",
"mocha": "~1.21.4",
"mocha": "~2.0.1",
"rewire": "~2.1.0",
"separated-coverage": "~2.3.0",
"sinon": "~1.10.0",
"unit-coverage": "~3.2.0",
"sinon": "~1.11.0",
"xml2js": "~0.4.2"

@@ -61,3 +61,3 @@ },

},
"separated-coverage": {
"unit-coverage": {
"common": [

@@ -83,4 +83,4 @@ "-a",

"test": "npm run lint && mocha",
"coverage": "scov run -p common",
"coverage-html": "scov run -p common -r html -o coverage.html",
"coverage": "unit-coverage run -p common",
"coverage-html": "unit-coverage run -p common -r html -o coverage.html",
"browserify": "browserify --standalone JscsStringChecker lib/string-checker.js -o jscs-browser.js",

@@ -90,3 +90,3 @@ "changelog": "git log `git describe --tags --abbrev=0`..HEAD --pretty=format:' * %s (%an)' | grep -v 'Merge pull request'",

"postpublish": "node publish/postpublish",
"travis": "npm run test && scov run -p common -r lcov -o out.lcov && cat out.lcov | coveralls"
"travis": "npm run test && unit-coverage run -p common -r lcov -o out.lcov && cat out.lcov | coveralls"
},

@@ -93,0 +93,0 @@ "files": [

@@ -52,3 +52,2 @@ {

"disallowKeywords": [ "with" ],
"disallowMultipleLineBreaks": true,
"validateQuoteMarks": "'",

@@ -55,0 +54,0 @@ "validateIndentation": 4,

# node-jscs
[![Build Status](https://travis-ci.org/jscs-dev/node-jscs.svg?branch=master)](https://travis-ci.org/jscs-dev/node-jscs) [![Coverage Status](https://img.shields.io/coveralls/jscs-dev/node-jscs.svg)](https://coveralls.io/r/jscs-dev/node-jscs?branch=master) [![Dependency Status](https://david-dm.org/jscs-dev/node-jscs.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs) [![devDependency Status](https://david-dm.org/jscs-dev/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs#info=devDependencies)
JSCS — JavaScript Code Style.
JSCS — JavaScript Code Style. [Twitter](https://twitter.com/jscs_dev) | [Mailing List](https://groups.google.com/group/jscs-dev)

@@ -21,2 +22,3 @@

- [Rules](#rules)
- [Plugins](#plugins)
- [Removed Rules](#removed-rules)

@@ -31,6 +33,7 @@ - [Browser Usage](#browser-usage)

* [Google](presets/google.json) - https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
* [Grunt](presets/grunt.json) - http://gruntjs.com/contributing#syntax
* [jQuery](presets/jquery.json) - https://contribute.jquery.org/style-guide/js/
* [MDCS](presets/mdcs.json) - https://github.com/mrdoob/three.js/wiki/Mr.doob's-Code-Style%E2%84%A2
* [Wikimedia](presets/wikimedia.json) - https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/js.md
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/javascript.md

@@ -81,3 +84,3 @@ ## Friendly packages

If there is no `--config` option specified, `jscs` it will consequentially search for `jscsConfig` option in `package.json` file then for `.jscsrc` and `.jscs.json` files in the current working directory then in nearest ancestor until it hits the system root.
If there is no `--config` option specified, `jscs` it will consequentially search for `jscsConfig` option in `package.json` file then for `.jscsrc` (which is a just JSON with comments) and `.jscs.json` files in the current working directory then in nearest ancestor until it hits the system root.

@@ -104,2 +107,14 @@ ### `--preset`

### `--esprima`
Attempts to parse your code with a custom Esprima version.
```
jscs path[ path[...]] --esprima=esprima-fb
```
### `--error-filter`
The path to a module that determines whether or not an error should be reported.
```
jscs path[ path[...]] --error-filter=path/to/my/module.js
```
### `--no-colors`

@@ -122,2 +137,12 @@ Clean output without colors.

### plugins
Paths to load plugins. See the wiki page for more details about the [Plugin API](https://github.com/jscs-dev/node-jscs/wiki/Plugin-API)
Values: Array of NPM package names or paths
```js
"plugins": ["jscs-plugin", "./lib/project-jscs-plugin"]
```
### additionalRules

@@ -221,2 +246,17 @@

### errorFilter
A filter function that determines whether or not to report an error.
This will be called for every found error.
Type: `String`
#### Example
```js
"errorFilter": "path/to/my/filter.js"
```
See [how to define an error filter](https://github.com/jscs-dev/node-jscs/wiki/Error-Filters).
## Error Suppression

@@ -303,16 +343,2 @@

```js
[
'if',
'else',
'for',
'while',
'do',
'try',
'catch',
'case',
'default'
]
```
JSHint: [`curly`](http://jshint.com/docs/options/#curly)

@@ -350,2 +376,36 @@

### requireSpaceBeforeKeywords
Requires space before keyword.
Type: `Array` or `Boolean`
Values: Array of quoted keywords or `true` to require all possible keywords to have a preceding space.
#### Example
```js
"requireSpaceBeforeKeywords": [
"else",
"while",
"catch"
]
```
##### Valid
```js
} else {
x++;
}
```
##### Invalid
```js
}else {
x++;
}
```
### requireSpaceAfterKeywords

@@ -426,2 +486,35 @@

### disallowSpaceBeforeKeywords
Disallows space before keyword.
Type: `Array` or `Boolean`
Values: Array of quoted keywords or `true` to disallow spaces before all possible keywords.
#### Example
```js
"disallowSpaceBeforeKeywords": [
"else",
"catch"
]
```
##### Valid
```js
}else {
y--;
}
```
##### Invalid
```js
} else {
y--;
}
```
### requireSpaceBeforeBlockStatements

@@ -445,11 +538,11 @@

if (cond) {
foo();
foo();
}
for (var e in elements) {
bar(e);
bar(e);
}
while (cond) {
foo();
foo();
}

@@ -462,11 +555,11 @@ ```

if (cond){
foo();
foo();
}
for (var e in elements){
bar(e);
bar(e);
}
while (cond){
foo();
foo();
}

@@ -494,11 +587,11 @@ ```

if (cond){
foo();
foo();
}
for (var e in elements){
bar(e);
bar(e);
}
while (cond){
foo();
foo();
}

@@ -511,11 +604,11 @@ ```

if (cond) {
foo();
foo();
}
for (var e in elements) {
bar(e);
bar(e);
}
while (cond) {
foo();
foo();
}

@@ -603,4 +696,14 @@ ```

Values: `"afterTest"`, `"beforeConsequent"`, `"afterConsequent"`, `"beforeAlternate"` as child properties, or `true` to set all properties to true. Child properties must be set to `true`.
Values: `"afterTest"`, `"beforeConsequent"`, `"afterConsequent"`, `"beforeAlternate"` as child properties, or `true` to set all properties to true. Child properties must be set to `true`. These token names correspond to:
```
var a = b ? c : d;
^ ^ ^ ^
| | | |
| | | └- beforeAlternate
| | └--- afterConsequent
| └-------- beforeConsequent
└---------- afterTest
```
#### Example

@@ -637,3 +740,3 @@

Requires space before `()` or `{}` in function expressions (both named and anonymous).
Requires space before `()` or `{}` in function expressions (both [named](#requirespacesinnamedfunctionexpression) and [anonymous](#requirespacesinanonymousfunctionexpression)).

@@ -656,4 +759,4 @@ Type: `Object`

```js
function () {}
function a () {}
var x = function () {};
var x = function a () {};
```

@@ -664,4 +767,4 @@

```js
function() {}
function (){}
var x = function() {};
var x = function a(){};
```

@@ -672,3 +775,3 @@

Disallows space before `()` or `{}` in function expressions (both named and anonymous).
Disallows space before `()` or `{}` in function expressions (both [named](#disallowspacesinnamedfunctionexpression) and [anonymous](#disallowspacesinanonymousfunctionexpression)).

@@ -691,4 +794,4 @@ Type: `Object`

```js
function(){}
function a(){}
var x = function(){};
var x = function a(){};
```

@@ -699,4 +802,4 @@

```js
function () {}
function a (){}
var x = function () {};
var x = function a (){};
```

@@ -725,3 +828,7 @@

```js
function () {}
var foo = function () {};
var Foo = {
foo: function () {};
}
array.map(function () {});
```

@@ -732,4 +839,7 @@

```js
function() {}
function (){}
var foo = function() {};
var Foo = {
foo: function (){};
}
array.map(function(){});
```

@@ -758,3 +868,7 @@

```js
function(){}
var foo = function(){};
var Foo = {
foo: function(){};
}
array.map(function(){});
```

@@ -765,4 +879,7 @@

```js
function () {}
function (){}
var foo = function () {};
var Foo = {
foo: function (){};
}
array.map(function() {});
```

@@ -791,3 +908,3 @@

```js
var x = function a () {}
var x = function a () {};
```

@@ -798,4 +915,4 @@

```js
var x = function a() {}
var x = function a(){}
var x = function a() {};
var x = function a(){};
```

@@ -824,3 +941,3 @@

```js
function a(){}
var x = function a(){};
```

@@ -831,4 +948,4 @@

```js
function a () {}
function a (){}
var x = function a () {};
var x = function a (){};
```

@@ -901,3 +1018,3 @@

Requires space before `()` or `{}` in function declarations and expressions.
Requires space before `()` or `{}` in function [declarations](#requirespacesinfunctiondeclaration) and [expressions](#requirespacesinfunctionexpression).

@@ -921,2 +1038,4 @@ Type: `Object`

function a () {}
var x = function a () {};
```

@@ -929,2 +1048,5 @@

function a (){}
var x = function a() {};
var x = function a () {};
```

@@ -935,3 +1057,3 @@

Disallows space before `()` or `{}` in function declarations and expressions.
Disallows space before `()` or `{}` in function [declarations](#disallowspacesinfunctiondeclaration) and [expressions](#disallowspacesinfunctionexpression).

@@ -955,2 +1077,4 @@ Type: `Object`

function a(){}
var x = function a(){};
```

@@ -963,2 +1087,5 @@

function a (){}
var x = function a () {};
var x = function a (){};
```

@@ -1027,4 +1154,8 @@

Values: `true` or 'strict' (to disallow multiple variable declarations within a for loop)
Values:
- `true` disallows multiple variable declarations except within a for loop
- `'strict'` disallows all multiple variable declarations
- `'exceptUndefined'` allows declarations where all variables are not defined
#### Example

@@ -1036,3 +1167,3 @@

##### Valid
##### Valid for `true`

@@ -1046,2 +1177,19 @@ ```js

##### Valid for `strict`
```js
var x = 1;
var y = 2;
```
##### Valid for `exceptUndefined`
```js
var a, b;
var x = 1;
var y = 2;
for (var i = 0, j = arr.length; i < j; i++) {}
```
##### Invalid

@@ -1052,2 +1200,4 @@

y = 2;
var x, y = 2, z;
```

@@ -1296,2 +1446,130 @@

### requirePaddingNewlinesBeforeKeywords
Requires an empty line above the specified keywords unless the keyword is the first expression in a block.
Type: `Array` or `Boolean`
Values: Array of quoted types or `true` to require padding new lines before all of the keywords below.
#### Example
```js
"requirePaddingNewlinesBeforeKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"void",
"while",
"with",
"return",
"typeof",
"function"
]
```
##### Valid
```js
function(a) {
if (!a) {
return false;
}
for (var i = 0; i < b; i++) {
if (!a[i]) {
return false;
}
}
return true;
}
```
##### Invalid
```js
function(a) {
if (!a) {
return false;
}
for (var i = 0; i < b; i++) {
if (!a[i]) {
return false;
}
}
return true;
}
```
### disallowPaddingNewlinesBeforeKeywords
Disallow an empty line above the specified keywords.
Type: `Array` or `Boolean`
Values: Array of quoted types or `true` to disallow padding new lines after all of the keywords below.
#### Example
```js
"requirePaddingNewlinesBeforeKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"void",
"while",
"with",
"return",
"typeof",
"function"
]
```
##### Valid
```js
function(a) {
if (!a) {
return false;
}
for (var i = 0; i < b; i++) {
if (!a[i]) {
return false;
}
}
return true;
}
```
##### Invalid
```js
function(a) {
if (!a) {
return false;
}
for (var i = 0; i < b; i++) {
if (!a[i]) {
return false;
}
}
return true;
}
```
### disallowEmptyBlocks

@@ -1570,11 +1848,16 @@

Disallows identifiers that start or end in `_`, except for some popular exceptions:
Disallows identifiers that start or end in `_`. Some popular identifiers are automatically listed as exceptions:
- `__proto__` (javascript)
- `_` (underscore.js)
- `__filename` (node.js global)
- `__dirname` (node.js global)
- `super_` (node.js, used by [`util.inherits`](http://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor))
Type: `Boolean`
Type: `Boolean` or `Object`
Values: `true`
Values:
- `true`
- `Object`:
- `allExcept`: array of quoted identifiers

@@ -1586,3 +1869,3 @@ JSHint: [`nomen`](http://www.jshint.com/docs/options/#nomen)

```js
"disallowDanglingUnderscores": true
"disallowDanglingUnderscores": { allExcept: ["_exception"] }
```

@@ -1594,2 +1877,3 @@

var x = 1;
var o = obj.__proto__;
var y = _.extend;

@@ -1599,2 +1883,3 @@ var z = __dirname;

var x_y = 1;
var v = _exception;
```

@@ -2326,2 +2611,37 @@

### disallowOperatorBeforeLineBreak
Requires putting certain operators on the next line rather than on the current line before a line break.
Type: `Array` or `Boolean`
Values: Array of operators to apply to or `true`
#### Example
```js
"disallowOperatorBeforeLineBreak": ["+", "."]
```
##### Valid
```js
$el.on( 'click', fn )
.appendTo( 'body' );
var x = 4 + 5 +
12 + 13;
```
##### Invalid
```js
$el.on( 'click', fn ).
appendTo( 'body' );
var x = 4 + 5
+ 12 + 13;
```
### disallowTrailingWhitespace

@@ -2395,3 +2715,4 @@

- `Object`:
- `ignoreSingleValue`: allows single property objects and single element arrays to not require a trailing comma
- `ignoreSingleValue`: allows single property objects and single element arrays to not require a trailing comma
- `ignoreSingleLine`: allows objects and arrays on a single line to not require a trailing comma

@@ -2418,2 +2739,9 @@ #### Example

##### Valid with ignoreSingleLine
```js
var car = [1, 2, 3];
var dar = {a: "a", b: "b"};
```
##### Invalid

@@ -2623,3 +2951,3 @@

if (1 == a) {
return
return
}

@@ -2632,3 +2960,3 @@ ```

if (a == 1) {
return
return
}

@@ -2655,3 +2983,3 @@ ```

if (a == 1) {
return
return
}

@@ -2664,3 +2992,3 @@ ```

if (1 == a) {
return
return
}

@@ -2671,7 +2999,11 @@ ```

Requires that a line comment (`//`) be followed by a space or slash space (`/// `).
Requires that a line comment (`//`) be followed by a space.
Type: `Boolean` or `String`
Type: `Boolean` or `Object` or `String`
Values: `true` or `'allowSlash'`
Values:
- `true`
- `"allowSlash"` (*deprecated* use `"except": ["/"]`) allows `/// ` format
- `Object`:
- `allExcept`: array of allowed strings before space `//(here) `

@@ -2681,3 +3013,3 @@ #### Example

```js
"requireSpaceAfterLineComment": true
"requireSpaceAfterLineComment": { "allExcept": ["#", "="] }
```

@@ -2690,2 +3022,4 @@

/*A comment*/
//# sourceURL=filename.js
//= require something
```

@@ -2787,3 +3121,3 @@

};)
})
```

@@ -2800,3 +3134,3 @@

};)
});
```

@@ -3211,3 +3545,3 @@

Requires the first alphabetical character of a comment to be uppercase
Requires the first alphabetical character of a comment to be uppercase, unless it is part of a multi-line textblock.

@@ -3236,3 +3570,13 @@ Type: `Boolean`

// A textblock is a set of lines
// that starts with a capitalized letter
// and has one or more non-capitalized lines
// afterwards
// A textblock may also have multiple lines.
// Those lines can be uppercase as well to support
// sentense breaks in textblocks
// 123 or any non-alphabetical starting character
// @are also valid anywhere
```

@@ -3239,0 +3583,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc