Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jshint

Package Overview
Dependencies
Maintainers
1
Versions
99
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jshint - npm Package Compare versions

Comparing version 2.4.4 to 2.5.0

19

package.json
{
"name": "jshint",
"version": "2.4.4",
"version": "2.5.0",
"homepage": "http://jshint.com/",

@@ -42,3 +42,4 @@ "description": "Static analysis tool for JavaScript",

"console-browserify": "0.1.x",
"exit": "0.1.x"
"exit": "0.1.x",
"strip-json-comments": "0.1.x"
},

@@ -57,16 +58,2 @@

"jshintConfig": {
"boss": true,
"node": true,
"strict": true,
"white": true,
"smarttabs": true,
"maxlen": 100,
"newcap": false,
"undef": true,
"unused": true,
"onecase": true,
"indent": 2
},
"licenses": [

@@ -73,0 +60,0 @@ {

6

README.md

@@ -13,5 +13,5 @@ JSHint, A Static Code Analysis Tool for JavaScript

JSHint is a community-driven tool to detect errors and potential problems
in JavaScript code and to enforce your team’s coding conventions. It is
very flexible so you can easily adjust it to your particular coding guidelines
and the environment you expect your code to execute in.
in JavaScript code. It is very flexible so you can easily adjust it to your
particular coding guidelines and the environment you expect your code to
execute in.

@@ -18,0 +18,0 @@ #### JSHint 2.x versus JSHint 3

"use strict";
var _ = require("underscore");
var cli = require("cli");
var path = require("path");
var shjs = require("shelljs");
var minimatch = require("minimatch");
var htmlparser = require("htmlparser2");
var exit = require("exit");
var JSHINT = require("./jshint.js").JSHINT;
var defReporter = require("./reporters/default").reporter;
var _ = require("underscore");
var cli = require("cli");
var path = require("path");
var shjs = require("shelljs");
var minimatch = require("minimatch");
var htmlparser = require("htmlparser2");
var exit = require("exit");
var stripJsonComments = require("strip-json-comments");
var JSHINT = require("./jshint.js").JSHINT;
var defReporter = require("./reporters/default").reporter;

@@ -19,2 +20,5 @@ var OPTIONS = {

"exclude-path": ["exclude-path", "Pass in a custom jshintignore file path", "string", null],
"filename": ["filename",
"Pass in a filename when using STDIN to emulate config lookup for that file name",
"string", null],
"verbose": ["verbose", "Show message codes"],

@@ -63,25 +67,2 @@ "show-non-errors": ["show-non-errors", "Show additional data generated by jshint"],

/**
* Removes JavaScript comments from a string by replacing
* everything between block comments and everything after
* single-line comments in a non-greedy way.
*
* English version of the regex:
* match '/*'
* then match zero or more instances of any character (incl. \n)
* except for instances of '* /' (without a space, obv.)
* then match '* /' (again, without a space)
*
* @param {string} str a string with potential JavaScript comments.
* @returns {string} a string without JavaScript comments.
*/
function removeComments(str) {
str = str || "";
str = str.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, "");
str = str.replace(/\/\/[^\n\r]*/g, ""); // Everything after '//'
return str;
}
/**
* Tries to find a configuration file in either project directory

@@ -303,5 +284,5 @@ * or in the home directory. Configuration files are named

lines = lines.map(function (line) {
return line.replace(startOffset, '');
return line.replace(startOffset, "");
});
data = lines.join('\n');
data = lines.join("\n");
}

@@ -319,2 +300,84 @@

/**
* Crude version of source maps: extract how much JavaSscript in HTML
* was shifted based on first JS line. For example if first js line
* is offset by 4 spaces, each line in this js fragment will have offset 4
* to restore the original column.
*
* @param {string} code a piece of code
* @param {string} when 'always' will extract the JS code, no matter what.
* 'never' won't do anything. 'auto' will check if the code looks like HTML
* before extracting it.
*
* @return {Array} extracted offsets
*/
function extractOffsets(code, when) {
// A JS file won't start with a less-than character, whereas a HTML file
// should always start with that.
if (when !== "always" && (when !== "auto" || !/^\s*</.test(code)))
return;
var inscript = false;
var index = 0;
var lineCounter = 0;
var startOffset;
var offsets = [];
// Test if current tag is a valid <script> tag.
function onopen(name, attrs) {
if (name !== "script")
return;
if (attrs.type && !/text\/javascript/.test(attrs.type.toLowerCase()))
return;
// Mark that we're inside a <script> a tag and push all new lines
// in between the last </script> tag and this <script> tag to preserve
// location information.
inscript = true;
var fragment = code.slice(index, parser.endIndex);
var n = fragment.match(/\n\r|\n|\r/g).length;
lineCounter += n;
startOffset = null;
}
function onclose(name) {
if (name !== "script" || !inscript)
return;
inscript = false;
index = parser.startIndex;
startOffset = null;
}
function ontext(data) {
if (!inscript)
return;
var lines = data.split(/\n\r|\n|\r/);
if (!startOffset) {
lines.some(function (line) {
if (!line) return;
startOffset = /^(\s*)/.exec(line)[1];
return true;
});
}
// check for startOffset again to remove leading white space from first line
lines.forEach(function () {
lineCounter += 1;
if (startOffset) {
offsets[lineCounter] = startOffset.length;
} else {
offsets[lineCounter] = 0;
}
});
}
var parser = new htmlparser.Parser({ onopentag: onopen, onclosetag: onclose, ontext: ontext });
parser.parseComplete(code);
return offsets;
}
/**
* Recursively gather all files that need to be linted,

@@ -383,3 +446,14 @@ * excluding those that user asked to ignore.

if (config.overrides) {
if (file) {
_.each(config.overrides, function (options, pattern) {
if ((new RegExp(pattern)).test(file)) _.extend(config, options);
});
}
delete config.overrides;
}
delete config.dirname;
buffer.push(code);

@@ -410,2 +484,9 @@ buffer = buffer.join("\n");

/**
* Returns a configuration file or nothing, if it can't be found.
*/
getConfig: function (fp) {
return loadNpmConfig(fp) || exports.loadConfig(findConfig(fp));
},
/**
* Loads and parses a configuration file.

@@ -427,3 +508,3 @@ *

try {
var config = JSON.parse(removeComments(shjs.cat(fp)));
var config = JSON.parse(stripJsonComments(shjs.cat(fp)));
config.dirname = path.dirname(fp);

@@ -492,3 +573,12 @@

cli.withStdin(function (code) {
lint(extract(code, opts.extract), results, opts.config || {}, data);
var config = opts.config;
if (opts.filename && !config) {
var filename = path.resolve(opts.filename);
config = loadNpmConfig(filename) ||
exports.loadConfig(findConfig(filename));
}
config = config || {};
lint(extract(code, opts.extract), results, config, data);
(opts.reporter || defReporter)(results, data, { verbose: opts.verbose });

@@ -502,3 +592,3 @@ cb(results.length === 0);

files.forEach(function (file) {
var config = opts.config || loadNpmConfig(file) || exports.loadConfig(findConfig(file));
var config = opts.config || exports.getConfig(file);
var code;

@@ -514,2 +604,15 @@

lint(extract(code, opts.extract), results, config, data, file);
if (results.length) {
var offsets = extractOffsets(code, opts.extract);
if (offsets && offsets.length) {
results.forEach(function (errorInfo) {
var line = errorInfo.error.line;
if (line >= 0 && line < offsets.length) {
var offset = +offsets[line];
errorInfo.error.character += offset;
}
});
}
}
});

@@ -603,2 +706,3 @@

extract: options.extract,
filename: options.filename,
useStdin: {"-": true, "/dev/stdin": true}[args[args.length - 1]]

@@ -605,0 +709,0 @@ }, done));

@@ -31,3 +31,4 @@ /*

BooleanLiteral: 8,
RegExp: 9
RegExp: 9,
TemplateLiteral: 10
};

@@ -849,2 +850,58 @@

/*
* Extract a template literal out of the next sequence of characters
* and/or lines or return 'null' if its not possible. Since template
* literals can span across multiple lines, this method has to move
* the char pointer.
*/
scanTemplateLiteral: function () {
// String must start with a backtick.
if (!state.option.esnext || this.peek() !== "`") {
return null;
}
var startLine = this.line;
var startChar = this.char;
var jump = 1;
var value = "";
// For now, do not perform any linting of the content of the template
// string. Just skip until the next backtick is found.
this.skip();
while (this.peek() !== "`") {
while (this.peek() === "") {
// End of line --- For template literals in ES6, no backslash is
// required to precede newlines.
if (!this.nextLine()) {
this.trigger("error", {
code: "E052",
line: startLine,
character: startChar
});
return {
type: Token.TemplateLiteral,
value: value,
isUnclosed: true
};
}
value += "\n";
}
// TODO: do more interesting linting here, similar to string literal
// linting.
var char = this.peek();
this.skip(jump);
value += char;
}
this.skip();
return {
type: Token.TemplateLiteral,
value: value,
isUnclosed: false
};
},
/*
* Extract a string out of the next sequence of characters and/or

@@ -1231,22 +1288,2 @@ * lines or return 'null' if its not possible. Since strings can

/*
* Scan for any occurence of mixed tabs and spaces. If smarttabs option
* is on, ignore tabs followed by spaces.
*
* Tabs followed by one space followed by a block comment are allowed.
*/
scanMixedSpacesAndTabs: function () {
var at, match;
if (state.option.smarttabs) {
// Negative look-behind for "//"
match = this.input.match(/(\/\/|^\s?\*)? \t/);
at = match && !match[1] ? 0 : -1;
} else {
at = this.input.search(/ \t|\t [^\*]/);
}
return at;
},
/*
* Scan for any occurence of non-breaking spaces. Non-breaking spaces

@@ -1284,8 +1321,2 @@ * can be mistakenly typed on OS X with option-space. Non UTF-8 web

}
if (this.peek() === "") { // EOL
if (!/^\s*$/.test(this.getLines()[this.line - 1]) && state.option.trailing) {
this.trigger("warning", { code: "W102", line: this.line, character: start });
}
}
}

@@ -1297,3 +1328,4 @@

var match = this.scanComments() ||
this.scanStringLiteral(checks);
this.scanStringLiteral(checks) ||
this.scanTemplateLiteral();

@@ -1325,4 +1357,3 @@ if (match) {

* Switch to the next line and reset all char pointers. Once
* switched, this method also checks for mixed spaces and tabs
* and other minor warnings.
* switched, this method also checks for other minor warnings.
*/

@@ -1368,7 +1399,2 @@ nextLine: function () {

char = this.scanMixedSpacesAndTabs();
if (char >= 0) {
this.trigger("warning", { code: "W099", line: this.line, character: char + 1 });
}
this.input = this.input.replace(/\t/g, state.tab);

@@ -1539,2 +1565,12 @@ char = this.scanUnsafeChars();

return create("(string)", token.value);
case Token.TemplateLiteral:
this.trigger("Template", {
line: this.line,
char: this.char,
from: this.from,
value: token.value
});
return create("(template)", token.value);
case Token.Identifier:

@@ -1541,0 +1577,0 @@ this.trigger("Identifier", {

@@ -69,3 +69,4 @@ "use strict";

E050: "Mozilla requires the yield expression to be parenthesized here.",
E051: "Regular parameters cannot come after default parameters."
E051: "Regular parameters cannot come after default parameters.",
E052: "Unclosed template literal."
};

@@ -80,11 +81,11 @@

W006: "Confusing minuses.",
W007: "Confusing pluses.",
W007: "Confusing plusses.",
W008: "A leading decimal point can be confused with a dot: '{a}'.",
W009: "The array literal notation [] is preferable.",
W010: "The object literal notation {} is preferable.",
W011: "Unexpected space after '{a}'.",
W012: "Unexpected space before '{a}'.",
W013: "Missing space after '{a}'.",
W011: null,
W012: null,
W013: null,
W014: "Bad line breaking before '{a}'.",
W015: "Expected '{a}' to have an indentation at {b} instead at {c}.",
W015: null,
W016: "Unexpected use of '{a}'.",

@@ -156,3 +157,3 @@ W017: "Bad operand.",

W080: "It's not necessary to initialize '{a}' to 'undefined'.",
W081: "Too many var statements.",
W081: null,
W082: "Function declarations should not be placed in blocks. " +

@@ -177,6 +178,6 @@ "Use a function expression or move the statement to the top of " +

W098: "'{a}' is defined but never used.",
W099: "Mixed spaces and tabs.",
W099: null,
W100: "This character may get silently deleted by one or more browsers.",
W101: "Line is too long.",
W102: "Trailing whitespace.",
W102: null,
W103: "The '{a}' property is deprecated.",

@@ -183,0 +184,0 @@ W104: "'{a}' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).",

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

/*jshint boss: true, rhino: true, unused: true, undef: true, white: true, quotmark: double */
/*jshint boss: true, rhino: true, unused: true, undef: true, quotmark: double */
/*global JSHINT, readFully */

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

@@ -21,4 +21,6 @@ "use strict";

this.cache = {}; // Node.JS doesn't have Map. Sniff.
this.ignoreLinterErrors = false; // Blank out non-multi-line-commented
// lines when ignoring linter errors
this.ignoredLines = {};
// Blank out non-multi-line-commented lines when ignoring linter errors
this.ignoreLinterErrors = false;
}

@@ -25,0 +27,0 @@ };

@@ -38,30 +38,2 @@ "use strict";

// Check for dangling underscores.
linter.on("Identifier", function style_scanDangling(data) {
if (!linter.getOption("nomen")) {
return;
}
// Underscore.js
if (data.name === "_") {
return;
}
// In Node, __dirname and __filename should be ignored.
if (linter.getOption("node")) {
if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) {
return;
}
}
if (/^(_+.*|.*_+)$/.test(data.name)) {
linter.warn("W105", {
line: data.line,
char: data.from,
data: [ "dangling '_'", data.name ]
});
}
});
// Check that all identifiers are using camelCase notation.

@@ -172,2 +144,2 @@ // Exceptions: names like MY_VAR and _myVar.

});
};
};

@@ -29,3 +29,2 @@ // jshint -W001

Math : false,
Map : false,
Number : false,

@@ -38,3 +37,2 @@ Object : false,

RegExp : false,
Set : false,
String : false,

@@ -44,5 +42,13 @@ SyntaxError : false,

URIError : false,
WeakMap : false
};
exports.newEcmaIdentifiers = {
Set : false,
Map : false,
WeakMap : false,
WeakSet : false,
Proxy : false,
Promise : false
};
// Global variables commonly provided by a web browser environment.

@@ -147,2 +153,3 @@

NodeFilter : false,
NodeList : false,
navigator : false,

@@ -604,1 +611,15 @@ onbeforeunload : true,

exports.mocha = {
// BDD
describe : false,
it : false,
before : false,
after : false,
beforeEach : false,
afterEach : false,
// TDD
suite : false,
test : false,
setup : false,
teardown : false
};

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