Socket
Socket
Sign inDemoInstall

eslint-plugin-unicorn

Package Overview
Dependencies
Maintainers
1
Versions
106
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-unicorn - npm Package Compare versions

Comparing version 11.0.2 to 12.0.0

rules/prefer-string-slice.js

1

index.js

@@ -58,2 +58,3 @@ 'use strict';

'unicorn/prefer-starts-ends-with': 'error',
'unicorn/prefer-string-slice': 'error',
'unicorn/prefer-text-content': 'error',

@@ -60,0 +61,0 @@ 'unicorn/prefer-type-error': 'error',

5

package.json
{
"name": "eslint-plugin-unicorn",
"version": "11.0.2",
"version": "12.0.0",
"description": "Various awesome ESLint rules",

@@ -37,2 +37,3 @@ "license": "MIT",

"eslint-ast-utils": "^1.1.0",
"eslint-template-visitor": "^1.0.0",
"import-modules": "^1.1.0",

@@ -45,4 +46,4 @@ "lodash.camelcase": "^4.3.0",

"lodash.upperfirst": "^4.3.1",
"read-pkg-up": "^6.0.0",
"regexpp": "^3.0.0",
"read-pkg": "^5.2.0",
"reserved-words": "^0.1.2",

@@ -49,0 +50,0 @@ "safe-regex": "^2.0.2",

@@ -76,2 +76,3 @@ # 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)

"unicorn/prefer-starts-ends-with": "error",
"unicorn/prefer-string-slice": "error",
"unicorn/prefer-text-content": "error",

@@ -127,2 +128,3 @@ "unicorn/prefer-type-error": "error",

- [prefer-starts-ends-with](docs/rules/prefer-starts-ends-with.md) - Prefer `String#startsWith()` & `String#endsWith()` over more complex alternatives.
- [prefer-string-slice](docs/rules/prefer-string-slice.md) - Prefer `String#slice()` over `String#substr()` and `String#substring()`. *(partly fixable)*
- [prefer-text-content](docs/rules/prefer-text-content.md) - Prefer `.textContent` over `.innerText`. *(fixable)*

@@ -161,2 +163,3 @@ - [prefer-type-error](docs/rules/prefer-type-error.md) - Enforce throwing `TypeError` in type checking conditions. *(fixable)*

- [Sam Verschueren](https://github.com/SamVerschueren)
- [Fisker Cheung](https://github.com/fisker)

@@ -163,0 +166,0 @@ ###### Former

'use strict';
const readPkg = require('read-pkg');
const readPkgUp = require('read-pkg-up');
const semver = require('semver');

@@ -20,3 +20,3 @@ const ci = require('ci-info');

const pkg = readPkg.sync();
const pkg = readPkgUp.sync().package;

@@ -293,3 +293,2 @@ const pkgDependencies = {

const compare = semverComparisonForOperator(condition);
if (compare(pkgVersion, desidedPkgVersion)) {

@@ -296,0 +295,0 @@ context.report({

@@ -8,2 +8,3 @@ 'use strict';

const getDocsUrl = require('./utils/get-docs-url');
const cartesianProductSamples = require('./utils/cartesian-product-samples');

@@ -14,2 +15,3 @@ const pascalCase = string => upperfirst(camelCase(string));

const PLACEHOLDER_REGEX = new RegExp(PLACEHOLDER, 'i');
const isIgnoredChar = char => !/^[a-z\d-_$]$/i.test(char);

@@ -79,15 +81,46 @@ function ignoreNumbers(fn) {

function fixFilename(chosenCase, filename) {
return filename
.split('.')
.map(ignoreNumbers(cases[chosenCase].fn))
.join('.');
function validateFilename(words, caseFunctions) {
return words
.filter(({ignored}) => !ignored)
.every(({word}) => caseFunctions.some(fn => fn(word) === word));
}
function fixFilename(words, caseFunctions, {leading, extension}) {
const replacements = words
.map(({word, ignored}) => ignored ? [word] : caseFunctions.map(fn => fn(word)));
const {
samples: combinations
} = cartesianProductSamples(replacements);
return combinations.map(parts => `${leading}${parts.join('')}${extension}`);
}
const leadingUnserscoresRegex = /^(_+)(.*)$/;
function splitFilename(filename) {
const res = leadingUnserscoresRegex.exec(filename);
const leading = (res && res[1]) || '';
const tailing = (res && res[2]) || filename;
const words = [];
let lastWord;
for (const char of tailing) {
const isIgnored = isIgnoredChar(char);
if (lastWord && lastWord.ignored === isIgnored) {
lastWord.word += char;
} else {
lastWord = {
word: char,
ignored: isIgnored
};
words.push(lastWord);
}
}
return {
leading: (res && res[1]) || '',
trailing: (res && res[2]) || filename
leading,
words
};

@@ -118,2 +151,3 @@ }

const chosenCases = getChosenCases(context);
const chosenCasesFunctions = chosenCases.map(case_ => ignoreNumbers(cases[case_].fn));
const filenameWithExtension = context.getFilename();

@@ -134,16 +168,25 @@

const splitName = splitFilename(filename);
const fixedFilenames = chosenCases.map(case_ => fixFilename(case_, splitName.trailing));
const renamedFilenames = fixedFilenames.map(x => splitName.leading + x + extension);
const {
leading,
words
} = splitFilename(filename);
const isValid = validateFilename(words, chosenCasesFunctions);
if (!fixedFilenames.includes(splitName.trailing)) {
context.report({
node,
messageId: chosenCases.length > 1 ? 'renameToCases' : 'renameToCase',
data: {
chosenCases: englishishJoinWords(chosenCases.map(x => cases[x].name)),
renamedFilenames: englishishJoinWords(renamedFilenames.map(x => `\`${x}\``))
}
});
if (isValid) {
return;
}
const renamedFilenames = fixFilename(words, chosenCasesFunctions, {
leading,
extension
});
context.report({
node,
messageId: chosenCases.length > 1 ? 'renameToCases' : 'renameToCase',
data: {
chosenCases: englishishJoinWords(chosenCases.map(x => cases[x].name)),
renamedFilenames: englishishJoinWords(renamedFilenames.map(x => `\`${x}\``))
}
});
}

@@ -150,0 +193,0 @@ };

@@ -13,2 +13,6 @@ 'use strict';

// Only report if it's outside an worker thread context. See #328.
let requiredWorkerThreadsModule = false;
const reports = [];
return {

@@ -18,2 +22,17 @@ CallExpression: node => {

if (callee.type === 'Identifier' && callee.name === 'require') {
const args = node.arguments;
if (args.length === 0) {
return;
}
const [argument] = args;
if (argument.type === 'Literal' && argument.value === 'worker_threads') {
requiredWorkerThreadsModule = true;
return;
}
}
if (callee.type === 'MemberExpression' && callee.object.name === 'process') {

@@ -26,6 +45,9 @@ if (callee.property.name === 'on' || callee.property.name === 'once') {

if (callee.property.name === 'exit' && !processEventHandler) {
context.report({
node,
message: 'Only use `process.exit()` in CLI apps. Throw an error instead.'
});
reports.push(
() =>
context.report({
node,
message: 'Only use `process.exit()` in CLI apps. Throw an error instead.'
})
);
}

@@ -38,2 +60,18 @@ }

}
},
ImportDeclaration: node => {
const {source} = node;
if (source.type === 'Literal' && source.value === 'worker_threads') {
requiredWorkerThreadsModule = true;
}
},
'Program:exit': () => {
if (!requiredWorkerThreadsModule) {
for (const report of reports) {
report();
}
}
}

@@ -40,0 +78,0 @@ };

@@ -9,2 +9,3 @@ 'use strict';

const avoidCapture = require('./utils/avoid-capture');
const cartesianProductSamples = require('./utils/cartesian-product-samples');

@@ -237,3 +238,8 @@ const isUpperCase = string => string === string.toUpperCase();

const getWordReplacements = (word, replacements) => {
const getWordReplacements = (word, {replacements, whitelist}) => {
// Skip constants and whitelist
if (isUpperCase(word) || whitelist.get(word)) {
return [];
}
const replacement = replacements.get(lowerFirst(word)) ||

@@ -253,23 +259,5 @@ replacements.get(word) ||

const getReplacementsFromCombinations = (combinations, length = Infinity) => {
const total = combinations.reduce((total, {length}) => total * length, 1);
const getNameReplacements = (name, options, limit = 3) => {
const {whitelist} = options;
const samples = Array.from({length: Math.min(total, length)}, (_, sampleIndex) => {
let indexLeft = sampleIndex;
return combinations.reduceRight((words, replacements) => {
const {length} = replacements;
const replacementIndex = indexLeft % length;
indexLeft -= replacementIndex;
indexLeft /= length;
return [replacements[replacementIndex], ...words];
}, []).join('');
});
return {
total,
samples
};
};
const getNameReplacements = (name, {replacements, whitelist}, limit = 3) => {
// Skip constants and whitelist

@@ -281,3 +269,3 @@ if (isUpperCase(name) || whitelist.get(name)) {

// Find exact replacements
const exactReplacements = getWordReplacements(name, replacements);
const exactReplacements = getWordReplacements(name, options);

@@ -296,3 +284,3 @@ if (exactReplacements.length > 0) {

const combinations = words.map(word => {
const wordReplacements = getWordReplacements(word, replacements);
const wordReplacements = getWordReplacements(word, options);

@@ -312,3 +300,11 @@ if (wordReplacements.length > 0) {

return getReplacementsFromCombinations(combinations, limit);
const {
total,
samples
} = cartesianProductSamples(combinations, limit);
return {
total,
samples: samples.map(words => words.join(''))
};
};

@@ -315,0 +311,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