eslint#Linter TypeScript Examples

The following examples show how to use eslint#Linter. 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: testkit.ts    From graphql-eslint with MIT License 6 votes vote down vote up
function defineParser(linter: Linter, parser: string): void {
  if (!parser) {
    return;
  }
  if (!parsers.has(linter)) {
    parsers.set(linter, new Set());
  }

  const defined = parsers.get(linter);
  if (!defined.has(parser)) {
    defined.add(parser);
    linter.defineParser(parser, require(parser));
  }
}
Example #2
Source File: testkit.ts    From graphql-eslint with MIT License 6 votes vote down vote up
function printCode(
  code: string,
  result: Partial<Linter.LintMessage> = {},
  linesOffset = Number.POSITIVE_INFINITY
): string {
  const { line, column, endLine, endColumn, message } = result;
  const location = <AST.SourceLocation>{};

  if (typeof line === 'number' && typeof column === 'number') {
    location.start = {
      line,
      column,
    };
  }

  if (typeof endLine === 'number' && typeof endColumn === 'number') {
    location.end = {
      line: endLine,
      column: endColumn,
    };
  }

  return codeFrameColumns(code, location, {
    linesAbove: linesOffset,
    linesBelow: linesOffset,
    message,
  });
}
Example #3
Source File: CodeLinter.ts    From yumeko with GNU Affero General Public License v3.0 6 votes vote down vote up
export function lint(content: string, ecmaVersion: Linter.ParserOptions["ecmaVersion"], rules: Partial<Linter.RulesRecord> ): Linter.LintMessage[] {
    if (/\bawait\b/i.test(content)) content = stripIndents`
        (async function () {
            ${content}
        })()
    `;
    const errors = linter.verify(content, {
        extends: "eslint:recommended",
        parserOptions: {
            ecmaVersion,
            sourceType: "module"
        },
        env: {
            es6: true,
            node: true
        },
        rules
    });
    return errors;
}
Example #4
Source File: Lint.ts    From yumeko with GNU Affero General Public License v3.0 6 votes vote down vote up
public constructor (client: YumekoClient) {
        super(client, "lint", {
            aliases: ["lint"],
            description: {
                content: "Lint your code",
                usage: "lint <code> [--ecma=<version>]",
                examples: ["lint \\`\\`\\`1+1\\`\\`\\`"]
            },
            category: "utility",
            permissions: {
                client: ["EMBED_LINKS", "ADD_REACTIONS"]
            },
            args: [
                {
                    identifier: "ecma",
                    match: "flag",
                    flag: "ecma",
                    default: 2018,
                    type: (_: Message, content: string): Linter.ParserOptions["ecmaVersion"] => {
                        const typeNumber = this.collector.runner.argsParser.getType("number");
                        const result: number = typeNumber(_, content) as any;
                        if (!ecmaVersions.includes(result)) throw new CustomError("!PARSING", `**Unsupported ECMA version. only supported: ${ecmaVersions.map(x => `\`${x}\``).join(", ")}**`);
                        return result as Linter.ParserOptions["ecmaVersion"];
                    }
                },
                {
                    identifier: "script",
                    match: "rest",
                    prompt: "What code do you want to lint ?",
                    type: (_: Message, content: string): TypeCodeReturn => {
                        const typeCode = this.collector.runner.argsParser.getType("code");
                        const result: TypeCodeReturn = typeCode(_, content) as any;
                        if (!result.lang || !["js", "javascript", "json"].includes(result.lang)) throw new CustomError("!PARSING", "Unsupported language. only supported `Javascript` and `JSON`**");
                        return result;
                    }
                }
            ]
        });
    }
Example #5
Source File: testing.ts    From eslint-config-kit with MIT License 6 votes vote down vote up
export async function testConfig({ config, files, extension }: Options) {
  const cli = new ESLint({
    baseConfig: config as Linter.Config<Linter.RulesRecord>,
    useEslintrc: false,
    cwd: path.resolve(process.cwd(), '../..'),
    ignore: false,
  })

  for (const file of files) {
    const filePath = path.resolve(process.cwd(), `./tests/${file}.${extension}`)
    const code = fs.readFileSync(filePath).toString()
    const isTS = ['ts', 'tsx'].includes(extension)
    const result = await cli.lintText(code, {
      filePath: isTS ? filePath : undefined,
    })
    expect(result).toMatchSnapshot()
  }
}
Example #6
Source File: Lint.ts    From yumeko with GNU Affero General Public License v3.0 6 votes vote down vote up
public anotate(code: string, errors: Linter.LintMessage[]): string {
        const splitted = code.split("\n");
        const results: string[] = [];
        for (const error of errors) {
            const line = splitted[error.line - 1];
            const anotation = `${" ".repeat(error.column - 1)}^ `;
            const reason = `[${error.line}:${error.column}] ${error.message}`;
            results.push(`${line}\n${anotation}\n${reason}`);
        }
        return trimArray(results).join("\n");
    }
Example #7
Source File: Lint.ts    From yumeko with GNU Affero General Public License v3.0 6 votes vote down vote up
public exec(msg: Message, { script, ecma }: { script: TypeCodeReturn; ecma: Linter.ParserOptions["ecmaVersion"]}, send = true): MessageEmbed|boolean {
        const embed = new MessageEmbed().setColor("RED");
        if (script.lang === "json") {
            try {
                JSON.parse(script.code);
                msg.react("734220684825329775");
                return true;
            } catch (e) {
                embed.setDescription(stripIndents`
                    ⛔ **Error**
                    ${codeBlock("js", String(e))}
                `);
                if (send) msg.ctx.send(embed);
                return embed;
            }
        }
        const errors = lint(script.code, ecma, { "no-console": 0 });
        if (!errors.length) {
            msg.react("734220684825329775");
            return true;
        }
        embed.setDescription(stripIndents`
            ⛔ **Errors**
            ${codeBlock("js", errors.map(x => `- [${x.line}:${x.column}] ${x.message}`).join("\n"))}
            ? **Annotated**
            ${codeBlock("js", this.anotate(script.code, errors))}
        `);
        if (send) msg.ctx.send(embed);
        return embed;
    }
Example #8
Source File: get-auto-jsonc-rules-config.ts    From eslint-plugin-jsonc with MIT License 6 votes vote down vote up
/**
 * Get config for the given filename
 * @param filename
 */
function getConfig(filename: string): Linter.Config {
    while (!isValidFilename(filename)) {
        const dir = dirname(filename)
        if (dir === filename) {
            return {}
        }
        // eslint-disable-next-line no-param-reassign -- ignore
        filename = dir
    }
    return getConfigResolver()(filename)
}
Example #9
Source File: get-auto-jsonc-rules-config.ts    From eslint-plugin-jsonc with MIT License 6 votes vote down vote up
/**
 * Get additional jsonc rules config from fileName
 * @param filename
 */
export function getAutoConfig(filename: string): {
    [name: string]: Linter.RuleEntry
} {
    const autoConfig: { [name: string]: Linter.RuleEntry } = {}

    const config = getConfig(filename)
    if (config.rules) {
        for (const ruleName of Object.keys(config.rules)) {
            const jsoncName = getJsoncRule(ruleName)
            if (jsoncName && !config.rules[jsoncName]) {
                const entry = config.rules[ruleName]
                if (entry && entry !== "off") {
                    autoConfig[jsoncName] = entry
                }
            }
        }
    }
    return autoConfig
}
Example #10
Source File: comma-dangle.ts    From eslint-plugin-jsonc with MIT License 6 votes vote down vote up
tester.run("comma-dangle", rule as any, {
    valid: ['{"key": "value"}'],
    invalid: [
        {
            code: '{"key": "value",}',
            output: '{"key": "value"}',
            errors: ["Unexpected trailing comma."],
        },
        {
            code: '{"key": [1,2],}',
            output: semver.gte(Linter.version, "8.11.0")
                ? '{"key": [1,2,],}'
                : '{"key": [1,2,]}',
            options: [{ arrays: "always", objects: "never" }],
            errors: ["Missing trailing comma.", "Unexpected trailing comma."],
        },
        {
            filename: "test.vue",
            code: `<i18n>{"key": "value",}</i18n><custom-block>{"key": "value",}</custom-block>`,
            output: `<i18n>{"key": "value"}</i18n><custom-block>{"key": "value",}</custom-block>`,
            parser: require.resolve("vue-eslint-parser"),
            errors: ["Unexpected trailing comma."],
        },
    ],
})
Example #11
Source File: CodeLinter.ts    From yumeko with GNU Affero General Public License v3.0 5 votes vote down vote up
linter = new Linter()
Example #12
Source File: processor.ts    From graphql-eslint with MIT License 5 votes vote down vote up
processor: Linter.Processor<Block | string> = {
  supportsAutofix: true,
  preprocess(code, filePath) {
    if (RELEVANT_KEYWORDS.every(keyword => !code.includes(keyword))) {
      return [code];
    }
    const extractedDocuments = parseCode({
      code,
      filePath,
      options: {
        globalGqlIdentifierName: ['gql', 'graphql'],
        skipIndent: true,
      },
    });

    const blocks: Block[] = extractedDocuments.map(item => ({
      filename: 'document.graphql',
      text: item.content,
      lineOffset: item.loc.start.line - 1,
      offset: item.start + 1,
    }));
    blocksMap.set(filePath, blocks);

    return [...blocks, code /* source code must be provided and be last */];
  },
  postprocess(messages, filePath) {
    const blocks = blocksMap.get(filePath) || [];
    for (let i = 0; i < blocks.length; i += 1) {
      const { lineOffset, offset } = blocks[i];

      for (const message of messages[i]) {
        message.line += lineOffset;
        // endLine can not exist if only `loc: { start, column }` was provided to context.report
        if (typeof message.endLine === 'number') {
          message.endLine += lineOffset;
        }
        if (message.fix) {
          message.fix.range[0] += offset;
          message.fix.range[1] += offset;
        }
        for (const suggestion of message.suggestions || []) {
          suggestion.fix.range[0] += offset;
          suggestion.fix.range[1] += offset;
        }
      }
    }

    return messages.flat();
  },
}
Example #13
Source File: get-auto-jsonc-rules-config.ts    From eslint-plugin-jsonc with MIT License 5 votes vote down vote up
configResolver: (filePath: string) => Linter.Config
Example #14
Source File: get-auto-jsonc-rules-config.ts    From eslint-plugin-jsonc with MIT License 5 votes vote down vote up
/**
 * Get config resolver
 */
function getConfigResolver(): (filePath: string) => Linter.Config {
    if (configResolver) {
        return configResolver
    }

    // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -- special
    const plugin = require("..")
    try {
        // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -- special
        const eslintrc = require("@eslint/eslintrc")
        const configArrayFactory =
            new eslintrc.Legacy.CascadingConfigArrayFactory({
                additionalPluginPool: new Map([
                    ["eslint-plugin-jsonc", plugin],
                ]),
                getEslintRecommendedConfig() {
                    // eslint-disable-next-line @typescript-eslint/no-require-imports -- ignore
                    return require("../../conf/eslint-recommended.js")
                },
                getEslintAllConfig() {
                    // eslint-disable-next-line @typescript-eslint/no-require-imports -- ignore
                    return require("../../conf/eslint-all.js")
                },
                // for v1.1.0
                eslintRecommendedPath: require.resolve(
                    "../../conf/eslint-recommended.js",
                ),
                eslintAllPath: require.resolve("../../conf/eslint-all.js"),
            })

        return (configResolver = (filePath: string) => {
            const absolutePath = resolve(process.cwd(), filePath)
            return configArrayFactory
                .getConfigArrayForFile(absolutePath)
                .extractConfig(absolutePath)
                .toCompatibleObjectAsConfigFileContent()
        })
    } catch {
        // ignore
    }
    try {
        // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -- special
        const eslint = require("eslint")
        const engine = new eslint.CLIEngine({})
        engine.addPlugin("eslint-plugin-jsonc", plugin)
        return (configResolver = (filePath) => {
            return engine.getConfigForFile(filePath)
        })
    } catch {
        // ignore
    }

    return () => ({})
}
Example #15
Source File: eslint-config.ts    From utopia with MIT License 5 votes vote down vote up
EsLintRecommended: Linter.RulesRecord = {
  // Currently on 6.8.0 ruleset: https://github.com/eslint/eslint/blob/v6.8.0/conf/eslint-recommended.js
  // This requires manually updating on each release. Urgh.
  'constructor-super': 'error',
  'for-direction': 'error',
  'getter-return': 'error',
  'no-async-promise-executor': 'error',
  'no-case-declarations': 'error',
  'no-class-assign': 'error',
  'no-compare-neg-zero': 'error',
  'no-cond-assign': 'error',
  'no-const-assign': 'error',
  'no-constant-condition': 'error',
  'no-control-regex': 'error',
  'no-debugger': 'error',
  'no-delete-var': 'error',
  'no-dupe-args': 'error',
  'no-dupe-class-members': 'error',
  'no-dupe-keys': 'error',
  'no-duplicate-case': 'error',
  'no-empty': 'error',
  'no-empty-character-class': 'error',
  'no-empty-pattern': 'error',
  'no-ex-assign': 'error',
  'no-extra-boolean-cast': 'error',
  'no-extra-semi': 'error',
  'no-fallthrough': 'error',
  'no-func-assign': 'error',
  'no-global-assign': 'error',
  'no-inner-declarations': 'error',
  'no-invalid-regexp': 'error',
  'no-irregular-whitespace': 'error',
  'no-misleading-character-class': 'error',
  'no-mixed-spaces-and-tabs': 'error',
  'no-new-symbol': 'error',
  'no-obj-calls': 'error',
  'no-octal': 'error',
  'no-prototype-builtins': 'error',
  'no-redeclare': 'error',
  'no-regex-spaces': 'error',
  'no-self-assign': 'error',
  'no-shadow-restricted-names': 'error',
  'no-sparse-arrays': 'error',
  'no-this-before-super': 'error',
  'no-undef': 'error',
  'no-unexpected-multiline': 'error',
  'no-unreachable': 'error',
  'no-unsafe-finally': 'error',
  'no-unsafe-negation': 'error',
  'no-unused-labels': 'error',
  'no-unused-vars': 'warn',
  'no-useless-catch': 'error',
  'no-useless-escape': 'error',
  'no-with': 'error',
  'require-yield': 'error',
  'use-isnan': 'error',
  'valid-typeof': 'error',
}
Example #16
Source File: auto.ts    From eslint-plugin-jsonc with MIT License 4 votes vote down vote up
tester.run("auto", rule as any, {
    valid: [
        {
            filename: path.join(ROOT_DIR, "test01", "sfc.vue"),
            code: `
<i18n>
{
    "foo": "bar"
}
</i18n>`,
            parser: require.resolve("vue-eslint-parser"),
        },
    ],
    invalid: [
        {
            filename: path.join(ROOT_DIR, "test01", "sfc.vue"),
            code: `
<i18n>
{
"foo": "bar"
    }
</i18n>
<block lang="json">
[1,[
    1,
    2 ],2]
</block>
<block lang="json">
{"a":1
    ,"b":2,}
</block>
<block lang="json">
{ "foo": 1,"bar": 2,"foo": 3 }
</block>`,
            output: `
<i18n>
{
    "foo": "bar"
}
</i18n>
<block lang="json">
[
1,
[
    1,
    2],
2
]
</block>
<block lang="json">
{"a": 1,
    "b": 2${semver.gte(Linter.version, "8.11.0") ? "," : ""}}
</block>
<block lang="json">
{"foo": 1,
"bar": 2,
"foo": 3}
</block>`,
            parser: require.resolve("vue-eslint-parser"),
            errors: [
                "[jsonc/indent] Expected indentation of 4 spaces but found 0.",
                "[jsonc/indent] Expected indentation of 0 spaces but found 4.",

                "[jsonc/array-bracket-newline] A linebreak is required after '['.",
                "[jsonc/array-element-newline] There should be a linebreak after this element.",
                "[jsonc/array-bracket-spacing] There should be no space before ']'.",
                "[jsonc/array-bracket-newline] A linebreak is required before ']'.",
                "[jsonc/array-element-newline] There should be a linebreak after this element.",
                "[jsonc/array-bracket-newline] A linebreak is required before ']'.",

                "[jsonc/key-spacing] Missing space before value for key 'a'.",
                "[jsonc/comma-style] ',' should be placed last.",
                "[jsonc/key-spacing] Missing space before value for key 'b'.",
                "[jsonc/comma-dangle] Unexpected trailing comma.",

                "[jsonc/object-curly-spacing] There should be no space after '{'.",
                "[jsonc/object-property-newline] Object properties must go on a new line.",
                "[jsonc/sort-keys] Expected object keys to be in ascending order. 'bar' should be before 'foo'.",
                "[jsonc/object-property-newline] Object properties must go on a new line.",
                "[jsonc/no-dupe-keys] Duplicate key 'foo'.",
                "[jsonc/object-curly-spacing] There should be no space before '}'.",
            ],
        },
        {
            filename: path.join(ROOT_DIR, "test02", "sfc.vue"),
            code: `
<i18n>
{
"foo": "bar"
    }
</i18n>`,
            output: `
<i18n>
{
    "foo": "bar"
}
</i18n>`,
            parser: require.resolve("vue-eslint-parser"),
            errors: [
                "[jsonc/indent] Expected indentation of 4 spaces but found 0.",
                "[jsonc/indent] Expected indentation of 0 spaces but found 4.",
            ],
        },
    ],
})
Example #17
Source File: eslintConfig.ts    From react-native-decompiler with GNU Affero General Public License v3.0 4 votes vote down vote up
eslintConfig: Linter.Config = {
  env: {
    node: true,
  },
  parserOptions: {
    ecmaVersion: 2020,
    ecmaFeatures: {
      jsx: true,
    },
    sourceType: 'module',
  },
  plugins: [
    'react',
    'import',
  ],
  rules: {
    'one-var': ['error', 'never'],
    'no-var': 'error',
    'prefer-const': ['error', {
      destructuring: 'any',
      ignoreReadBeforeAssign: true,
    }],
    'prefer-arrow-callback': ['error', {
      allowNamedFunctions: false,
      allowUnboundThis: true,
    }],
    eqeqeq: ['error', 'always', { null: 'ignore' }],
    semi: ['error', 'always'],
    'arrow-body-style': ['error', 'as-needed', {
      requireReturnForObjectLiteral: false,
    }],
    'no-confusing-arrow': ['error', {
      allowParens: true,
    }],
    'eol-last': ['error', 'always'],
    indent: ['error', 2, {
      SwitchCase: 1,
      VariableDeclarator: 1,
      outerIIFEBody: 1,
      // MemberExpression: null,
      FunctionDeclaration: {
        parameters: 1,
        body: 1,
      },
      FunctionExpression: {
        parameters: 1,
        body: 1,
      },
      CallExpression: {
        arguments: 1,
      },
      ArrayExpression: 1,
      ObjectExpression: 1,
      ImportDeclaration: 1,
      flatTernaryExpressions: false,
      // list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js
      // eslint-disable-next-line max-len
      ignoredNodes: ['JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXFragment', 'JSXOpeningFragment', 'JSXClosingFragment', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
      ignoreComments: false,
    }],
    'object-shorthand': ['error', 'always', {
      ignoreConstructors: false,
      avoidQuotes: true,
    }],
    'comma-dangle': ['error', {
      arrays: 'always-multiline',
      objects: 'always-multiline',
      imports: 'always-multiline',
      exports: 'always-multiline',
      functions: 'always-multiline',
    }],
    'space-before-function-paren': ['error', {
      anonymous: 'always',
      named: 'never',
      asyncArrow: 'always',
    }],
    curly: ['error', 'all'],
    'block-spacing': ['error', 'always'],
    'brace-style': ['error', '1tbs', { allowSingleLine: true }],
    yoda: 'error',
    'no-trailing-spaces': ['error', {
      skipBlankLines: false,
      ignoreComments: false,
    }],
    'prefer-template': 'error',
    'template-curly-spacing': 'error',
    'no-else-return': 'error',
    'react/jsx-one-expression-per-line': 'error',
    'no-undef-init': 'error',
    'prefer-object-spread': 'error',
    'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
    'import/newline-after-import': 'error',
    'import/first': 'error',
  },
}
Example #18
Source File: eslintConfig.ts    From react-native-decompiler with GNU Affero General Public License v3.0 4 votes vote down vote up
eslintConfig: Linter.Config = {
  env: {
    node: true,
  },
  parserOptions: {
    ecmaVersion: 2020,
    ecmaFeatures: {
      jsx: true,
    },
    sourceType: 'module',
  },
  plugins: [
    'react',
    'import',
  ],
  rules: {
    'one-var': ['error', 'never'],
    'no-var': 'error',
    'prefer-const': ['error', {
      destructuring: 'any',
      ignoreReadBeforeAssign: true,
    }],
    'prefer-arrow-callback': ['error', {
      allowNamedFunctions: false,
      allowUnboundThis: true,
    }],
    eqeqeq: ['error', 'always', { null: 'ignore' }],
    semi: ['error', 'always'],
    'arrow-body-style': ['error', 'as-needed', {
      requireReturnForObjectLiteral: false,
    }],
    'no-confusing-arrow': ['error', {
      allowParens: true,
    }],
    'eol-last': ['error', 'always'],
    indent: ['error', 2, {
      SwitchCase: 1,
      VariableDeclarator: 1,
      outerIIFEBody: 1,
      // MemberExpression: null,
      FunctionDeclaration: {
        parameters: 1,
        body: 1,
      },
      FunctionExpression: {
        parameters: 1,
        body: 1,
      },
      CallExpression: {
        arguments: 1,
      },
      ArrayExpression: 1,
      ObjectExpression: 1,
      ImportDeclaration: 1,
      flatTernaryExpressions: false,
      // list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js
      // eslint-disable-next-line max-len
      ignoredNodes: ['JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXFragment', 'JSXOpeningFragment', 'JSXClosingFragment', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
      ignoreComments: false,
    }],
    'object-shorthand': ['error', 'always', {
      ignoreConstructors: false,
      avoidQuotes: true,
    }],
    'comma-dangle': ['error', {
      arrays: 'always-multiline',
      objects: 'always-multiline',
      imports: 'always-multiline',
      exports: 'always-multiline',
      functions: 'always-multiline',
    }],
    'space-before-function-paren': ['error', {
      anonymous: 'always',
      named: 'never',
      asyncArrow: 'always',
    }],
    curly: ['error', 'all'],
    'block-spacing': ['error', 'always'],
    'brace-style': ['error', '1tbs', { allowSingleLine: true }],
    yoda: 'error',
    'no-trailing-spaces': ['error', {
      skipBlankLines: false,
      ignoreComments: false,
    }],
    'prefer-template': 'error',
    'template-curly-spacing': 'error',
    'no-else-return': 'error',
    'react/jsx-one-expression-per-line': 'error',
    'no-undef-init': 'error',
    'prefer-object-spread': 'error',
    'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
    'import/newline-after-import': 'error',
    'import/first': 'error',
  },
}
Example #19
Source File: eslint-config.ts    From utopia with MIT License 4 votes vote down vote up
ESLINT_CONFIG: Linter.Config = {
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
      modules: true,
    },
  },
  env: {
    es2020: true,
    browser: true,
  },
  extends: [], // Not supported in browser - to add these, you have to explicitly add them below
  plugins: [], // plugin rules are loaded using the CustomUtopiaLinter
  globals: {
    __DEV__: false,
    __dirname: false,
    alert: false,
    Blob: false,
    cancelAnimationFrame: false,
    cancelIdleCallback: false,
    clearImmediate: true,
    clearInterval: false,
    clearTimeout: false,
    console: false,
    escape: false,
    Event: false,
    EventTarget: false,
    exports: false,
    fetch: false,
    File: false,
    FileReader: false,
    FormData: false,
    global: false,
    Map: true,
    module: false,
    navigator: false,
    process: false,
    Promise: true,
    requestAnimationFrame: true,
    requestIdleCallback: true,
    require: false,
    Set: true,
    setImmediate: true,
    setInterval: false,
    setTimeout: false,
    WebSocket: false,
    window: false,
    XMLHttpRequest: false,
  },
  rules: {
    ...EsLintRecommended,
    // basic eslint rules
    // http://eslint.org/docs/rules/
    'array-callback-return': 'warn',
    'default-case': ['warn', { commentPattern: '^no default$' }],
    'dot-location': ['warn', 'property'],
    eqeqeq: ['warn', 'smart'],
    'new-parens': 'warn',
    'no-array-constructor': 'warn',
    'no-caller': 'warn',
    'no-cond-assign': ['warn', 'except-parens'],
    'no-const-assign': 'warn',
    'no-control-regex': 'warn',
    'no-delete-var': 'warn',
    'no-dupe-args': 'warn',
    'no-dupe-class-members': 'warn',
    'no-dupe-keys': 'warn',
    'no-duplicate-case': 'warn',
    'no-empty-character-class': 'warn',
    'no-empty-pattern': 'warn',
    'no-eval': 'warn',
    'no-ex-assign': 'warn',
    'no-extend-native': 'warn',
    'no-extra-bind': 'warn',
    'no-extra-label': 'warn',
    'no-fallthrough': 'warn',
    'no-func-assign': 'warn',
    'no-implied-eval': 'warn',
    'no-invalid-regexp': 'warn',
    'no-iterator': 'warn',
    'no-label-var': 'warn',
    'no-labels': ['warn', { allowLoop: true, allowSwitch: false }],
    'no-lone-blocks': 'warn',
    'no-loop-func': 'warn',
    'no-mixed-operators': [
      'warn',
      {
        groups: [
          ['&', '|', '^', '~', '<<', '>>', '>>>'],
          ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
          ['&&', '||'],
          ['in', 'instanceof'],
        ],
        allowSamePrecedence: false,
      },
    ],
    'no-multi-str': 'warn',
    'no-native-reassign': 'warn',
    'no-negated-in-lhs': 'warn',
    'no-new-func': 'warn',
    'no-new-object': 'warn',
    'no-new-symbol': 'warn',
    'no-new-wrappers': 'warn',
    'no-obj-calls': 'warn',
    'no-octal': 'warn',
    'no-octal-escape': 'warn',
    'no-regex-spaces': 'warn',
    'no-restricted-syntax': ['warn', 'WithStatement'],
    'no-script-url': 'warn',
    'no-self-assign': 'warn',
    'no-self-compare': 'warn',
    'no-sequences': 'warn',
    'no-shadow-restricted-names': 'warn',
    'no-sparse-arrays': 'warn',
    'no-template-curly-in-string': 'warn',
    'no-this-before-super': 'warn',
    'no-throw-literal': 'warn',
    'no-undef': 'error',
    'no-unreachable': 'warn',
    'no-unused-expressions': [
      'error',
      {
        allowShortCircuit: true,
        allowTernary: true,
        allowTaggedTemplates: true,
      },
    ],
    'no-unused-labels': 'warn',
    // disabling 'no-unused-vars' because the current ui.js is not working nicely with it
    // 'no-unused-vars': [
    //   'warn',
    //   {
    //     args: 'none',
    //     ignoreRestSiblings: true,
    //   },
    // ],
    'no-use-before-define': [
      'error',
      {
        functions: false,
        classes: true,
        variables: true,
      },
    ],
    'no-useless-computed-key': 'warn',
    'no-useless-concat': 'warn',
    'no-useless-constructor': 'warn',
    'no-useless-escape': 'warn',
    'no-useless-rename': [
      'warn',
      {
        ignoreDestructuring: false,
        ignoreImport: false,
        ignoreExport: false,
      },
    ],
    'no-with': 'warn',
    'no-whitespace-before-property': 'warn',
    'require-yield': 'warn',
    'rest-spread-spacing': ['warn', 'never'],
    strict: ['warn', 'never'],
    'unicode-bom': ['warn', 'never'],
    'use-isnan': 'warn',
    'valid-typeof': 'warn',
    'no-restricted-properties': [
      'error',
      {
        object: 'require',
        property: 'ensure',
        message:
          'Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting',
      },
      {
        object: 'System',
        property: 'import',
        message:
          'Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting',
      },
    ],
    'getter-return': 'warn',

    // PLUGINS
    // to use a rule from a plugin please add and load them first in EslintPluginRules

    // https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules
    'react/forbid-foreign-prop-types': ['warn', { allowInPropTypes: true }],
    'react/jsx-no-comment-textnodes': 'warn',
    'react/jsx-no-duplicate-props': 'warn',
    'react/jsx-no-target-blank': 'warn',
    'react/jsx-no-undef': 'error',
    'react/jsx-pascal-case': [
      'warn',
      {
        allowAllCaps: true,
        ignore: [],
      },
    ],
    'react/jsx-uses-vars': 'warn',
    'react/no-danger-with-children': 'warn',
    'react/no-deprecated': 'warn',
    'react/no-direct-mutation-state': 'warn',
    'react/no-is-mounted': 'warn',
    'react/no-typos': 'error',
    'react/require-render-return': 'error',
    'react/style-prop-object': 'warn',

    // https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks
    'react-hooks/exhaustive-deps': 'warn',
    'react-hooks/rules-of-hooks': 'error',

    // https://github.com/benmosher/eslint-plugin-import/tree/master/docs/rules
    'import/first': 'error',
    'import/no-amd': 'error',
    'import/no-webpack-loader-syntax': 'error',

    // https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules
    'jsx-a11y/accessible-emoji': 'warn',
    'jsx-a11y/alt-text': 'warn',
    'jsx-a11y/anchor-has-content': 'warn',
    'jsx-a11y/anchor-is-valid': [
      'warn',
      {
        aspects: ['noHref', 'invalidHref'],
      },
    ],
    'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
    'jsx-a11y/aria-props': 'warn',
    'jsx-a11y/aria-proptypes': 'warn',
    'jsx-a11y/aria-role': ['warn', { ignoreNonDOM: true }],
    'jsx-a11y/aria-unsupported-elements': 'warn',
    'jsx-a11y/heading-has-content': 'warn',
    'jsx-a11y/iframe-has-title': 'warn',
    'jsx-a11y/img-redundant-alt': 'warn',
    'jsx-a11y/no-access-key': 'warn',
    'jsx-a11y/no-distracting-elements': 'warn',
    'jsx-a11y/no-redundant-roles': 'warn',
    'jsx-a11y/role-has-required-aria-props': 'warn',
    'jsx-a11y/role-supports-aria-props': 'warn',
    'jsx-a11y/scope': 'warn',
  },
  settings: {
    react: {
      version: '17.0.0-rc.1',
    },
  },
}
Example #20
Source File: testkit.ts    From graphql-eslint with MIT License 4 votes vote down vote up
runGraphQLTests<Options, WithTypeInfo extends boolean = false>(
    ruleId: string,
    rule: GraphQLESLintRule<Options, WithTypeInfo>,
    tests: {
      valid: (string | GraphQLValidTestCase<Options>)[];
      invalid: GraphQLInvalidTestCase<Options>[];
    }
  ): void {
    const ruleTests = Linter.version.startsWith('8')
      ? tests
      : {
          valid: tests.valid.map(test => {
            if (typeof test === 'string') {
              return test;
            }
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const { name, ...testCaseOptions } = test;
            return testCaseOptions;
          }),
          invalid: tests.invalid.map(test => {
            // ESLint 7 throws an error on CI - Unexpected top-level property "name"
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            const { name, ...testCaseOptions } = test;
            return testCaseOptions;
          }),
        };
    super.run(ruleId, rule as any, ruleTests);

    const linter = new Linter();
    linter.defineRule(ruleId, rule as any);

    const hasOnlyTest = [...tests.valid, ...tests.invalid].some(t => typeof t !== 'string' && t.only);

    // for (const [index, testCase] of tests.valid.entries()) {
    //   const { name, code, filename, only }: RuleTester.ValidTestCase =
    //     typeof testCase === 'string' ? { code: testCase } : testCase;
    //
    //   if (hasOnlyTest && !only) {
    //     continue;
    //   }
    //
    //   const verifyConfig = getVerifyConfig(ruleId, this.config, testCase);
    //   defineParser(linter, verifyConfig.parser);
    //
    //   const messages = linter.verify(code, verifyConfig, { filename });
    //   const codeFrame = printCode(code, { line: 0, column: 0 });
    //
    //   it(name || `Valid #${index + 1}\n${codeFrame}`, () => {
    //     expect(messages).toEqual([]);
    //   });
    // }

    for (const [idx, testCase] of tests.invalid.entries()) {
      const { only, filename, options, name } = testCase;
      if (hasOnlyTest && !only) {
        continue;
      }

      const code = removeTrailingBlankLines(testCase.code);
      const verifyConfig = getVerifyConfig(ruleId, this.config, testCase);
      defineParser(linter, verifyConfig.parser);

      const messages = linter.verify(code, verifyConfig, filename);
      if (messages.length === 0) {
        throw new Error('Invalid case should have at least one error.');
      }
      const codeFrame = indentCode(printCode(code, { line: 0, column: 0 }));
      const messageForSnapshot = ['#### ⌨️ Code', codeFrame];

      if (options) {
        const opts = JSON.stringify(options, null, 2).slice(1, -1);
        messageForSnapshot.push('#### ⚙️ Options', indentCode(removeTrailingBlankLines(opts), 2));
      }

      for (const [index, message] of messages.entries()) {
        if (message.fatal) {
          throw new Error(message.message);
        }

        const codeWithMessage = printCode(code, message, 1);
        messageForSnapshot.push(printWithIndex('#### ❌ Error', index, messages.length), indentCode(codeWithMessage));

        const { suggestions } = message;

        // Don't print suggestions in snapshots for too big codes
        if (suggestions && (code.match(/\n/g) || '').length < 1000) {
          for (const [i, suggestion] of message.suggestions.entries()) {
            const title = printWithIndex('#### ? Suggestion', i, suggestions.length, suggestion.desc);
            const output = applyFix(code, suggestion.fix);
            const codeFrame = printCode(output, { line: 0, column: 0 });
            messageForSnapshot.push(title, indentCode(codeFrame, 2));
          }
        }
      }

      if (rule.meta.fixable) {
        const { fixed, output } = linter.verifyAndFix(code, verifyConfig, filename);
        if (fixed) {
          messageForSnapshot.push('#### ? Autofix output', indentCode(printCode(output)));
        }
      }
      it(name || `Invalid #${idx + 1}`, () => {
        expect(messageForSnapshot.join('\n\n')).toMatchSnapshot();
      });
    }
  }