graphql#TokenKind TypeScript Examples

The following examples show how to use graphql#TokenKind. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From graphql-eslint with MIT License 7 votes vote down vote up
export function extractTokens(filePath: string, code: string): AST.Token[] {
  const source = new Source(code, filePath);
  const lexer = getLexer(source);
  const tokens: AST.Token[] = [];
  let token = lexer.advance();

  while (token && token.kind !== TokenKind.EOF) {
    const result = convertToken(token, token.kind) as AST.Token;
    tokens.push(result);
    token = lexer.advance();
  }

  return tokens;
}
Example #2
Source File: utils.ts    From graphql-eslint with MIT License 7 votes vote down vote up
export function extractComments(loc: Location): Comment[] {
  if (!loc) {
    return [];
  }
  const comments: Comment[] = [];
  let token = loc.startToken;

  while (token) {
    if (token.kind === TokenKind.COMMENT) {
      const comment = convertToken(
        token,
        // `eslint-disable` directive works only with `Block` type comment
        token.value.trimStart().startsWith('eslint') ? 'Block' : 'Line'
      );
      comments.push(comment);
    }
    token = token.next;
  }
  return comments;
}
Example #3
Source File: no-hashtag-description.ts    From graphql-eslint with MIT License 4 votes vote down vote up
rule: GraphQLESLintRule = {
  meta: {
    type: 'suggestion',
    hasSuggestions: true,
    schema: [],
    messages: {
      [HASHTAG_COMMENT]:
        'Using hashtag `#` for adding GraphQL descriptions is not allowed. Prefer using `"""` for multiline, or `"` for a single line description.',
    },
    docs: {
      description:
        'Requires to use `"""` or `"` for adding a GraphQL description instead of `#`.\nAllows to use hashtag for comments, as long as it\'s not attached to an AST definition.',
      category: 'Schema',
      url: 'https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/no-hashtag-description.md',
      examples: [
        {
          title: 'Incorrect',
          code: /* GraphQL */ `
            # Represents a user
            type User {
              id: ID!
              name: String
            }
          `,
        },
        {
          title: 'Correct',
          code: /* GraphQL */ `
            " Represents a user "
            type User {
              id: ID!
              name: String
            }
          `,
        },
        {
          title: 'Correct',
          code: /* GraphQL */ `
            # This file defines the basic User type.
            # This comment is valid because it's not attached specifically to an AST object.

            " Represents a user "
            type User {
              id: ID! # This one is also valid, since it comes after the AST object
              name: String
            }
          `,
        },
      ],
      recommended: true,
    },
  },
  create(context) {
    const selector = 'Document[definitions.0.kind!=/^(OperationDefinition|FragmentDefinition)$/]';
    return {
      [selector](node: GraphQLESTreeNode<DocumentNode>) {
        const rawNode = node.rawNode();
        let token = rawNode.loc.startToken;

        while (token) {
          const { kind, prev, next, value, line, column } = token;
          if (kind === TokenKind.COMMENT && prev && next) {
            const isEslintComment = value.trimStart().startsWith('eslint');
            const linesAfter = next.line - line;

            if (!isEslintComment && line !== prev.line && next.kind === TokenKind.NAME && linesAfter < 2) {
              context.report({
                messageId: HASHTAG_COMMENT,
                loc: {
                  line,
                  column: column - 1,
                },
                suggest: ['"""', '"'].map(descriptionSyntax => ({
                  desc: `Replace with \`${descriptionSyntax}\` description syntax`,
                  fix: fixer =>
                    fixer.replaceTextRange(
                      [token.start, token.end] as [number, number],
                      [descriptionSyntax, value.trim(), descriptionSyntax].join('')
                    ),
                })),
              });
            }
          }
          token = next;
        }
      },
    };
  },
}
Example #4
Source File: require-description.ts    From graphql-eslint with MIT License 4 votes vote down vote up
rule: GraphQLESLintRule<[RequireDescriptionRuleConfig]> = {
  meta: {
    docs: {
      category: 'Schema',
      description: 'Enforce descriptions in type definitions and operations.',
      url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
      examples: [
        {
          title: 'Incorrect',
          usage: [{ types: true, FieldDefinition: true }],
          code: /* GraphQL */ `
            type someTypeName {
              name: String
            }
          `,
        },
        {
          title: 'Correct',
          usage: [{ types: true, FieldDefinition: true }],
          code: /* GraphQL */ `
            """
            Some type description
            """
            type someTypeName {
              """
              Name description
              """
              name: String
            }
          `,
        },
        {
          title: 'Correct',
          usage: [{ OperationDefinition: true }],
          code: /* GraphQL */ `
            # Create a new user
            mutation createUser {
              # ...
            }
          `,
        },
      ],
      configOptions: [
        {
          types: true,
          [Kind.DIRECTIVE_DEFINITION]: true,
        },
      ],
      recommended: true,
    },
    type: 'suggestion',
    messages: {
      [RULE_ID]: 'Description is required for `{{ nodeName }}`.',
    },
    schema: {
      type: 'array',
      minItems: 1,
      maxItems: 1,
      items: {
        type: 'object',
        additionalProperties: false,
        minProperties: 1,
        properties: {
          types: {
            type: 'boolean',
            description: `Includes:\n\n${TYPES_KINDS.map(kind => `- \`${kind}\``).join('\n')}`,
          },
          ...Object.fromEntries(
            [...ALLOWED_KINDS].sort().map(kind => {
              let description = `Read more about this kind on [spec.graphql.org](https://spec.graphql.org/October2021/#${kind}).`;
              if (kind === Kind.OPERATION_DEFINITION) {
                description += '\n\n> You must use only comment syntax `#` and not description syntax `"""` or `"`.';
              }
              return [kind, { type: 'boolean', description }];
            })
          ),
        },
      },
    },
  },
  create(context) {
    const { types, ...restOptions } = context.options[0] || {};

    const kinds = new Set<string>(types ? TYPES_KINDS : []);
    for (const [kind, isEnabled] of Object.entries(restOptions)) {
      if (isEnabled) {
        kinds.add(kind);
      } else {
        kinds.delete(kind);
      }
    }

    const selector = [...kinds].join(',');

    return {
      [selector](node: SelectorNode) {
        let description = '';
        const isOperation = node.kind === Kind.OPERATION_DEFINITION;
        if (isOperation) {
          const rawNode = node.rawNode();
          const { prev, line } = rawNode.loc.startToken;
          if (prev.kind === TokenKind.COMMENT) {
            const value = prev.value.trim();
            const linesBefore = line - prev.line;
            if (!value.startsWith('eslint') && linesBefore === 1) {
              description = value;
            }
          }
        } else {
          description = node.description?.value.trim() || '';
        }

        if (description.length === 0) {
          context.report({
            loc: isOperation ? getLocation(node.loc.start, node.operation) : node.name.loc,
            messageId: RULE_ID,
            data: {
              nodeName: getNodeName(node),
            },
          });
        }
      },
    };
  },
}