Skip to content

Commit

Permalink
add sortSpreads option (#7)
Browse files Browse the repository at this point in the history
* add sortSpreads option

* 0.3.0
  • Loading branch information
jay-es committed Jul 19, 2022
1 parent 6649aa2 commit 2ae6bc6
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 9 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export default defineComponent({
components: { Foo, Bar, Baz },
});

// spreads must be grouped at the top
export default defineComponent({
components: { Bar, Baz, Foo, ...others },
});

// not only in Vue-specific context
const myObject = {
components: { Foo, Bar, Baz },
Expand All @@ -76,8 +81,43 @@ export default defineComponent({
components: { Bar, Baz, Foo },
});

// spreads must be grouped at the top
export default defineComponent({
components: { ...others, Bar, Baz, Foo },
});

// not only in Vue-specific context
const myObject = {
components: { Bar, Baz, Foo },
};
```

### Options

This rule accepts a configuration object:

```js
{
"@jay-es/vue-sort-components/vue-sort-components": ["error", { sortSpreads: false }]
}
```

- `sortSpreads` - if `true`, enforce spread properties to be sorted. Default is `false`.

#### sortSpreads

Examples of **incorrect** code for the `{ sortSpreads: true }` option:

```js
export default defineComponent({
components: { ...others2, ...others1, Bar, Baz },
});
```

Examples of **correct** code for the `{ sortSpreads: true }` option:

```js
export default defineComponent({
components: { ...others1, ...others2, Bar, Baz },
});
```
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jay-es/eslint-plugin-vue-sort-components",
"version": "0.2.0",
"version": "0.3.0",
"description": "A plugin for ESLint to keep order of component names",
"main": "lib/index.js",
"files": [
Expand Down
22 changes: 19 additions & 3 deletions src/rules/vue-sort-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ const getArgName = (arg: Expression): string =>

const compareNodes = (
a: Property | SpreadElement,
b: Property | SpreadElement
b: Property | SpreadElement,
sortSpreads: boolean
): -1 | 0 | 1 => {
if (a.type === "Property" && b.type === "Property") {
return naturalCompare(getKeyName(a), getKeyName(b));
}

if (a.type === "SpreadElement" && b.type === "SpreadElement") {
return naturalCompare(getArgName(a.argument), getArgName(b.argument));
return sortSpreads
? naturalCompare(getArgName(a.argument), getArgName(b.argument))
: 0;
}

return a.type === "SpreadElement" ? -1 : 1;
Expand All @@ -27,11 +30,22 @@ export const sortComponentsRule: Rule.RuleModule = {
meta: {
type: "layout",
fixable: "code",
schema: [
{
type: "object",
properties: {
sortSpreads: { type: "boolean" },
},
additionalProperties: false,
},
],
messages: {
sortComponents: "Component names must be sorted.",
},
},
create(context) {
const sortSpreads: boolean = context.options[0]?.sortSpreads ?? false;

return {
Property(node) {
const { value } = node;
Expand All @@ -43,7 +57,9 @@ export const sortComponentsRule: Rule.RuleModule = {
}

const { properties } = value;
const sorted = [...properties].sort(compareNodes);
const sorted = [...properties].sort((a, b) =>
compareNodes(a, b, sortSpreads)
);
const sameOrder = properties.every((v, i) => v === sorted[i]);

if (sameOrder) {
Expand Down
36 changes: 33 additions & 3 deletions tests/rules/vue-sort-components.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,20 @@ ruleTester.run("vue-sort-components", sortComponentsRule, {
code: "const obj = { components: { ...others, bar, baz, foo } }",
parserOptions: { ecmaVersion: 2018 },
},
// not components

// options.sortSpreads
{
code: "const obj = { components: { ...others2, ...others1, bar, baz, foo } }",
parserOptions: { ecmaVersion: 2018 },
},
{
options: [{ sortSpreads: true }],
code: "const obj = { components: { ...others1, ...others2, bar, baz, foo } }",
parserOptions: { ecmaVersion: 2018 },
},

// not applied
// non-component
{
code: "const obj = { nested: { foo, bar } }",
parserOptions: { ecmaVersion: 6 },
Expand Down Expand Up @@ -65,8 +78,25 @@ ruleTester.run("vue-sort-components", sortComponentsRule, {
},
// spread
{
code: "const obj = { components: { bar, ...others, foo, ...others2 } }",
output: "const obj = { components: { ...others, ...others2, bar, foo } }",
code: "const obj = { components: { bar, ...others, foo } }",
output: "const obj = { components: { ...others, bar, foo } }",
parserOptions: { ecmaVersion: 2018 },
errors: [{ messageId: "sortComponents" }],
},

// options.sortSpreads
{
code: "const obj = { components: { bar, ...others2, foo, ...others1 } }",
output:
"const obj = { components: { ...others2, ...others1, bar, foo } }",
parserOptions: { ecmaVersion: 2018 },
errors: [{ messageId: "sortComponents" }],
},
{
options: [{ sortSpreads: true }],
code: "const obj = { components: { bar, ...others2, foo, ...others1 } }",
output:
"const obj = { components: { ...others1, ...others2, bar, foo } }",
parserOptions: { ecmaVersion: 2018 },
errors: [{ messageId: "sortComponents" }],
},
Expand Down

0 comments on commit 2ae6bc6

Please sign in to comment.