diff --git a/superset-frontend/.eslintignore b/superset-frontend/.eslintignore deleted file mode 100644 index 794f3b68c1e..00000000000 --- a/superset-frontend/.eslintignore +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -**/*{.,-}min.js -**/*.sh -coverage/** -dist/* -src/assets/images/* -node_modules/* -node_modules*/* -vendor/* -docs/* -src/dashboard/deprecated/* -src/temp/* -**/node_modules -*.d.ts -coverage/ -esm/ -lib/ -tmp/ -storybook-static/ diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js deleted file mode 100644 index 58ccbb58f9d..00000000000 --- a/superset-frontend/.eslintrc.js +++ /dev/null @@ -1,537 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// Register TypeScript require hook so ESLint can load .ts plugin files -require('tsx/cjs'); - -const packageConfig = require('./package.json'); - -const importCoreModules = []; -Object.entries(packageConfig.dependencies).forEach(([pkg]) => { - if (/@superset-ui/.test(pkg)) { - importCoreModules.push(pkg); - } -}); - -// ignore files in production mode -let ignorePatterns = []; -if (process.env.NODE_ENV === 'production') { - ignorePatterns = [ - '*.test.{js,ts,jsx,tsx}', - 'plugins/**/test/**/*', - 'packages/**/test/**/*', - 'packages/generator-superset/**/*', - ]; -} - -const restrictedImportsRules = { - 'no-design-icons': { - name: '@ant-design/icons', - message: - 'Avoid importing icons directly from @ant-design/icons. Use the src/components/Icons component instead.', - }, - 'no-moment': { - name: 'moment', - message: - 'Please use the dayjs library instead of moment.js. See https://day.js.org', - }, - 'no-lodash-memoize': { - name: 'lodash/memoize', - message: 'Lodash Memoize is unsafe! Please use memoize-one instead', - }, - 'no-testing-library-react': { - name: '@superset-ui/core/spec', - message: 'Please use spec/helpers/testing-library instead', - }, - 'no-testing-library-react-dom-utils': { - name: '@testing-library/react-dom-utils', - message: 'Please use spec/helpers/testing-library instead', - }, - 'no-antd': { - name: 'antd', - message: 'Please import Ant components from the index of src/components', - }, - 'no-superset-theme': { - name: '@superset-ui/core', - importNames: ['supersetTheme'], - message: - 'Please use the theme directly from the ThemeProvider rather than importing supersetTheme.', - }, - 'no-query-string': { - name: 'query-string', - message: 'Please use the URLSearchParams API instead of query-string.', - }, - 'no-jest-mock-console': { - name: 'jest-mock-console', - message: 'Please use native Jest spies, i.e. jest.spyOn(console, "warn")', - }, -}; - -module.exports = { - extends: [ - 'eslint:recommended', - 'plugin:import/recommended', - 'plugin:react-prefer-function-component/recommended', - 'plugin:storybook/recommended', - 'prettier', - ], - parser: '@babel/eslint-parser', - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - requireConfigFile: false, - babelOptions: { - presets: ['@babel/preset-react', '@babel/preset-env'], - }, - }, - env: { - browser: true, - node: true, - es2020: true, - }, - settings: { - 'import/resolver': { - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], - moduleDirectory: ['node_modules', '.'], - }, - typescript: { - alwaysTryTypes: true, - project: [ - './tsconfig.json', - './packages/superset-ui-core/tsconfig.json', - './packages/superset-ui-chart-controls/', - './plugins/*/tsconfig.json', - ], - }, - }, - 'import/core-modules': importCoreModules, - react: { - version: 'detect', - }, - }, - plugins: [ - 'import', - 'lodash', - 'theme-colors', - 'icons', - 'i18n-strings', - 'react-prefer-function-component', - 'react-you-might-not-need-an-effect', - 'prettier', - ], - rules: { - // === Essential Superset customizations === - - // Prettier integration - 'prettier/prettier': 'error', - - // Custom Superset rules - 'theme-colors/no-literal-colors': 'error', - 'icons/no-fa-icons-usage': 'error', - 'i18n-strings/no-template-vars': 'error', - 'i18n-strings/no-eager-t-in-config': 'off', // enabled only for controlPanel files via overrides below - - // Core ESLint overrides for Superset - 'no-console': 'warn', - 'no-unused-vars': 'off', // TypeScript handles this - camelcase: [ - 'error', - { - allow: ['^UNSAFE_', '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'], - properties: 'never', - }, - ], - 'prefer-destructuring': ['error', { object: true, array: false }], - 'no-prototype-builtins': 0, - curly: 'off', - - // Import plugin overrides - 'import/extensions': [ - 'error', - 'ignorePackages', - { - js: 'never', - jsx: 'never', - ts: 'never', - tsx: 'never', - }, - ], - 'import/no-cycle': 0, - 'import/prefer-default-export': 0, - 'import/no-named-as-default-member': 0, - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: [ - 'test/**', - 'tests/**', - 'spec/**', - '**/__tests__/**', - '**/__mocks__/**', - '*.test.{js,jsx,ts,tsx}', - '*.spec.{js,jsx,ts,tsx}', - '**/*.test.{js,jsx,ts,tsx}', - '**/*.spec.{js,jsx,ts,tsx}', - '**/jest.config.js', - '**/jest.setup.js', - '**/webpack.config.js', - '**/webpack.config.*.js', - '**/.eslintrc*.js', - ], - optionalDependencies: false, - }, - ], - - // React plugin overrides - 'react-prefer-function-component/react-prefer-function-component': 1, - - // React effect best practices - 'react-you-might-not-need-an-effect/no-empty-effect': 'error', - 'react-you-might-not-need-an-effect/no-pass-live-state-to-parent': 'error', - 'react-you-might-not-need-an-effect/no-initialize-state': 'error', - - // Lodash - 'lodash/import-scope': [2, 'member'], - - // React effect best practices - 'react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change': - 'error', - 'react-you-might-not-need-an-effect/no-chain-state-updates': 'error', - 'react-you-might-not-need-an-effect/no-event-handler': 'error', - 'react-you-might-not-need-an-effect/no-derived-state': 'error', - - // Storybook - 'storybook/prefer-pascal-case': 'error', - - // File progress - 'file-progress/activate': 1, - - // React effect rules - 'react-you-might-not-need-an-effect/no-adjust-state-on-prop-change': - 'error', - 'react-you-might-not-need-an-effect/no-pass-data-to-parent': 'error', - - // Restricted imports - 'no-restricted-imports': [ - 'error', - { - paths: Object.values(restrictedImportsRules).filter(Boolean), - patterns: ['antd/*'], - }, - ], - - // Temporarily disabled for migration - 'no-unsafe-optional-chaining': 0, - 'no-import-assign': 0, - 'import/no-relative-packages': 0, - 'no-promise-executor-return': 0, - 'import/no-import-module-exports': 0, - - // Restrict certain syntax patterns - 'no-restricted-syntax': [ - 'error', - { - selector: - "ImportDeclaration[source.value='react'] :matches(ImportDefaultSpecifier, ImportNamespaceSpecifier)", - message: - 'Default React import is not required due to automatic JSX runtime in React 16.4', - }, - { - selector: 'ImportNamespaceSpecifier[parent.source.value!=/^(\\.|src)/]', - message: 'Wildcard imports are not allowed', - }, - ], - }, - overrides: [ - // Eager t()/tn() in `label`/`description` config props is captured at - // module-load time, before i18n initializes — labels stay in the fallback - // language even after the user switches. Surfaced as a warning (with - // autofix to `() => t(...)`) wherever this is a real foot-gun: - // controlPanel files. Many pre-existing call sites need conversion; - // run `eslint --fix` on a controlPanel file to sweep it. Promote to - // `'error'` once the codebase is clean. - { - files: ['**/controlPanel.{ts,tsx,js,jsx}'], - rules: { - 'i18n-strings/no-eager-t-in-config': 'warn', - }, - }, - // Ban JavaScript files in src/ - all new code must be TypeScript - { - files: ['src/**/*.js', 'src/**/*.jsx'], - rules: { - 'no-restricted-syntax': [ - 'error', - { - selector: 'Program', - message: - 'JavaScript files are not allowed in src/. Please use TypeScript (.ts/.tsx) instead.', - }, - ], - }, - }, - // Ban JavaScript files in plugins/ - all plugin source code must be TypeScript - { - files: ['plugins/**/src/**/*.js', 'plugins/**/src/**/*.jsx'], - rules: { - 'no-restricted-syntax': [ - 'error', - { - selector: 'Program', - message: - 'JavaScript files are not allowed in plugins/. Please use TypeScript (.ts/.tsx) instead.', - }, - ], - }, - }, - // Ban JavaScript files in packages/ - with exceptions for config files and generators - { - files: ['packages/**/src/**/*.js', 'packages/**/src/**/*.jsx'], - excludedFiles: [ - 'packages/generator-superset/**/*', // Yeoman generator templates run via Node - 'packages/**/__mocks__/**/*', // Test mocks - ], - rules: { - 'no-restricted-syntax': [ - 'error', - { - selector: 'Program', - message: - 'JavaScript files are not allowed in packages/. Please use TypeScript (.ts/.tsx) instead.', - }, - ], - }, - }, - { - files: ['*.ts', '*.tsx'], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: ['plugin:@typescript-eslint/recommended', 'prettier'], - plugins: ['@typescript-eslint/eslint-plugin'], - rules: { - // TypeScript-specific rule overrides - '@typescript-eslint/ban-ts-ignore': 0, - '@typescript-eslint/ban-ts-comment': 0, - '@typescript-eslint/ban-types': 0, - '@typescript-eslint/naming-convention': [ - 'error', - { - selector: 'enum', - format: ['PascalCase'], - }, - { - selector: 'enumMember', - format: ['PascalCase'], - }, - ], - '@typescript-eslint/no-empty-function': 0, - '@typescript-eslint/no-explicit-any': 0, - '@typescript-eslint/no-use-before-define': 'error', - '@typescript-eslint/no-non-null-assertion': 0, - '@typescript-eslint/explicit-function-return-type': 0, - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/no-unused-vars': 'warn', - '@typescript-eslint/prefer-optional-chain': 'error', - - // Disable base rules that conflict with TS versions - 'no-unused-vars': 'off', - 'no-use-before-define': 'off', - 'no-shadow': 'off', - - // Import overrides for TypeScript - 'import/extensions': [ - 'error', - 'ignorePackages', - { - js: 'never', - jsx: 'never', - ts: 'never', - tsx: 'never', - }, - ], - }, - settings: { - 'import/resolver': { - typescript: {}, - }, - }, - }, - { - files: ['packages/**'], - rules: { - 'import/no-extraneous-dependencies': [ - 'error', - { devDependencies: true }, - ], - 'no-restricted-imports': [ - 'error', - { - paths: [ - restrictedImportsRules['no-moment'], - restrictedImportsRules['no-lodash-memoize'], - restrictedImportsRules['no-superset-theme'], - ], - patterns: [], - }, - ], - }, - }, - { - files: ['plugins/**'], - rules: { - 'no-restricted-imports': [ - 'error', - { - paths: [ - restrictedImportsRules['no-moment'], - restrictedImportsRules['no-lodash-memoize'], - ], - patterns: [], - }, - ], - }, - }, - { - files: ['src/components/**', 'src/theme/**'], - rules: { - 'no-restricted-imports': [ - 'error', - { - paths: Object.values(restrictedImportsRules).filter( - r => r.name !== 'antd', - ), - patterns: [], - }, - ], - }, - }, - { - files: [ - '*.test.ts', - '*.test.tsx', - '*.test.js', - '*.test.jsx', - '*.stories.tsx', - '*.stories.jsx', - 'fixtures.*', - '**/test/**/*', - '**/tests/**/*', - 'spec/**/*', - '**/fixtures/**/*', - '**/__mocks__/**/*', - '**/spec/**/*', - ], - excludedFiles: 'cypress-base/cypress/**/*', - plugins: ['jest-dom', 'no-only-tests', 'testing-library'], - extends: ['plugin:jest-dom/recommended', 'plugin:testing-library/react'], - rules: { - 'import/no-extraneous-dependencies': [ - 'error', - { devDependencies: true }, - ], - 'prefer-promise-reject-errors': 0, - 'max-classes-per-file': 0, - - // Temporary for migration - 'testing-library/await-async-queries': 0, - 'testing-library/await-async-utils': 0, - 'testing-library/no-await-sync-events': 0, - 'testing-library/no-render-in-lifecycle': 0, - 'testing-library/no-unnecessary-act': 0, - 'testing-library/no-wait-for-multiple-assertions': 0, - 'testing-library/prefer-screen-queries': 0, - 'testing-library/await-async-events': 0, - 'testing-library/no-node-access': 0, - 'testing-library/no-wait-for-side-effects': 0, - 'testing-library/prefer-presence-queries': 0, - 'testing-library/render-result-naming-convention': 0, - 'testing-library/no-container': 0, - 'testing-library/prefer-find-by': 0, - 'testing-library/no-manual-cleanup': 0, - - 'no-restricted-syntax': [ - 'error', - { - selector: - "ImportDeclaration[source.value='react'] :matches(ImportDefaultSpecifier, ImportNamespaceSpecifier)", - message: - 'Default React import is not required due to automatic JSX runtime in React 16.4', - }, - ], - 'no-restricted-imports': 0, - }, - }, - { - files: [ - '*.test.ts', - '*.test.tsx', - '*.test.js', - '*.test.jsx', - '*.stories.tsx', - '*.stories.jsx', - 'fixtures.*', - '**/test/**/*', - '**/tests/**/*', - 'spec/**/*', - '**/fixtures/**/*', - '**/__mocks__/**/*', - '**/spec/**/*', - 'cypress-base/cypress/**/*', - 'Stories.tsx', - 'packages/superset-ui-core/src/theme/index.tsx', - ], - rules: { - 'theme-colors/no-literal-colors': 0, - 'icons/no-fa-icons-usage': 0, - 'i18n-strings/no-template-vars': 0, - 'no-restricted-imports': 0, - }, - }, - { - files: [ - 'packages/**/*.stories.*', - 'packages/**/*.overview.*', - 'packages/**/fixtures.*', - ], - rules: { - 'import/no-extraneous-dependencies': 'off', - }, - }, - { - files: ['playwright/**/*.ts', 'playwright/**/*.js'], - rules: { - 'import/no-extraneous-dependencies': [ - 'error', - { devDependencies: true }, - ], - }, - }, - ], - ignorePatterns, -}; diff --git a/superset-frontend/.eslintrc.minimal.js b/superset-frontend/.eslintrc.minimal.js deleted file mode 100644 index b6b796e0ad2..00000000000 --- a/superset-frontend/.eslintrc.minimal.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// Register TypeScript require hook so ESLint can load .ts plugin files -require('tsx/cjs'); - -/** - * MINIMAL ESLint config - ONLY for rules OXC doesn't support - * This config is designed to be run alongside OXC linter - * - * Only covers: - * - Custom Superset plugins (theme-colors, icons, i18n) - * - Prettier formatting - * - File progress indicator - */ - -module.exports = { - root: true, - // Don't report on eslint-disable comments for rules we don't have - reportUnusedDisableDirectives: false, - // Simple parser - no TypeScript needed since OXC handles that - parser: '@babel/eslint-parser', - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - requireConfigFile: false, - babelOptions: { - presets: ['@babel/preset-react', '@babel/preset-env'], - }, - }, - env: { - browser: true, - node: true, - es2020: true, - }, - plugins: [ - // ONLY custom Superset plugins that OXC doesn't support - 'theme-colors', - 'icons', - 'i18n-strings', - 'file-progress', - 'prettier', - ], - rules: { - // === ONLY rules that OXC cannot handle === - - // Prettier integration (formatting) - 'prettier/prettier': 'error', - - // Custom Superset plugins - 'theme-colors/no-literal-colors': 'error', - 'icons/no-fa-icons-usage': 'error', - 'i18n-strings/no-template-vars': 'error', - 'file-progress/activate': 1, - - // Explicitly turn off all other rules to avoid conflicts - // when the config gets merged with other configs - 'import/no-unresolved': 'off', - 'import/extensions': 'off', - '@typescript-eslint/naming-convention': 'off', - }, - overrides: [ - { - // Disable custom rules in test/story files - files: [ - '**/*.test.*', - '**/*.spec.*', - '**/*.stories.*', - '**/test/**', - '**/tests/**', - '**/spec/**', - '**/__tests__/**', - '**/__mocks__/**', - 'cypress-base/**', - 'packages/superset-ui-core/src/theme/index.tsx', - ], - rules: { - 'theme-colors/no-literal-colors': 0, - 'icons/no-fa-icons-usage': 0, - 'i18n-strings/no-template-vars': 0, - 'file-progress/activate': 0, - }, - }, - ], - // Only check src/ files where theme/icon rules matter - ignorePatterns: [ - 'node_modules', - 'dist', - 'build', - '.next', - 'coverage', - '*.min.js', - 'vendor', - // Skip packages/plugins since they have different theming rules - 'packages/**', - 'plugins/**', - // Skip generated/external files - '*.generated.*', - '*.config.js', - 'webpack.*', - // Temporary analysis files - '*.js', // Skip all standalone JS files in root - '*.json', - ], -}; diff --git a/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/no-template-vars.test.ts b/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/no-template-vars.test.ts index 50607273da2..7476ce8aee0 100644 --- a/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/no-template-vars.test.ts +++ b/superset-frontend/eslint-rules/eslint-plugin-i18n-strings/no-template-vars.test.ts @@ -31,12 +31,13 @@ const plugin: { rules: Record } = require('.'); // Tests //------------------------------------------------------------------------------ -const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } }); +const ruleTester = new RuleTester({ languageOptions: { ecmaVersion: 6 } }); const rule: Rule.RuleModule = plugin.rules['no-template-vars']; -const errors: Array<{ type: string }> = [ +const errors: Array<{ message: string }> = [ { - type: 'CallExpression', + message: + "Don't use variables in translation string templates. Flask-babel is a static translation service, so it can't handle strings that include variables", }, ]; diff --git a/superset-frontend/eslint-rules/eslint-plugin-icons/no-fontawesome.test.ts b/superset-frontend/eslint-rules/eslint-plugin-icons/no-fontawesome.test.ts index 9e8c080a16f..fc0d19d33aa 100644 --- a/superset-frontend/eslint-rules/eslint-plugin-icons/no-fontawesome.test.ts +++ b/superset-frontend/eslint-rules/eslint-plugin-icons/no-fontawesome.test.ts @@ -31,7 +31,10 @@ const plugin: { rules: Record } = require('.'); // Tests //------------------------------------------------------------------------------ const ruleTester = new RuleTester({ - parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } }, + languageOptions: { + ecmaVersion: 6, + parserOptions: { ecmaFeatures: { jsx: true } }, + }, }); const rule: Rule.RuleModule = plugin.rules['no-fa-icons-usage']; diff --git a/superset-frontend/eslint.config.minimal.js b/superset-frontend/eslint.config.minimal.js new file mode 100644 index 00000000000..c9746f7cce4 --- /dev/null +++ b/superset-frontend/eslint.config.minimal.js @@ -0,0 +1,137 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * MINIMAL ESLint flat config - ONLY for rules OXC doesn't support. + * + * This config is run alongside the OXC (oxlint) linter, which handles the + * bulk of linting. ESLint here only covers the custom Superset plugins and + * Prettier formatting that oxlint cannot express. It is consumed by + * `scripts/oxlint-metrics-uploader.js` (`npm run lint-stats`). + * + * Migrated from the legacy `.eslintrc.minimal.js` (eslintrc) format to flat + * config for ESLint v9+/v10, where eslintrc is no longer supported. + * + * Only covers: + * - Custom Superset plugins (theme-colors, icons, i18n-strings) + * - Prettier formatting + */ + +// Register the TypeScript require hook so ESLint can load the .ts plugin files +// from eslint-rules/*. +require('tsx/cjs'); + +const tsParser = require('@typescript-eslint/parser'); +const prettierPlugin = require('eslint-plugin-prettier'); +const themeColorsPlugin = require('eslint-plugin-theme-colors'); +const iconsPlugin = require('eslint-plugin-icons'); +const i18nStringsPlugin = require('eslint-plugin-i18n-strings'); + +module.exports = [ + // Files this config applies to. Flat config has no `--ext`; globs live here. + // Only check src/ files where the theme/icon/i18n rules matter. + { + ignores: [ + 'node_modules/**', + 'dist/**', + 'build/**', + '.next/**', + 'coverage/**', + '**/*.min.js', + 'vendor/**', + // Skip packages/plugins since they have different theming rules + 'packages/**', + 'plugins/**', + // Skip generated/external/config files + '**/*.generated.*', + '**/*.config.js', + '**/webpack.*', + '*.json', + ], + }, + { + files: ['**/*.{js,jsx,ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + sourceType: 'module', + // The @typescript-eslint parser handles both TS/TSX and plain JS/JSX and + // is compatible with ESLint v10's scope manager. (The legacy + // @babel/eslint-parser does not support ESLint v10.) The custom rules + // here are pure AST visitors and do not require type information, so no + // `project` is configured — this keeps parsing fast. + parser: tsParser, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + // Don't report on eslint-disable comments for rules we don't have. + linterOptions: { + reportUnusedDisableDirectives: false, + }, + plugins: { + prettier: prettierPlugin, + 'theme-colors': themeColorsPlugin, + icons: iconsPlugin, + 'i18n-strings': i18nStringsPlugin, + }, + rules: { + // Prettier integration (formatting) + 'prettier/prettier': 'error', + + // Custom Superset plugins + 'theme-colors/no-literal-colors': 'error', + 'icons/no-fa-icons-usage': 'error', + 'i18n-strings/no-template-vars': 'error', + // Enabled only for controlPanel files via the override below. + 'i18n-strings/no-eager-t-in-config': 'off', + }, + }, + { + // Eager t()/tn() in `label`/`description` config props is captured at + // module-load time, before i18n initializes — labels stay in the fallback + // language even after the user switches. Surfaced as a warning (with + // autofix to `() => t(...)`) wherever this is a real foot-gun: + // controlPanel files. Promote to `'error'` once the codebase is clean. + files: ['**/controlPanel.{ts,tsx,js,jsx}'], + rules: { + 'i18n-strings/no-eager-t-in-config': 'warn', + }, + }, + { + // Disable custom rules in test/story files + files: [ + '**/*.test.*', + '**/*.spec.*', + '**/*.stories.*', + '**/test/**', + '**/tests/**', + '**/spec/**', + '**/__tests__/**', + '**/__mocks__/**', + 'cypress-base/**', + ], + rules: { + 'theme-colors/no-literal-colors': 'off', + 'icons/no-fa-icons-usage': 'off', + 'i18n-strings/no-template-vars': 'off', + }, + }, +]; diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json index cce868caddd..7812bbfe6a9 100644 --- a/superset-frontend/oxlint.json +++ b/superset-frontend/oxlint.json @@ -287,13 +287,15 @@ "ignorePatterns": [ "packages/generator-superset/**/*", "cypress-base/**", - "node_modules/**", + "**/node_modules/**", "build/**", - "dist/**", - "lib/**", - "esm/**", - "*.min.js", + "**/dist/**", + "**/lib/**", + "**/esm/**", + "**/*.min.js", + "**/*.d.ts", "coverage/**", + "storybook-static/**", ".git/**", "**/*.config.js", "**/*.config.ts" diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 9d6c9021948..a3eb242f0b3 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -214,8 +214,8 @@ "@types/rison": "0.1.0", "@types/tinycolor2": "^1.4.3", "@types/unzipper": "^0.10.11", - "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.59.4", + "@typescript-eslint/eslint-plugin": "^8.61.0", + "@typescript-eslint/parser": "^8.61.0", "babel-jest": "^30.4.1", "babel-loader": "^10.1.1", "babel-plugin-dynamic-import-node": "^2.3.3", @@ -228,8 +228,8 @@ "cross-env": "^10.1.0", "css-loader": "^7.1.4", "css-minimizer-webpack-plugin": "^8.0.0", - "eslint": "^8.56.0", - "eslint-config-prettier": "^7.2.0", + "eslint": "^10.4.1", + "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-cypress": "^3.6.0", @@ -237,11 +237,11 @@ "eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.5.0", - "eslint-plugin-lodash": "^7.4.0", + "eslint-plugin-lodash": "^8.0.0", "eslint-plugin-no-only-tests": "^3.4.0", "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-react-prefer-function-component": "^5.0.0", - "eslint-plugin-react-you-might-not-need-an-effect": "^0.10.4", + "eslint-plugin-react-you-might-not-need-an-effect": "^1.0.0", "eslint-plugin-storybook": "10.4.2", "eslint-plugin-testing-library": "^7.16.2", "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", @@ -3805,92 +3805,108 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@exodus/bytes": { @@ -4069,20 +4085,42 @@ "@hapi/hoek": "^11.0.2" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/types": "^0.15.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -4099,13 +4137,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", @@ -11305,6 +11349,26 @@ "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", "license": "MIT" }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -12097,17 +12161,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", - "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", + "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/type-utils": "8.60.1", - "@typescript-eslint/utils": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -12120,7 +12184,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.60.1", + "@typescript-eslint/parser": "^8.61.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -12136,16 +12200,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", - "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", + "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "debug": "^4.4.3" }, "engines": { @@ -12161,14 +12225,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", - "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", + "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.60.1", - "@typescript-eslint/types": "^8.60.1", + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", "debug": "^4.4.3" }, "engines": { @@ -12183,14 +12247,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", - "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", + "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1" + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12201,9 +12265,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", - "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", + "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", "dev": true, "license": "MIT", "engines": { @@ -12218,15 +12282,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", - "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", + "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -12243,9 +12307,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", - "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", + "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", "dev": true, "license": "MIT", "engines": { @@ -12257,16 +12321,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", - "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", + "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.60.1", - "@typescript-eslint/tsconfig-utils": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -12324,16 +12388,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", - "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", + "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1" + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12348,13 +12412,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", - "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", + "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/types": "8.61.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -18856,71 +18920,73 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", + "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^10.2.4", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } @@ -19198,9 +19264,9 @@ } }, "node_modules/eslint-plugin-lodash": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-7.4.0.tgz", - "integrity": "sha512-Tl83UwVXqe1OVeBRKUeWcfg6/pCW1GTRObbdnbEJgYwjxp5Q92MEWQaH9+dmzbRt6kvYU1Mp893E79nJiCSM8A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-8.0.0.tgz", + "integrity": "sha512-7DA8485FolmWRzh+8t4S8Pzin2TTuWfb0ZW3j/2fYElgk82ZanFz8vDcvc4BBPceYdX1p/za+tkbO68maDBGGw==", "dev": true, "license": "MIT", "dependencies": { @@ -19210,7 +19276,7 @@ "node": ">=10" }, "peerDependencies": { - "eslint": ">=2" + "eslint": ">=9.0.0" } }, "node_modules/eslint-plugin-no-only-tests": { @@ -19262,9 +19328,9 @@ "license": "MIT" }, "node_modules/eslint-plugin-react-you-might-not-need-an-effect": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-you-might-not-need-an-effect/-/eslint-plugin-react-you-might-not-need-an-effect-0.10.4.tgz", - "integrity": "sha512-T6UFIOl2yWzVJ7LRk27z6EbJm2pfO4+VCTp2TBRsmAUREkDFUXjtWxoD9NsDcg6NmMFETZLbAD1XzV/w/GOmqw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-you-might-not-need-an-effect/-/eslint-plugin-react-you-might-not-need-an-effect-1.0.0.tgz", + "integrity": "sha512-8exakZ5dCJdZb7TA3P8vD47HlnM3IllA9sjKzU22wyLEx0PZBDjFPxT5+5Rb10tSE6uWmwoBsgClIDNuJ8UW6g==", "dev": true, "license": "MIT", "dependencies": { @@ -19376,38 +19442,56 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19426,29 +19510,6 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -19456,19 +19517,35 @@ "dev": true, "license": "MIT" }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19488,13 +19565,13 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19514,9 +19591,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -20042,16 +20119,30 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/file-entry-cache/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" } }, "node_modules/file-saver": { @@ -21824,13 +21915,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/h3-js": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-4.2.1.tgz", @@ -23710,16 +23794,6 @@ "node": ">=8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 033a6b19617..d58c3868719 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -297,8 +297,8 @@ "@types/rison": "0.1.0", "@types/tinycolor2": "^1.4.3", "@types/unzipper": "^0.10.11", - "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.59.4", + "@typescript-eslint/eslint-plugin": "^8.61.0", + "@typescript-eslint/parser": "^8.61.0", "babel-jest": "^30.4.1", "babel-loader": "^10.1.1", "babel-plugin-dynamic-import-node": "^2.3.3", @@ -311,8 +311,8 @@ "cross-env": "^10.1.0", "css-loader": "^7.1.4", "css-minimizer-webpack-plugin": "^8.0.0", - "eslint": "^8.56.0", - "eslint-config-prettier": "^7.2.0", + "eslint": "^10.4.1", + "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-cypress": "^3.6.0", @@ -320,11 +320,11 @@ "eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.5.0", - "eslint-plugin-lodash": "^7.4.0", + "eslint-plugin-lodash": "^8.0.0", "eslint-plugin-no-only-tests": "^3.4.0", "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-react-prefer-function-component": "^5.0.0", - "eslint-plugin-react-you-might-not-need-an-effect": "^0.10.4", + "eslint-plugin-react-you-might-not-need-an-effect": "^1.0.0", "eslint-plugin-storybook": "10.4.2", "eslint-plugin-testing-library": "^7.16.2", "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", @@ -414,7 +414,16 @@ "@jest/types": "^30.4.0", "jest-util": "^30.4.0", "jest-circus": "^30.4.0", - "jest-environment-node": "^30.4.0" + "jest-environment-node": "^30.4.0", + "@babel/eslint-parser": { + "eslint": "$eslint" + }, + "eslint-plugin-import": { + "eslint": "$eslint" + }, + "eslint-plugin-jest-dom": { + "eslint": "$eslint" + } }, "readme": "ERROR: No README data found!", "scarfSettings": { diff --git a/superset-frontend/scripts/oxlint-metrics-uploader.js b/superset-frontend/scripts/oxlint-metrics-uploader.js index 191bded07b4..14c296632a8 100644 --- a/superset-frontend/scripts/oxlint-metrics-uploader.js +++ b/superset-frontend/scripts/oxlint-metrics-uploader.js @@ -134,9 +134,11 @@ async function runOxlintAndProcess() { console.log('Running minimal ESLint for custom rules...'); let eslintOutput = '[]'; try { - // Run ESLint and capture output directly + // Run ESLint and capture output directly. + // Flat config (eslint.config.minimal.js) is explicitly selected via + // --config; ESLint v9+/v10 no longer support eslintrc or --no-eslintrc. eslintOutput = execSync( - 'npx eslint --no-eslintrc --config .eslintrc.minimal.js --no-inline-config --format json src', + 'npx eslint --config eslint.config.minimal.js --no-inline-config --format json src', { encoding: 'utf8', maxBuffer: 50 * 1024 * 1024,