Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
eslint-plugin-canonical
Advanced tools
ESLint rules for Canonical ruleset.
npm install eslint --save-dev
npm install @babel/eslint-parser --save-dev
npm install eslint-plugin-canonical --save-dev
parser
property to babel-eslint
.plugins
section and specify eslint-plugin-canonical
as a plugin.{
"parser": "@babel/eslint-parser",
"plugins": [
"canonical"
],
"rules": {
"canonical/filename-match-exported": 0,
"canonical/filename-match-regex": 0,
"canonical/filename-no-index": 0,
"canonical/id-match": 0,
"canonical/no-restricted-strings": 0,
"canonical/sort-keys": 0
}
}
This plugin exports a recommended configuration that enforces Canonical type good practices.
To enable this configuration use the extends property in your .eslintrc
config file:
{
"extends": [
"plugin:canonical/recommended"
],
"plugins": [
"canonical"
]
}
See ESLint documentation for more information about extending configuration files.
filename-match-exported
Match the file name against the default exported value in the module. Files that dont have a default export will
be ignored. The exports of index.js
are matched against their parent directory.
// Considered problem only if the file isn't named foo.js or foo/index.js
export default function foo() {}
// Considered problem only if the file isn't named Foo.js or Foo/index.js
module.exports = class Foo() {}
// Considered problem only if the file isn't named someVariable.js or someVariable/index.js
module.exports = someVariable;
// Never considered a problem
export default { foo: "bar" };
If your filename policy doesn't quite match with your variable naming policy, you can add one or multiple transforms:
"canonical/filename-match-exported": [ 2, "kebab" ]
Now, in your code:
// Considered problem only if file isn't named variable-name.js or variable-name/index.js
export default function variableName;
Available transforms: 'snake', 'kebab', 'camel', and 'pascal' (camel-cased with first letter in upper case).
For multiple transforms simply specify an array like this (null in this case stands for no transform):
"canonical/filename-match-exported": [2, [ null, "kebab", "snake" ] ]
If you prefer to use suffixes for your files (e.g. Foo.react.js
for a React component file),
you can use a second configuration parameter. It allows you to remove parts of a filename matching a regex pattern
before transforming and matching against the export.
"canonical/filename-match-exported": [ 2, null, "\\.react$" ]
Now, in your code:
// Considered problem only if file isn't named variableName.react.js, variableName.js or variableName/index.js
export default function variableName;
If you also want to match exported function calls you can use the third option (a boolean flag).
"canonical/filename-match-exported": [ 2, null, null, true ]
Now, in your code:
// Considered problem only if file isn't named functionName.js or functionName/index.js
export default functionName();
The following patterns are considered problems:
module.exports = exported;
// Message: Filename 'fooBar' must match the exported name 'exported'.
module.exports = class Foo {};
// Message: Filename 'foo' must match the exported name 'Foo'.
module.exports = class Foo { render() { return <span>Test Class</span>; } };
// Message: Filename 'foo' must match the exported name 'Foo'.
module.exports = function foo() {};
// Message: Filename 'bar' must match the exported name 'foo'.
module.exports = function foo() { return <span>Test Fn</span> };
// Message: Filename 'bar' must match the exported name 'foo'.
export default exported;
// Message: Filename 'fooBar' must match the exported name 'exported'.
export default class Foo {};
// Message: Filename 'bar' must match the exported name 'Foo'.
export default class Foo { render() { return <span>Test Class</span>; } };
// Message: Filename 'bar' must match the exported name 'Foo'.
export default function foo() {};
// Message: The directory 'fooBar' must be named 'foo', after the exported value of its index file.
export default function foo() { return <span>Test Fn</span> };
// Message: The directory 'fooBar' must be named 'foo', after the exported value of its index file.
module.exports = exported;
// Message: The directory 'eslint-plugin-canonical' must be named 'exported', after the exported value of its index file.
module.exports = class Foo { render() { return <span>Test Class</span>; } };
// Message: Filename 'Foo.react' must match the exported name 'Foo'.
// Options: ["snake"]
module.exports = variableName;
// Message: Filename 'variableName' must match the exported and transformed name 'variable_name'.
// Options: ["kebab"]
export default variableName;
// Message: Filename 'variableName' must match the exported and transformed name 'variable-name'.
// Options: ["pascal"]
export default variableName;
// Message: Filename 'variableName' must match the exported and transformed name 'VariableName'.
// Options: [[null]]
export default variableName;
// Message: Filename 'VariableName' must match the exported name 'variableName'.
// Options: [["pascal","snake"]]
export default variableName;
// Message: Filename 'variableName' must match any of the exported and transformed names 'VariableName', 'variable_name'.
// Options: [null,"\\.react$"]
export default class Foo { render() { return <span>Test Class</span>; } };
// Message: Filename 'Foo.bar' must match the exported name 'Foo'.
// Options: [null,"\\.react$"]
export default class Foo { render() { return <span>Test Class</span>; } };
// Message: The directory 'Foo.react' must be named 'Foo', after the exported value of its index file.
// Options: [null,null,true]
module.exports = foo();
// Message: Filename 'bar' must match the exported name 'foo'.
The following patterns are not considered problems:
module.exports = function() {};
var foo = 'bar';
export default foo();
module.exports = exported;
module.exports = class Foo {};
module.exports = class Foo { render() { return <span>Test Class</span>; } };
module.exports = function foo() {};
module.exports = foo();
module.exports = function foo() { return <span>Test Fn</span> };
export default exported;
export default class Foo {};
export default class Foo { render() { return <span>Test Class</span>; } };
export default function foo() {};
export default function foo() { return <span>Test Fn</span> };
export default function foo() {};
export default function foo() { return <span>Test Fn</span> };
export default function index() {};
// Options: ["snake"]
module.exports = variableName;
// Options: ["snake"]
module.exports = variableName;
// Options: ["kebab"]
module.exports = variableName;
// Options: ["camel"]
module.exports = variable_name;
// Options: ["snake"]
export default variableName;
// Options: ["kebab"]
export default variableName;
// Options: ["camel"]
export default variable_name;
// Options: ["pascal"]
export default variable_name;
// Options: [["pascal","camel"]]
export default variable_name;
// Options: [["pascal","camel"]]
export default variable_name;
// Options: [null,"\\.react$"]
module.exports = class Foo { render() { return <span>Test Class</span>; } };
// Options: [null,"\\.react$"]
export default class Foo { render() { return <span>Test Class</span>; } };
// Options: [null,null,true]
module.exports = foo();
filename-match-regex
A rule to enforce a certain file naming convention using a regular expression.
The convention can be configured using a regular expression (the default is camelCase.js
). Additionally
exporting files can be ignored with a second configuration parameter.
"canonical/filename-match-regex": [2, "^[a-z_]+$", true]
With these configuration options, camelCase.js
will be reported as an error while snake_case.js
will pass.
Additionally the files that have a named default export (according to the logic in the match-exported
rule) will be
ignored. They could be linted with the match-exported
rule. Please note that exported function calls are not
respected in this case.
The following patterns are considered problems:
var foo = 'bar';
// Message: Filename 'foo_bar.js' does not match the naming convention.
var foo = 'bar';
// Message: Filename 'fooBAR.js' does not match the naming convention.
var foo = 'bar';
// Message: Filename 'fooBar$.js' does not match the naming convention.
// Options: ["^[a-z_]$"]
var foo = 'bar';
// Message: Filename 'fooBar.js' does not match the naming convention.
The following patterns are not considered problems:
var foo = 'bar';
var foo = 'bar';
var foo = 'bar';
// Options: ["^[a-z_]+$"]
var foo = 'bar';
// Options: ["^[a-z_]+$"]
var foo = 'bar';
var foo = 'bar';
// Options: [null,true]
module.exports = foo
// Options: ["^[a-z_]$",true]
module.exports = foo
// Options: ["^[a-z_]+$",true]
module.exports = foo()
filename-no-index
Having a bunch of index.js
files can have negative influence on developer experience, e.g. when
opening files by name. When enabling this rule. index.js
files will always be considered a problem.
The following patterns are considered problems:
var foo = 'bar';
// Message: 'index.js' files are not allowed.
var foo = 'bar';
// Message: 'index.js' files are not allowed.
The following patterns are not considered problems:
var foo = 'bar';
var foo = 'bar';
var foo = 'bar';
var foo = 'bar';
id-match
The --fix
option on the command line automatically fixes problems reported by this rule.
Note: This rule is equivalent to id-match
, except for addition of ignoreNamedImports
.
This rule requires identifiers in assignments and function
definitions to match a specified regular expression.
"properties": false
(default) does not check object properties"properties": true
requires object literal properties and member expression assignment properties to match the specified regular expression"classFields": false
(default) does not class field names"classFields": true
requires class field names to match the specified regular expression"onlyDeclarations": false
(default) requires all variable names to match the specified regular expression"onlyDeclarations": true
requires only var
, function
, and class
declarations to match the specified regular expression"ignoreDestructuring": false
(default) enforces id-match
for destructured identifiers"ignoreDestructuring": true
does not check destructured identifiers"ignoreNamedImports": false
(default) enforces id-match
for named imports"ignoreNamedImports": true
does not check named importsThe following patterns are considered problems:
// Options: ["^[a-z]+$",{"onlyDeclarations":true}]
var __foo = "Matthieu"
// Message: undefined
// Options: ["^[a-z]+$"]
first_name = "Matthieu"
// Message: undefined
// Options: ["^z"]
first_name = "Matthieu"
// Message: undefined
// Options: ["^[a-z]+(_[A-Z][a-z])*$"]
Last_Name = "Larcher"
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
var obj = {key: no_under}
// Message: Identifier 'no_under' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$"]
function no_under21(){}
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
obj.no_under22 = function(){};
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
no_under23.foo = function(){};
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
[no_under24.baz]
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
if (foo.bar_baz === boom.bam_pow) { [no_under25.baz] }
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
foo.no_under26 = boom.bam_pow
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
var foo = { no_under27: boom.bam_pow }
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
foo.qux.no_under28 = { bar: boom.bam_pow }
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
var o = {no_under29: 1}
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
obj.no_under30 = 2;
// Message: undefined
// Options: ["^[^_]+$",{"properties":true}]
var { category_id: category_alias } = query;
// Message: Identifier 'category_alias' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"ignoreDestructuring":true,"properties":true}]
var { category_id: category_alias } = query;
// Message: Identifier 'category_alias' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"ignoreDestructuring":true,"properties":true}]
var { category_id: categoryId, ...other_props } = query;
// Message: Identifier 'other_props' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
var { category_id } = query;
// Message: Identifier 'category_id' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
var { category_id = 1 } = query;
// Message: Identifier 'category_id' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import no_camelcased from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import * as no_camelcased from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$"]
export * as no_camelcased from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import { no_camelcased as no_camel_cased } from "external module";
// Message: Identifier 'no_camel_cased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import { camelCased as no_camel_cased } from "external module";
// Message: Identifier 'no_camel_cased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import { camelCased, no_camelcased } from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import { no_camelcased as camelCased, another_no_camelcased } from "external-module";
// Message: Identifier 'another_no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import camelCased, { no_camelcased } from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
import no_camelcased, { another_no_camelcased as camelCased } from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
function foo({ no_camelcased }) {};
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
function foo({ no_camelcased = 'default value' }) {};
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
const no_camelcased = 0; function foo({ camelcased_value = no_camelcased }) {}
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Message: Identifier 'camelcased_value' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
const { bar: no_camelcased } = foo;
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
function foo({ value_1: my_default }) {}
// Message: Identifier 'my_default' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
function foo({ isCamelcased: no_camelcased }) {};
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
var { foo: bar_baz = 1 } = quz;
// Message: Identifier 'bar_baz' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"properties":true}]
const { no_camelcased = false } = bar;
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$"]
class x { _foo() {} }
// Message: Identifier '_foo' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"classFields":true}]
class x { _foo = 1; }
// Message: Identifier '_foo' does not match the pattern '^[^_]+$'.
// Options: ["^[^_]+$",{"ignoreNamedImports":false}]
import { no_camelcased } from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
The following patterns are not considered problems:
// Options: ["^[a-z]+$",{"onlyDeclarations":true}]
__foo = "Matthieu"
// Options: ["^[a-z]+$"]
firstname = "Matthieu"
// Options: ["[a-z]+"]
first_name = "Matthieu"
// Options: ["^f"]
firstname = "Matthieu"
// Options: ["^[a-z]+(_[A-Z][a-z]+)*$"]
last_Name = "Larcher"
// Options: ["^[a-z]+(_[A-Z][a-z])*$"]
param = "none"
// Options: ["^[^_]+$"]
function noUnder(){}
// Options: ["^[^_]+$"]
no_under()
// Options: ["^[^_]+$"]
foo.no_under2()
// Options: ["^[^_]+$"]
var foo = bar.no_under3;
// Options: ["^[^_]+$"]
var foo = bar.no_under4.something;
// Options: ["^[^_]+$"]
foo.no_under5.qux = bar.no_under6.something;
// Options: ["^[^_]+$"]
if (bar.no_under7) {}
// Options: ["^[^_]+$"]
var obj = { key: foo.no_under8 };
// Options: ["^[^_]+$"]
var arr = [foo.no_under9];
// Options: ["^[^_]+$"]
[foo.no_under10]
// Options: ["^[^_]+$"]
var arr = [foo.no_under11.qux];
// Options: ["^[^_]+$"]
[foo.no_under12.nesting]
// Options: ["^[^_]+$"]
if (foo.no_under13 === boom.no_under14) { [foo.no_under15] }
// Options: ["^[a-z$]+([A-Z][a-z]+)*$"]
var myArray = new Array(); var myDate = new Date();
// Options: ["^[^_]+$"]
var x = obj._foo;
// Options: ["^[^_]+$",{"onlyDeclarations":true,"properties":true}]
var obj = {key: no_under}
// Options: ["^[^_]+$",{"properties":true}]
var {key_no_under: key} = {}
// Options: ["^[^_]+$",{"ignoreDestructuring":true,"properties":true}]
var { category_id } = query;
// Options: ["^[^_]+$",{"ignoreDestructuring":true,"properties":true}]
var { category_id: category_id } = query;
// Options: ["^[^_]+$",{"ignoreDestructuring":true,"properties":true}]
var { category_id = 1 } = query;
// Options: ["^[^_]+$",{"properties":true}]
var o = {key: 1}
// Options: ["^[^_]+$",{"properties":false}]
var o = {no_under16: 1}
// Options: ["^[^_]+$",{"properties":false}]
obj.no_under17 = 2;
// Options: ["^[^_]+$",{"properties":false}]
var obj = {
no_under18: 1
};
obj.no_under19 = 2;
// Options: ["^[^_]+$",{"properties":false}]
obj.no_under20 = function(){};
// Options: ["^[^_]+$",{"properties":false}]
var x = obj._foo2;
// Options: ["^[^_]+$"]
class x { foo() {} }
// Options: ["^[^_]+$"]
class x { #foo() {} }
// Options: ["^[^_]+$",{"ignoreNamedImports":true}]
import { no_camelcased } from "external-module";
// Message: Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.
no-restricted-strings
Disallow specified strings.
The following patterns are considered problems:
// Options: [["bar"]]
var foo = "bar"
// Message: Disallowed string: 'bar'.
// Options: [["bar"]]
const foo = `bar ${baz}`;
// Message: Disallowed string in template: 'bar'.
The following patterns are not considered problems:
const foo = "bar";
The 1st option is an array of strings that cannot be contained in the codebase.
sort-keys
The --fix
option on the command line automatically fixes problems reported by this rule.
Note: This rule is equivalent to sort-keys
, except that it is fixable.
This rule requires identifiers in assignments and function
definitions to match a specified regular expression.
The 1st option is "asc" or "desc".
The 2nd option is an object which has 3 properties.
caseSensitive
- if true, enforce properties to be in case-sensitive order. Default is true.minKeys
- Specifies the minimum number of keys that an object should have in order for the object's unsorted keys to produce an error. Default is 2, which means by default all objects with unsorted keys will result in lint errors.natural
- if true, enforce properties to be in natural order. Default is false. Natural Order compares strings containing combination of letters and numbers in the way a human being would sort. It basically sorts numerically, instead of sorting alphabetically. So the number 10 comes after the number 3 in Natural Sorting.The following patterns are considered problems:
var obj = {
// comment
// comment 2
a:1,
_:2,
b:3
}
// Message: undefined
var obj = {
/* comment
comment 2 */
a:1,
_:2,
b:3
}
// Message: undefined
var obj = {a:1, _:2, b:3} // default
// Message: undefined
var obj = {a:1, c:2, b:3}
// Message: undefined
var obj = {b_:1, a:2, b:3}
// Message: undefined
var obj = {b_:1, c:2, C:3}
// Message: undefined
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
var obj = {...z, c:1, b:1}
// Message: undefined
var obj = {...z, ...c, d:4, b:1, ...y, ...f, e:2, a:1}
// Message: undefined
// Message: undefined
var obj = {c:1, b:1, ...a}
// Message: undefined
var obj = {...z, ...a, c:1, b:1}
// Message: undefined
var obj = {...z, b:1, a:1, ...d, ...c}
// Message: undefined
// Options: ["desc"]
var obj = {...z, a:2, b:0, ...x, ...c}
// Message: undefined
// Options: ["desc"]
var obj = {...z, a:2, b:0, ...x}
// Message: undefined
// Options: ["desc"]
var obj = {...z, '':1, a:2}
// Message: undefined
var obj = {a:1, [b+c]:2, '':3}
// Message: undefined
// Options: ["desc"]
var obj = {'':1, [b+c]:2, a:3}
// Message: undefined
// Options: ["desc"]
var obj = {b:1, [f()]:2, '':3, a:4}
// Message: undefined
var obj = {a:1, b:3, [a]: -1, c:2}
// Message: undefined
var obj = {a:1, c:{y:1, x:1}, b:1}
// Message: undefined
// Message: undefined
// Options: ["asc"]
var obj = {a:1, _:2, b:3} // asc
// Message: undefined
// Options: ["asc"]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["asc"]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["asc"]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["asc"]
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
// Options: ["asc"]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Options: ["asc"]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {a:1, _:2, b:3} // asc, insensitive
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {$:1, A:3, _:2, a:4}
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Options: ["asc",{"caseSensitive":false}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {a:1, _:2, b:3} // asc, natural
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {$:1, A:3, _:2, a:4}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Options: ["asc",{"natural":true}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {a:1, _:2, b:3} // asc, natural, insensitive
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {$:1, A:3, _:2, a:4}
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {1:1, '11':2, 2:4, A:3}
// Message: undefined
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Options: ["desc"]
var obj = {a:1, _:2, b:3} // desc
// Message: undefined
// Options: ["desc"]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["desc"]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["desc"]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["desc"]
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
// Message: undefined
// Options: ["desc"]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Message: undefined
// Options: ["desc"]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {a:1, _:2, b:3} // desc, insensitive
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {a:1, _:2, b:3} // desc, natural
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
// Message: undefined
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {1:1, 2:4, A:3, '11':2}
// Message: undefined
// Message: undefined
// Options: ["desc",{"natural":true}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {a:1, _:2, b:3} // desc, natural, insensitive
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {a:1, c:2, b:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, a:2, b:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, c:2, C:3}
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {$:1, _:2, A:3, a:4}
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {1:1, 2:4, '11':2, A:3}
// Message: undefined
// Message: undefined
// Message: undefined
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {'#':1, À:3, 'Z':2, è:4}
// Message: undefined
// Message: undefined
The following patterns are not considered problems:
// Options: []
var obj = {_:2, a:1, b:3} // default
// Options: []
var obj = {a:1, b:3, c:2}
// Options: []
var obj = {a:2, b:3, b_:1}
// Options: []
var obj = {C:3, b_:1, c:2}
// Options: []
var obj = {$:1, A:3, _:2, a:4}
// Options: []
var obj = {1:1, '11':2, 2:4, A:3}
// Options: []
var obj = {'#':1, 'Z':2, À:3, è:4}
// Options: []
var obj = {a:1, b:3, [a + b]: -1, c:2}
// Options: []
var obj = {'':1, [f()]:2, a:3}
// Options: ["desc"]
var obj = {a:1, [b++]:2, '':3}
// Options: []
var obj = {a:1, ...z, b:1}
// Options: []
var obj = {b:1, ...z, a:1}
// Options: []
var obj = {...a, b:1, ...c, d:1}
// Options: []
var obj = {...a, b:1, ...d, ...c, e:2, z:5}
// Options: []
var obj = {b:1, ...c, ...d, e:2}
// Options: []
var obj = {a:1, ...z, '':2}
// Options: ["desc"]
var obj = {'':1, ...z, 'a':2}
// Options: []
var obj = {...z, a:1, b:1}
// Options: []
var obj = {...z, ...c, a:1, b:1}
// Options: []
var obj = {a:1, b:1, ...z}
// Options: ["desc"]
var obj = {...z, ...x, a:1, ...c, ...d, f:5, e:4}
// Options: []
function fn(...args) { return [...args].length; }
// Options: []
function g() {}; function f(...args) { return g(...args); }
// Options: []
let {a, b} = {}
// Options: []
var obj = {a:1, b:{x:1, y:1}, c:1}
// Options: ["asc"]
var obj = {_:2, a:1, b:3} // asc
// Options: ["asc"]
var obj = {a:1, b:3, c:2}
// Options: ["asc"]
var obj = {a:2, b:3, b_:1}
// Options: ["asc"]
var obj = {C:3, b_:1, c:2}
// Options: ["asc"]
var obj = {$:1, A:3, _:2, a:4}
// Options: ["asc"]
var obj = {1:1, '11':2, 2:4, A:3}
// Options: ["asc"]
var obj = {'#':1, 'Z':2, À:3, è:4}
// Options: ["asc",{"caseSensitive":false}]
var obj = {_:2, a:1, b:3} // asc, insensitive
// Options: ["asc",{"caseSensitive":false}]
var obj = {a:1, b:3, c:2}
// Options: ["asc",{"caseSensitive":false}]
var obj = {a:2, b:3, b_:1}
// Options: ["asc",{"caseSensitive":false}]
var obj = {b_:1, C:3, c:2}
// Options: ["asc",{"caseSensitive":false}]
var obj = {b_:1, c:3, C:2}
// Options: ["asc",{"caseSensitive":false}]
var obj = {$:1, _:2, A:3, a:4}
// Options: ["asc",{"caseSensitive":false}]
var obj = {1:1, '11':2, 2:4, A:3}
// Options: ["asc",{"caseSensitive":false}]
var obj = {'#':1, 'Z':2, À:3, è:4}
// Options: ["asc",{"natural":true}]
var obj = {_:2, a:1, b:3} // asc, natural
// Options: ["asc",{"natural":true}]
var obj = {a:1, b:3, c:2}
// Options: ["asc",{"natural":true}]
var obj = {a:2, b:3, b_:1}
// Options: ["asc",{"natural":true}]
var obj = {C:3, b_:1, c:2}
// Options: ["asc",{"natural":true}]
var obj = {$:1, _:2, A:3, a:4}
// Options: ["asc",{"natural":true}]
var obj = {1:1, 2:4, '11':2, A:3}
// Options: ["asc",{"natural":true}]
var obj = {'#':1, 'Z':2, À:3, è:4}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {_:2, a:1, b:3} // asc, natural, insensitive
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {a:1, b:3, c:2}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {a:2, b:3, b_:1}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, C:3, c:2}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, c:3, C:2}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {$:1, _:2, A:3, a:4}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {1:1, 2:4, '11':2, A:3}
// Options: ["asc",{"caseSensitive":false,"natural":true}]
var obj = {'#':1, 'Z':2, À:3, è:4}
// Options: ["desc"]
var obj = {b:3, a:1, _:2} // desc
// Options: ["desc"]
var obj = {c:2, b:3, a:1}
// Options: ["desc"]
var obj = {b_:1, b:3, a:2}
// Options: ["desc"]
var obj = {c:2, b_:1, C:3}
// Options: ["desc"]
var obj = {a:4, _:2, A:3, $:1}
// Options: ["desc"]
var obj = {A:3, 2:4, '11':2, 1:1}
// Options: ["desc"]
var obj = {è:4, À:3, 'Z':2, '#':1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {b:3, a:1, _:2} // desc, insensitive
// Options: ["desc",{"caseSensitive":false}]
var obj = {c:2, b:3, a:1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {b_:1, b:3, a:2}
// Options: ["desc",{"caseSensitive":false}]
var obj = {c:2, C:3, b_:1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {C:2, c:3, b_:1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {a:4, A:3, _:2, $:1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {A:3, 2:4, '11':2, 1:1}
// Options: ["desc",{"caseSensitive":false}]
var obj = {è:4, À:3, 'Z':2, '#':1}
// Options: ["desc",{"natural":true}]
var obj = {b:3, a:1, _:2} // desc, natural
// Options: ["desc",{"natural":true}]
var obj = {c:2, b:3, a:1}
// Options: ["desc",{"natural":true}]
var obj = {b_:1, b:3, a:2}
// Options: ["desc",{"natural":true}]
var obj = {c:2, b_:1, C:3}
// Options: ["desc",{"natural":true}]
var obj = {a:4, A:3, _:2, $:1}
// Options: ["desc",{"natural":true}]
var obj = {A:3, '11':2, 2:4, 1:1}
// Options: ["desc",{"natural":true}]
var obj = {è:4, À:3, 'Z':2, '#':1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {b:3, a:1, _:2} // desc, natural, insensitive
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {c:2, b:3, a:1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {b_:1, b:3, a:2}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {c:2, C:3, b_:1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {C:2, c:3, b_:1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {a:4, A:3, _:2, $:1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {A:3, '11':2, 2:4, 1:1}
// Options: ["desc",{"caseSensitive":false,"natural":true}]
var obj = {è:4, À:3, 'Z':2, '#':1}
FAQs
Canonical linting rules for ESLint.
The npm package eslint-plugin-canonical receives a total of 56,126 weekly downloads. As such, eslint-plugin-canonical popularity was classified as popular.
We found that eslint-plugin-canonical demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.