Skip to content

Commit

Permalink
feat: add eslint-plugin-eslint-plugin (#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimitri POSTOLOV committed Sep 20, 2021
1 parent 1ff320a commit 75165c6
Show file tree
Hide file tree
Showing 19 changed files with 190 additions and 197 deletions.
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

48 changes: 48 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module.exports = {
reportUnusedDisableDirectives: true,
ignorePatterns: ['examples'],
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'standard',
'plugin:eslint-plugin/recommended',
'prettier',
],
plugins: ['unicorn'],
rules: {
'no-empty': 'off',
'no-console': 'error',
'no-prototype-builtins': 'off',
'no-useless-constructor': 'off',
'no-unused-vars': 'off', // disable base rule as it can report incorrect errors
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/ban-types': 'off',
'unicorn/prefer-array-some': 'error',
'unicorn/prefer-includes': 'error',
'eslint-plugin/test-case-shorthand-strings': 'error',
},
overrides: [
{
files: ['*.{spec,test}.{ts,js}'],
env: {
jest: true,
},
},
{
files: ['**/tests/mocks/*.{ts,js}'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
},
},
],
};
49 changes: 0 additions & 49 deletions .eslintrc.json

This file was deleted.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"scripts": {
"generate:docs": "ts-node scripts/generate-docs.ts",
"postinstall": "patch-package",
"lint": "eslint --config .eslintrc.json --ext ts,js .",
"lint": "eslint --ignore-path .gitignore --ext ts,js .",
"prebuild": "rimraf packages/*/dist",
"transpile-ts": "tsc --project tsconfig.json",
"build": "yarn transpile-ts && bob build",
Expand All @@ -39,13 +39,14 @@
"eslint": "7.32.0",
"eslint-config-prettier": "8.3.0",
"eslint-config-standard": "16.0.3",
"eslint-plugin-eslint-plugin": "^3.5.3",
"eslint-plugin-import": "2.24.2",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "5.1.0",
"eslint-plugin-standard": "5.0.0",
"eslint-plugin-unicorn": "35.0.0",
"husky": "7.0.2",
"jest": "27.2.0",
"eslint-plugin-unicorn": "35.0.0",
"json-schema-to-markdown": "1.1.1",
"lint-staged": "11.1.2",
"patch-package": "6.4.7",
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
"devDependencies": {
"@types/eslint": "7.28.0",
"@types/graphql-depth-limit": "1.1.3",
"@types/lodash.lowercase": "^4.3.6",
"bob-the-bundler": "1.5.1",
"graphql": "15.5.3",
"typescript": "4.4.3",
"@types/lodash.camelcase": "4.3.6"
"typescript": "4.4.3"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
Expand Down
15 changes: 10 additions & 5 deletions packages/plugin/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { statSync } from 'fs';
import { dirname } from 'path';
import { Lexer, GraphQLSchema, Token, DocumentNode, Source } from 'graphql';
import { Lexer, GraphQLSchema, Source, ObjectTypeDefinitionNode, ObjectTypeExtensionNode, Kind } from 'graphql';
import { AST } from 'eslint';
import { asArray, Source as LoaderSource } from '@graphql-tools/utils';
import lowerCase from 'lodash.lowercase';
import { GraphQLESLintRuleContext } from './types';
import { SiblingOperations } from './sibling-operations';
import { UsedFields, ReachableTypes } from './graphql-ast';
import { GraphQLESTreeNode } from './estree-parser';

export function requireSiblingsOperations(
ruleName: string,
Expand Down Expand Up @@ -144,10 +145,14 @@ export const loaderCache: Record<string, LoaderSource[]> = new Proxy(Object.crea
},
});

const isObjectType = (node): boolean => ['ObjectTypeDefinition', 'ObjectTypeExtension'].includes(node.type);
export const isQueryType = (node): boolean => isObjectType(node) && node.name.value === 'Query';
export const isMutationType = (node): boolean => isObjectType(node) && node.name.value === 'Mutation';
export const isSubscriptionType = (node): boolean => isObjectType(node) && node.name.value === 'Subscription';
type ObjectTypeNode = GraphQLESTreeNode<ObjectTypeDefinitionNode | ObjectTypeExtensionNode>;

const isObjectType = (node: ObjectTypeNode): boolean =>
[Kind.OBJECT_TYPE_DEFINITION, Kind.OBJECT_TYPE_EXTENSION].includes(node.type);
export const isQueryType = (node: ObjectTypeNode): boolean => isObjectType(node) && node.name.value === 'Query';
export const isMutationType = (node: ObjectTypeNode): boolean => isObjectType(node) && node.name.value === 'Mutation';
export const isSubscriptionType = (node: ObjectTypeNode): boolean =>
isObjectType(node) && node.name.value === 'Subscription';

export enum CaseStyle {
camelCase = 'camelCase',
Expand Down
38 changes: 16 additions & 22 deletions packages/plugin/tests/avoid-typename-prefix.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,22 @@ const ruleTester = new GraphQLRuleTester();

ruleTester.runGraphQLTests('avoid-typename-prefix', rule, {
valid: [
{
code: /* GraphQL */ `
type User {
id: ID!
}
`,
},
{
code: /* GraphQL */ `
interface Node {
id: ID!
}
`,
},
{
code: /* GraphQL */ `
type User {
# eslint-disable-next-line
userId: ID!
}
`,
},
/* GraphQL */ `
type User {
id: ID!
}
`,
/* GraphQL */ `
interface Node {
id: ID!
}
`,
/* GraphQL */ `
type User {
# eslint-disable-next-line
userId: ID!
}
`,
],
invalid: [
{
Expand Down
4 changes: 1 addition & 3 deletions packages/plugin/tests/description-style.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ ruleTester.runGraphQLTests('description-style', rule, {
code: BLOCK_SDL,
options: [{ style: 'block' }],
},
{
code: INLINE_SDL,
},
INLINE_SDL,
],
invalid: [
{
Expand Down
66 changes: 28 additions & 38 deletions packages/plugin/tests/eslint-directives.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,34 @@ const ruleTester = new GraphQLRuleTester();

ruleTester.runGraphQLTests('test-directives', rule, {
valid: [
{
code: /* GraphQL */ `
# eslint-disable-next-line
query {
a
}
`,
},
{
code: /* GraphQL */ `
# eslint-disable-next-line test-directives
query {
a
}
`,
},
{
code: `
query { # eslint-disable-line test-directives
a
}
`,
},
{
code: `
query { # eslint-disable-line
a
}
`,
},
{
code: /* GraphQL */ `
# eslint-disable
query {
a
}
`,
},
/* GraphQL */ `
# eslint-disable-next-line
query {
a
}
`,
/* GraphQL */ `
# eslint-disable-next-line test-directives
query {
a
}
`,
`
query { # eslint-disable-line test-directives
a
}
`,
`
query { # eslint-disable-line
a
}
`,
/* GraphQL */ `
# eslint-disable
query {
a
}
`,
{
filename: join(__dirname, 'mocks/test-directives-with-import.graphql'),
code: ruleTester.fromMockFile('test-directives-with-import.graphql'),
Expand Down
7 changes: 1 addition & 6 deletions packages/plugin/tests/input-name.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ ruleTester.runGraphQLTests('input-name', rule, {
options: [{ checkInputType: true }],
},
{
code: 'type Mutation { SetMessage(input: SetMessageInput): String }',
options: [{ checkInputType: true }],
},
{
code:
'type Mutation { CreateMessage(input: CreateMessageInput): String DeleteMessage(input: DeleteMessageInput): Boolean }',
code: 'type Mutation { CreateMessage(input: CreateMessageInput): String DeleteMessage(input: DeleteMessageInput): Boolean }',
options: [{ checkInputType: true }],
},
{
Expand Down
2 changes: 0 additions & 2 deletions packages/plugin/tests/mocks/two-fragments-in-code-file.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const USER_FIELDS = /* GraphQL */ `
fragment UserFields on User {
id
firstName
}
`;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ALL_USER_FIELDS = /* GraphQL */ `
fragment UserFields on User {
id
Expand Down
4 changes: 1 addition & 3 deletions packages/plugin/tests/mocks/unique-fragment.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// eslint-disable-next-line no-undef
const USER_FIELDS = gql`
const USER_FIELDS = /* GraphQL */ `
fragment UserFields on User {
id
}
`;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const GET_USER = /* GraphQL */ `
query User {
user {
Expand Down
14 changes: 7 additions & 7 deletions packages/plugin/tests/naming-convention.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ ruleTester.runGraphQLTests('naming-convention', rule, {
code: 'input Test { item: String }',
options: [{ InputObjectTypeDefinition: 'PascalCase', InputValueDefinition: 'camelCase' }],
},
{
code:
'input test { item: String } enum B { Test } interface A { i: String } fragment PictureFragment on Picture { uri } scalar Hello',
},
'input test { item: String } enum B { Test } interface A { i: String } fragment PictureFragment on Picture { uri } scalar Hello',
{
code: 'type TypeOne { aField: String } enum Z { VALUE_ONE VALUE_TWO }',
options: [
Expand Down Expand Up @@ -214,12 +211,15 @@ ruleTester.runGraphQLTests('naming-convention', rule, {
],
},
{
code:
'type One { getFoo: String, queryBar: String } type Query { getA(id: ID!): String, queryB: String } extend type Query { getC: String }',
code: 'type One { getFoo: String, queryBar: String } type Query { getA(id: ID!): String, queryB: String } extend type Query { getC: String }',
options: [
{
ObjectTypeDefinition: { style: 'PascalCase', forbiddenPrefixes: ['On'] },
FieldDefinition: { style: 'camelCase', forbiddenPrefixes: ['foo', 'bar'], forbiddenSuffixes: ['Foo'] },
FieldDefinition: {
style: 'camelCase',
forbiddenPrefixes: ['foo', 'bar'],
forbiddenSuffixes: ['Foo'],
},
QueryDefinition: { style: 'camelCase', forbiddenPrefixes: ['get', 'query'] },
},
],
Expand Down
6 changes: 1 addition & 5 deletions packages/plugin/tests/no-anonymous-operations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import rule from '../src/rules/no-anonymous-operations';
const ruleTester = new GraphQLRuleTester();

ruleTester.runGraphQLTests('no-anonymous-operations', rule, {
valid: [
{ code: `query myQuery { a }` },
{ code: `mutation doSomething { a }` },
{ code: `subscription myData { a }` },
],
valid: ['query myQuery { a }', 'mutation doSomething { a }', 'subscription myData { a }'],
invalid: [
{ code: `query { a }`, errors: 1 },
{ code: `mutation { a }`, errors: 1 },
Expand Down

0 comments on commit 75165c6

Please sign in to comment.