Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/empty-singers-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-eslint/eslint-plugin": feat
---

feat: add a new option `{` for alphabetize rule to sort fields `selection set`
2 changes: 1 addition & 1 deletion packages/plugin/src/configs/operations-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export = {
selections: ['OperationDefinition', 'FragmentDefinition'],
variables: true,
arguments: ['Field', 'Directive'],
groups: ['...', 'id', '*', 'createdAt', 'updatedAt'],
groups: ['...', 'id', '*', '{'],
},
],
'@graphql-eslint/lone-executable-definition': 'error',
Expand Down
52 changes: 52 additions & 0 deletions packages/plugin/src/rules/alphabetize/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,57 @@ ruleTester.run<RuleOptions>('alphabetize', rule, {
`,
errors: 4,
},
{
name: 'should sort selection set at the end',
options: [
{
selections: ['OperationDefinition'],
groups: ['id', '*', 'updatedAt', '{'],
},
],
code: /* GraphQL */ `
{
zz
updatedAt
createdAt {
__typename
}
aa
user {
id
}
aab {
id
}
}
`,
errors: 2,
},
{
name: 'should sort selection set at the start',
options: [
{
selections: ['OperationDefinition'],
groups: ['{', 'id', '*', 'updatedAt'],
},
],
code: /* GraphQL */ `
{
zz
updatedAt
createdAt {
__typename
}
aa
user {
id
}
aab {
id
}
}
`,
errors: 3,
},
],
});
22 changes: 11 additions & 11 deletions packages/plugin/src/rules/alphabetize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,13 @@ const schema = {
groups: {
...ARRAY_DEFAULT_OPTIONS,
minItems: 2,
description:
"Custom order group. Example: `['id', '*', 'createdAt', 'updatedAt', '...']` where `...` stands for fragment spreads, and `*` stands for everything else.",
description: [
"Order group. Example: `['...', 'id', '*', '{']` where:",
'- `...` stands for fragment spreads',
'- `id` stands for field with name `id`',
'- `*` stands for everything else',
'- `{` stands for fields `selection set`',
].join('\n'),
},
},
},
Expand Down Expand Up @@ -203,7 +208,7 @@ export const rule: GraphQLESLintRule<RuleOptions> = {
selections: selectionsEnum,
variables: true,
arguments: [Kind.FIELD, Kind.DIRECTIVE],
groups: ['...', 'id', '*', 'createdAt', 'updatedAt'],
groups: ['...', 'id', '*', '{'],
},
],
},
Expand Down Expand Up @@ -417,16 +422,11 @@ function getIndex({
}): number {
// Try an exact match
let index = groups.indexOf(getName(node));

if (index === -1 && 'selectionSet' in node && node.selectionSet) index = groups.indexOf('{');
// Check for the fragment spread group
if (index === -1 && node.kind === Kind.FRAGMENT_SPREAD) {
index = groups.indexOf('...');
}

if (index === -1 && node.kind === Kind.FRAGMENT_SPREAD) index = groups.indexOf('...');
// Check for the catch-all group
if (index === -1) {
index = groups.indexOf('*');
}
if (index === -1) index = groups.indexOf('*');
return index;
}

Expand Down
135 changes: 135 additions & 0 deletions packages/plugin/src/rules/alphabetize/snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,141 @@ exports[`alphabetize > invalid > should sort definitions 1`] = `
59 | # END
`;

exports[`alphabetize > invalid > should sort selection set at the end 1`] = `
#### ⌨️ Code

1 | {
2 | zz
3 | updatedAt
4 | createdAt {
5 | __typename
6 | }
7 | aa
8 | user {
9 | id
10 | }
11 | aab {
12 | id
13 | }
14 | }

#### ⚙️ Options

{
"selections": [
"OperationDefinition"
],
"groups": [
"id",
"*",
"updatedAt",
"{"
]
}

#### ❌ Error 1/2

6 | }
> 7 | aa
| ^^ field "aa" should be before field "createdAt"
8 | user {

#### ❌ Error 2/2

10 | }
> 11 | aab {
| ^^^ field "aab" should be before field "user"
12 | id

#### 🔧 Autofix output

1 | {
2 | aa
3 | zz
4 | updatedAt
5 | aab {
6 | id
7 | }
8 | createdAt {
9 | __typename
10 | }
11 | user {
12 | id
13 | }
14 | }
`;

exports[`alphabetize > invalid > should sort selection set at the start 1`] = `
#### ⌨️ Code

1 | {
2 | zz
3 | updatedAt
4 | createdAt {
5 | __typename
6 | }
7 | aa
8 | user {
9 | id
10 | }
11 | aab {
12 | id
13 | }
14 | }

#### ⚙️ Options

{
"selections": [
"OperationDefinition"
],
"groups": [
"{",
"id",
"*",
"updatedAt"
]
}

#### ❌ Error 1/3

3 | updatedAt
> 4 | createdAt {
| ^^^^^^^^^ field "createdAt" should be before field "updatedAt"
5 | __typename

#### ❌ Error 2/3

7 | aa
> 8 | user {
| ^^^^ field "user" should be before field "aa"
9 | id

#### ❌ Error 3/3

10 | }
> 11 | aab {
| ^^^ field "aab" should be before field "user"
12 | id

#### 🔧 Autofix output

1 | {
2 | aab {
3 | id
4 | }
5 | createdAt {
6 | __typename
7 | }
8 | user {
9 | id
10 | }
11 | aa
12 | zz
13 | updatedAt
14 | }
`;

exports[`alphabetize > invalid > should sort selections by group when \`*\` is between 1`] = `
#### ⌨️ Code

Expand Down
8 changes: 6 additions & 2 deletions website/src/pages/rules/alphabetize.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,12 @@ Definitions – `type`, `interface`, `enum`, `scalar`, `input`, `union` and `dir

### `groups` (array)

Custom order group. Example: `['id', '*', 'createdAt', 'updatedAt', '...']` where `...` stands for
fragment spreads, and `*` stands for everything else.
Custom order group. Example: `['...', 'id', '*', '{']` where:

- `...` stands for fragment spreads
- `id` stands for field with name `id`
- `*` stands for everything else
- `{` stands for field `selection set`

The object is an array with all elements of the type `string`.

Expand Down