Skip to content

Commit 922c057

Browse files
authored
fix relay-page-info (#1012)
1 parent cf687a5 commit 922c057

File tree

4 files changed

+30
-35
lines changed

4 files changed

+30
-35
lines changed

docs/rules/relay-page-info.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Set of rules to follow Relay specification for `PageInfo` object.
99

1010
- `PageInfo` must be an Object type
1111
- `PageInfo` must contain fields `hasPreviousPage` and `hasNextPage`, that return non-null Boolean
12-
- `PageInfo` must contain fields `startCursor` and `endCursor`, that return either String, Scalar, or a non-null wrapper around one of those types
12+
- `PageInfo` must contain fields `startCursor` and `endCursor`, that return either String or Scalar, which can be null if there are no results
1313

1414
## Usage Examples
1515

packages/plugin/src/rules/relay-page-info.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const rule: GraphQLESLintRule = {
2121
'',
2222
'- `PageInfo` must be an Object type',
2323
'- `PageInfo` must contain fields `hasPreviousPage` and `hasNextPage`, that return non-null Boolean',
24-
'- `PageInfo` must contain fields `startCursor` and `endCursor`, that return either String, Scalar, or a non-null wrapper around one of those types',
24+
'- `PageInfo` must contain fields `startCursor` and `endCursor`, that return either String or Scalar, which can be null if there are no results',
2525
].join('\n'),
2626
url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
2727
examples: [
@@ -70,30 +70,25 @@ const rule: GraphQLESLintRule = {
7070
typeName: 'Boolean' | 'String'
7171
): void => {
7272
const field = fieldMap[fieldName];
73-
const isStringType = typeName === 'String';
74-
7573
let isAllowedType = false;
74+
7675
if (field) {
77-
let type = field.gqlType;
76+
const type = field.gqlType;
7877
if (typeName === 'Boolean') {
7978
isAllowedType =
8079
type.kind === Kind.NON_NULL_TYPE &&
8180
type.gqlType.kind === Kind.NAMED_TYPE &&
8281
type.gqlType.name.value === 'Boolean';
83-
} else {
84-
if (type.kind === Kind.NON_NULL_TYPE) {
85-
type = type.gqlType;
86-
}
87-
if (type.kind === Kind.NAMED_TYPE) {
88-
isAllowedType = type.name.value === 'String' || isScalarType(schema.getType(type.name.value));
89-
}
82+
} else if (type.kind === Kind.NAMED_TYPE) {
83+
isAllowedType = type.name.value === 'String' || isScalarType(schema.getType(type.name.value));
9084
}
9185
}
9286

9387
if (!isAllowedType) {
94-
const returnType = isStringType
95-
? 'either String, Scalar, or a non-null wrapper around one of those types'
96-
: 'non-null Boolean';
88+
const returnType =
89+
typeName === 'Boolean'
90+
? 'non-null Boolean'
91+
: 'either String or Scalar, which can be null if there are no results';
9792
context.report({
9893
node: field ? field.name : node.name,
9994
message: field

packages/plugin/tests/__snapshots__/relay-page-info.spec.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ exports[`when extend type 1`] = `
5454
2 | extend type PageInfo {
5555
3 | hasPreviousPage: Boolean!
5656
4 | hasNextPage: Boolean!
57-
5 | startCursor: String!
58-
6 | endCursor: String!
57+
5 | startCursor: String
58+
6 | endCursor: String
5959
7 | }
6060

6161
#### ❌ Error 1/4
@@ -73,13 +73,13 @@ exports[`when extend type 1`] = `
7373
#### ❌ Error 3/4
7474

7575
> 1 | type PageInfo
76-
| ^^^^^^^^ \`PageInfo\` must contain a field \`startCursor\`, that return either String, Scalar, or a non-null wrapper around one of those types.
76+
| ^^^^^^^^ \`PageInfo\` must contain a field \`startCursor\`, that return either String or Scalar, which can be null if there are no results.
7777
2 | extend type PageInfo {
7878

7979
#### ❌ Error 4/4
8080

8181
> 1 | type PageInfo
82-
| ^^^^^^^^ \`PageInfo\` must contain a field \`endCursor\`, that return either String, Scalar, or a non-null wrapper around one of those types.
82+
| ^^^^^^^^ \`PageInfo\` must contain a field \`endCursor\`, that return either String or Scalar, which can be null if there are no results.
8383
2 | extend type PageInfo {
8484
`;
8585

@@ -100,7 +100,7 @@ exports[`when fields is missing or incorrect return type 1`] = `
100100
#### ❌ Error 2/4
101101

102102
> 1 | type PageInfo {
103-
| ^^^^^^^^ \`PageInfo\` must contain a field \`endCursor\`, that return either String, Scalar, or a non-null wrapper around one of those types.
103+
| ^^^^^^^^ \`PageInfo\` must contain a field \`endCursor\`, that return either String or Scalar, which can be null if there are no results.
104104
2 | hasPreviousPage: [Boolean!]!
105105

106106
#### ❌ Error 3/4
@@ -114,7 +114,7 @@ exports[`when fields is missing or incorrect return type 1`] = `
114114

115115
2 | hasPreviousPage: [Boolean!]!
116116
> 3 | startCursor: [String]
117-
| ^^^^^^^^^^^ Field \`startCursor\` must return either String, Scalar, or a non-null wrapper around one of those types.
117+
| ^^^^^^^^^^^ Field \`startCursor\` must return either String or Scalar, which can be null if there are no results.
118118
4 | }
119119
`;
120120

@@ -125,8 +125,8 @@ exports[`when input 1`] = `
125125
2 | extend input PageInfo {
126126
3 | hasPreviousPage: Boolean!
127127
4 | hasNextPage: Boolean!
128-
5 | startCursor: String!
129-
6 | endCursor: String!
128+
5 | startCursor: String
129+
6 | endCursor: String
130130
7 | }
131131

132132
#### ❌ Error 1/2
@@ -150,8 +150,8 @@ exports[`when interface 1`] = `
150150
2 | extend interface PageInfo {
151151
3 | hasPreviousPage: Boolean!
152152
4 | hasNextPage: Boolean!
153-
5 | startCursor: String!
154-
6 | endCursor: String!
153+
5 | startCursor: String
154+
6 | endCursor: String
155155
7 | }
156156

157157
#### ❌ Error 1/2

packages/plugin/tests/relay-page-info.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ ruleTester.runGraphQLTests('relay-page-info', rule, {
1818
type PageInfo {
1919
hasPreviousPage: Boolean!
2020
hasNextPage: Boolean!
21-
startCursor: String!
22-
endCursor: String # can be null
21+
startCursor: String
22+
endCursor: String
2323
}
2424
`),
2525
{
@@ -28,8 +28,8 @@ ruleTester.runGraphQLTests('relay-page-info', rule, {
2828
type PageInfo {
2929
hasPreviousPage: Boolean!
3030
hasNextPage: Boolean!
31-
startCursor: Int # can be null
32-
endCursor: Float!
31+
startCursor: Int
32+
endCursor: Float
3333
}
3434
`),
3535
},
@@ -61,8 +61,8 @@ ruleTester.runGraphQLTests('relay-page-info', rule, {
6161
extend input PageInfo {
6262
hasPreviousPage: Boolean!
6363
hasNextPage: Boolean!
64-
startCursor: String!
65-
endCursor: String!
64+
startCursor: String
65+
endCursor: String
6666
}
6767
`),
6868
errors: 2,
@@ -87,8 +87,8 @@ ruleTester.runGraphQLTests('relay-page-info', rule, {
8787
extend interface PageInfo {
8888
hasPreviousPage: Boolean!
8989
hasNextPage: Boolean!
90-
startCursor: String!
91-
endCursor: String!
90+
startCursor: String
91+
endCursor: String
9292
}
9393
`),
9494
errors: 2,
@@ -100,8 +100,8 @@ ruleTester.runGraphQLTests('relay-page-info', rule, {
100100
extend type PageInfo {
101101
hasPreviousPage: Boolean!
102102
hasNextPage: Boolean!
103-
startCursor: String!
104-
endCursor: String!
103+
startCursor: String
104+
endCursor: String
105105
}
106106
`),
107107
errors: 4,

0 commit comments

Comments
 (0)