eslint-plugin-sort
Advanced tools
Comparing version 1.5.0 to 2.0.0
"use strict"; | ||
var _sortImports = _interopRequireDefault(require("./rules/sort-imports")); | ||
var _imports = _interopRequireDefault(require("./rules/imports")); | ||
var _sortImportSpecifiers = _interopRequireDefault(require("./rules/sort-import-specifiers")); | ||
var _importMembers = _interopRequireDefault(require("./rules/import-members")); | ||
var _sortObjectPatterns = _interopRequireDefault(require("./rules/sort-object-patterns")); | ||
var _destructuringProperties = _interopRequireDefault(require("./rules/destructuring-properties")); | ||
var _sortObjectProperties = _interopRequireDefault(require("./rules/sort-object-properties")); | ||
var _objectProperties = _interopRequireDefault(require("./rules/object-properties")); | ||
@@ -18,4 +18,4 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
rules: { | ||
"sort/destructured-properties": "warn", | ||
"sort/imported-variables": "warn", | ||
"sort/destructuring-properties": "warn", | ||
"sort/import-members": "warn", | ||
"sort/imports": ["warn", { | ||
@@ -34,4 +34,3 @@ groups: [{ | ||
order: 3 | ||
}], | ||
separator: "" | ||
}] | ||
}], | ||
@@ -43,7 +42,7 @@ "sort/object-properties": "warn" | ||
rules: { | ||
"destructured-properties": _sortObjectPatterns.default, | ||
"imported-variables": _sortImportSpecifiers.default, | ||
imports: _sortImports.default, | ||
"object-properties": _sortObjectProperties.default | ||
"destructuring-properties": _destructuringProperties.default, | ||
"import-members": _importMembers.default, | ||
"imports": _imports.default, | ||
"object-properties": _objectProperties.default | ||
} | ||
}; |
109
lib/utils.js
@@ -6,47 +6,34 @@ "use strict"; | ||
}); | ||
exports.getSorter = getSorter; | ||
exports.getTextWithComments = getTextWithComments; | ||
exports.getNodeGroupRange = getNodeGroupRange; | ||
exports.getSortValue = getSortValue; | ||
exports.isUnsorted = exports.getTextBetweenNodes = exports.getTextRange = void 0; | ||
exports.alphaSorter = alphaSorter; | ||
exports.enumerate = enumerate; | ||
exports.filterNodes = void 0; | ||
exports.getName = getName; | ||
exports.getNodeRange = getNodeRange; | ||
exports.getNodeText = getNodeText; | ||
exports.getTextRange = void 0; | ||
exports.isUnsorted = isUnsorted; | ||
function getSorter(sortFn) { | ||
return (a, b) => { | ||
const aText = sortFn(a); | ||
const bText = sortFn(b); | ||
if (aText === Infinity) return 1; | ||
if (aText === -Infinity) return -1; | ||
if (aText > bText) return 1; | ||
if (aText < bText) return -1; | ||
return 0; | ||
}; | ||
/** | ||
* Returns true if any node in the source array is different from the same | ||
* positioned node in the sorted array. | ||
*/ | ||
function isUnsorted(nodes, sorted) { | ||
return nodes.some((node, i) => node !== sorted[i]); | ||
} | ||
/** | ||
* Enumerates two node arrays and returns only the pairs where | ||
* the nodes are not equal. | ||
*/ | ||
const getTextRange = (left, right) => [left.range[0], right.range[1]]; | ||
exports.getTextRange = getTextRange; | ||
function getTextWithComments(source, node) { | ||
return source.getText().slice(...getTextRange(source.getCommentsBefore(node)[0] || node, node)); | ||
function enumerate(a, b) { | ||
return a.map((val, index) => [val, b[index]]).filter(x => x[0] !== x[1]); | ||
} | ||
/** | ||
* Get's the string name of a node used for sorting or errors. | ||
*/ | ||
const getTextBetweenNodes = (source, left, right) => { | ||
const nextComments = right ? source.getCommentsBefore(right) : []; | ||
const nextNodeStart = nextComments[0] || right; | ||
const text = source.getText().slice(left.range[1], nextNodeStart ? nextNodeStart.range[0] : left.range[1]); | ||
return text; | ||
}; | ||
exports.getTextBetweenNodes = getTextBetweenNodes; | ||
function getNodeGroupRange(source, nodes) { | ||
return getTextRange(source.getCommentsBefore(nodes[0])[0] || nodes[0], nodes[nodes.length - 1]); | ||
} | ||
function getSortValue(node) { | ||
if (!node) { | ||
return ""; | ||
} | ||
switch (node.type) { | ||
function getName(node) { | ||
switch (node?.type) { | ||
case "Identifier": | ||
@@ -57,5 +44,6 @@ return node.name; | ||
return node.value.toString(); | ||
// `a${b}c${d}` becomes `abcd` | ||
case "TemplateLiteral": | ||
return node.quasis.reduce((acc, quasi, index) => acc + quasi.value.raw + getSortValue(node.expressions[index]), ""); | ||
return node.quasis.reduce((acc, quasi, i) => acc + quasi.value.raw + getName(node.expressions[i]), ""); | ||
} | ||
@@ -65,5 +53,44 @@ | ||
} | ||
/** | ||
* Filters an array of nodes to only include those matching the provided type. | ||
* @param nodes - The array of nodes to filter | ||
* @param type - Only nodes matching this `type` will be returned | ||
*/ | ||
const isUnsorted = (a, b) => getSortValue(a).toLowerCase() > getSortValue(b).toLowerCase(); | ||
exports.isUnsorted = isUnsorted; | ||
const filterNodes = (nodes, type) => nodes.filter(node => node.type === type); | ||
/** | ||
* Function that returns a simple alphanumeric sort function. The return value | ||
* of this function should be passed to `Array.prototype.sort()`. | ||
*/ | ||
exports.filterNodes = filterNodes; | ||
function alphaSorter(sortFn) { | ||
return (a, b) => sortFn(a).localeCompare(sortFn(b)); | ||
} | ||
/** | ||
* Returns an AST range between two nodes. | ||
*/ | ||
const getTextRange = (left, right) => [left.range[0], right.range[1]]; | ||
/** | ||
* Returns an AST range for a node and it's preceding comments. | ||
*/ | ||
exports.getTextRange = getTextRange; | ||
function getNodeRange(source, node, includeComments = true) { | ||
return getTextRange(includeComments && source.getCommentsBefore(node)[0] || node, node); | ||
} | ||
/** | ||
* Returns a node's text with it's preceding comments. | ||
*/ | ||
function getNodeText(source, node, includeComments = true) { | ||
return source.getText().slice(...getNodeRange(source, node, includeComments)); | ||
} |
{ | ||
"name": "eslint-plugin-sort", | ||
"description": "Autofixable sort rules for ESLint.", | ||
"version": "1.5.0", | ||
"description": "Auto-fixable sort rules for ESLint.", | ||
"version": "2.0.0", | ||
"author": "Mark Skelton", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mskelton/eslint-plugin-sort.git" | ||
}, | ||
"packageManager": "yarn@3.1.1", | ||
"repository": "github:mskelton/eslint-plugin-sort", | ||
"homepage": "https://github.com/mskelton/eslint-plugin-sort#readme", | ||
"bugs": { | ||
"url": "https://github.com/mskelton/eslint-plugin-sort/issues" | ||
}, | ||
"homepage": "https://github.com/mskelton/eslint-plugin-sort#readme", | ||
"license": "MIT", | ||
"license": "ISC", | ||
"keywords": [ | ||
@@ -29,3 +27,4 @@ "eslint", | ||
"lint": "eslint . --ext .ts", | ||
"test": "jest" | ||
"test": "jest", | ||
"ts": "tsc" | ||
}, | ||
@@ -36,19 +35,20 @@ "peerDependencies": { | ||
"devDependencies": { | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.9.0", | ||
"@babel/preset-env": "^7.9.5", | ||
"@babel/preset-typescript": "^7.9.0", | ||
"@mskelton/tsconfig": "^1.0.2", | ||
"@types/eslint": "^6.8.0", | ||
"@types/jest": "^25.2.1", | ||
"@types/node": "^13.13.2", | ||
"@typescript-eslint/eslint-plugin": "^2.29.0", | ||
"@typescript-eslint/parser": "^2.29.0", | ||
"babel-jest": "^25.4.0", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"jest": "^25.4.0", | ||
"prettier": "^2.0.5", | ||
"typescript": "^3.8.3" | ||
"@babel/cli": "^7.16.7", | ||
"@babel/core": "^7.16.7", | ||
"@babel/preset-env": "^7.16.7", | ||
"@babel/preset-typescript": "^7.16.7", | ||
"@mskelton/tsconfig": "^1.1.1", | ||
"@types/eslint": "^8.2.2", | ||
"@types/jest": "^27.4.0", | ||
"@types/node": "^17.0.8", | ||
"@typescript-eslint/eslint-plugin": "^5.9.0", | ||
"@typescript-eslint/parser": "^5.9.0", | ||
"babel-jest": "^27.4.6", | ||
"eslint": "^8.6.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"jest": "^27.4.7", | ||
"prettier": "^2.5.1", | ||
"semantic-release": "^18.0.1", | ||
"typescript": "^4.5.4" | ||
} | ||
} |
101
README.md
@@ -6,13 +6,16 @@ # eslint-plugin-sort | ||
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg)](#contributors) | ||
> Autofixable sort rules for ESLint. | ||
Auto-fixable sort rules for ESLint. | ||
## Installation | ||
### npm | ||
```sh | ||
# npm | ||
npm install -D eslint-plugin-sort | ||
``` | ||
# Yarn | ||
### Yarn | ||
```sh | ||
yarn add -D eslint-plugin-sort | ||
@@ -23,7 +26,8 @@ ``` | ||
After installing, add `sort` to your list of ESLint plugins and extend the recommended configuration. This will enable all available rules as warnings. | ||
After installing, add `sort` to your list of ESLint plugins and extend the | ||
recommended configuration. This will enable all available rules as warnings. | ||
```json | ||
{ | ||
"extends": ["plugin:sort/recommended"], | ||
"extends": "plugin:sort/recommended", | ||
"plugins": ["sort"] | ||
@@ -35,3 +39,4 @@ } | ||
While the recommended configuration is the simplest way to use this plugin, you can also configure the rules manually based on your needs. | ||
While the recommended configuration is the simplest way to use this plugin, you | ||
can also configure the rules manually based on your needs. | ||
@@ -58,5 +63,6 @@ ### `sort/object-properties` 🔧 | ||
### `sort/destructured-properties` 🔧 | ||
### `sort/destructuring-properties` 🔧 | ||
Sorts properties in object destructuring patterns alphabetically and case insensitive in ascending order. | ||
Sorts properties in object destructuring patterns alphabetically and case | ||
insensitive in ascending order. | ||
@@ -79,5 +85,5 @@ Examples of **incorrect** code for this rule. | ||
### `sort/imported-variables` 🔧 | ||
### `sort/import-members` 🔧 | ||
Sorts imported variable names alphabetically and case insensitive in ascending order. | ||
Sorts import members alphabetically and case insensitive in ascending order. | ||
@@ -122,3 +128,6 @@ Examples of **incorrect** code for this rule. | ||
While the previous examples for this rule show very basic import sorting, this rule has a very powerful mechanism for sorting imports into groups. This allows you to separate common groups of imports to make it easier to scan your imports at a glance. | ||
While the previous examples for this rule show very basic import sorting, this | ||
rule has a very powerful mechanism for sorting imports into groups. This allows | ||
you to separate common groups of imports to make it easier to scan your imports | ||
at a glance. | ||
@@ -131,7 +140,10 @@ There are three built-in sort groups you can use: | ||
- Imports which do not throw an error when calling `require.resolve`. | ||
- Useful for differentiating between path aliases (e.g. `components/Hello`) and dependencies (e.g. `react`) | ||
- Useful for differentiating between path aliases (e.g. `components/Hello`) | ||
and dependencies (e.g. `react`) | ||
1. `other` | ||
- Catch all sort group for any imports which did not match other sort groups. | ||
You can also define custom regex sort groups if the built-in sort groups aren't enough. The following configuration shows an example of using the built-in sort groups as well as a custom regex sort group. | ||
You can also define custom regex sort groups if the built-in sort groups aren't | ||
enough. The following configuration shows an example of using the built-in sort | ||
groups as well as a custom regex sort group. | ||
@@ -158,10 +170,7 @@ ```json | ||
import "index.css" | ||
import React from "react" | ||
import { createStore } from "redux" | ||
import c from "c" | ||
import a from "../a" | ||
import b from "./b" | ||
import c from "c" | ||
import image1 from "my-library/static/image.svg" | ||
@@ -174,44 +183,18 @@ import image2 from "static/image.jpg" | ||
It's important to understand the difference between the order of the sort groups in the `groups` array, and the `order` property of each sort group. When sorting imports, this plugin will find the first sort group which the import would apply to and then assign it an order using the `order` property. This allows you to define a hierarchy of sort groups in descending specificity (e.g. side effect then regex) while still having full control over the order of the sort groups in the resulting code. | ||
It's important to understand the difference between the order of the sort groups | ||
in the `groups` array, and the `order` property of each sort group. When sorting | ||
imports, this plugin will find the first sort group which the import would apply | ||
to and then assign it an order using the `order` property. This allows you to | ||
define a hierarchy of sort groups in descending specificity (e.g. side effect | ||
then regex) while still having full control over the order of the sort groups in | ||
the resulting code. | ||
For example, the `other` sort group will match any import and thus should always be last in the list of sort groups. However, if you want to sort static asset imports (e.g. `.png` or `.jpg`) after the `other` sort group, you can use the `order` property to give the static assets a higher order than the `other` sort group. | ||
For example, the `other` sort group will match any import and thus should always | ||
be last in the list of sort groups. However, if you want to sort static asset | ||
imports (e.g. `.png` or `.jpg`) after the `other` sort group, you can use the | ||
`order` property to give the static assets a higher order than the `other` sort | ||
group. | ||
The configuration example above shows how this works where the static asset imports are the second sort group even though they have the highest order and are thus the last sort group in the resulting code. | ||
#### Custom Separator | ||
If you are using sort groups, you have the option to provide a custom separator between sort groups. For example, the following configuration would separate groups by newlines. | ||
```json | ||
{ | ||
"sort/imports": [ | ||
"warn", | ||
{ | ||
"groups": [ | ||
// ... | ||
], | ||
"separator": "\n" | ||
} | ||
] | ||
} | ||
``` | ||
## Contributors ✨ | ||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<!-- prettier-ignore-start --> | ||
<!-- markdownlint-disable --> | ||
<table> | ||
<tr> | ||
<td align="center"><a href="https://github.com/mskelton"><img src="https://avatars3.githubusercontent.com/u/25914066?v=4" width="100px;" alt="Mark Skelton"/><br /><sub><b>Mark Skelton</b></sub></a><br /><a href="https://github.com/mskelton/eslint-plugin-sort/commits?author=mskelton" title="Code">💻</a> <a href="https://github.com/mskelton/eslint-plugin-sort/commits?author=mskelton" title="Documentation">📖</a></td> | ||
</tr> | ||
</table> | ||
<!-- markdownlint-enable --> | ||
<!-- prettier-ignore-end --> | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! | ||
The configuration example above shows how this works where the static asset | ||
imports are the second sort group even though they have the highest order and | ||
are thus the last sort group in the resulting code. |
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
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
18463
17
11
355
192
2
1