Skip to content

Commit b3e7f55

Browse files
committed
ESLint: enable some of the rules previously blocked by TS convertion
1 parent 44613cc commit b3e7f55

File tree

8 files changed

+86
-83
lines changed

8 files changed

+86
-83
lines changed

.eslintrc.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ overrides:
473473
'@typescript-eslint/ban-tslint-comment': error
474474
'@typescript-eslint/ban-types': off # TODO temporarily disabled
475475
'@typescript-eslint/class-literal-property-style': off # TODO enable after TS conversion
476-
'@typescript-eslint/consistent-indexed-object-style': off # TODO enable after TS conversion
476+
'@typescript-eslint/consistent-indexed-object-style': [error, index-signature]
477477
'@typescript-eslint/consistent-type-assertions': off # TODO temporarily disable
478478
'@typescript-eslint/consistent-type-definitions': error
479479
'@typescript-eslint/consistent-type-imports': error
@@ -507,7 +507,7 @@ overrides:
507507
'@typescript-eslint/no-require-imports': error
508508
'@typescript-eslint/no-this-alias': error
509509
'@typescript-eslint/no-type-alias': off # TODO consider
510-
'@typescript-eslint/no-unnecessary-boolean-literal-compare': off # FIXME requires on strictNullChecks
510+
'@typescript-eslint/no-unnecessary-boolean-literal-compare': error
511511
'@typescript-eslint/no-unnecessary-condition': off # TODO temporary disable
512512
'@typescript-eslint/no-unnecessary-qualifier': error
513513
'@typescript-eslint/no-unnecessary-type-arguments': error
@@ -522,9 +522,9 @@ overrides:
522522
'@typescript-eslint/non-nullable-type-assertion-style': off #TODO temporarily disabled
523523
'@typescript-eslint/prefer-as-const': error
524524
'@typescript-eslint/prefer-enum-initializers': error
525-
'@typescript-eslint/prefer-for-of': off # TODO switch to error after TS migration
525+
'@typescript-eslint/prefer-for-of': error
526526
'@typescript-eslint/prefer-function-type': error
527-
'@typescript-eslint/prefer-includes': off # TODO switch to error after IE11 drop
527+
'@typescript-eslint/prefer-includes': error
528528
'@typescript-eslint/prefer-literal-enum-member': error
529529
'@typescript-eslint/prefer-namespace-keyword': error
530530
'@typescript-eslint/prefer-nullish-coalescing': error
@@ -534,7 +534,7 @@ overrides:
534534
'@typescript-eslint/prefer-reduce-type-parameter': error
535535
'@typescript-eslint/prefer-regexp-exec': off
536536
'@typescript-eslint/prefer-return-this-type': error
537-
'@typescript-eslint/prefer-string-starts-ends-with': off # TODO switch to error after IE11 drop
537+
'@typescript-eslint/prefer-string-starts-ends-with': error
538538
'@typescript-eslint/prefer-ts-expect-error': error
539539
'@typescript-eslint/promise-function-async': off
540540
'@typescript-eslint/require-array-sort-compare': error

src/language/blockString.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ export function dedentBlockStringValue(rawString: string): string {
3535
}
3636

3737
function isBlank(str: string): boolean {
38-
for (let i = 0; i < str.length; ++i) {
39-
if (str[i] !== ' ' && str[i] !== '\t') {
38+
for (const char of str) {
39+
if (char !== ' ' && char !== '\t') {
4040
return false;
4141
}
4242
}
@@ -96,9 +96,9 @@ export function printBlockString(
9696
preferMultipleLines: boolean = false,
9797
): string {
9898
const isSingleLine = !value.includes('\n');
99-
const hasLeadingSpace = value[0] === ' ' || value[0] === '\t';
100-
const hasTrailingQuote = value[value.length - 1] === '"';
101-
const hasTrailingSlash = value[value.length - 1] === '\\';
99+
const hasLeadingSpace = value.startsWith(' ') || value.startsWith('\t');
100+
const hasTrailingQuote = value.endsWith('"');
101+
const hasTrailingSlash = value.endsWith('\\');
102102
const printAsMultipleLines =
103103
!isSingleLine ||
104104
hasTrailingQuote ||

src/language/visitor.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -211,20 +211,25 @@ export function visit(
211211
node = parent;
212212
parent = ancestors.pop();
213213
if (isEdited) {
214-
node = inArray
215-
? node.slice()
216-
: Object.defineProperties({}, Object.getOwnPropertyDescriptors(node));
217-
let editOffset = 0;
218-
for (let ii = 0; ii < edits.length; ii++) {
219-
let editKey: any = edits[ii][0];
220-
const editValue = edits[ii][1];
221-
if (inArray) {
222-
editKey -= editOffset;
214+
if (inArray) {
215+
node = node.slice();
216+
217+
let editOffset = 0;
218+
for (const [editKey, editValue] of edits) {
219+
const arrayKey = editKey - editOffset;
220+
if (editValue === null) {
221+
node.splice(arrayKey, 1);
222+
editOffset++;
223+
} else {
224+
node[arrayKey] = editValue;
225+
}
223226
}
224-
if (inArray && editValue === null) {
225-
node.splice(editKey, 1);
226-
editOffset++;
227-
} else {
227+
} else {
228+
node = Object.defineProperties(
229+
{},
230+
Object.getOwnPropertyDescriptors(node),
231+
);
232+
for (const [editKey, editValue] of edits) {
228233
node[editKey] = editValue;
229234
}
230235
}

src/utilities/assertValidName.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function assertValidName(name: string): string {
2020
*/
2121
export function isValidNameError(name: string): GraphQLError | undefined {
2222
devAssert(typeof name === 'string', 'Expected name to be a string.');
23-
if (name.length > 1 && name[0] === '_' && name[1] === '_') {
23+
if (name.startsWith('__')) {
2424
return new GraphQLError(
2525
`Name "${name}" must not begin with "__", which is reserved by GraphQL introspection.`,
2626
);

src/utilities/stripIgnoredCharacters.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ function dedentBlockString(blockStr: string): string {
112112
body = '\n' + body;
113113
}
114114

115-
const lastChar = body[body.length - 1];
116-
const hasTrailingQuote = lastChar === '"' && body.slice(-4) !== '\\"""';
117-
if (hasTrailingQuote || lastChar === '\\') {
115+
const hasTrailingQuote = body.endsWith('"') && !body.endsWith('\\"""');
116+
if (hasTrailingQuote || body.endsWith('\\')) {
118117
body += '\n';
119118
}
120119

src/utilities/typedQueryDocumentNode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import type { DocumentNode, ExecutableDefinitionNode } from '../language/ast';
33
* Wrapper type that contains DocumentNode and types that can be deduced from it.
44
*/
55
export interface TypedQueryDocumentNode<
6-
TResponseData = Record<string, any>,
7-
TRequestVariables = Record<string, any>,
6+
TResponseData = { [key: string]: any },
7+
TRequestVariables = { [key: string]: any },
88
> extends DocumentNode {
99
readonly definitions: ReadonlyArray<ExecutableDefinitionNode>;
1010
// FIXME: remove once TS implements proper way to enforce nominal typing

src/validation/rules/OverlappingFieldsCanBeMergedRule.ts

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,12 @@ function collectConflictsBetweenFieldsAndFragment(
238238
return;
239239
}
240240

241-
const [fieldMap2, fragmentNames2] = getReferencedFieldsAndFragmentNames(
242-
context,
243-
cachedFieldsAndFragmentNames,
244-
fragment,
245-
);
241+
const [fieldMap2, referencedFragmentNames] =
242+
getReferencedFieldsAndFragmentNames(
243+
context,
244+
cachedFieldsAndFragmentNames,
245+
fragment,
246+
);
246247

247248
// Do not compare a fragment's fieldMap to itself.
248249
if (fieldMap === fieldMap2) {
@@ -263,15 +264,15 @@ function collectConflictsBetweenFieldsAndFragment(
263264

264265
// (E) Then collect any conflicts between the provided collection of fields
265266
// and any fragment names found in the given fragment.
266-
for (let i = 0; i < fragmentNames2.length; i++) {
267+
for (const referencedFragmentName of referencedFragmentNames) {
267268
collectConflictsBetweenFieldsAndFragment(
268269
context,
269270
conflicts,
270271
cachedFieldsAndFragmentNames,
271272
comparedFragmentPairs,
272273
areMutuallyExclusive,
273274
fieldMap,
274-
fragmentNames2[i],
275+
referencedFragmentName,
275276
);
276277
}
277278
}
@@ -310,16 +311,18 @@ function collectConflictsBetweenFragments(
310311
return;
311312
}
312313

313-
const [fieldMap1, fragmentNames1] = getReferencedFieldsAndFragmentNames(
314-
context,
315-
cachedFieldsAndFragmentNames,
316-
fragment1,
317-
);
318-
const [fieldMap2, fragmentNames2] = getReferencedFieldsAndFragmentNames(
319-
context,
320-
cachedFieldsAndFragmentNames,
321-
fragment2,
322-
);
314+
const [fieldMap1, referencedFragmentNames1] =
315+
getReferencedFieldsAndFragmentNames(
316+
context,
317+
cachedFieldsAndFragmentNames,
318+
fragment1,
319+
);
320+
const [fieldMap2, referencedFragmentNames2] =
321+
getReferencedFieldsAndFragmentNames(
322+
context,
323+
cachedFieldsAndFragmentNames,
324+
fragment2,
325+
);
323326

324327
// (F) First, collect all conflicts between these two collections of fields
325328
// (not including any nested fragments).
@@ -335,28 +338,28 @@ function collectConflictsBetweenFragments(
335338

336339
// (G) Then collect conflicts between the first fragment and any nested
337340
// fragments spread in the second fragment.
338-
for (let j = 0; j < fragmentNames2.length; j++) {
341+
for (const referencedFragmentName2 of referencedFragmentNames2) {
339342
collectConflictsBetweenFragments(
340343
context,
341344
conflicts,
342345
cachedFieldsAndFragmentNames,
343346
comparedFragmentPairs,
344347
areMutuallyExclusive,
345348
fragmentName1,
346-
fragmentNames2[j],
349+
referencedFragmentName2,
347350
);
348351
}
349352

350353
// (G) Then collect conflicts between the second fragment and any nested
351354
// fragments spread in the first fragment.
352-
for (let i = 0; i < fragmentNames1.length; i++) {
355+
for (const referencedFragmentName1 of referencedFragmentNames1) {
353356
collectConflictsBetweenFragments(
354357
context,
355358
conflicts,
356359
cachedFieldsAndFragmentNames,
357360
comparedFragmentPairs,
358361
areMutuallyExclusive,
359-
fragmentNames1[i],
362+
referencedFragmentName1,
360363
fragmentName2,
361364
);
362365
}
@@ -403,49 +406,45 @@ function findConflictsBetweenSubSelectionSets(
403406

404407
// (I) Then collect conflicts between the first collection of fields and
405408
// those referenced by each fragment name associated with the second.
406-
if (fragmentNames2.length !== 0) {
407-
for (let j = 0; j < fragmentNames2.length; j++) {
408-
collectConflictsBetweenFieldsAndFragment(
409-
context,
410-
conflicts,
411-
cachedFieldsAndFragmentNames,
412-
comparedFragmentPairs,
413-
areMutuallyExclusive,
414-
fieldMap1,
415-
fragmentNames2[j],
416-
);
417-
}
409+
for (const fragmentName2 of fragmentNames2) {
410+
collectConflictsBetweenFieldsAndFragment(
411+
context,
412+
conflicts,
413+
cachedFieldsAndFragmentNames,
414+
comparedFragmentPairs,
415+
areMutuallyExclusive,
416+
fieldMap1,
417+
fragmentName2,
418+
);
418419
}
419420

420421
// (I) Then collect conflicts between the second collection of fields and
421422
// those referenced by each fragment name associated with the first.
422-
if (fragmentNames1.length !== 0) {
423-
for (let i = 0; i < fragmentNames1.length; i++) {
424-
collectConflictsBetweenFieldsAndFragment(
425-
context,
426-
conflicts,
427-
cachedFieldsAndFragmentNames,
428-
comparedFragmentPairs,
429-
areMutuallyExclusive,
430-
fieldMap2,
431-
fragmentNames1[i],
432-
);
433-
}
423+
for (const fragmentName1 of fragmentNames1) {
424+
collectConflictsBetweenFieldsAndFragment(
425+
context,
426+
conflicts,
427+
cachedFieldsAndFragmentNames,
428+
comparedFragmentPairs,
429+
areMutuallyExclusive,
430+
fieldMap2,
431+
fragmentName1,
432+
);
434433
}
435434

436435
// (J) Also collect conflicts between any fragment names by the first and
437436
// fragment names by the second. This compares each item in the first set of
438437
// names to each item in the second set of names.
439-
for (let i = 0; i < fragmentNames1.length; i++) {
440-
for (let j = 0; j < fragmentNames2.length; j++) {
438+
for (const fragmentName1 of fragmentNames1) {
439+
for (const fragmentName2 of fragmentNames2) {
441440
collectConflictsBetweenFragments(
442441
context,
443442
conflicts,
444443
cachedFieldsAndFragmentNames,
445444
comparedFragmentPairs,
446445
areMutuallyExclusive,
447-
fragmentNames1[i],
448-
fragmentNames2[j],
446+
fragmentName1,
447+
fragmentName2,
449448
);
450449
}
451450
}
@@ -511,16 +510,16 @@ function collectConflictsBetween(
511510
for (const [responseName, fields1] of Object.entries(fieldMap1)) {
512511
const fields2 = fieldMap2[responseName];
513512
if (fields2) {
514-
for (let i = 0; i < fields1.length; i++) {
515-
for (let j = 0; j < fields2.length; j++) {
513+
for (const field1 of fields1) {
514+
for (const field2 of fields2) {
516515
const conflict = findConflict(
517516
context,
518517
cachedFieldsAndFragmentNames,
519518
comparedFragmentPairs,
520519
parentFieldsAreMutuallyExclusive,
521520
responseName,
522-
fields1[i],
523-
fields2[j],
521+
field1,
522+
field2,
524523
);
525524
if (conflict) {
526525
conflicts.push(conflict);

src/validation/rules/SingleFieldSubscriptionsRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function SingleFieldSubscriptionsRule(
6161
for (const fieldNodes of fields.values()) {
6262
const field = fieldNodes[0];
6363
const fieldName = field.name.value;
64-
if (fieldName[0] === '_' && fieldName[1] === '_') {
64+
if (fieldName.startsWith('__')) {
6565
context.reportError(
6666
new GraphQLError(
6767
operationName != null

0 commit comments

Comments
 (0)