eslint-plugin-unicorn
Advanced tools
Comparing version 15.0.1 to 16.0.0
@@ -49,3 +49,2 @@ 'use strict'; | ||
'unicorn/prefer-event-key': 'error', | ||
'unicorn/prefer-exponentiation-operator': 'error', | ||
'unicorn/prefer-flat-map': 'error', | ||
@@ -59,2 +58,4 @@ 'unicorn/prefer-includes': 'error', | ||
'unicorn/prefer-reflect-apply': 'error', | ||
// TODO: Enable this by default when it's shipping in a Node.js LTS version. | ||
'unicorn/prefer-replace-all': 'off', | ||
'unicorn/prefer-spread': 'error', | ||
@@ -61,0 +62,0 @@ 'unicorn/prefer-starts-ends-with': 'error', |
{ | ||
"name": "eslint-plugin-unicorn", | ||
"version": "15.0.1", | ||
"version": "16.0.0", | ||
"description": "Various awesome ESLint rules", | ||
@@ -14,8 +14,8 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=8" | ||
"node": ">=10" | ||
}, | ||
"scripts": { | ||
"test": "xo && nyc ava", | ||
"lint": "./test/lint/lint.js", | ||
"integration": "./test/integration/test.js" | ||
"lint": "node ./test/lint/lint.js", | ||
"integration": "node ./test/integration/test.js" | ||
}, | ||
@@ -52,3 +52,3 @@ "files": [ | ||
"safe-regex": "^2.1.1", | ||
"semver": "^6.3.0" | ||
"semver": "^7.1.2" | ||
}, | ||
@@ -65,6 +65,6 @@ "devDependencies": { | ||
"eslint-ava-rule-tester": "^4.0.0", | ||
"eslint-plugin-eslint-plugin": "2.1.0", | ||
"eslint-plugin-eslint-plugin": "^2.2.1", | ||
"execa": "^4.0.0", | ||
"listr": "^0.14.3", | ||
"nyc": "^14.1.1", | ||
"nyc": "^15.0.0", | ||
"outdent": "^0.7.0", | ||
@@ -91,2 +91,5 @@ "pify": "^4.0.1", | ||
], | ||
"rules": { | ||
"prefer-named-capture-group": "off" | ||
}, | ||
"overrides": [ | ||
@@ -93,0 +96,0 @@ { |
@@ -11,3 +11,2 @@ # eslint-plugin-unicorn [![Build Status](https://travis-ci.org/sindresorhus/eslint-plugin-unicorn.svg?branch=master)](https://travis-ci.org/sindresorhus/eslint-plugin-unicorn) [![Coverage Status](https://coveralls.io/repos/github/sindresorhus/eslint-plugin-unicorn/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/eslint-plugin-unicorn?branch=master) | ||
## Install | ||
@@ -19,3 +18,2 @@ | ||
## Usage | ||
@@ -69,3 +67,2 @@ | ||
"unicorn/prefer-event-key": "error", | ||
"unicorn/prefer-exponentiation-operator": "error", | ||
"unicorn/prefer-flat-map": "error", | ||
@@ -79,2 +76,3 @@ "unicorn/prefer-includes": "error", | ||
"unicorn/prefer-reflect-apply": "error", | ||
"unicorn/prefer-replace-all": "off", | ||
"unicorn/prefer-spread": "error", | ||
@@ -94,3 +92,2 @@ "unicorn/prefer-starts-ends-with": "error", | ||
## Rules | ||
@@ -122,7 +119,6 @@ | ||
- [no-zero-fractions](docs/rules/no-zero-fractions.md) - Disallow number literals with zero fractions or dangling dots. *(fixable)* | ||
- [number-literal-case](docs/rules/number-literal-case.md) - Enforce lowercase identifier and uppercase value for number literals. *(fixable)* | ||
- [number-literal-case](docs/rules/number-literal-case.md) - Enforce proper case for numeric literals. *(fixable)* | ||
- [prefer-add-event-listener](docs/rules/prefer-add-event-listener.md) - Prefer `.addEventListener()` and `.removeEventListener()` over `on`-functions. *(partly fixable)* | ||
- [prefer-dataset](docs/rules/prefer-dataset.md) - Prefer using `.dataset` on DOM elements over `.setAttribute(…)`. *(fixable)* | ||
- [prefer-event-key](docs/rules/prefer-event-key.md) - Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. *(partly fixable)* | ||
- [prefer-exponentiation-operator](docs/rules/prefer-exponentiation-operator.md) - Prefer the exponentiation operator over `Math.pow()` *(fixable)* | ||
- [prefer-flat-map](docs/rules/prefer-flat-map.md) - Prefer `.flatMap(…)` over `.map(…).flat()`. *(fixable)* | ||
@@ -136,2 +132,3 @@ - [prefer-includes](docs/rules/prefer-includes.md) - Prefer `.includes()` over `.indexOf()` when checking for existence or non-existence. *(fixable)* | ||
- [prefer-reflect-apply](docs/rules/prefer-reflect-apply.md) - Prefer `Reflect.apply()` over `Function#apply()`. *(fixable)* | ||
- [prefer-replace-all](docs/rules/prefer-replace-all.md) - Prefer `String#replaceAll()` over regex searches with the global flag. *(fixable)* | ||
- [prefer-spread](docs/rules/prefer-spread.md) - Prefer the spread operator over `Array.from()`. *(fixable)* | ||
@@ -147,3 +144,6 @@ - [prefer-starts-ends-with](docs/rules/prefer-starts-ends-with.md) - Prefer `String#startsWith()` & `String#endsWith()` over more complex alternatives. | ||
## Deprecated Rules | ||
- [prefer-exponentiation-operator](docs/rules/prefer-exponentiation-operator.md) - Use the built-in ESLint [`prefer-exponentiation-operator`](https://eslint.org/docs/rules/prefer-exponentiation-operator) rule instead. | ||
## Recommended config | ||
@@ -168,3 +168,2 @@ | ||
## Maintainers | ||
@@ -175,3 +174,2 @@ | ||
- [futpib](https://github.com/futpib) | ||
- [Sam Verschueren](https://github.com/SamVerschueren) | ||
- [Fisker Cheung](https://github.com/fisker) | ||
@@ -182,1 +180,2 @@ | ||
- [Jeroen Engels](https://github.com/jfmengels) | ||
- [Sam Verschueren](https://github.com/SamVerschueren) |
@@ -162,4 +162,8 @@ 'use strict'; | ||
function tryToCoerceVersion(rawVersion) { | ||
let version = rawVersion; | ||
if (!rawVersion) { | ||
return false; | ||
} | ||
let version = String(rawVersion); | ||
// Remove leading things like `^1.0.0`, `>1.0.0` | ||
@@ -316,6 +320,6 @@ const leadingNoises = [ | ||
const packageVersion = tryToCoerceVersion(packageJson.version); | ||
const desidedPackageVersion = tryToCoerceVersion(version); | ||
const decidedPackageVersion = tryToCoerceVersion(version); | ||
const compare = semverComparisonForOperator(condition); | ||
if (compare(packageVersion, desidedPackageVersion)) { | ||
if (packageVersion && compare(packageVersion, decidedPackageVersion)) { | ||
context.report({ | ||
@@ -322,0 +326,0 @@ node: null, |
@@ -337,3 +337,3 @@ 'use strict'; | ||
elementNode && | ||
elementNode.id.type === 'ObjectPattern' | ||
(elementNode.id.type === 'ObjectPattern' || elementNode.id.type === 'ArrayPattern') | ||
) { | ||
@@ -340,0 +340,0 @@ removeDeclaration = arrayReferences.length === 1; |
@@ -8,7 +8,7 @@ 'use strict'; | ||
// Groups: | ||
// 1. Integer part | ||
// 2. Dangling dot or dot with zeroes | ||
// 3. Dot with digits except last zeroes | ||
// 4. Scientific notation | ||
const RE_DANGLINGDOT_OR_ZERO_FRACTIONS = /^([+-]?\d*)(?:(\.0*)|(\.\d*[1-9])0+)(e[+-]?\d+)?$/; // TODO: Possibly use named capture groups when targeting Node.js 10 | ||
// 1. Integer part. | ||
// 2. Dangling dot or dot with zeroes. | ||
// 3. Dot with digits except last zeroes. | ||
// 4. Scientific notation. | ||
const RE_DANGLINGDOT_OR_ZERO_FRACTIONS = /^(?<integerPart>[+-]?\d*)(?:(?<dotAndZeroes>\.0*)|(?<dotAndDigits>\.\d*[1-9])0+)(?<scientificNotationSuffix>e[+-]?\d+)?$/; | ||
@@ -27,3 +27,9 @@ const create = context => { | ||
const [, integerPart, dotAndZeroes, dotAndDigits, scientificNotationSuffix] = match; | ||
const { | ||
integerPart, | ||
dotAndZeroes, | ||
dotAndDigits, | ||
scientificNotationSuffix | ||
} = match.groups; | ||
const isDanglingDot = dotAndZeroes === '.'; | ||
@@ -30,0 +36,0 @@ |
'use strict'; | ||
const getDocumentationUrl = require('./utils/get-documentation-url'); | ||
const fix = value => { | ||
if (!/^0[A-Za-z]/.test(value)) { | ||
return value; | ||
const fix = (value, isBigInt) => { | ||
value = value.toLowerCase(); | ||
if (value.startsWith('0x')) { | ||
value = '0x' + value.slice(2).toUpperCase(); | ||
} | ||
const indicator = value[1].toLowerCase(); | ||
const newValue = value.slice(2).toUpperCase(); | ||
return `0${indicator}${newValue}`; | ||
return `${value}${isBigInt ? 'n' : ''}`; | ||
}; | ||
@@ -18,10 +16,16 @@ | ||
Literal: node => { | ||
const value = node.raw; | ||
const fixedValue = fix(value); | ||
const {value, raw, bigint} = node; | ||
const isBigInt = Boolean(bigint); | ||
if (value !== fixedValue) { | ||
if (typeof value !== 'number' && !isBigInt) { | ||
return; | ||
} | ||
const fixed = fix(isBigInt ? bigint : raw, isBigInt); | ||
if (raw !== fixed) { | ||
context.report({ | ||
node, | ||
message: 'Invalid number literal casing.', | ||
fix: fixer => fixer.replaceText(node, fixedValue) | ||
fix: fixer => fixer.replaceText(node, fixed) | ||
}); | ||
@@ -28,0 +32,0 @@ } |
@@ -61,3 +61,7 @@ 'use strict'; | ||
fixable: 'code' | ||
} | ||
}, | ||
deprecated: true, | ||
replacedBy: [ | ||
'prefer-exponentiation-operator' | ||
] | ||
}; |
'use strict'; | ||
const getDocumentationUrl = require('./utils/get-documentation-url'); | ||
const isValueNotUsable = require('./utils/is-value-not-usable'); | ||
@@ -15,10 +16,2 @@ const getArgumentNameForReplaceChildOrInsertBefore = nodeArguments => { | ||
const isPartOfVariableAssignment = nodeParentType => { | ||
if (nodeParentType === 'VariableDeclarator' || nodeParentType === 'AssignmentExpression') { | ||
return true; | ||
} | ||
return false; | ||
}; | ||
const checkForReplaceChildOrInsertBefore = (context, node) => { | ||
@@ -46,3 +39,3 @@ const identifierName = node.callee.property.name; | ||
const parentNode = node.callee.object.name; | ||
// This check makes sure that only the first method of chained methods with same identifier name e.g: parentNode.insertBefore(alfa, beta).insertBefore(charlie, delta); gets transformed | ||
// This check makes sure that only the first method of chained methods with same identifier name e.g: parentNode.insertBefore(alfa, beta).insertBefore(charlie, delta); gets reported | ||
if (!parentNode) { | ||
@@ -54,14 +47,12 @@ return; | ||
let fix = fixer => fixer.replaceText( | ||
node, | ||
`${oldChildNodeArgument}.${preferredSelector}(${newChildNodeArgument})` | ||
); | ||
const fix = isValueNotUsable(node) ? | ||
// Report error when the method is part of a variable assignment | ||
// but don't offer to autofix `.replaceWith()` and `.before()` | ||
// which don't have a return value. | ||
fixer => fixer.replaceText( | ||
node, | ||
`${oldChildNodeArgument}.${preferredSelector}(${newChildNodeArgument})` | ||
) : | ||
undefined; | ||
// Report error when the method is part of a variable assignment | ||
// but don't offer to autofix `.replaceWith()` and `.before()` | ||
// which don't have a return value. | ||
if (isPartOfVariableAssignment(node.parent.type)) { | ||
fix = undefined; | ||
} | ||
return context.report({ | ||
@@ -118,15 +109,13 @@ node, | ||
let fix = fixer => | ||
fixer.replaceText( | ||
node, | ||
`${referenceNode}.${preferredSelector}(${insertedTextArgument})` | ||
); | ||
const fix = identifierName === 'insertAdjacentElement' && !isValueNotUsable(node) ? | ||
// Report error when the method is part of a variable assignment | ||
// but don't offer to autofix `.insertAdjacentElement()` | ||
// which doesn't have a return value. | ||
undefined : | ||
fixer => | ||
fixer.replaceText( | ||
node, | ||
`${referenceNode}.${preferredSelector}(${insertedTextArgument})` | ||
); | ||
// Report error when the method is part of a variable assignment | ||
// but don't offer to autofix `.insertAdjacentElement()` | ||
// which don't have a return value. | ||
if (identifierName === 'insertAdjacentElement' && isPartOfVariableAssignment(node.parent.type)) { | ||
fix = undefined; | ||
} | ||
return context.report({ | ||
@@ -133,0 +122,0 @@ node, |
'use strict'; | ||
const getDocumentationUrl = require('./utils/get-documentation-url'); | ||
const isValueNotUsable = require('./utils/is-value-not-usable'); | ||
const getMethodName = memberExpression => memberExpression.property.name; | ||
const ignoredParentTypes = [ | ||
'ArrayExpression', | ||
'IfStatement', | ||
'MemberExpression', | ||
'Property', | ||
'ReturnStatement', | ||
'VariableDeclarator' | ||
]; | ||
const ignoredGrandparentTypes = [ | ||
'ExpressionStatement' | ||
]; | ||
const create = context => { | ||
return { | ||
CallExpression(node) { | ||
const { | ||
callee, | ||
parent | ||
} = node; | ||
const {callee} = node; | ||
const { | ||
parent: grandparent | ||
} = (parent || {}); | ||
if (callee.type === 'MemberExpression' && getMethodName(callee) === 'appendChild') { | ||
let fix = fixer => fixer.replaceText(callee.property, 'append'); | ||
const fix = isValueNotUsable(node) ? fixer => fixer.replaceText(callee.property, 'append') : undefined; | ||
if (parent && ignoredParentTypes.includes(parent.type)) { | ||
fix = undefined; | ||
} | ||
if (grandparent && ignoredGrandparentTypes.includes(grandparent.type)) { | ||
fix = undefined; | ||
} | ||
context.report({ | ||
@@ -43,0 +16,0 @@ node, |
'use strict'; | ||
const getDocumentationUrl = require('./utils/get-documentation-url'); | ||
const isValueNotUsable = require('./utils/is-value-not-usable'); | ||
@@ -68,6 +69,8 @@ const getMethodName = callee => { | ||
if (argumentName) { | ||
const fix = isValueNotUsable(node) ? fixer => fixer.replaceText(node, `${argumentName}.remove()`) : undefined; | ||
context.report({ | ||
node, | ||
message: `Prefer \`${argumentName}.remove()\` over \`${callerName}.removeChild(${argumentName})\`.`, | ||
fix: fixer => fixer.replaceText(node, `${argumentName}.remove()`) | ||
fix | ||
}); | ||
@@ -74,0 +77,0 @@ } |
@@ -10,2 +10,10 @@ 'use strict'; | ||
const create = context => { | ||
const {sortCharacterClasses} = context.options[0] || {}; | ||
const blacklist = []; | ||
if (sortCharacterClasses === false) { | ||
blacklist.push('charClassClassrangesMerge'); | ||
} | ||
return { | ||
@@ -24,3 +32,3 @@ 'Literal[regex]': node => { | ||
try { | ||
optimized = optimize(original).toString(); | ||
optimized = optimize(original, undefined, {blacklist}).toString(); | ||
} catch (_) {} | ||
@@ -74,2 +82,12 @@ | ||
const schema = [{ | ||
type: 'object', | ||
properties: { | ||
sortCharacterClasses: { | ||
type: 'boolean', | ||
default: true | ||
} | ||
} | ||
}]; | ||
module.exports = { | ||
@@ -82,4 +100,5 @@ create, | ||
}, | ||
fixable: 'code' | ||
fixable: 'code', | ||
schema | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
181667
63
5683
171
+ Addedsemver@7.6.3(transitive)
Updatedsemver@^7.1.2