@graphql-eslint/eslint-plugin 3.0.0-alpha-698204a.0 → 3.0.0-alpha-0a996de.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.mjs CHANGED
@@ -32,21 +32,22 @@ const schemaRecommendedConfig = {
32
32
  'error',
33
33
  {
34
34
  types: 'PascalCase',
35
- fields: 'camelCase',
36
- overrides: {
37
- EnumValueDefinition: 'UPPER_CASE',
38
- 'FieldDefinition[parent.name.value=Query]': {
39
- forbiddenPrefixes: ['query', 'get'],
40
- forbiddenSuffixes: ['Query'],
41
- },
42
- 'FieldDefinition[parent.name.value=Mutation]': {
43
- forbiddenPrefixes: ['mutation'],
44
- forbiddenSuffixes: ['Mutation'],
45
- },
46
- 'FieldDefinition[parent.name.value=Subscription]': {
47
- forbiddenPrefixes: ['subscription'],
48
- forbiddenSuffixes: ['Subscription'],
49
- },
35
+ FieldDefinition: 'camelCase',
36
+ InputValueDefinition: 'camelCase',
37
+ Argument: 'camelCase',
38
+ DirectiveDefinition: 'camelCase',
39
+ EnumValueDefinition: 'UPPER_CASE',
40
+ 'FieldDefinition[parent.name.value=Query]': {
41
+ forbiddenPrefixes: ['query', 'get'],
42
+ forbiddenSuffixes: ['Query'],
43
+ },
44
+ 'FieldDefinition[parent.name.value=Mutation]': {
45
+ forbiddenPrefixes: ['mutation'],
46
+ forbiddenSuffixes: ['Mutation'],
47
+ },
48
+ 'FieldDefinition[parent.name.value=Subscription]': {
49
+ forbiddenPrefixes: ['subscription'],
50
+ forbiddenSuffixes: ['Subscription'],
50
51
  },
51
52
  },
52
53
  ],
@@ -54,9 +55,9 @@ const schemaRecommendedConfig = {
54
55
  '@graphql-eslint/no-hashtag-description': 'error',
55
56
  '@graphql-eslint/no-typename-prefix': 'error',
56
57
  '@graphql-eslint/no-unreachable-types': 'error',
57
- '@graphql-eslint/possible-type-extension': 'error',
58
58
  '@graphql-eslint/provided-required-arguments': 'error',
59
59
  '@graphql-eslint/require-deprecation-reason': 'error',
60
+ '@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
60
61
  '@graphql-eslint/strict-id-in-types': 'error',
61
62
  '@graphql-eslint/unique-directive-names': 'error',
62
63
  '@graphql-eslint/unique-directive-names-per-location': 'error',
@@ -85,8 +86,8 @@ const schemaAllConfig = {
85
86
  '@graphql-eslint/no-root-type': 'off',
86
87
  '@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
87
88
  '@graphql-eslint/no-unused-fields': 'off',
89
+ '@graphql-eslint/possible-type-extension': 'off',
88
90
  '@graphql-eslint/require-deprecation-date': 'error',
89
- '@graphql-eslint/require-description': ['error', { types: true, overrides: { DirectiveDefinition: true } }],
90
91
  '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
91
92
  },
92
93
  };
@@ -108,16 +109,13 @@ const operationsRecommendedConfig = {
108
109
  '@graphql-eslint/naming-convention': [
109
110
  'error',
110
111
  {
111
- overrides: {
112
- Argument: 'camelCase',
113
- VariableDefinition: 'camelCase',
114
- OperationDefinition: {
115
- style: 'PascalCase',
116
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
117
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
118
- },
119
- FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
112
+ VariableDefinition: 'camelCase',
113
+ OperationDefinition: {
114
+ style: 'PascalCase',
115
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
116
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
120
117
  },
118
+ FragmentDefinition: { style: 'PascalCase', forbiddenPrefixes: ['Fragment'], forbiddenSuffixes: ['Fragment'] },
121
119
  },
122
120
  ],
123
121
  '@graphql-eslint/no-anonymous-operations': 'error',
@@ -383,9 +381,9 @@ const validationToRule = (name, ruleName, docs, getDocumentNode) => {
383
381
  [name]: {
384
382
  meta: {
385
383
  docs: {
384
+ recommended: true,
386
385
  ...docs,
387
386
  graphQLJSRuleName: ruleName,
388
- recommended: true,
389
387
  requiresSchema,
390
388
  url: `https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/${name}.md`,
391
389
  description: `${docs.description}\n\n> This rule is a wrapper around a \`graphql-js\` validation function. [You can find its source code here](https://github.com/graphql/graphql-js/blob/main/src/validation/rules/${ruleName}Rule.ts).`,
@@ -561,6 +559,7 @@ const GRAPHQL_JS_VALIDATIONS = Object.assign({}, validationToRule('executable-de
561
559
  category: 'Schema',
562
560
  description: `A type extension is only valid if the type is defined and has the same kind.`,
563
561
  requiresSchema: false,
562
+ recommended: false, // TODO: enable after https://github.com/dotansimha/graphql-eslint/issues/787 will be fixed
564
563
  }), validationToRule('provided-required-arguments', 'ProvidedRequiredArguments', {
565
564
  category: ['Schema', 'Operations'],
566
565
  description: `A field or directive is only valid if all required (non-null without a default value) field arguments have been provided.`,
@@ -906,23 +905,21 @@ const rule$1 = {
906
905
  properties: {
907
906
  style: {
908
907
  enum: ['block', 'inline'],
909
- default: 'inline',
908
+ default: 'block',
910
909
  },
911
910
  },
912
911
  },
913
912
  ],
914
913
  },
915
914
  create(context) {
916
- const { style } = context.options[0] || { style: 'inline' };
917
- const wrongDescriptionType = style === 'block' ? 'inline' : 'block';
915
+ const { style = 'block' } = context.options[0] || {};
916
+ const isBlock = style === 'block';
918
917
  return {
919
- '[description.type="StringValue"]': node => {
920
- if (node.description.block !== (style === 'block')) {
921
- context.report({
922
- loc: getLocation(node.description.loc),
923
- message: `Unexpected ${wrongDescriptionType} description`,
924
- });
925
- }
918
+ [`.description[type=StringValue][block!=${isBlock}]`](node) {
919
+ context.report({
920
+ loc: getLocation(node.loc),
921
+ message: `Unexpected ${isBlock ? 'inline' : 'block'} description`,
922
+ });
926
923
  },
927
924
  };
928
925
  },
@@ -1248,7 +1245,6 @@ const rule$3 = {
1248
1245
  },
1249
1246
  };
1250
1247
 
1251
- const FIELDS_KINDS = [Kind.FIELD_DEFINITION, Kind.INPUT_VALUE_DEFINITION, Kind.ARGUMENT, Kind.DIRECTIVE_DEFINITION];
1252
1248
  const KindToDisplayName = {
1253
1249
  // types
1254
1250
  [Kind.OBJECT_TYPE_DEFINITION]: 'Type',
@@ -1290,20 +1286,56 @@ const rule$4 = {
1290
1286
  examples: [
1291
1287
  {
1292
1288
  title: 'Incorrect',
1293
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1289
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1294
1290
  code: /* GraphQL */ `
1295
1291
  type user {
1296
1292
  first_name: String!
1297
1293
  }
1294
+ `,
1295
+ },
1296
+ {
1297
+ title: 'Incorrect',
1298
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1299
+ code: /* GraphQL */ `
1300
+ fragment UserFragment on User {
1301
+ # ...
1302
+ }
1303
+ `,
1304
+ },
1305
+ {
1306
+ title: 'Incorrect',
1307
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1308
+ code: /* GraphQL */ `
1309
+ type Query {
1310
+ getUsers: [User!]!
1311
+ }
1298
1312
  `,
1299
1313
  },
1300
1314
  {
1301
1315
  title: 'Correct',
1302
- usage: [{ types: 'PascalCase', fields: 'camelCase' }],
1316
+ usage: [{ types: 'PascalCase', FieldDefinition: 'camelCase' }],
1303
1317
  code: /* GraphQL */ `
1304
1318
  type User {
1305
1319
  firstName: String
1306
1320
  }
1321
+ `,
1322
+ },
1323
+ {
1324
+ title: 'Correct',
1325
+ usage: [{ FragmentDefinition: { style: 'PascalCase', forbiddenSuffixes: ['Fragment'] } }],
1326
+ code: /* GraphQL */ `
1327
+ fragment UserFields on User {
1328
+ # ...
1329
+ }
1330
+ `,
1331
+ },
1332
+ {
1333
+ title: 'Correct',
1334
+ usage: [{ 'FieldDefinition[parent.name.value=Query]': { forbiddenPrefixes: ['get'] } }],
1335
+ code: /* GraphQL */ `
1336
+ type Query {
1337
+ users: [User!]!
1338
+ }
1307
1339
  `,
1308
1340
  },
1309
1341
  ],
@@ -1311,39 +1343,37 @@ const rule$4 = {
1311
1343
  schema: [
1312
1344
  {
1313
1345
  types: 'PascalCase',
1314
- fields: 'camelCase',
1315
- overrides: {
1316
- EnumValueDefinition: 'UPPER_CASE',
1317
- 'FieldDefinition[parent.name.value=Query]': {
1318
- forbiddenPrefixes: ['query', 'get'],
1319
- forbiddenSuffixes: ['Query'],
1320
- },
1321
- 'FieldDefinition[parent.name.value=Mutation]': {
1322
- forbiddenPrefixes: ['mutation'],
1323
- forbiddenSuffixes: ['Mutation'],
1324
- },
1325
- 'FieldDefinition[parent.name.value=Subscription]': {
1326
- forbiddenPrefixes: ['subscription'],
1327
- forbiddenSuffixes: ['Subscription'],
1328
- },
1346
+ FieldDefinition: 'camelCase',
1347
+ InputValueDefinition: 'camelCase',
1348
+ Argument: 'camelCase',
1349
+ DirectiveDefinition: 'camelCase',
1350
+ EnumValueDefinition: 'UPPER_CASE',
1351
+ 'FieldDefinition[parent.name.value=Query]': {
1352
+ forbiddenPrefixes: ['query', 'get'],
1353
+ forbiddenSuffixes: ['Query'],
1354
+ },
1355
+ 'FieldDefinition[parent.name.value=Mutation]': {
1356
+ forbiddenPrefixes: ['mutation'],
1357
+ forbiddenSuffixes: ['Mutation'],
1358
+ },
1359
+ 'FieldDefinition[parent.name.value=Subscription]': {
1360
+ forbiddenPrefixes: ['subscription'],
1361
+ forbiddenSuffixes: ['Subscription'],
1329
1362
  },
1330
1363
  },
1331
1364
  ],
1332
1365
  operations: [
1333
1366
  {
1334
- overrides: {
1335
- Argument: 'camelCase',
1336
- VariableDefinition: 'camelCase',
1337
- OperationDefinition: {
1338
- style: 'PascalCase',
1339
- forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1340
- forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1341
- },
1342
- FragmentDefinition: {
1343
- style: 'PascalCase',
1344
- forbiddenPrefixes: ['Fragment'],
1345
- forbiddenSuffixes: ['Fragment'],
1346
- },
1367
+ VariableDefinition: 'camelCase',
1368
+ OperationDefinition: {
1369
+ style: 'PascalCase',
1370
+ forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
1371
+ forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
1372
+ },
1373
+ FragmentDefinition: {
1374
+ style: 'PascalCase',
1375
+ forbiddenPrefixes: ['Fragment'],
1376
+ forbiddenSuffixes: ['Fragment'],
1347
1377
  },
1348
1378
  },
1349
1379
  ],
@@ -1385,12 +1415,15 @@ const rule$4 = {
1385
1415
  properties: {
1386
1416
  types: {
1387
1417
  ...schemaOption$1,
1388
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1389
- },
1390
- fields: {
1391
- ...schemaOption$1,
1392
- description: `Includes:\n\n${FIELDS_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
1418
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
1393
1419
  },
1420
+ ...Object.fromEntries(ALLOWED_KINDS.map(kind => [
1421
+ kind,
1422
+ {
1423
+ ...schemaOption$1,
1424
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
1425
+ },
1426
+ ])),
1394
1427
  allowLeadingUnderscore: {
1395
1428
  type: 'boolean',
1396
1429
  default: false,
@@ -1399,36 +1432,25 @@ const rule$4 = {
1399
1432
  type: 'boolean',
1400
1433
  default: false,
1401
1434
  },
1402
- overrides: {
1403
- type: 'object',
1404
- additionalProperties: false,
1405
- description: [
1406
- 'May contain the following `ASTNode` names:',
1407
- '',
1408
- ...ALLOWED_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`),
1409
- '',
1410
- "> It's also possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with `ASTNode` name",
1411
- '>',
1412
- '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`',
1413
- ].join('\n'),
1414
- patternProperties: {
1415
- [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1416
- },
1417
- },
1418
1435
  },
1436
+ patternProperties: {
1437
+ [`^(${ALLOWED_KINDS.join('|')})(.+)?$`]: schemaOption$1,
1438
+ },
1439
+ description: [
1440
+ "> It's possible to use a [`selector`](https://eslint.org/docs/developer-guide/selectors) that starts with allowed `ASTNode` names which are described below.",
1441
+ '>',
1442
+ '> Paste or drop code into the editor in [ASTExplorer](https://astexplorer.net) and inspect the generated AST to compose your selector.',
1443
+ '>',
1444
+ '> Example: pattern property `FieldDefinition[parent.name.value=Query]` will match only fields for type `Query`.',
1445
+ ].join('\n'),
1419
1446
  },
1420
1447
  },
1421
1448
  },
1422
1449
  create(context) {
1423
- const options = {
1424
- overrides: {},
1425
- ...context.options[0],
1426
- };
1450
+ const options = context.options[0] || {};
1451
+ const { allowLeadingUnderscore, allowTrailingUnderscore, types, ...restOptions } = options;
1427
1452
  function normalisePropertyOption(kind) {
1428
- let style = options.overrides[kind];
1429
- if (!style) {
1430
- style = TYPES_KINDS.includes(kind) ? options.types : options.fields;
1431
- }
1453
+ const style = restOptions[kind] || types;
1432
1454
  return typeof style === 'object' ? style : { style };
1433
1455
  }
1434
1456
  const checkNode = (selector) => (node) => {
@@ -1448,10 +1470,10 @@ const rule$4 = {
1448
1470
  }
1449
1471
  function getErrorMessage() {
1450
1472
  let name = nodeName;
1451
- if (options.allowLeadingUnderscore) {
1473
+ if (allowLeadingUnderscore) {
1452
1474
  name = name.replace(/^_*/, '');
1453
1475
  }
1454
- if (options.allowTrailingUnderscore) {
1476
+ if (allowTrailingUnderscore) {
1455
1477
  name = name.replace(/_*$/, '');
1456
1478
  }
1457
1479
  if (prefix && !name.startsWith(prefix)) {
@@ -1485,15 +1507,13 @@ const rule$4 = {
1485
1507
  });
1486
1508
  };
1487
1509
  const listeners = {};
1488
- if (!options.allowLeadingUnderscore) {
1510
+ if (!allowLeadingUnderscore) {
1489
1511
  listeners['Name[value=/^_/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1490
1512
  }
1491
- if (!options.allowTrailingUnderscore) {
1513
+ if (!allowTrailingUnderscore) {
1492
1514
  listeners['Name[value=/_$/]:matches([parent.kind!=Field], [parent.kind=Field][parent.alias])'] = checkUnderscore;
1493
1515
  }
1494
- const selectors = new Set([options.types && TYPES_KINDS, options.fields && FIELDS_KINDS, Object.keys(options.overrides)]
1495
- .flat()
1496
- .filter(Boolean));
1516
+ const selectors = new Set([types && TYPES_KINDS, Object.keys(restOptions)].flat().filter(Boolean));
1497
1517
  for (const selector of selectors) {
1498
1518
  listeners[selector] = checkNode(selector);
1499
1519
  }
@@ -1898,18 +1918,18 @@ const rule$9 = {
1898
1918
  },
1899
1919
  };
1900
1920
 
1901
- const ROOT_TYPES = ['query', 'mutation', 'subscription'];
1921
+ const ROOT_TYPES = ['mutation', 'subscription'];
1902
1922
  const rule$a = {
1903
1923
  meta: {
1904
1924
  type: 'suggestion',
1905
1925
  docs: {
1906
1926
  category: 'Schema',
1907
- description: 'Disallow using root types for `read-only` or `write-only` schemas.',
1927
+ description: 'Disallow using root types `mutation` and/or `subscription`.',
1908
1928
  url: 'https://github.com/dotansimha/graphql-eslint/blob/master/docs/rules/no-root-type.md',
1909
1929
  requiresSchema: true,
1910
1930
  examples: [
1911
1931
  {
1912
- title: 'Incorrect (`read-only` schema)',
1932
+ title: 'Incorrect',
1913
1933
  usage: [{ disallow: ['mutation', 'subscription'] }],
1914
1934
  code: /* GraphQL */ `
1915
1935
  type Mutation {
@@ -1918,16 +1938,7 @@ const rule$a = {
1918
1938
  `,
1919
1939
  },
1920
1940
  {
1921
- title: 'Incorrect (`write-only` schema)',
1922
- usage: [{ disallow: ['query'] }],
1923
- code: /* GraphQL */ `
1924
- type Query {
1925
- users: [User!]!
1926
- }
1927
- `,
1928
- },
1929
- {
1930
- title: 'Correct (`read-only` schema)',
1941
+ title: 'Correct',
1931
1942
  usage: [{ disallow: ['mutation', 'subscription'] }],
1932
1943
  code: /* GraphQL */ `
1933
1944
  type Query {
@@ -1962,7 +1973,6 @@ const rule$a = {
1962
1973
  const schema = requireGraphQLSchemaFromContext('no-root-type', context);
1963
1974
  const disallow = new Set(context.options[0].disallow);
1964
1975
  const rootTypeNames = [
1965
- disallow.has('query') && schema.getQueryType(),
1966
1976
  disallow.has('mutation') && schema.getMutationType(),
1967
1977
  disallow.has('subscription') && schema.getSubscriptionType(),
1968
1978
  ]
@@ -2542,7 +2552,7 @@ const rule$h = {
2542
2552
  examples: [
2543
2553
  {
2544
2554
  title: 'Incorrect',
2545
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2555
+ usage: [{ types: true, FieldDefinition: true }],
2546
2556
  code: /* GraphQL */ `
2547
2557
  type someTypeName {
2548
2558
  name: String
@@ -2551,7 +2561,7 @@ const rule$h = {
2551
2561
  },
2552
2562
  {
2553
2563
  title: 'Correct',
2554
- usage: [{ types: true, overrides: { FieldDefinition: true } }],
2564
+ usage: [{ types: true, FieldDefinition: true }],
2555
2565
  code: /* GraphQL */ `
2556
2566
  """
2557
2567
  Some type description
@@ -2568,11 +2578,10 @@ const rule$h = {
2568
2578
  configOptions: [
2569
2579
  {
2570
2580
  types: true,
2571
- overrides: {
2572
- [Kind.DIRECTIVE_DEFINITION]: true,
2573
- },
2581
+ [Kind.DIRECTIVE_DEFINITION]: true,
2574
2582
  },
2575
2583
  ],
2584
+ recommended: true,
2576
2585
  },
2577
2586
  type: 'suggestion',
2578
2587
  messages: {
@@ -2589,22 +2598,23 @@ const rule$h = {
2589
2598
  properties: {
2590
2599
  types: {
2591
2600
  type: 'boolean',
2592
- description: `Includes:\n\n${TYPES_KINDS.map(kind => `- [${kind}](https://spec.graphql.org/October2021/#${kind})`).join('\n')}`,
2593
- },
2594
- overrides: {
2595
- type: 'object',
2596
- description: 'Configuration for precise `ASTNode`',
2597
- additionalProperties: false,
2598
- properties: Object.fromEntries(ALLOWED_KINDS$1.map(kind => [kind, { type: 'boolean' }])),
2601
+ description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
2599
2602
  },
2603
+ ...Object.fromEntries([...ALLOWED_KINDS$1].sort().map(kind => [
2604
+ kind,
2605
+ {
2606
+ type: 'boolean',
2607
+ description: `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`,
2608
+ },
2609
+ ])),
2600
2610
  },
2601
2611
  },
2602
2612
  },
2603
2613
  },
2604
2614
  create(context) {
2605
- const { types, overrides = {} } = context.options[0];
2615
+ const { types, ...restOptions } = context.options[0];
2606
2616
  const kinds = new Set(types ? TYPES_KINDS : []);
2607
- for (const [kind, isEnabled] of Object.entries(overrides)) {
2617
+ for (const [kind, isEnabled] of Object.entries(restOptions)) {
2608
2618
  if (isEnabled) {
2609
2619
  kinds.add(kind);
2610
2620
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-eslint/eslint-plugin",
3
- "version": "3.0.0-alpha-698204a.0",
3
+ "version": "3.0.0-alpha-0a996de.0",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "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 || ^16.0.0"