Socket
Socket
Sign inDemoInstall

jscs

Package Overview
Dependencies
Maintainers
3
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.4.5 to 1.5.1

lib/comment-helper.js

13

lib/checker.js

@@ -9,2 +9,3 @@ var vowFs = require('vow-fs');

var excludeFiles = require('./options/exclude-files');
var fileExtensions = require('./options/file-extensions');

@@ -30,2 +31,3 @@ /**

fileExtensions(config, this);
excludeFiles(config, this, cwd);

@@ -45,3 +47,3 @@ additionalRules(config, this, cwd);

var _this = this;
if (this._shouldProcess(path) && path.match(/\.js$/)) {
if (this._shouldProcess(path)) {
return vowFs.read(path, 'utf8').then(function(data) {

@@ -123,3 +125,4 @@ return _this.checkString(data, path);

/**
* Returns true if specified path is not in exluded list.
* Returns true if specified path is not in exluded list and if
* the file extension matches a file extension to process.
*

@@ -131,2 +134,8 @@ * @returns {Boolean}

var extension = path.extname(testPath).toLowerCase();
if (this._fileExtensions.indexOf(extension) < 0 &&
this._fileExtensions.indexOf('*') < 0) {
return false;
}
return this._excludes.every(function(exclude) {

@@ -133,0 +142,0 @@ return !exclude.match(testPath);

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

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

@@ -18,6 +19,6 @@ var Vow = require('vow');

module.exports = function(program) {
var reporterPath, reporter;
var promise = Vow.promise();
var reporterPath, reporter, config;
var defer = Vow.defer();
var promise = defer.promise();
var checker = new Checker();
var config = configFile.load(program.config);
var args = program.args;

@@ -29,2 +30,15 @@

try {
config = configFile.load(program.config);
} catch (e) {
console.error('Config source is corrupted -', e.toString());
defer.reject(1);
return {
checker: checker,
reporter: program.reporter,
promise: promise
};
}
/**

@@ -41,8 +55,31 @@ * Trying to load config.

return promise.reject(1);
defer.reject(1);
return {
checker: checker,
reporter: program.reporter,
promise: promise
};
}
if (program.preset && !preset.exists(program.preset)) {
console.error(preset.getDoesNotExistError(program.preset));
defer.reject(1);
return {
checker: checker,
reporter: program.reporter,
promise: promise
};
}
if (args.length === 0) {
console.error('No input files specified. Try option --help for usage information.');
return promise.reject(1);
defer.reject(1);
return {
checker: checker,
reporter: program.reporter,
promise: promise
};
}

@@ -74,3 +111,9 @@

console.error('Reporter "%s" doesn\'t exist.', reporterPath);
return promise.reject(1);
defer.reject(1);
return {
checker: checker,
reporter: reporterPath,
promise: promise
};
}

@@ -91,10 +134,10 @@

if (!errors.isEmpty()) {
promise.reject(2);
defer.reject(2);
}
});
promise.fulfill(0);
defer.resolve(0);
}).fail(function(e) {
console.error(e.stack);
promise.reject(1);
defer.reject(1);
});

@@ -101,0 +144,0 @@

var presets = {
// https://contribute.jquery.org/style-guide/js/
jquery: require('../../presets/jquery.json'),
google: require('../../presets/google.json')
// https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
google: require('../../presets/google.json'),
// https://github.com/ymaps/codestyle/blob/master/js.md
yandex: require('../../presets/yandex.json'),
// https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript
wikimedia: require('../../presets/wikimedia.json')
};
module.exports = function(config) {
if (!config.preset) {
return;
}
module.exports = {
/**
* Get does not exist error
* @param {String} preset
* @return {String}
*/
getDoesNotExistError: function(preset) {
return 'Preset "' + preset + '" does not exist';
},
/**
* Is preset exists in jscs
* @param {String} preset
* @return {Boolean}
*/
exists: function(preset) {
return !!presets[preset];
},
var preset = presets[config.preset];
/**
* Extend jscs config with preset rules
* @param {Object} config
* @return {Boolean}
*/
extend: function(config) {
if (!config.preset) {
return true;
}
delete config.preset;
for (var rule in preset) {
if (!(rule in config)) {
config[rule] = preset[rule];
var preset = presets[config.preset];
if (!preset) {
return false;
}
delete config.preset;
for (var rule in preset) {
if (!(rule in config)) {
config[rule] = preset[rule];
}
}
return true;
}
};

2

lib/rules/disallow-dangling-underscores.js

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

var value = token.value;
if ((value[0] === '_' || value.slice( -1 ) === '_') &&
if ((value[0] === '_' || value.slice(-1) === '_') &&
!allowedIdentifiers[value]

@@ -36,0 +36,0 @@ ) {

@@ -1,3 +0,1 @@

var assert = require('assert');
module.exports = function() {};

@@ -7,9 +5,3 @@

configure: function(operators) {
assert(Array.isArray(operators), 'disallowLeftStickedOperators option requires array value');
this._operatorIndex = {};
for (var i = 0, l = operators.length; i < l; i++) {
this._operatorIndex[operators[i]] = true;
}
},
configure: function() {},

@@ -21,17 +13,14 @@ getOptionName: function() {

check: function(file, errors) {
var operators = this._operatorIndex;
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (operators[token.value]) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] === token.range[0]) {
errors.add(
'Operator ' + token.value + ' should not stick to preceding expression',
token.loc.start
);
}
}
});
errors.add(
'The disallowLeftStickedOperators rule is no longer supported.' +
'\nPlease use the following rules instead:' +
'\n' +
'\nrequireSpaceBeforeBinaryOperators' +
'\nrequireSpaceBeforePostfixUnaryOperators' +
'\nrequireSpacesInConditionalExpression',
1,
0
);
}
};

@@ -19,55 +19,25 @@ var assert = require('assert');

check: function(file, errors) {
var _commentLineMap;
var lines = file.getLines();
var tokens = file.getTokens();
function getCommentLines() {
if (!_commentLineMap) {
_commentLineMap = file.getComments().reduce(function(map, comment) {
for (var x = comment.loc.start.line; x <= comment.loc.end.line; x++) {
map[x] = 1;
}
return map;
}, {});
}
return _commentLineMap;
}
function hasEmptyLine(startLine, endLine) {
var commentLines = getCommentLines();
for (var x = startLine; x < endLine; x++) {
if (!commentLines[x]) {
return true;
}
}
return false;
}
file.iterateNodesByType('BlockStatement', function(node) {
if (node.body.length === 0) {
return;
}
var tokens = file.getTokens();
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]);
var openingBracket = tokens[openingBracketPos];
var nextToken = tokens[openingBracketPos + 1];
var startLine = openingBracket.loc.start.line + 1;
var nextLine = nextToken.loc.start.line;
var startLine = openingBracket.loc.start.line;
if (startLine < nextLine && hasEmptyLine(startLine, nextLine)) {
errors.add('Expected no padding newline after opening curly brace', openingBracket.loc.end);
}
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1);
var closingBracket = tokens[closingBracketPos];
var prevToken = tokens[closingBracketPos - 1];
var closingLine = closingBracket.loc.start.line;
var prevLine = prevToken.loc.start.line + 1;
if (closingLine > prevLine && hasEmptyLine(prevLine, closingLine)) {
errors.add('Expected no padding newline before closing curly brace', prevToken.loc.end);
if (lines[startLine] === lines[closingLine]) {
return;
}
if (lines[startLine] === '') {
errors.add('Expected no padding newline after opening curly brace', openingBracket.loc.end);
}
if (lines[closingLine - 2] === '') {
errors.add('Expected no padding newline before closing curly brace', closingBracket.loc.start);
}
});

@@ -74,0 +44,0 @@ }

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

disallowQuotedKeysInObjects === true || disallowQuotedKeysInObjects === 'allButReserved',
this.getOptionName() + ' options should be "true" or an array of exceptions'
this.getOptionName() + ' options should be true or "allButReserved" value'
);

@@ -14,0 +14,0 @@

@@ -1,3 +0,1 @@

var assert = require('assert');
module.exports = function() {};

@@ -7,9 +5,3 @@

configure: function(operators) {
assert(Array.isArray(operators), 'disallowRightStickedOperators option requires array value');
this._operatorIndex = {};
for (var i = 0, l = operators.length; i < l; i++) {
this._operatorIndex[operators[i]] = true;
}
},
configure: function() {},

@@ -21,17 +13,14 @@ getOptionName: function() {

check: function(file, errors) {
var operators = this._operatorIndex;
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (operators[token.value]) {
var nextToken = tokens[i + 1];
if (nextToken && nextToken.range[0] === token.range[1]) {
errors.add(
'Operator ' + token.value + ' should not stick to following expression',
token.loc.start
);
}
}
});
errors.add(
'The disallowRightStickedOperators rule is no longer supported.' +
'\nPlease use the following rules instead:' +
'\n' +
'\nrequireSpaceAfterBinaryOperators' +
'\nrequireSpaceAfterPrefixUnaryOperators' +
'\nrequireSpacesInConditionalExpression',
1,
0
);
}
};
var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../utils').binaryOperators;

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

module.exports.prototype = {
configure: function(operators) {
var isTrue = operators === true;
configure: function(operators) {
assert(Array.isArray(operators), 'disallowSpaceAfterBinaryOperators option requires array value');
assert(
Array.isArray(operators) || isTrue,
'disallowSpaceAfterBinaryOperators option requires array or true value'
);
if (isTrue) {
operators = allOperators;
}
this._operatorIndex = {};

@@ -25,35 +35,72 @@ for (var i = 0, l = operators.length; i < l; i++) {

// 2 + 2, 2 == 2
file.iterateNodesByType(['BinaryExpression'], function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.right.range[0] - 1,
node.operator,
true
);
file.iterateNodesByType(
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'],
function(node) {
if (operators[node.operator]) {
var indent;
var range = node.right.range[0];
if (!part) {
errors.add(
'Operator ' + node.operator + ' should stick to following expression',
tokenHelper.findOperatorByRangeStart(file, node.right.range[0], node.operator).loc.start
if (tokenHelper.isTokenParenthesis(file, range - 1, true)) {
indent = node.operator.length + 1;
} else {
indent = node.operator.length;
}
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
range - indent,
node.operator,
true
);
if (!part) {
var loc = tokenHelper.findOperatorByRangeStart(
file, node.right.range[0], node.operator, true
).loc.start;
errors.add(
'Operator ' + node.operator + ' should stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, node.operator.length)
);
}
}
}
});
);
// Comma and assignment
if (operators[','] || operators['=']) {
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)
);
}
}
// ":" for object property only but not for ternar
if (operators[':']) {
file.iterateNodesByType(['ObjectExpression'], function(node) {
node.properties.forEach(function(prop) {
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'),
tokens = file.getTokens();
errorIfApplicable(token, tokens.indexOf(token), tokens, ':');
});
});
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',' && operator !== '=' || !operators[operator]) {
if (operator !== ',') {
return;
}
var nextToken = tokens[i + 1];
if (nextToken && nextToken.range[0] !== token.range[1]) {
errors.add(
'Operator ' + operator + ' should stick to following expression',
token.loc.start
);
}
errorIfApplicable(token, i, tokens, operator);
});

@@ -60,0 +107,0 @@ }

var assert = require('assert');
var defaultOperators = require('../utils').unaryOperators;

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

configure: function(operators) {
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
this.getOptionName() + ' option requires array or true value'
);
if (isTrue) {
operators = defaultOperators;
}
this._operatorIndex = {};

@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) {

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

@@ -9,3 +10,13 @@ module.exports = function() {};

configure: function(operators) {
assert(Array.isArray(operators), 'disallowSpaceBeforeBinaryOperators option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
'disallowSpaceBeforeBinaryOperators option requires array or true value'
);
if (isTrue) {
operators = allOperators;
}
this._operatorIndex = {};

@@ -24,39 +35,64 @@ for (var i = 0, l = operators.length; i < l; i++) {

// 2 + 2, 2 == 2
file.iterateNodesByType(['BinaryExpression'], function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.left.range[1],
node.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 stick to preceding expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
if (!part) {
errors.add(
'Operator ' + node.operator + ' should stick to preceding expression',
tokenHelper.findOperatorByRangeStart(file, node.right.range[0], node.operator).loc.start
);
}
}
});
}
// Comma and assignment
if (operators[','] || operators['=']) {
// ":" for object property only but not for ternar
if (operators[':']) {
file.iterateNodesByType(['ObjectExpression'], function(node) {
node.properties.forEach(function(prop) {
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'),
tokens = file.getTokens();
errorIfApplicable(token, tokens.indexOf(token), tokens, ':');
});
});
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',' && operator !== '=' || !operators[operator]) {
if (operator !== ',') {
return;
}
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] !== token.range[0]) {
errors.add(
'Operator ' + operator + ' should stick to preceding expression',
token.loc.start
errorIfApplicable(token, i, tokens, operator);
});
}
// For everything else
file.iterateNodesByType(
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'],
function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.left.range[1],
node.operator
);
if (!part) {
errors.add(
'Operator ' + node.operator + ' should stick to preceding expression',
tokenHelper.findOperatorByRangeStart(
file, node.right.range[0], node.operator, true
).loc.start
);
}
}
});
}
}
);
}
};
var assert = require('assert');
var defaultOperators = require('../utils').incrementAndDecrementOperators;

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

configure: function(operators) {
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
this.getOptionName() + ' option requires array or true value'
);
if (isTrue) {
operators = defaultOperators;
}
this._operatorIndex = {};

@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) {

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

file.iterateNodesByType(['FunctionExpression'], function(node) {
var parent = node.parentNode;
// Ignore syntactic sugar for getters and setters.
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) {
return;
}
// anonymous function expressions only

@@ -51,0 +57,0 @@ if (!node.id) {

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

file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) {
var parent = node.parentNode;
// Ignore syntactic sugar for getters and setters.
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) {
return;
}
if (beforeOpeningRoundBrace) {

@@ -50,0 +56,0 @@ var nodeBeforeRoundBrace = node;

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

assert(
typeof disallow === 'boolean',
this.getOptionName() + ' option requires boolean value'
disallow === true || disallow === 'all' || disallow === 'nested',
this.getOptionName() + ' option requires "all"(true value) or "nested" string'
);
assert(
disallow === true,
this.getOptionName() + ' option requires true value or should be removed'
);
this._mode = disallow === true ? 'all' : disallow;
},

@@ -24,27 +22,42 @@

check: function(file, errors) {
file.iterateNodesByType('ArrayExpression', function(node) {
var mode = this._mode;
file.iterateNodesByType(['ArrayExpression'], function(node) {
var tokens = file.getTokens();
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]);
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1);
var openingBracket = tokens[openingBracketPos];
var nextToken = tokens[openingBracketPos + 1];
var brackets = {
opening: tokens[openingBracketPos],
closing: tokens[closingBracketPos]
};
if (openingBracket.loc.start.line === nextToken.loc.start.line &&
openingBracket.range[1] !== nextToken.range[0]
) {
errors.add('Illegal space after opening square brace', openingBracket.loc.end);
}
var insideTokens = {
prev: tokens[closingBracketPos - 1],
next: tokens[openingBracketPos + 1]
};
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1);
var closingBracket = tokens[closingBracketPos];
var prevToken = tokens[closingBracketPos - 1];
if (mode === 'all') {
check(brackets, errors, insideTokens);
if (closingBracket.loc.start.line === prevToken.loc.start.line &&
closingBracket.range[0] !== prevToken.range[1]
) {
errors.add('Illegal space before closing square brace', prevToken.loc.end);
} else if (node.parentNode.type === 'ArrayExpression') {
check(brackets, errors, insideTokens);
}
});
}
};
};
function check(brackets, errors, insideTokens) {
if (brackets.opening.loc.start.line === insideTokens.next.loc.start.line &&
brackets.opening.range[1] !== insideTokens.next.range[0]
) {
errors.add('Illegal space after opening square brace', brackets.opening.loc.end);
}
if (brackets.closing.loc.start.line === insideTokens.prev.loc.start.line &&
brackets.closing.range[0] !== insideTokens.prev.range[1]
) {
errors.add('Illegal space before closing square brace', insideTokens.prev.loc.end);
}
}

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

assert(
typeof disallowSpacesInsideObjectBrackets === 'boolean',
'disallowSpacesInsideObjectBrackets option requires boolean value'
disallowSpacesInsideObjectBrackets === true || disallowSpacesInsideObjectBrackets === 'all' ||
disallowSpacesInsideObjectBrackets === 'nested',
'disallowSpacesInsideObjectBrackets option requires "all"(true value) or "nested" string'
);
assert(
disallowSpacesInsideObjectBrackets === true,
'disallowSpacesInsideObjectBrackets option requires true value or should be removed'
);
this._mode = disallowSpacesInsideObjectBrackets === true ? 'all' : disallowSpacesInsideObjectBrackets;
},

@@ -24,27 +23,42 @@

check: function(file, errors) {
var mode = this._mode;
file.iterateNodesByType('ObjectExpression', function(node) {
var tokens = file.getTokens();
var openingBracketPos = file.getTokenPosByRangeStart(node.range[0]);
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1);
var openingBracket = tokens[openingBracketPos];
var nextToken = tokens[openingBracketPos + 1];
var brackets = {
opening: tokens[openingBracketPos],
closing: tokens[closingBracketPos]
};
if (openingBracket.loc.start.line === nextToken.loc.start.line &&
openingBracket.range[1] !== nextToken.range[0]
) {
errors.add('Illegal space after opening curly brace', openingBracket.loc.end);
}
var insideTokens = {
prev: tokens[closingBracketPos - 1],
next: tokens[openingBracketPos + 1]
};
var closingBracketPos = file.getTokenPosByRangeStart(node.range[1] - 1);
var closingBracket = tokens[closingBracketPos];
var prevToken = tokens[closingBracketPos - 1];
if (mode === 'all') {
check(brackets, errors, insideTokens);
if (closingBracket.loc.start.line === prevToken.loc.start.line &&
closingBracket.range[0] !== prevToken.range[1]
) {
errors.add('Illegal space before closing curly brace', prevToken.loc.end);
} else if (node.parentNode.type === 'Property') {
check(brackets, errors, insideTokens);
}
});
}
};
};
function check(brackets, errors, insideTokens) {
if (brackets.opening.loc.start.line === insideTokens.next.loc.start.line &&
brackets.opening.range[1] !== insideTokens.next.range[0]
) {
errors.add('Illegal space after opening curly brace', brackets.opening.loc.end);
}
if (brackets.closing.loc.start.line === insideTokens.prev.loc.start.line &&
brackets.closing.range[0] !== insideTokens.prev.range[1]
) {
errors.add('Illegal space before closing curly brace', insideTokens.prev.loc.end);
}
}
var assert = require('assert');
var commentHelper = require('../comment-helper');

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

configure: function(maximumLineLength) {
assert(
typeof maximumLineLength === 'number',
'maximumLineLength option requires number value'
);
this._tabSize = '';
this._allowRegex = false;
this._allowComments = false;
this._allowUrlComments = false;
this._maximumLineLength = maximumLineLength;
if (typeof maximumLineLength === 'object') {
assert(
typeof maximumLineLength.value === 'number',
'maximumLineLength option requires the "value" property to be defined'
);
this._maximumLineLength = maximumLineLength.value;
var tabSize = maximumLineLength.tabSize || 0;
while (tabSize--) {
this._tabSize += ' ';
}
this._allowRegex = (maximumLineLength.allowRegex === true);
this._allowComments = (maximumLineLength.allowComments === true);
this._allowUrlComments = (maximumLineLength.allowUrlComments === true);
} else {
assert(
typeof maximumLineLength === 'number',
'maximumLineLength option requires number value or options object'
);
this._maximumLineLength = maximumLineLength;
}
},

@@ -24,6 +48,30 @@

var lines = file.getLines();
var lines = this._allowComments ? commentHelper.getLinesWithCommentsRemoved(file) : file.getLines();
var line;
if (this._allowRegex) {
file.iterateTokensByType('RegularExpression', function(token) {
for (var i = token.loc.start.line; i <= token.loc.end.line; i++) {
lines[i - 1] = '';
}
});
}
if (this._allowUrlComments) {
file.getComments().forEach(function(comment) {
for (var i = comment.loc.start.line; i <= comment.loc.end.line; i++) {
lines[i - 1] = lines[i - 1].replace(/(http|https|ftp):\/\/[^\s$]+/, '');
}
});
}
for (var i = 0, l = lines.length; i < l; i++) {
if (lines[i].length > maximumLineLength) {
errors.add('Line must be at most ' + maximumLineLength + ' characters', i + 1, 0);
line = this._tabSize ? lines[i].replace(/\t/g, this._tabSize) : lines[i];
if (line.length > maximumLineLength) {
errors.add(
'Line must be at most ' + maximumLineLength + ' characters',
i + 1,
lines[i].length
);
}

@@ -30,0 +78,0 @@ }

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

configure: function(requireCamelCaseOrUpperCaseIdentifiers) {
configure: function(requireCamelCase) {
assert(
typeof requireCamelCaseOrUpperCaseIdentifiers === 'boolean',
'requireCamelCaseOrUpperCaseIdentifiers option requires boolean value'
requireCamelCase === true || requireCamelCase === 'ignoreProperties',
'requireCamelCaseOrUpperCaseIdentifiers option requires true value or `ignoreProperties` string'
);
assert(
requireCamelCaseOrUpperCaseIdentifiers === true,
'requireCamelCaseOrUpperCaseIdentifiers option requires true value or should be removed'
);
this._ignoreProperties = (requireCamelCase === 'ignoreProperties');
},

@@ -24,14 +22,23 @@

check: function(file, errors) {
file.iterateTokensByType('Identifier', function(token) {
file.iterateTokensByType('Identifier', function(token, index, tokens) {
var value = token.value;
if (value.replace(/^_+|_+$/g, '').indexOf('_') > -1 && value.toUpperCase() !== value) {
errors.add(
'All identifiers must be camelCase or UPPER_CASE',
token.loc.start.line,
token.loc.start.column
);
if (value.replace(/^_+|_+$/g, '').indexOf('_') === -1 || value.toUpperCase() === value) {
return;
}
});
if (this._ignoreProperties) {
if (index + 1 < tokens.length && tokens[index + 1].value === ':') {
return;
}
if (index > 0 && tokens[index - 1].value === '.') {
return;
}
}
errors.add(
'All identifiers must be camelCase or UPPER_CASE',
token.loc.start.line,
token.loc.start.column
);
}.bind(this));
}
};

@@ -1,3 +0,1 @@

var assert = require('assert');
module.exports = function() {};

@@ -7,9 +5,3 @@

configure: function(operators) {
assert(Array.isArray(operators), 'requireLeftStickedOperators option requires array value');
this._operatorIndex = {};
for (var i = 0, l = operators.length; i < l; i++) {
this._operatorIndex[operators[i]] = true;
}
},
configure: function() {},

@@ -21,17 +13,14 @@ getOptionName: function() {

check: function(file, errors) {
var operators = this._operatorIndex;
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (operators[token.value]) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] !== token.range[0]) {
errors.add(
'Operator ' + token.value + ' should stick to preceding expression',
token.loc.start
);
}
}
});
errors.add(
'The requireLeftStickedOperators rule is no longer supported.' +
'\nPlease use the following rules instead:' +
'\n' +
'\ndisallowSpaceBeforeBinaryOperators' +
'\ndisallowSpaceBeforePostfixUnaryOperators' +
'\ndisallowSpacesInConditionalExpressions',
1,
0
);
}
};

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

// Don't go in nested scopes
if ( !firstParent && type && ['FunctionDeclaration', 'FunctionExpression'].indexOf(type) > -1) {
if (!firstParent && type && ['FunctionDeclaration', 'FunctionExpression'].indexOf(type) > -1) {
return false;
}
if ( firstParent ) {
if (firstParent) {
firstParent = false;

@@ -34,0 +34,0 @@ }

var assert = require('assert');
var tokenHelper = require('../token-helper');
var defaultOperators = require('../utils').binaryOperators.slice();
defaultOperators.push('?');
module.exports = function() {};

@@ -8,3 +12,13 @@

configure: function(operators) {
assert(Array.isArray(operators), 'requireOperatorBeforeLineBreak option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
'requireOperatorBeforeLineBreak option requires array value or true value'
);
if (isTrue) {
operators = defaultOperators;
}
this._operatorIndex = {};

@@ -22,16 +36,58 @@ for (var i = 0, l = operators.length; i < l; i++) {

var operators = this._operatorIndex;
var tokens = file.getTokens();
var throughTokens = ['?', ':', ','];
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (operators[token.value]) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) {
errors.add(
'Operator ' + token.value + ' should not be on a new line',
token.loc.start
);
function errorIfApplicable(token, i, tokens) {
var prevToken = tokens[i - 1];
if (prevToken && prevToken.loc.end.line !== token.loc.start.line) {
var loc = token.loc.start;
errors.add(
'Operator ' + token.value + ' should not be on a new line',
loc.line,
tokenHelper.getPointerEntities(loc.column, token.value.length)
);
}
}
throughTokens = throughTokens.filter(function(operator) {
return operators[operator];
});
if (throughTokens.length) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (throughTokens.every(function() {
return throughTokens.indexOf(operator) >= 0;
})) {
errorIfApplicable(token, i, tokens, operator);
}
});
}
file.iterateNodesByType(
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'],
function(node) {
var operator = node.operator;
if (!operators[operator]) {
return;
}
var token = tokenHelper.findOperatorByRangeStart(
file,
node.left.argument ? node.left.argument.range[0] : node.left.range[0],
operator
);
errorIfApplicable(
token,
tokens.indexOf(token),
tokens
);
}
});
);
}
};

@@ -1,3 +0,1 @@

var assert = require('assert');
module.exports = function() {};

@@ -7,9 +5,3 @@

configure: function(operators) {
assert(Array.isArray(operators), 'requireRightStickedOperators option requires array value');
this._operatorIndex = {};
for (var i = 0, l = operators.length; i < l; i++) {
this._operatorIndex[operators[i]] = true;
}
},
configure: function() {},

@@ -21,17 +13,14 @@ getOptionName: function() {

check: function(file, errors) {
var operators = this._operatorIndex;
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
if (operators[token.value]) {
var nextToken = tokens[i + 1];
if (nextToken && nextToken.range[0] !== token.range[1]) {
errors.add(
'Operator ' + token.value + ' should stick to following expression',
token.loc.start
);
}
}
});
errors.add(
'The requireRightStickedOperators rule is no longer supported.' +
'\nPlease use the following rules instead:' +
'\n' +
'\ndisallowSpaceAfterBinaryOperators' +
'\ndisallowSpaceAfterPrefixUnaryOperators' +
'\ndisallowSpacesInConditionalExpressions',
1,
0
);
}
};
var assert = require('assert');
var tokenHelper = require('../token-helper');
var allOperators = require('../utils').binaryOperators;

@@ -9,3 +10,13 @@ module.exports = function() {};

configure: function(operators) {
assert(Array.isArray(operators), 'requireSpaceAfterBinaryOperators option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
'requireSpaceAfterBinaryOperators option requires array or true value'
);
if (isTrue) {
operators = allOperators;
}
this._operatorIndex = {};

@@ -24,40 +35,75 @@ for (var i = 0, l = operators.length; i < l; i++) {

// 2 + 2, 2 == 2
file.iterateNodesByType(['BinaryExpression'], function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.right.range[0] - 1,
node.operator,
true
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)
);
if (part) {
errors.add(
'Operator ' + node.operator + ' should not stick to following expression',
part.loc.start
);
}
}
});
}
// Comma and assignment
if (operators[','] || operators['=']) {
// ":" for object property only but not for ternar
if (operators[':']) {
file.iterateNodesByType(['ObjectExpression'], function(node) {
node.properties.forEach(function(prop) {
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'),
tokens = file.getTokens();
errorIfApplicable(token, tokens.indexOf(token), tokens, ':');
});
});
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',' && operator !== '=' || !operators[operator]) {
if (operator !== ',') {
return;
}
var nextToken = tokens[i + 1];
if (nextToken && nextToken.range[0] === token.range[1]) {
errors.add(
'Operator ' + operator + ' should not stick to following expression',
token.loc.start
errorIfApplicable(token, i, tokens, operator);
});
}
// For everything else
file.iterateNodesByType(
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'],
function(node) {
if (operators[node.operator]) {
var indent;
var range = node.right.range[0];
if (tokenHelper.isTokenParenthesis(file, range - 1, true)) {
indent = node.operator.length + 1;
} else {
indent = node.operator.length;
}
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
range - indent,
node.operator,
true
);
if (part) {
var loc = part.loc.start;
errors.add(
'Operator ' + node.operator + ' should not stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, node.operator.length)
);
}
}
});
}
}
);
}
};
var assert = require('assert');
var util = require('util');
var texts = [
'Missing space after "%s" keyword',
'Should be one space instead of %d, after "%s" keyword'
];

@@ -22,13 +27,27 @@ module.exports = function() {};

function getCommentIfExists(start, end) {
return file.getComments().filter(function(comment) {
return start <= comment.range[0] && end >= comment.range[1];
})[0];
}
file.iterateTokensByType(['Keyword'], function(token, i, tokens) {
if (keywordIndex[token.value]) {
var nextToken = tokens[i + 1];
var comment = getCommentIfExists(token.range[1], nextToken.range[0]);
nextToken = comment || nextToken;
var diff = nextToken.range[0] - token.range[1];
if (nextToken &&
nextToken.loc.end.line === token.loc.start.line &&
nextToken.range[0] - token.range[1] !== 1
diff !== 1
) {
if (nextToken.type !== 'Punctuator' || nextToken.value !== ';') {
errors.add(
'Missing space after `' + token.value + '` keyword',
util.format.apply(null,
diff === 1 ?
[texts[0], token.value] :
[texts[1], diff, token.value]
),
nextToken.loc.start.line,

@@ -35,0 +54,0 @@ nextToken.loc.start.column

var assert = require('assert');
var defaultOperators = require('../utils').unaryOperators;

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

configure: function(operators) {
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
this.getOptionName() + ' option requires array or true value'
);
if (isTrue) {
operators = defaultOperators;
}
this._operatorIndex = {};

@@ -27,5 +38,15 @@ for (var i = 0, l = operators.length; i < l; i++) {

if (node.prefix && operatorIndex[node.operator]) {
var argument = node.argument.type;
var operatorTokenIndex = file.getTokenPosByRangeStart(node.range[0]);
var operatorToken = tokens[operatorTokenIndex];
var nextToken = tokens[operatorTokenIndex + 1];
// Do not report consecutive operators (#405)
if (
argument === 'UnaryExpression' || argument === 'UpdateExpression' &&
nextToken.value !== '('
) {
return;
}
if (operatorToken.range[1] === nextToken.range[0]) {

@@ -32,0 +53,0 @@ errors.add('Operator ' + node.operator + ' should not stick to operand', node.loc.start);

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

@@ -9,3 +10,13 @@ module.exports = function() {};

configure: function(operators) {
assert(Array.isArray(operators), 'requireSpaceBeforeBinaryOperators option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
'requireSpaceBeforeBinaryOperators option requires array or true value'
);
if (isTrue) {
operators = allOperators;
}
this._operatorIndex = {};

@@ -24,39 +35,64 @@ for (var i = 0, l = operators.length; i < l; i++) {

// 2 + 2, 2 == 2
file.iterateNodesByType(['BinaryExpression'], function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.left.range[1],
node.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)
);
if (part) {
errors.add(
'Operator ' + node.operator + ' should not stick to preceding expression',
part.loc.start
);
}
}
});
}
// Comma and assignment
if (operators[','] || operators['=']) {
// ":" for object property only but not for ternar
if (operators[':']) {
file.iterateNodesByType(['ObjectExpression'], function(node) {
node.properties.forEach(function(prop) {
var token = tokenHelper.findOperatorByRangeStart(file, prop.range[0], ':'),
tokens = file.getTokens();
errorIfApplicable(token, tokens.indexOf(token), tokens, ':');
});
});
}
// Comma
if (operators[',']) {
file.iterateTokensByType('Punctuator', function(token, i, tokens) {
var operator = token.value;
if (operator !== ',' && operator !== '=' || !operators[operator]) {
if (operator !== ',') {
return;
}
var prevToken = tokens[i - 1];
if (prevToken && prevToken.range[1] === token.range[0]) {
errors.add(
'Operator ' + operator + ' should not stick to preceding expression',
token.loc.start
errorIfApplicable(token, i, tokens, operator);
});
}
// For everything else
file.iterateNodesByType(
['BinaryExpression', 'AssignmentExpression', 'LogicalExpression'],
function(node) {
if (operators[node.operator]) {
var part = tokenHelper.getTokenByRangeStartIfPunctuator(
file,
node.left.range[1],
node.operator
);
if (part) {
var loc = part.loc.start;
errors.add(
'Operator ' + node.operator + ' should not stick to following expression',
loc.line,
tokenHelper.getPointerEntities(loc.column, node.operator.length)
);
}
}
});
}
}
);
}
};
var assert = require('assert');
var defaultOperators = require('../utils').incrementAndDecrementOperators;

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

configure: function(operators) {
assert(Array.isArray(operators), this.getOptionName() + ' option requires array value');
var isTrue = operators === true;
assert(
Array.isArray(operators) || isTrue,
this.getOptionName() + ' option requires array or true value'
);
if (isTrue) {
operators = defaultOperators;
}
this._operatorIndex = {};

@@ -11,0 +22,0 @@ for (var i = 0, l = operators.length; i < l; i++) {

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

file.iterateNodesByType(['FunctionExpression'], function(node) {
var parent = node.parentNode;
// Ignore syntactic sugar for getters and setters.
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) {
return;
}
if (!node.id) {

@@ -51,0 +57,0 @@

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

file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) {
var parent = node.parentNode;
// Ignore syntactic sugar for getters and setters.
if (parent.type === 'Property' && (parent.kind === 'get' || parent.kind === 'set')) {
return;
}
if (beforeOpeningRoundBrace) {

@@ -50,0 +56,0 @@ var nodeBeforeRoundBrace = node;

@@ -48,8 +48,4 @@ var assert = require('assert');

if (closingBracket.range[0] === prevToken.range[1]) {
if (!isNested) {
errors.add('Missing space before closing curly brace', closingBracket.loc.start);
}
} else if (isNested && closingBracket.loc.start.line === prevToken.loc.start.line) {
errors.add('Illegal space between closing curly braces', prevToken.loc.end);
if (closingBracket.range[0] === prevToken.range[1] && !isNested) {
errors.add('Missing space before closing curly brace', closingBracket.loc.start);
}

@@ -56,0 +52,0 @@ });

var assert = require('assert');
var commentHelper = require('../comment-helper');

@@ -37,32 +38,2 @@ module.exports = function() {};

check: function(file, errors) {
function getLinesWithCommentsRemoved() {
var lines = file.getLines().concat();
file.getComments().reverse().forEach(function(comment) {
var startLine = comment.loc.start.line;
var startCol = comment.loc.start.column;
var endLine = comment.loc.end.line;
var endCol = comment.loc.end.column;
var i = startLine - 1;
if (startLine === endLine) {
lines[i] = lines[i].substring(0, startCol) + lines[i].substring(endCol);
} else {
lines[i] = lines[i].substring(0, startCol);
for (var x = i + 1; x < endLine - 1; x++) {
lines[x] = '';
}
lines[x] = lines[x].substring(endCol + 1);
if (lines[x] !== '') {
errors.add(
'Multiline comments should not have tokens on its ending line',
x + 1,
endCol
);
}
}
});
return lines;
}
function isMultiline(node) {

@@ -80,3 +51,3 @@ return node.loc.start.line !== node.loc.end.line;

var loc = node.loc;
if ( popAfter ) {
if (popAfter) {
linesToCheck[loc.end.line - 1].popAfter = true;

@@ -228,4 +199,4 @@ } else {

if ( children.length > 0 &&
node.loc.start.column === children[0].loc.start.column ) {
if (children.length > 0 &&
node.loc.start.column === children[0].loc.start.column) {
indents = 0;

@@ -282,3 +253,3 @@ }

var lines = getLinesWithCommentsRemoved();
var lines = commentHelper.getLinesWithCommentsRemoved(file, errors);
var indentStack = [0];

@@ -285,0 +256,0 @@ var linesToCheck = lines.map(function() {

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

var mark = str[0];
var stripped = str.substring(1, str.length -1);
var stripped = str.substring(1, str.length - 1);

@@ -45,0 +45,0 @@ if (quoteMark === true) {

@@ -62,5 +62,7 @@ var esprima = require('esprima');

this.registerRule(new (require('./rules/validate-jsdoc'))());
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'))());

@@ -117,2 +119,5 @@ this.registerRule(new (require('./rules/disallow-spaces-inside-array-brackets'))());

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'))());
},

@@ -135,4 +140,9 @@

this.throwNonCamelCaseErrorIfNeeded(config);
preset(config);
if (config.preset && !preset.exists(config.preset)) {
throw new Error(preset.getDoesNotExistError(config.preset));
}
preset.extend(config);
var configRules = Object.keys(config);

@@ -221,3 +231,3 @@ var activeRules = this._activeRules;

// Do not process the rule if it's equals to null (#203)
if (this._config[rule.getOptionName()] !== null ) {
if (this._config[rule.getOptionName()] !== null) {
rule.check(file, errors);

@@ -224,0 +234,0 @@ }

@@ -7,3 +7,3 @@ /**

* @param {Boolean} [backward=false] Direction
* @returns {Object}
* @returns {Object|null}
*/

@@ -17,5 +17,2 @@ exports.getTokenByRangeStart = function(file, range, backward) {

// we should check for "(" if we go backward
var parenthesis = backward ? '(' : ')';
// if token is ")" -> get next token

@@ -26,6 +23,3 @@ // for example (a) + (b)

// ------------------^
if (token &&
token.type === 'Punctuator' &&
token.value === parenthesis
) {
if (this.isTokenParenthesis(file, range, backward)) {
var pos = backward ? token.range[0] - 1 : token.range[1];

@@ -36,6 +30,27 @@ tokenPos = file.getTokenPosByRangeStart(pos);

return token;
return token || null;
};
/**
* Is next/previous token a parentheses?
*
* @param {JsFile} file
* @param {Number} range
* @param {Boolean} [backward=false] Direction
* @returns {Boolean}
*/
exports.isTokenParenthesis = function(file, range, backward) {
var tokens = file.getTokens();
// get next token
var tokenPos = file.getTokenPosByRangeStart(range);
var token = tokens[tokenPos];
// we should check for "(" if we go backward
var parenthesis = backward ? '(' : ')';
return token && token.type === 'Punctuator' && token.value === parenthesis;
};
/**
* Returns true if token is punctuator

@@ -52,3 +67,3 @@ *

/**
* Find previous operator by range start
* Find next/previous operator by range start
*

@@ -58,9 +73,10 @@ * @param {JsFile} file

* @param {String} operator
* @param {Boolean} [backward=false] Direction
* @returns {Object|null}
*/
exports.findOperatorByRangeStart = function(file, range, operator) {
exports.findOperatorByRangeStart = function(file, range, operator, backward) {
var tokens = file.getTokens();
var index = file.getTokenPosByRangeStart(range);
while (index) {
while (tokens[ index ]) {
if (tokens[ index ].value === operator) {

@@ -70,7 +86,10 @@ return tokens[ index ];

index--;
if (backward) {
index--;
} else {
index++;
}
}
return null;
};

@@ -96,1 +115,11 @@

};
/**
* Get column for long entities
* @param {Number} column
* @param {Number} length
* @return {Number}
*/
exports.getPointerEntities = function(column, length) {
return column - 1 + Math.ceil(length / 2);
};

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

'new': true,
'null': true,
'return': true,

@@ -97,1 +98,36 @@ 'switch': true,

};
/**
* All possible binary operators supported by JSCS
* @type {Array}
*/
exports.binaryOperators = [
// assignment operators
'=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
'&=', '|=', '^=',
'+', '-', '*', '/', '%', '<<', '>>', '>>>', '&',
'|', '^', '&&', '||', '===', '==', '>=',
'<=', '<', '>', '!=', '!==',
',', ':'
];
/**
* Increment and decrement operators
* @type {Array}
*/
exports.incrementAndDecrementOperators = ['++', '--'];
/**
* All possible unary operators supported by JSCS
* @type {Array}
*/
exports.unaryOperators = ['-', '+', '!', '~'].concat(exports.incrementAndDecrementOperators);
/**
* All possible operators support by JSCS
* @type {Array}
*/
exports.operators = exports.binaryOperators.concat(exports.unaryOperators);

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

"name": "jscs",
"version": "1.4.5",
"version": "1.5.1",
"main": "lib/checker",

@@ -31,16 +31,16 @@ "homepage": "https://github.com/mdevils/node-jscs",

"commander": "~2.2.0",
"esprima": "~1.1.1",
"glob": "~3.2.9",
"minimatch": "~0.2.14",
"esprima": "~1.2.2",
"glob": "~4.0.0",
"minimatch": "~0.3.0",
"strip-json-comments": "~0.1.1",
"vow": "~0.3.12",
"vow-fs": "~0.2.3",
"vow": "~0.4.3",
"vow-fs": "~0.3.1",
"xmlbuilder": "~2.2.1"
},
"devDependencies": {
"browserify": "~3.43.0",
"browserify": "~4.1.5",
"hooker": "~0.2.3",
"jshint": "~2.5.0",
"mocha": "~1.18.2",
"sinon": "~1.9.1",
"mocha": "~1.20.1",
"sinon": "~1.10.0",
"xml2js": "~0.4.2"

@@ -47,0 +47,0 @@ },

{
"requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
"disallowLeftStickedOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowRightStickedOperators": ["?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"requireRightStickedOperators": ["!"],
"requireLeftStickedOperators": [","],
"disallowImplicitTypeConversion": ["string"],
"disallowKeywords": ["with"],
"disallowMultipleLineBreaks": true,
"disallowKeywordsOnNewLine": ["else"],
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"maximumLineLength": {
"value": 80,
"allowComments": true,
"allowRegex": true
},
"validateIndentation": 2,
"validateQuoteMarks": "'",
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireLineFeedAtFileEnd": true,

@@ -18,6 +52,2 @@ "requireSpacesInFunctionExpression": {

},
"disallowSpacesInFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideArrayBrackets": true,
"validateJSDoc": {

@@ -27,4 +57,4 @@ "checkParamNames": true,

},
"validateIndentation": 4,
"validateQuoteMarks": "'"
"disallowMultipleLineBreaks": true
}
{
"requireCurlyBraces": [ "if", "else", "for", "while", "do" ],
"requireSpaceAfterKeywords": [ "if", "else", "for", "while", "do", "switch", "return" ],
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireParenthesesAroundIIFE": true,
"requireMultipleVarDecl": "onevar",
"requireCommaBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireDotNotation": true,
"maximumLineLength": {
"value": 100,
"tabSize": 4,
"allowUrlComments": true,
"allowRegex": true
},
"validateQuoteMarks": { "mark": "\"", "escape": true },
"disallowMixedSpacesAndTabs": "smart",
"disallowTrailingWhitespace": true,
"disallowMultipleLineStrings": true,
"disallowTrailingComma": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"requireMultipleVarDecl": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpacesInsideObjectBrackets": "all",
"requireSpacesInsideArrayBrackets": "all",
"disallowLeftStickedOperators": [ "?" ],
"disallowRightStickedOperators": [ "?", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ],
"requireSpaceBeforeBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ],
"disallowSpaceAfterPrefixUnaryOperators": [ "++", "--", "+", "-" ],
"disallowSpaceBeforePostfixUnaryOperators": [ "++", "--" ],
"requireRightStickedOperators": [ "!" ],
"requireLeftStickedOperators": [ "," ],
"requireSpacesInConditionalExpression": true,
"requireSpaceAfterBinaryOperators": true,
"requireLineFeedAtFileEnd": true,
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"validateLineBreaks": "LF",
"disallowKeywords": [ "with" ],
"disallowMultipleLineBreaks": true,
"disallowKeywordsOnNewLine": [ "else" ],
"requireLineFeedAtFileEnd": true,
"disallowSpacesInFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpaceAfterObjectKeys": true,
"validateLineBreaks": "LF"
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpaceBeforePostfixUnaryOperators": true,
"disallowSpaceBeforeBinaryOperators": [ ",", ":" ],
"disallowMultipleLineBreaks": true
}

@@ -5,4 +5,11 @@ # node-jscs [![Build Status](https://travis-ci.org/mdevils/node-jscs.svg?branch=master)](https://travis-ci.org/mdevils/node-jscs) [![Dependency Status](https://david-dm.org/mdevils/node-jscs.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs) [![devDependency Status](https://david-dm.org/mdevils/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs#info=devDependencies)

`jscs` is a code style checker. You can configure `jscs` for your project in detail using **over 60** validation rules. [jQuery](https://github.com/mdevils/node-jscs/blob/master/lib/presets/jquery.json) preset is also available.
`jscs` is a code style checker. You can configure `jscs` for your project in detail using **over 60** validation rules, including presets from popular style guides like jQuery.
## Presets
* [jQuery](presets/jquery.json) - https://contribute.jquery.org/style-guide/js/
* [Wikimedia](presets/wikimedia.json) - https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript
* [Google](presets/google.json) - https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
* [Yandex](presets/yandex.json) - https://github.com/ymaps/codestyle/blob/master/js.md
## Friendly packages

@@ -102,6 +109,8 @@

If you want specifically disable preset rule assign it to `null`
```js
"preset": "jquery",
"requireCurlyBraces": null
If you want specifically disable preset rule assign it to `null`, like so:
```json
{
"preset": "jquery",
"requireCurlyBraces": null
}
```

@@ -123,2 +132,22 @@

### fileExtensions
Changes the set of file extensions that will be processed.
Type: `Array` or `String` or `"*"`
Values: A single file extension or an Array of file extensions, beginning with a `.`. The matching is case _insensitive_. If `"*"` is provided, all files regardless of extension will match.
#### Example
```js
"fileExtensions": [".js", ".jsx"]
```
#### Default
```js
"fileExtensions": [".js"]
```
## Rules

@@ -370,5 +399,5 @@

Type: `Object` or `true`
Type: `Object` or `Boolean`
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`.

@@ -407,5 +436,5 @@ #### Example

Type: `Object` or `true`
Type: `Object` or `Boolean`
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`.

@@ -447,3 +476,3 @@ #### Example

Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`.
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`.

@@ -512,3 +541,3 @@ #### Example

Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`.
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`.

@@ -575,3 +604,3 @@ #### Example

Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`.
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`.

@@ -638,3 +667,3 @@ #### Example

Values: `beforeOpeningRoundBrace` and `beforeOpeningCurlyBrace` as child properties. Child properties must be set to `true`.
Values: `"beforeOpeningRoundBrace"` and `"beforeOpeningCurlyBrace"` as child properties. Child properties must be set to `true`.

@@ -644,3 +673,3 @@ #### Example

```js
"requireSpacesInFunctionExpression": {
"requireSpacesInFunctionDeclaration": {
"beforeOpeningRoundBrace": true,

@@ -676,3 +705,3 @@ "beforeOpeningCurlyBrace": true

```js
"disallowSpacesInFunctionExpression": {
"disallowSpacesInFunctionDeclaration": {
"beforeOpeningRoundBrace": true,

@@ -733,6 +762,6 @@ "beforeOpeningCurlyBrace": true

Values: `true` or `onevar`
Values: `true` or `"onevar"`
if `requireMultipleVarDecl` defined as a `boolean` value, it will report only consecutive vars, if, on the other hand,
value equals to `onevar` string, `requireMultipleVarDecl` will allow only one `var` per function scope.
if `requireMultipleVarDecl` defined as a `true` value, it will report only consecutive vars, if, on the other hand,
value equals to `"onevar"` string, `requireMultipleVarDecl` will allow only one `var` per function scope.

@@ -934,5 +963,5 @@ JSHint: [`onevar`](http://jshint.com/docs/options/#onevar)

Type: `Boolean`
Type: `Boolean` or `String`
Values: `true`
Values: `"all"` or `true` for strict mode, `"nested"` ignores closing brackets in a row.

@@ -942,15 +971,21 @@ #### Example

```js
"disallowSpacesInsideObjectBrackets": true
"disallowSpacesInsideObjectBrackets": "all"
```
##### Valid
##### Valid for mode `"all"`
```js
var x = {a: 1};
var x = {a: {b: 1}};
```
##### Valid for mode `"nested"`
```js
var x = { a: {b: 1} };
```
##### Invalid
```js
var x = { a: 1 };
var x = { a: { b: 1 } };
```

@@ -962,5 +997,5 @@

Type: `Boolean`
Type: `Boolean` or `String`
Values: `true`
Values: `"all"` or `true` for strict mode, `"nested"` ignores closing brackets in a row.

@@ -970,15 +1005,21 @@ #### Example

```js
"disallowSpacesInsideArrayBrackets": true
"disallowSpacesInsideArrayBrackets": "all"
```
##### Valid
##### Valid for mode `"all"`
```js
var x = [1];
var x = [[1]];
```
##### Valid for mode `"nested"`
```js
var x = [ [1] ];
```
##### Invalid
```js
var x = [ 1 ];
var x = [ [ 1 ] ];
```

@@ -1050,3 +1091,3 @@

Values: "all" for strict mode, "allButNested" ignores closing brackets in a row.
Values: `"all"` for strict mode, `"allButNested"` ignores closing brackets in a row.

@@ -1077,2 +1118,35 @@ #### Example

### requireSpacesInsideParentheses
Requires space after opening round bracket and before closing.
Type: `String`
Values: `"all"` for strict mode, `"allButNested"` ignores nested brackets in a row.
#### Example
```js
"requireSpacesInsideParentheses": "all"
```
##### Valid for mode `"all"`
```js
var x = Math.pow( ( 1 + 2 ), ( 3 + 4 ) );
```
##### Valid for mode `"allButNested"`
```js
var x = Math.pow(( 1 + 2 ), ( 3 + 4 ));
```
##### Invalid
```js
var x = Math.pow(1 + 2, 3 + 4);
```
### disallowQuotedKeysInObjects

@@ -1274,5 +1348,5 @@

Values:
- `"all"` for strict mode,
- `"skipWithFunction"` ignores objects if one of the property values is a function expression,
- `"skipWithLineBreak"` ignores objects if there are line breaks between properties
- `"all"` for strict mode,
- `"skipWithFunction"` ignores objects if one of the property values is a function expression,
- `"skipWithLineBreak"` ignores objects if there are line breaks between properties

@@ -1306,5 +1380,5 @@ #### Example

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to require all possible binary operators to appear before line breaks

@@ -1318,2 +1392,3 @@ JSHint: [`laxbreak`](http://www.jshint.com/docs/options/#laxbreak)

"?",
"=",
"+",

@@ -1323,3 +1398,2 @@ "-",

"*",
"=",
"==",

@@ -1351,133 +1425,2 @@ "===",

### disallowLeftStickedOperators
Disallows sticking operators to the left.
Type: `Array`
Values: Array of quoted operators
#### Example
```js
"disallowLeftStickedOperators": [
"?",
"+",
"-",
"/",
"*",
"=",
"==",
"===",
"!=",
"!==",
">",
">=",
"<",
"<="
]
```
##### Valid
```js
x = y ? 1 : 2;
```
##### Invalid
```js
x = y? 1 : 2;
```
### requireRightStickedOperators
Requires sticking operators to the right.
Type: `Array`
Values: Array of quoted operators
#### Example
```js
"requireRightStickedOperators": ["!"]
```
##### Valid
```js
x = !y;
```
##### Invalid
```js
x = ! y;
```
### disallowRightStickedOperators
Disallows sticking operators to the right.
Type: `Array`
Values: Array of quoted operators
#### Example
```js
"disallowRightStickedOperators": [
"?",
"+",
"/",
"*",
":",
"=",
"==",
"===",
"!=",
"!==",
">",
">=",
"<",
"<="
]
```
##### Valid
```js
x = y + 1;
```
##### Invalid
```js
x = y +1;
```
### requireLeftStickedOperators
Requires sticking operators to the left.
Type: `Array`
Values: Array of quoted operators
#### Example
```js
"requireLeftStickedOperators": [","]
```
##### Valid
```js
x = [1, 2];
```
##### Invalid
```js
x = [1 , 2];
```
### disallowSpaceAfterPrefixUnaryOperators

@@ -1487,5 +1430,5 @@

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to disallow space after prefix for all unary operators

@@ -1514,5 +1457,5 @@ #### Example

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to require space after prefix for all unary operators

@@ -1541,5 +1484,5 @@ #### Example

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to disallow space before postfix for all unary operators (i.e. increment/decrement operators)

@@ -1568,5 +1511,5 @@ #### Example

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to require space before postfix for all unary operators (i.e. increment/decrement operators)

@@ -1594,5 +1537,5 @@ #### Example

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to disallow space before all possible binary operators

@@ -1609,3 +1552,2 @@ #### Example

"*",
"=",
"==",

@@ -1615,2 +1557,3 @@ "===",

"!=="
// etc
]

@@ -1635,5 +1578,5 @@ ```

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to require space before all possible binary operators

@@ -1650,3 +1593,2 @@ #### Example

"*",
"=",
"==",

@@ -1656,2 +1598,3 @@ "===",

"!=="
// etc
]

@@ -1676,5 +1619,5 @@ ```

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to disallow space after all possible binary operators

@@ -1691,3 +1634,2 @@ #### Example

"*",
"=",
"==",

@@ -1697,2 +1639,3 @@ "===",

"!=="
// etc
]

@@ -1717,5 +1660,5 @@ ```

Type: `Array`
Type: `Array` or `Boolean`
Values: Array of quoted operators
Values: Array of quoted operators or `true` to require space after all possible binary operators

@@ -1732,3 +1675,2 @@ #### Example

"*",
"=",
"==",

@@ -1738,2 +1680,3 @@ "===",

"!=="
// etc
]

@@ -1790,5 +1733,5 @@ ```

Type: `Boolean`
Type: `Boolean` or `String`
Values: `true`
Values: `true` or `"ignoreProperties"`

@@ -1803,3 +1746,3 @@ JSHint: [`camelcase`](http://jshint.com/docs/options/#camelcase)

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

@@ -1814,3 +1757,3 @@ ```js

##### Invalid
##### Invalid for mode `true`

@@ -1823,2 +1766,23 @@ ```js

##### Valid for mode `ignoreProperties`
```js
var camelCase = 0;
var CamelCase = 1;
var _camelCase = 2;
var camelCase_ = 3;
var UPPER_CASE = 4;
var obj.snake_case = 5;
var camelCase = { snake_case: 6 };
```
##### Invalid for mode `ignoreProperties`
```js
var lower_case = 1;
var Mixed_case = 2;
var mixed_Case = 3;
var snake_case = { snake_case: 6 };
```
### disallowKeywords

@@ -1998,3 +1962,3 @@

```js
"validateIndentation": "\t",
"validateIndentation": "\t"
```

@@ -2271,5 +2235,12 @@

Type: `Integer`
Type: `Integer` or `Object`
Values: A positive integer
Values:
- `Integer`: lines should be at most the number of characters specified
- `Object`:
- `value`: lines should be at most the number of characters specified
- `tabSize`: considered the tab character as number of specified spaces
- `allowComments`: allows comments to break the rule
- `allowUrlComments`: allows comments with long urls to break the rule
- `allowRegex`: allows regular expression literals to break the rule

@@ -2336,3 +2307,3 @@ JSHint: [`maxlen`](http://jshint.com/docs/options/#maxlen)

```js
"safeContextKeyword": [ "that" ]
"safeContextKeyword": ["that"]
```

@@ -2383,3 +2354,31 @@

```
### requireYodaConditions
Requires the variable to be the right hand operator when doing a boolean comparison
Type: `Boolean`
Values: `true`
#### Example
```js
"requireYodaConditions": true
```
##### Valid
```js
if (1 == a) {
return
}
```
##### Invalid
```js
if (a == 1) {
return
}
```
### disallowYodaConditions

@@ -2465,2 +2464,90 @@

### requireSpaceAfterLineComment
Requires that a line comment (`//`) be followed by a space.
Type: `Boolean`
Values: `true`
#### Example
```js
"requireSpaceAfterLineComment": true
```
##### Valid
```js
// A comment
/*A comment*/
```
##### Invalid
```js
//A comment
```
### disallowSpaceAfterLineComment
Requires that a line comment (`//`) not be followed by a space.
Type: `Boolean`
Values: `true`
#### Example
```js
"disallowSpaceAfterLineComment": true
```
##### Valid
```js
//A comment
/* A comment*/
```
##### Invalid
```js
// A comment
```
## Removed Rules
### ~~disallowLeftStickedOperators~~
Use the following rules instead:
* requireSpaceBeforeBinaryOperators
* requireSpaceBeforePostfixUnaryOperators
* requireSpacesInConditionalExpression
### ~~disallowRightStickedOperators~~
Use the following rules instead:
* requireSpaceAfterBinaryOperators
* requireSpaceAfterPrefixUnaryOperators
* requireSpacesInConditionalExpression
### ~~requireLeftStickedOperators~~
Use the following rules instead:
* disallowSpaceBeforeBinaryOperators
* disallowSpaceBeforePostfixUnaryOperators
* disallowSpacesInConditionalExpressions
### ~~requireRightStickedOperators~~
Use the following rules instead:
* disallowSpaceAfterBinaryOperators
* disallowSpaceAfterPrefixUnaryOperators
* disallowSpacesInConditionalExpressions
## Browser Usage

@@ -2467,0 +2554,0 @@

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