Migrate to ESLint 9 with flat config (#57110)
This commit is contained in:
227
eslint.config.js
Normal file
227
eslint.config.js
Normal file
@@ -0,0 +1,227 @@
|
||||
import js from '@eslint/js'
|
||||
import tseslint from '@typescript-eslint/eslint-plugin'
|
||||
import tsParser from '@typescript-eslint/parser'
|
||||
import github from 'eslint-plugin-github'
|
||||
import importPlugin from 'eslint-plugin-import'
|
||||
import jsxA11y from 'eslint-plugin-jsx-a11y'
|
||||
import primerReact from 'eslint-plugin-primer-react'
|
||||
import eslintComments from 'eslint-plugin-eslint-comments'
|
||||
import i18nText from 'eslint-plugin-i18n-text'
|
||||
import filenames from 'eslint-plugin-filenames'
|
||||
import noOnlyTests from 'eslint-plugin-no-only-tests'
|
||||
import prettierPlugin from 'eslint-plugin-prettier'
|
||||
import prettier from 'eslint-config-prettier'
|
||||
import globals from 'globals'
|
||||
|
||||
export default [
|
||||
// JavaScript and MJS files configuration
|
||||
{
|
||||
files: ['**/*.{js,mjs}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
...globals.commonjs,
|
||||
...globals.es2020,
|
||||
},
|
||||
parserOptions: {
|
||||
requireConfigFile: false,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: true,
|
||||
node: true,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
github,
|
||||
import: importPlugin,
|
||||
'eslint-comments': eslintComments,
|
||||
'i18n-text': i18nText,
|
||||
filenames,
|
||||
'no-only-tests': noOnlyTests,
|
||||
prettier: prettierPlugin,
|
||||
},
|
||||
rules: {
|
||||
// ESLint recommended rules
|
||||
...js.configs.recommended.rules,
|
||||
|
||||
// GitHub plugin recommended rules
|
||||
...github.configs.recommended.rules,
|
||||
|
||||
// Import plugin error rules
|
||||
...importPlugin.configs.errors.rules,
|
||||
|
||||
// JavaScript-specific overrides
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
{
|
||||
packageDir: '.',
|
||||
},
|
||||
],
|
||||
'import/extensions': 'off',
|
||||
'no-console': 'off',
|
||||
camelcase: 'off',
|
||||
'no-shadow': 'off',
|
||||
'prefer-template': 'off',
|
||||
'no-constant-condition': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'import/no-named-as-default-member': 'off',
|
||||
'one-var': 'off',
|
||||
'import/no-namespace': 'off',
|
||||
'import/no-anonymous-default-export': 'off',
|
||||
'object-shorthand': 'off',
|
||||
'no-empty': 'off',
|
||||
'prefer-const': 'off',
|
||||
'import/no-named-as-default': 'off',
|
||||
'no-useless-concat': 'off',
|
||||
'func-style': 'off',
|
||||
|
||||
// Disable GitHub plugin rules that were disabled in original config
|
||||
'github/array-foreach': 'off',
|
||||
'github/no-then': 'off',
|
||||
|
||||
// Disable rules that might not exist or cause issues initially
|
||||
'i18n-text/no-en': 'off',
|
||||
'filenames/match-regex': 'off',
|
||||
'eslint-comments/no-use': 'off',
|
||||
'eslint-comments/no-unused-disable': 'off',
|
||||
'eslint-comments/no-unlimited-disable': 'off',
|
||||
|
||||
// Disable new ESLint 9 rules that are causing issues
|
||||
'no-constant-binary-expression': 'off',
|
||||
},
|
||||
},
|
||||
|
||||
// TypeScript and TSX files configuration
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
...globals.commonjs,
|
||||
...globals.es2020,
|
||||
},
|
||||
parserOptions: {
|
||||
requireConfigFile: false,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: true,
|
||||
node: true,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
github,
|
||||
import: importPlugin,
|
||||
'eslint-comments': eslintComments,
|
||||
'i18n-text': i18nText,
|
||||
filenames,
|
||||
'no-only-tests': noOnlyTests,
|
||||
prettier: prettierPlugin,
|
||||
'@typescript-eslint': tseslint,
|
||||
'primer-react': primerReact,
|
||||
'jsx-a11y': jsxA11y,
|
||||
},
|
||||
rules: {
|
||||
// ESLint recommended rules
|
||||
...js.configs.recommended.rules,
|
||||
|
||||
// GitHub plugin recommended rules
|
||||
...github.configs.recommended.rules,
|
||||
|
||||
// Import plugin error rules
|
||||
...importPlugin.configs.errors.rules,
|
||||
|
||||
// TypeScript ESLint recommended rules
|
||||
...tseslint.configs.recommended.rules,
|
||||
|
||||
// Primer React recommended rules
|
||||
...primerReact.configs.recommended.rules,
|
||||
|
||||
// JSX A11y recommended rules
|
||||
...jsxA11y.configs.recommended.rules,
|
||||
|
||||
// TypeScript-specific overrides
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
{
|
||||
packageDir: '.',
|
||||
},
|
||||
],
|
||||
'import/extensions': 'off',
|
||||
'no-console': 'off',
|
||||
camelcase: 'off',
|
||||
'no-shadow': 'off',
|
||||
'prefer-template': 'off',
|
||||
'no-constant-condition': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'no-undef': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'no-redeclare': 'off', // Allow function overloads in TypeScript
|
||||
'import/no-named-as-default-member': 'off',
|
||||
'one-var': 'off',
|
||||
'import/no-namespace': 'off',
|
||||
'import/no-anonymous-default-export': 'off',
|
||||
'object-shorthand': 'off',
|
||||
'no-empty': 'off',
|
||||
'prefer-const': 'off',
|
||||
'import/no-named-as-default': 'off',
|
||||
'no-useless-concat': 'off',
|
||||
'func-style': 'off',
|
||||
|
||||
// TypeScript ESLint specific rules
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
|
||||
// Disable GitHub plugin rules that were disabled in original config
|
||||
'github/array-foreach': 'off',
|
||||
'github/no-then': 'off',
|
||||
|
||||
// Disable rules that might not exist or cause issues initially
|
||||
'i18n-text/no-en': 'off',
|
||||
'filenames/match-regex': 'off',
|
||||
'eslint-comments/no-use': 'off',
|
||||
'eslint-comments/no-unused-disable': 'off',
|
||||
'eslint-comments/no-unlimited-disable': 'off',
|
||||
|
||||
// Disable new ESLint 9 rules that are causing issues
|
||||
'no-constant-binary-expression': 'off',
|
||||
|
||||
// Disable stricter TypeScript rules initially
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/no-wrapper-object-types': 'off',
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
|
||||
'@typescript-eslint/no-unsafe-function-type': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/prefer-as-const': 'off',
|
||||
|
||||
// React/JSX specific rules
|
||||
'jsx-a11y/no-onchange': 'off',
|
||||
},
|
||||
},
|
||||
|
||||
// Ignored patterns
|
||||
{
|
||||
ignores: [
|
||||
'tmp/*',
|
||||
'.next/',
|
||||
'src/bookmarklets/*',
|
||||
'rest-api-description/',
|
||||
'docs-internal-data/',
|
||||
'src/code-scanning/scripts/generate-code-scanning-query-list.ts',
|
||||
],
|
||||
},
|
||||
|
||||
// Prettier config (should be last to override formatting rules)
|
||||
prettier,
|
||||
]
|
||||
2018
package-lock.json
generated
2018
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
112
package.json
112
package.json
@@ -154,101 +154,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es2020": true,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2022,
|
||||
"requireConfigFile": "false",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"typescript": true,
|
||||
"node": true
|
||||
}
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:github/recommended",
|
||||
"plugin:import/errors",
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"import/no-extraneous-dependencies": [
|
||||
"error",
|
||||
{
|
||||
"packageDir": "."
|
||||
}
|
||||
],
|
||||
"import/extensions": "off",
|
||||
"no-console": "off",
|
||||
"github/array-foreach": "off",
|
||||
"camelcase": "off",
|
||||
"i18n-text/no-en": "off",
|
||||
"no-shadow": "off",
|
||||
"prefer-template": "off",
|
||||
"filenames/match-regex": "off",
|
||||
"no-constant-condition": "off",
|
||||
"no-unused-vars": "off",
|
||||
"github/no-then": "off",
|
||||
"import/no-named-as-default-member": "off",
|
||||
"one-var": "off",
|
||||
"import/no-namespace": "off",
|
||||
"import/no-anonymous-default-export": "off",
|
||||
"object-shorthand": "off",
|
||||
"eslint-comments/no-use": "off",
|
||||
"no-empty": "off",
|
||||
"prefer-const": "off",
|
||||
"import/no-named-as-default": "off",
|
||||
"eslint-comments/no-unused-disable": "off",
|
||||
"no-useless-concat": "off",
|
||||
"func-style": "off",
|
||||
"eslint-comments/no-unlimited-disable": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/*.tsx",
|
||||
"**/*.ts"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"primer-react",
|
||||
"jsx-a11y"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:primer-react/recommended",
|
||||
"plugin:jsx-a11y/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"camelcase": "off",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-use-before-define": "off",
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"jsx-a11y/no-onchange": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"tmp/*",
|
||||
"!/.*",
|
||||
"/.next/",
|
||||
"src/bookmarklets/*",
|
||||
"rest-api-description/",
|
||||
"docs-internal-data/",
|
||||
"src/code-scanning/scripts/generate-code-scanning-query-list.ts"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@elastic/elasticsearch": "8.13.1",
|
||||
"@github/failbot": "0.8.3",
|
||||
"@gr2m/gray-matter": "4.0.3-with-pr-137",
|
||||
"@horizon-rs/language-guesser": "0.1.1",
|
||||
"@octokit/plugin-retry": "8.0.1",
|
||||
"@octokit/request-error": "7.0.0",
|
||||
@@ -282,7 +191,6 @@
|
||||
"github-slugger": "^2.0.0",
|
||||
"glob": "11.0.2",
|
||||
"got": "^14.4.7",
|
||||
"@gr2m/gray-matter": "4.0.3-with-pr-137",
|
||||
"hast-util-from-parse5": "^8.0.3",
|
||||
"hast-util-to-string": "^3.0.1",
|
||||
"hastscript": "^9.0.1",
|
||||
@@ -343,6 +251,7 @@
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@axe-core/playwright": "^4.10.1",
|
||||
"@eslint/js": "^9.33.0",
|
||||
"@github/markdownlint-github": "^0.6.3",
|
||||
"@graphql-inspector/core": "^6.1.0",
|
||||
"@graphql-tools/load": "^8.0.19",
|
||||
@@ -375,14 +284,21 @@
|
||||
"cross-env": "^10.0.0",
|
||||
"csp-parse": "0.0.2",
|
||||
"csv-parse": "6.1.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^10.0.3",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-import-resolver-typescript": "^4.4.2",
|
||||
"eslint-plugin-github": "^5.0.2",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-escompat": "^3.11.4",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-filenames": "^1.3.2",
|
||||
"eslint-plugin-github": "^6.0.0",
|
||||
"eslint-plugin-i18n-text": "^1.0.1",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-primer-react": "^7.0.2",
|
||||
"eslint-plugin-no-only-tests": "^3.3.0",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"eslint-plugin-primer-react": "^8.0.0",
|
||||
"event-to-promise": "^0.8.0",
|
||||
"globals": "^16.3.0",
|
||||
"graphql": "^16.9.0",
|
||||
"http-status-code": "^2.1.0",
|
||||
"husky": "^9.1.7",
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import path from 'path'
|
||||
import { escapeRegExp } from 'lodash-es'
|
||||
|
||||
/* eslint-disable prefer-regex-literals */
|
||||
|
||||
// slash at the beginning of a filename
|
||||
const leadingPathSeparator = new RegExp(`^${escapeRegExp(path.sep)}`)
|
||||
const windowsLeadingPathSeparator = new RegExp('^/')
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('get-data', () => {
|
||||
const jaTranslationsRoot = path.join(dd.root, 'translations', 'ja-JP')
|
||||
fs.mkdirSync(jaTranslationsRoot, { recursive: true })
|
||||
languages.ja.dir = jaTranslationsRoot
|
||||
new DataDirectory( // eslint-disable-line no-new
|
||||
new DataDirectory(
|
||||
{
|
||||
data: {
|
||||
ui: {
|
||||
@@ -242,7 +242,7 @@ describe('get-data on corrupt translations', () => {
|
||||
const jaTranslationsRoot = path.join(dd.root, 'translations', 'ja-JP')
|
||||
fs.mkdirSync(jaTranslationsRoot, { recursive: true })
|
||||
languages.ja.dir = jaTranslationsRoot
|
||||
new DataDirectory( // eslint-disable-line no-new
|
||||
new DataDirectory(
|
||||
{
|
||||
data: {
|
||||
variables: {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable camelcase */
|
||||
import Cookies from '@/frame/components/lib/cookies'
|
||||
import { parseUserAgent } from './user-agent'
|
||||
import { Router } from 'next/router'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { allVersionKeys } from '@/versions/lib/all-versions'
|
||||
import { productIds } from '@/products/lib/all-products'
|
||||
import { allTools } from '@/tools/lib/all-tools'
|
||||
|
||||
const versionPattern = '^\\d+(\\.\\d+)?(\\.\\d+)?$' // eslint-disable-line
|
||||
const versionPattern = '^\\d+(\\.\\d+)?(\\.\\d+)?$'
|
||||
|
||||
const context = {
|
||||
type: 'object',
|
||||
|
||||
@@ -12,11 +12,8 @@ type UseQueryParamReturn<T extends string | boolean> = {
|
||||
}
|
||||
|
||||
// Overloads so we can use this for a boolean or string query param
|
||||
// eslint-disable-next-line no-redeclare
|
||||
export function useQueryParam(queryParamKey: string, isBoolean: true): UseQueryParamReturn<boolean>
|
||||
// eslint-disable-next-line no-redeclare
|
||||
export function useQueryParam(queryParamKey: string, isBoolean?: false): UseQueryParamReturn<string>
|
||||
// eslint-disable-next-line no-redeclare
|
||||
export function useQueryParam(
|
||||
queryParamKey: string,
|
||||
isBoolean?: boolean,
|
||||
|
||||
@@ -358,7 +358,6 @@ const semverRange = {
|
||||
format: 'semver',
|
||||
// This is JSON pointer syntax with ajv so we can specify the bad version
|
||||
// in the error message.
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
errorMessage: 'Must be a valid SemVer range: ${0}',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
// eslint-disable-next-line import/named
|
||||
import { visit, Test } from 'unist-util-visit'
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown'
|
||||
import { toMarkdown } from 'mdast-util-to-markdown'
|
||||
import yaml from 'js-yaml'
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { type Node, type Nodes, type Definition, type Link } from 'mdast'
|
||||
|
||||
import frontmatter from '@/frame/lib/read-frontmatter'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import fs from 'fs'
|
||||
|
||||
/* Writes string to file to be uploaded as an action artifact.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable no-invalid-this */
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { getAutomaticRequestLogger } from '@/observability/logger/middleware/get-automatic-request-logger'
|
||||
import type { Request, Response, NextFunction } from 'express'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { createLogger } from '@/observability/logger'
|
||||
import { initLoggerContext, updateLoggerContext } from '@/observability/logger/lib/logger-context'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { createLogger } from '@/observability/logger'
|
||||
|
||||
|
||||
@@ -3,6 +3,17 @@ import dereferenceJsonSchema from 'dereference-json-schema'
|
||||
import { existsSync } from 'fs'
|
||||
import { readFile, readdir } from 'fs/promises'
|
||||
|
||||
// OpenAPI 3.0 schema interface with the properties we need to access
|
||||
// The dereference-json-schema library returns a DereferencedJSONSchema type
|
||||
// but the actual object contains OpenAPI-specific properties that aren't in that type
|
||||
interface OpenAPISchema {
|
||||
openapi?: string
|
||||
info?: any
|
||||
servers?: any[]
|
||||
paths?: Record<string, Record<string, any>>
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export const MODELS_GATEWAY_ROOT = 'models-gateway'
|
||||
const MODELS_GATEWAY_PATH = 'docs/api'
|
||||
|
||||
@@ -40,14 +51,16 @@ export async function injectModelsSchema(schema: any, schemaName: string): Promi
|
||||
const deferencedYaml = dereferenceJsonSchema.dereferenceSync(loadedYaml)
|
||||
|
||||
// Copy over top-level OpenAPI fields
|
||||
schema.openapi = schema.openapi || deferencedYaml.openapi
|
||||
schema.info = schema.info || deferencedYaml.info
|
||||
schema.servers = schema.servers || deferencedYaml.servers
|
||||
// Cast to OpenAPISchema because dereference-json-schema doesn't include OpenAPI-specific properties in its type
|
||||
const openApiYaml = deferencedYaml as OpenAPISchema
|
||||
schema.openapi = schema.openapi || openApiYaml.openapi
|
||||
schema.info = schema.info || openApiYaml.info
|
||||
schema.servers = schema.servers || openApiYaml.servers
|
||||
|
||||
// Process each path and operation in the YAML
|
||||
for (const path of Object.keys(deferencedYaml.paths)) {
|
||||
for (const operation of Object.keys(deferencedYaml.paths[path])) {
|
||||
const operationObject = deferencedYaml.paths[path][operation]
|
||||
for (const path of Object.keys(openApiYaml.paths || {})) {
|
||||
for (const operation of Object.keys(openApiYaml.paths![path])) {
|
||||
const operationObject = openApiYaml.paths![path][operation]
|
||||
|
||||
// Use values from the YAML where possible
|
||||
const name = operationObject.summary || ''
|
||||
@@ -85,8 +98,8 @@ export async function injectModelsSchema(schema: any, schemaName: string): Promi
|
||||
|
||||
// Preserve operation-level servers if present
|
||||
// !Needed! to use models.github.ai instead of api.github.com
|
||||
if (deferencedYaml.servers) {
|
||||
enhancedOperation.servers = deferencedYaml.servers
|
||||
if (openApiYaml.servers) {
|
||||
enhancedOperation.servers = openApiYaml.servers
|
||||
}
|
||||
|
||||
// Add the enhanced operation to the schema
|
||||
|
||||
Reference in New Issue
Block a user