diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ca67fc429584..000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,76 +0,0 @@ -// Note: All paths are relative to the directory in which eslint is being run, rather than the directory where this file -// lives - -// ESLint config docs: https://eslint.org/docs/user-guide/configuring/ - -module.exports = { - root: true, - env: { - es2017: true, - }, - parserOptions: { - ecmaVersion: 2020, - }, - extends: ['@sentry-internal/sdk'], - ignorePatterns: [ - 'coverage/**', - 'build/**', - 'dist/**', - 'cjs/**', - 'esm/**', - 'examples/**', - 'test/manual/**', - 'types/**', - 'scripts/*.js', - ], - rules: { - '@typescript-eslint/no-explicit-any': 'error', - }, - reportUnusedDisableDirectives: true, - overrides: [ - { - files: ['*.ts', '*.tsx', '*.d.ts'], - parserOptions: { - project: ['tsconfig.json'], - }, - }, - { - files: ['test/**/*.ts', 'test/**/*.tsx'], - parserOptions: { - project: ['tsconfig.test.json'], - }, - rules: { - '@typescript-eslint/no-explicit-any': 'off', - }, - }, - { - files: ['scripts/**/*.ts'], - parserOptions: { - project: ['tsconfig.dev.json'], - }, - }, - { - files: ['*.tsx'], - rules: { - // Turn off jsdoc on tsx files until jsdoc is fixed for tsx files - // See: https://github.com/getsentry/sentry-javascript/issues/3871 - 'jsdoc/require-jsdoc': 'off', - }, - }, - { - files: ['scenarios/**', 'dev-packages/rollup-utils/**', 'dev-packages/bundle-analyzer-scenarios/**'], - parserOptions: { - sourceType: 'module', - }, - rules: { - 'no-console': 'off', - }, - }, - { - files: ['vite.config.ts'], - parserOptions: { - project: ['tsconfig.test.json'], - }, - }, - ], -}; diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 718c70a0cb24..5b84a70ffbd6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -308,7 +308,7 @@ jobs: with: dependency_cache_key: ${{ needs.job_build.outputs.dependency_cache_key }} - name: Lint source files - run: yarn lint:eslint + run: yarn lint:oxlint - name: Lint for ES compatibility run: yarn lint:es-compatibility diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000000..1d05d5b782dc --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,165 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "import", "jsdoc", "jest", "vitest"], + "jsPlugins": [ + { + "name": "sdk", + "specifier": "@sentry-internal/eslint-plugin-sdk" + } + ], + "categories": {}, + "rules": { + // === Base rules from eslint-config-sdk/base.js === + "no-console": "error", + "no-alert": "error", + "no-param-reassign": "error", + "prefer-template": "error", + "no-bitwise": "error", + "complexity": ["error", { "max": 33 }], + "no-unused-expressions": ["error", { "allowShortCircuit": true }], + "guard-for-in": "error", + "array-callback-return": ["error", { "allowImplicit": true }], + "quotes": ["error", "single", { "avoidEscape": true }], + "no-return-await": "error", + "max-lines": ["error", { "max": 300, "skipComments": true, "skipBlankLines": true }], + + // === Import rules === + "import/namespace": "off", + "import/no-unresolved": "off", + + // === Jest/Vitest rules === + "jest/no-focused-tests": "error", + "jest/no-disabled-tests": "error", + + // === Rules turned off (not enforced in ESLint or causing false positives) === + "no-control-regex": "off", + "jsdoc/check-tag-names": "off", + "jsdoc/require-yields": "off", + "no-useless-rename": "off", + "no-constant-binary-expression": "off", + "jest/no-conditional-expect": "off", + "jest/expect-expect": "off", + "jest/no-standalone-expect": "off", + "jest/require-to-throw-message": "off", + "jest/valid-title": "off", + "jest/no-export": "off", + "jest/valid-describe-callback": "off", + "vitest/hoisted-apis-on-top": "off", + "vitest/no-conditional-tests": "off", + "no-unsafe-optional-chaining": "off", + "no-eval": "off", + "no-import-assign": "off", + + // === Custom SDK rules (via JS plugin) === + "sdk/no-eq-empty": "error" + }, + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx", "**/*.d.ts"], + "rules": { + "typescript/ban-ts-comment": "error", + "typescript/consistent-type-imports": "error", + "typescript/no-unnecessary-type-assertion": "error", + "typescript/prefer-for-of": "error", + "typescript/no-floating-promises": ["error", { "ignoreVoid": true }], + "typescript/no-dynamic-delete": "error", + "typescript/no-unsafe-member-access": "error", + "typescript/unbound-method": "error", + "typescript/no-explicit-any": "error", + "typescript/no-empty-function": "off", + "typescript/prefer-optional-chain": ["error"] + } + }, + { + "files": ["**/*.js", "**/*.mjs", "**/*.cjs"], + "rules": { + "typescript/ban-ts-comment": "off", + "typescript/consistent-type-imports": "off", + "typescript/prefer-optional-chain": "off", + "typescript/no-unnecessary-type-assertion": "off", + "typescript/prefer-for-of": "off", + "typescript/no-floating-promises": "off", + "typescript/no-dynamic-delete": "off", + "typescript/no-unsafe-member-access": "off", + "typescript/unbound-method": "off", + "typescript/no-explicit-any": "off" + } + }, + { + "files": [ + "**/*.test.ts", + "**/*.test.tsx", + "**/*.test.js", + "**/*.test.jsx", + "**/test/**", + "**/tests/**", + "**/suites/**", + "**/loader-suites/**" + ], + "rules": { + "typescript/explicit-function-return-type": "off", + "no-unused-expressions": "off", + "typescript/no-unused-expressions": "off", + "typescript/no-unnecessary-type-assertion": "off", + "typescript/no-unsafe-member-access": "off", + "typescript/no-explicit-any": "off", + "typescript/no-non-null-assertion": "off", + "typescript/no-floating-promises": "off", + "typescript/unbound-method": "off", + "max-lines": "off", + "complexity": "off", + "typescript/prefer-optional-chain": "off" + } + }, + { + "files": ["*.tsx"], + "rules": { + "jsdoc/require-jsdoc": "off" + } + }, + { + "files": ["*.config.js", "*.config.mjs", "*.config.ts", "vite.config.ts", ".size-limit.js"], + "rules": { + "no-console": "off", + "max-lines": "off" + } + }, + { + "files": [ + "**/scenarios/**", + "**/rollup-utils/**", + "**/bundle-analyzer-scenarios/**", + "**/bundle-analyzer-scenarios/*.cjs", + "**/bundle-analyzer-scenarios/*.js" + ], + "rules": { + "no-console": "off" + } + }, + { + "files": ["**/src/**"], + "rules": { + "no-restricted-globals": ["error", "window", "document", "location", "navigator"], + "sdk/no-class-field-initializers": "error", + "sdk/no-regexp-constructor": "error" + } + } + ], + "env": { + "es2017": true, + "node": true + }, + "globals": {}, + "ignorePatterns": [ + "coverage/**", + "build/**", + "dist/**", + "cjs/**", + "esm/**", + "examples/**", + "test/manual/**", + "types/**", + "scripts/*.js", + "node_modules/**" + ] +} diff --git a/dev-packages/.eslintrc.js b/dev-packages/.eslintrc.js deleted file mode 100644 index 15dafc98d9db..000000000000 --- a/dev-packages/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - extends: ['../.eslintrc.js'], - rules: { - // tests often have just cause to do evil - '@typescript-eslint/no-explicit-any': 'off', - }, -}; diff --git a/dev-packages/.oxlintrc.json b/dev-packages/.oxlintrc.json new file mode 100644 index 000000000000..f44c8f60b0db --- /dev/null +++ b/dev-packages/.oxlintrc.json @@ -0,0 +1,9 @@ +{ + "$schema": "../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "rules": { + "typescript/no-explicit-any": "off", + "max-lines": "off", + "no-unused-expressions": "off" + } +} diff --git a/dev-packages/browser-integration-tests/.eslintrc.js b/dev-packages/browser-integration-tests/.eslintrc.js deleted file mode 100644 index 6e8960a45a06..000000000000 --- a/dev-packages/browser-integration-tests/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - env: { - browser: true, - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - ignorePatterns: [ - 'suites/**/subject.js', - 'suites/**/dist/*', - 'loader-suites/**/dist/*', - 'loader-suites/**/subject.js', - 'scripts/**', - 'fixtures/**', - 'tmp/**', - ], - overrides: [ - { - files: ['loader-suites/**/{subject,init}.js'], - globals: { - Sentry: true, - }, - }, - ], - parserOptions: { - sourceType: 'module', - }, -}; diff --git a/dev-packages/browser-integration-tests/.oxlintrc.json b/dev-packages/browser-integration-tests/.oxlintrc.json new file mode 100644 index 000000000000..6cae296602da --- /dev/null +++ b/dev-packages/browser-integration-tests/.oxlintrc.json @@ -0,0 +1,31 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "browser": true, + "node": true + }, + "ignorePatterns": [ + "suites/**/subject.js", + "suites/**/dist/*", + "loader-suites/**/dist/*", + "loader-suites/**/subject.js", + "scripts/**", + "fixtures/**", + "tmp/**" + ], + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx"], + "rules": { + "typescript/no-unsafe-member-access": "off" + } + }, + { + "files": ["loader-suites/**/{subject,init}.js"], + "globals": { + "Sentry": "readonly" + } + } + ] +} diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 30023887705c..0c11e3aeb694 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -10,8 +10,8 @@ "scripts": { "clean": "rimraf -g suites/**/dist loader-suites/**/dist tmp", "install-browsers": "[[ -z \"$SKIP_PLAYWRIGHT_BROWSER_INSTALL\" ]] && npx playwright install --with-deps || echo 'Skipping browser installation'", - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix", + "lint": "oxlint .", + "fix": "oxlint . --fix", "type-check": "tsc", "postinstall": "yarn install-browsers", "pretest": "yarn clean && yarn type-check", diff --git a/dev-packages/bundler-tests/.eslintrc.js b/dev-packages/bundler-tests/.eslintrc.js deleted file mode 100644 index 5c6808c0f73e..000000000000 --- a/dev-packages/bundler-tests/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extends: ['../.eslintrc.js'], - parserOptions: { - sourceType: 'module', - }, -}; diff --git a/dev-packages/bundler-tests/.oxlintrc.json b/dev-packages/bundler-tests/.oxlintrc.json new file mode 100644 index 000000000000..e4b415b5e548 --- /dev/null +++ b/dev-packages/bundler-tests/.oxlintrc.json @@ -0,0 +1,4 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"] +} diff --git a/dev-packages/clear-cache-gh-action/.eslintrc.cjs b/dev-packages/clear-cache-gh-action/.eslintrc.cjs deleted file mode 100644 index 9f5a866e852f..000000000000 --- a/dev-packages/clear-cache-gh-action/.eslintrc.cjs +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - parserOptions: { - sourceType: 'module', - ecmaVersion: 'latest', - }, - - overrides: [ - { - files: ['*.mjs'], - extends: ['@sentry-internal/sdk'], - }, - ], -}; diff --git a/dev-packages/clear-cache-gh-action/.oxlintrc.json b/dev-packages/clear-cache-gh-action/.oxlintrc.json new file mode 100644 index 000000000000..e4b415b5e548 --- /dev/null +++ b/dev-packages/clear-cache-gh-action/.oxlintrc.json @@ -0,0 +1,4 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"] +} diff --git a/dev-packages/clear-cache-gh-action/package.json b/dev-packages/clear-cache-gh-action/package.json index 29dc3b517475..1f802be1676e 100644 --- a/dev-packages/clear-cache-gh-action/package.json +++ b/dev-packages/clear-cache-gh-action/package.json @@ -10,8 +10,8 @@ "main": "index.mjs", "type": "module", "scripts": { - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix" + "lint": "oxlint .", + "fix": "oxlint . --fix" }, "dependencies": { "@actions/core": "1.10.1", diff --git a/dev-packages/cloudflare-integration-tests/.eslintrc.js b/dev-packages/cloudflare-integration-tests/.eslintrc.js deleted file mode 100644 index 2cd3ff680383..000000000000 --- a/dev-packages/cloudflare-integration-tests/.eslintrc.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - overrides: [ - { - files: ['*.ts'], - parserOptions: { - project: ['tsconfig.json'], - sourceType: 'module', - }, - }, - { - files: ['suites/**/*.ts', 'suites/**/*.mjs'], - globals: { - fetch: 'readonly', - }, - rules: { - '@typescript-eslint/typedef': 'off', - // Explicitly allow ts-ignore with description for Node integration tests - // Reason: We run these tests on TS3.8 which doesn't support `@ts-expect-error` - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-ignore': 'allow-with-description', - 'ts-expect-error': true, - }, - ], - // We rely on having imports after init() is called for OTEL - 'import/first': 'off', - }, - }, - ], -}; diff --git a/dev-packages/cloudflare-integration-tests/.oxlintrc.json b/dev-packages/cloudflare-integration-tests/.oxlintrc.json new file mode 100644 index 000000000000..56d441ab0c82 --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/.oxlintrc.json @@ -0,0 +1,25 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + }, + "overrides": [ + { + "files": ["suites/**/*.ts", "suites/**/*.mjs"], + "globals": { + "fetch": "readonly" + }, + "rules": { + "typescript/ban-ts-comment": [ + "error", + { + "ts-ignore": "allow-with-description", + "ts-expect-error": true + } + ], + "import/first": "off" + } + } + ] +} diff --git a/dev-packages/cloudflare-integration-tests/package.json b/dev-packages/cloudflare-integration-tests/package.json index fef2c1372cf3..09b20aa9b977 100644 --- a/dev-packages/cloudflare-integration-tests/package.json +++ b/dev-packages/cloudflare-integration-tests/package.json @@ -7,8 +7,8 @@ }, "private": true, "scripts": { - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix", + "lint": "oxlint .", + "fix": "oxlint . --fix", "test": "vitest run", "test:watch": "yarn test --watch" }, diff --git a/dev-packages/e2e-tests/.eslintrc.js b/dev-packages/e2e-tests/.eslintrc.js deleted file mode 100644 index f285653c3e52..000000000000 --- a/dev-packages/e2e-tests/.eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - ignorePatterns: ['test-applications/**', 'tmp/**'], - parserOptions: { - sourceType: 'module', - }, -}; diff --git a/dev-packages/e2e-tests/.oxlintrc.json b/dev-packages/e2e-tests/.oxlintrc.json new file mode 100644 index 000000000000..e4484cb69ed7 --- /dev/null +++ b/dev-packages/e2e-tests/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + }, + "ignorePatterns": ["test-applications/**", "tmp/**"] +} diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index c88ed8e1c9df..3a5742e1faf6 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -4,8 +4,8 @@ "license": "MIT", "private": true, "scripts": { - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:ts": "tsc --noEmit", "test:e2e": "run-s test:validate-configuration test:validate-test-app-setups test:run", "test:run": "ts-node run.ts", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/.eslintrc.js b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/.eslintrc.js deleted file mode 100644 index e0a82f1826e3..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/.eslintrc.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * This is intended to be a basic starting point for linting in your app. - * It relies on recommended configs out of the box for simplicity, but you can - * and should modify this configuration to best suit your team's needs. - */ - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - env: { - browser: true, - commonjs: true, - es6: true, - }, - - // Base config - extends: ['eslint:recommended'], - - overrides: [ - // React - { - files: ['**/*.{js,jsx,ts,tsx}'], - plugins: ['react', 'jsx-a11y'], - extends: [ - 'plugin:react/recommended', - 'plugin:react/jsx-runtime', - 'plugin:react-hooks/recommended', - 'plugin:jsx-a11y/recommended', - ], - settings: { - react: { - version: 'detect', - }, - formComponents: ['Form'], - linkComponents: [ - { name: 'Link', linkAttribute: 'to' }, - { name: 'NavLink', linkAttribute: 'to' }, - ], - 'import/resolver': { - typescript: {}, - }, - }, - }, - - // Typescript - { - files: ['**/*.{ts,tsx}'], - plugins: ['@typescript-eslint', 'import'], - parser: '@typescript-eslint/parser', - settings: { - 'import/internal-regex': '^~/', - 'import/resolver': { - node: { - extensions: ['.ts', '.tsx'], - }, - typescript: { - alwaysTryTypes: true, - }, - }, - }, - extends: ['plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'plugin:import/typescript'], - }, - - // Node - { - files: ['.eslintrc.js', 'server.mjs'], - env: { - node: true, - }, - }, - ], -}; diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express/.eslintrc.cjs b/dev-packages/e2e-tests/test-applications/create-remix-app-express/.eslintrc.cjs deleted file mode 100644 index 7adbd6f482f6..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express/.eslintrc.cjs +++ /dev/null @@ -1,79 +0,0 @@ -/** - * This is intended to be a basic starting point for linting in your app. - * It relies on recommended configs out of the box for simplicity, but you can - * and should modify this configuration to best suit your team's needs. - */ - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - env: { - browser: true, - commonjs: true, - es6: true, - }, - - // Base config - extends: ['eslint:recommended'], - - overrides: [ - // React - { - files: ['**/*.{js,jsx,ts,tsx}'], - plugins: ['react', 'jsx-a11y'], - extends: [ - 'plugin:react/recommended', - 'plugin:react/jsx-runtime', - 'plugin:react-hooks/recommended', - 'plugin:jsx-a11y/recommended', - ], - settings: { - react: { - version: 'detect', - }, - formComponents: ['Form'], - linkComponents: [ - { name: 'Link', linkAttribute: 'to' }, - { name: 'NavLink', linkAttribute: 'to' }, - ], - 'import/resolver': { - typescript: {}, - }, - }, - }, - - // Typescript - { - files: ['**/*.{ts,tsx}'], - plugins: ['@typescript-eslint', 'import'], - parser: '@typescript-eslint/parser', - settings: { - 'import/internal-regex': '^~/', - 'import/resolver': { - node: { - extensions: ['.ts', '.tsx'], - }, - typescript: { - alwaysTryTypes: true, - }, - }, - }, - extends: ['plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'plugin:import/typescript'], - }, - - // Node - { - files: ['.eslintrc.cjs', 'server.js'], - env: { - node: true, - }, - }, - ], -}; diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2-non-vite/.eslintrc.js b/dev-packages/e2e-tests/test-applications/create-remix-app-v2-non-vite/.eslintrc.js deleted file mode 100644 index f2faf1470fd8..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2-non-vite/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node'], -}; diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/.eslintrc.js b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/.eslintrc.js deleted file mode 100644 index f2faf1470fd8..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node'], -}; diff --git a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintignore b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintignore deleted file mode 100644 index a362bcaa13b5..000000000000 --- a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -build -node_modules -bin -*.d.ts -dist diff --git a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintrc.cjs b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintrc.cjs deleted file mode 100644 index 85eb86d14b9e..000000000000 --- a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/.eslintrc.cjs +++ /dev/null @@ -1,79 +0,0 @@ -/** - * This is intended to be a basic starting point for linting in your app. - * It relies on recommended configs out of the box for simplicity, but you can - * and should modify this configuration to best suit your team's needs. - */ - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - env: { - browser: true, - commonjs: true, - es6: true, - }, - - // Base config - extends: ['eslint:recommended'], - - overrides: [ - // React - { - files: ['**/*.{js,jsx,ts,tsx}'], - plugins: ['react', 'jsx-a11y'], - extends: [ - 'plugin:react/recommended', - 'plugin:react/jsx-runtime', - 'plugin:react-hooks/recommended', - 'plugin:jsx-a11y/recommended', - ], - settings: { - react: { - version: 'detect', - }, - formComponents: ['Form'], - linkComponents: [ - { name: 'Link', linkAttribute: 'to' }, - { name: 'NavLink', linkAttribute: 'to' }, - ], - 'import/resolver': { - typescript: {}, - }, - }, - }, - - // Typescript - { - files: ['**/*.{ts,tsx}'], - plugins: ['@typescript-eslint', 'import'], - parser: '@typescript-eslint/parser', - settings: { - 'import/internal-regex': '^~/', - 'import/resolver': { - node: { - extensions: ['.ts', '.tsx'], - }, - typescript: { - alwaysTryTypes: true, - }, - }, - }, - extends: ['plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'plugin:import/typescript'], - }, - - // Node - { - files: ['.eslintrc.cjs', 'server.ts'], - env: { - node: true, - }, - }, - ], -}; diff --git a/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintignore b/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintignore deleted file mode 100644 index a362bcaa13b5..000000000000 --- a/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -build -node_modules -bin -*.d.ts -dist diff --git a/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintrc.cjs b/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintrc.cjs deleted file mode 100644 index 85eb86d14b9e..000000000000 --- a/dev-packages/e2e-tests/test-applications/remix-hydrogen/.eslintrc.cjs +++ /dev/null @@ -1,79 +0,0 @@ -/** - * This is intended to be a basic starting point for linting in your app. - * It relies on recommended configs out of the box for simplicity, but you can - * and should modify this configuration to best suit your team's needs. - */ - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - env: { - browser: true, - commonjs: true, - es6: true, - }, - - // Base config - extends: ['eslint:recommended'], - - overrides: [ - // React - { - files: ['**/*.{js,jsx,ts,tsx}'], - plugins: ['react', 'jsx-a11y'], - extends: [ - 'plugin:react/recommended', - 'plugin:react/jsx-runtime', - 'plugin:react-hooks/recommended', - 'plugin:jsx-a11y/recommended', - ], - settings: { - react: { - version: 'detect', - }, - formComponents: ['Form'], - linkComponents: [ - { name: 'Link', linkAttribute: 'to' }, - { name: 'NavLink', linkAttribute: 'to' }, - ], - 'import/resolver': { - typescript: {}, - }, - }, - }, - - // Typescript - { - files: ['**/*.{ts,tsx}'], - plugins: ['@typescript-eslint', 'import'], - parser: '@typescript-eslint/parser', - settings: { - 'import/internal-regex': '^~/', - 'import/resolver': { - node: { - extensions: ['.ts', '.tsx'], - }, - typescript: { - alwaysTryTypes: true, - }, - }, - }, - extends: ['plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'plugin:import/typescript'], - }, - - // Node - { - files: ['.eslintrc.cjs', 'server.ts'], - env: { - node: true, - }, - }, - ], -}; diff --git a/dev-packages/external-contributor-gh-action/.eslintrc.cjs b/dev-packages/external-contributor-gh-action/.eslintrc.cjs deleted file mode 100644 index 9f5a866e852f..000000000000 --- a/dev-packages/external-contributor-gh-action/.eslintrc.cjs +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - parserOptions: { - sourceType: 'module', - ecmaVersion: 'latest', - }, - - overrides: [ - { - files: ['*.mjs'], - extends: ['@sentry-internal/sdk'], - }, - ], -}; diff --git a/dev-packages/external-contributor-gh-action/.oxlintrc.json b/dev-packages/external-contributor-gh-action/.oxlintrc.json new file mode 100644 index 000000000000..e4b415b5e548 --- /dev/null +++ b/dev-packages/external-contributor-gh-action/.oxlintrc.json @@ -0,0 +1,4 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"] +} diff --git a/dev-packages/external-contributor-gh-action/package.json b/dev-packages/external-contributor-gh-action/package.json index 625141f1baca..31c46f4fc43d 100644 --- a/dev-packages/external-contributor-gh-action/package.json +++ b/dev-packages/external-contributor-gh-action/package.json @@ -10,8 +10,8 @@ "main": "index.mjs", "type": "module", "scripts": { - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix" + "lint": "oxlint .", + "fix": "oxlint . --fix" }, "dependencies": { "@actions/core": "1.10.1" diff --git a/dev-packages/node-core-integration-tests/.eslintrc.js b/dev-packages/node-core-integration-tests/.eslintrc.js deleted file mode 100644 index ce21050cd142..000000000000 --- a/dev-packages/node-core-integration-tests/.eslintrc.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - overrides: [ - { - files: ['utils/**/*.ts', 'src/**/*.ts'], - parserOptions: { - project: ['tsconfig.json'], - sourceType: 'module', - }, - }, - { - files: ['suites/**/*.ts', 'suites/**/*.mjs'], - parserOptions: { - project: ['tsconfig.test.json'], - sourceType: 'module', - ecmaVersion: 'latest', - }, - globals: { - fetch: 'readonly', - }, - rules: { - '@typescript-eslint/typedef': 'off', - // Explicitly allow ts-ignore with description for Node integration tests - // Reason: We run these tests on TS3.8 which doesn't support `@ts-expect-error` - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-ignore': 'allow-with-description', - 'ts-expect-error': true, - }, - ], - // We rely on having imports after init() is called for OTEL - 'import/first': 'off', - }, - }, - ], -}; diff --git a/dev-packages/node-core-integration-tests/.oxlintrc.json b/dev-packages/node-core-integration-tests/.oxlintrc.json new file mode 100644 index 000000000000..56d441ab0c82 --- /dev/null +++ b/dev-packages/node-core-integration-tests/.oxlintrc.json @@ -0,0 +1,25 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + }, + "overrides": [ + { + "files": ["suites/**/*.ts", "suites/**/*.mjs"], + "globals": { + "fetch": "readonly" + }, + "rules": { + "typescript/ban-ts-comment": [ + "error", + { + "ts-ignore": "allow-with-description", + "ts-expect-error": true + } + ], + "import/first": "off" + } + } + ] +} diff --git a/dev-packages/node-core-integration-tests/package.json b/dev-packages/node-core-integration-tests/package.json index dfe4f49d879d..50deffe3fd96 100644 --- a/dev-packages/node-core-integration-tests/package.json +++ b/dev-packages/node-core-integration-tests/package.json @@ -16,8 +16,8 @@ "build:types": "tsc -p tsconfig.types.json", "clean": "rimraf -g **/node_modules && run-p clean:script", "clean:script": "node scripts/clean.js", - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix", + "lint": "oxlint .", + "fix": "oxlint . --fix", "type-check": "tsc", "test": "vitest run", "test:watch": "yarn test --watch" diff --git a/dev-packages/node-integration-tests/.eslintrc.js b/dev-packages/node-integration-tests/.eslintrc.js deleted file mode 100644 index ce21050cd142..000000000000 --- a/dev-packages/node-integration-tests/.eslintrc.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - overrides: [ - { - files: ['utils/**/*.ts', 'src/**/*.ts'], - parserOptions: { - project: ['tsconfig.json'], - sourceType: 'module', - }, - }, - { - files: ['suites/**/*.ts', 'suites/**/*.mjs'], - parserOptions: { - project: ['tsconfig.test.json'], - sourceType: 'module', - ecmaVersion: 'latest', - }, - globals: { - fetch: 'readonly', - }, - rules: { - '@typescript-eslint/typedef': 'off', - // Explicitly allow ts-ignore with description for Node integration tests - // Reason: We run these tests on TS3.8 which doesn't support `@ts-expect-error` - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-ignore': 'allow-with-description', - 'ts-expect-error': true, - }, - ], - // We rely on having imports after init() is called for OTEL - 'import/first': 'off', - }, - }, - ], -}; diff --git a/dev-packages/node-integration-tests/.oxlintrc.json b/dev-packages/node-integration-tests/.oxlintrc.json new file mode 100644 index 000000000000..56d441ab0c82 --- /dev/null +++ b/dev-packages/node-integration-tests/.oxlintrc.json @@ -0,0 +1,25 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + }, + "overrides": [ + { + "files": ["suites/**/*.ts", "suites/**/*.mjs"], + "globals": { + "fetch": "readonly" + }, + "rules": { + "typescript/ban-ts-comment": [ + "error", + { + "ts-ignore": "allow-with-description", + "ts-expect-error": true + } + ], + "import/first": "off" + } + } + ] +} diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index b9a3c628cd54..1f7a4fb8b644 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -16,8 +16,8 @@ "build:types": "tsc -p tsconfig.types.json", "clean": "rimraf -g suites/**/node_modules suites/**/tmp_* && run-p clean:script", "clean:script": "node scripts/clean.js", - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix", + "lint": "oxlint .", + "fix": "oxlint . --fix", "type-check": "tsc", "test": "vitest run", "test:watch": "yarn test --watch" diff --git a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts index 9a9fa28b1022..de78cdf978aa 100644 --- a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts @@ -1,7 +1,7 @@ import { afterAll, describe, expect, test } from 'vitest'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; -// eslint-disable-next-line @sentry-internal/sdk/no-skipped-tests +// eslint-disable-next-line jest/no-disabled-tests describe.skip('tedious auto instrumentation', { timeout: 75_000 }, () => { afterAll(() => { cleanupChildProcesses(); diff --git a/dev-packages/node-overhead-gh-action/.eslintrc.cjs b/dev-packages/node-overhead-gh-action/.eslintrc.cjs deleted file mode 100644 index 3560c39da4eb..000000000000 --- a/dev-packages/node-overhead-gh-action/.eslintrc.cjs +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - overrides: [ - { - files: ['**/*.mjs'], - parserOptions: { - project: ['tsconfig.json'], - sourceType: 'module', - }, - }, - ], -}; diff --git a/dev-packages/node-overhead-gh-action/.oxlintrc.json b/dev-packages/node-overhead-gh-action/.oxlintrc.json new file mode 100644 index 000000000000..5bffa72a1a08 --- /dev/null +++ b/dev-packages/node-overhead-gh-action/.oxlintrc.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + } +} diff --git a/dev-packages/node-overhead-gh-action/package.json b/dev-packages/node-overhead-gh-action/package.json index d030685ed3aa..6615cf3bb5a2 100644 --- a/dev-packages/node-overhead-gh-action/package.json +++ b/dev-packages/node-overhead-gh-action/package.json @@ -19,8 +19,8 @@ "clean": "rimraf -g **/node_modules", "db:up": "docker compose up", "db:down": "docker compose down --volumes", - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix" + "lint": "oxlint .", + "fix": "oxlint . --fix" }, "dependencies": { "@sentry/node": "10.42.0", diff --git a/dev-packages/rollup-utils/.eslintrc.cjs b/dev-packages/rollup-utils/.eslintrc.cjs deleted file mode 100644 index c44899e31665..000000000000 --- a/dev-packages/rollup-utils/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - ignorePatterns: ['otelLoaderTemplate.js.tmpl'], - sourceType: 'module', -}; diff --git a/dev-packages/rollup-utils/.oxlintrc.json b/dev-packages/rollup-utils/.oxlintrc.json new file mode 100644 index 000000000000..51607dded1a4 --- /dev/null +++ b/dev-packages/rollup-utils/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "ignorePatterns": ["otelLoaderTemplate.js.tmpl"] +} diff --git a/dev-packages/size-limit-gh-action/.eslintrc.cjs b/dev-packages/size-limit-gh-action/.eslintrc.cjs deleted file mode 100644 index ad9dd7b90cb4..000000000000 --- a/dev-packages/size-limit-gh-action/.eslintrc.cjs +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], - parserOptions: { - sourceType: 'module', - ecmaVersion: 'latest', - }, - - overrides: [ - { - files: ['**/*.mjs'], - extends: ['@sentry-internal/sdk'], - }, - ], -}; diff --git a/dev-packages/size-limit-gh-action/.oxlintrc.json b/dev-packages/size-limit-gh-action/.oxlintrc.json new file mode 100644 index 000000000000..e4b415b5e548 --- /dev/null +++ b/dev-packages/size-limit-gh-action/.oxlintrc.json @@ -0,0 +1,4 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"] +} diff --git a/dev-packages/size-limit-gh-action/package.json b/dev-packages/size-limit-gh-action/package.json index ad80de1ade6d..425e7ff3475c 100644 --- a/dev-packages/size-limit-gh-action/package.json +++ b/dev-packages/size-limit-gh-action/package.json @@ -10,8 +10,8 @@ "main": "index.mjs", "type": "module", "scripts": { - "lint": "eslint . --format stylish", - "fix": "eslint . --format stylish --fix" + "lint": "oxlint .", + "fix": "oxlint . --fix" }, "dependencies": { "@actions/artifact": "^6.1.0", diff --git a/dev-packages/test-utils/.eslintrc.js b/dev-packages/test-utils/.eslintrc.js deleted file mode 100644 index d486b3046d17..000000000000 --- a/dev-packages/test-utils/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - env: { - node: true, - }, - // todo: remove regexp plugin from here once we add it to base.js eslint config for the whole project - extends: ['../.eslintrc.js', 'plugin:regexp/recommended'], - plugins: ['regexp'], -}; diff --git a/dev-packages/test-utils/.oxlintrc.json b/dev-packages/test-utils/.oxlintrc.json new file mode 100644 index 000000000000..5bffa72a1a08 --- /dev/null +++ b/dev-packages/test-utils/.oxlintrc.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "env": { + "node": true + } +} diff --git a/dev-packages/test-utils/package.json b/dev-packages/test-utils/package.json index f82711f0b678..155705375b71 100644 --- a/dev-packages/test-utils/package.json +++ b/dev-packages/test-utils/package.json @@ -31,8 +31,8 @@ "node": ">=18" }, "scripts": { - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "build": "run-s build:transpile build:types", "build:tarball": "run-s build:transpile build:types", "build:dev": "yarn build", diff --git a/nx.json b/nx.json index 7cd807e089fb..5cc18211d58b 100644 --- a/nx.json +++ b/nx.json @@ -51,7 +51,7 @@ "inputs": ["default"], "dependsOn": ["^build:types", "build:types"], "outputs": [], - "cache": true + "cache": false }, "test:unit": { "dependsOn": ["build:types", "^build:types", "build:transpile", "^build:transpile"], diff --git a/package.json b/package.json index 91bc549e4527..ae538903cca2 100644 --- a/package.json +++ b/package.json @@ -21,14 +21,14 @@ "clean:tarballs": "rimraf {packages,dev-packages}/*/*.tgz", "clean:watchman": "watchman watch-del \".\"", "clean:all": "run-s clean:build clean:tarballs clean:caches clean:deps clean:watchman", - "fix": "run-s fix:oxfmt fix:eslint", - "fix:eslint": "nx run-many -t fix", + "fix": "run-s fix:oxfmt fix:oxlint", + "fix:oxlint": "oxlint packages/ --fix", "fix:oxfmt": "oxfmt . --write", "format:check": "oxfmt . --check", "format": "oxfmt . --write", - "lint": "run-s lint:oxfmt lint:eslint", - "lint:eslint": "nx run-many -t lint", + "lint": "run-s lint:oxfmt lint:oxlint", "lint:oxfmt": "oxfmt . --check", + "lint:oxlint": "OXLINT_TSGOLINT_DANGEROUSLY_SUPPRESS_PROGRAM_DIAGNOSTICS=true oxlint . --type-aware", "lint:es-compatibility": "nx run-many -t lint:es-compatibility", "dedupe-deps:check": "yarn-deduplicate yarn.lock --list --fail", "dedupe-deps:fix": "yarn-deduplicate yarn.lock", @@ -125,13 +125,14 @@ "deepmerge": "^4.2.2", "downlevel-dts": "~0.11.0", "es-check": "^7.2.1", - "eslint": "8.57.0", "jsdom": "^21.1.2", "madge": "8.0.0", "nodemon": "^3.1.10", "npm-run-all2": "^6.2.0", "nx": "22.5.0", "oxfmt": "^0.32.0", + "oxlint": "^1.50.0", + "oxlint-tsgolint": "^0.16.0", "rimraf": "^5.0.10", "rollup": "^4.59.0", "rollup-plugin-cleanup": "^3.2.1", diff --git a/packages/angular/.eslintrc.cjs b/packages/angular/.eslintrc.cjs deleted file mode 100644 index f7b591f35685..000000000000 --- a/packages/angular/.eslintrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - env: { - browser: true, - }, - extends: ['../../.eslintrc.js'], - ignorePatterns: ['setup-test.ts', 'patch-vitest.ts'], - rules: { - // Angular transpiles this correctly/relies on this - '@sentry-internal/sdk/no-class-field-initializers': 'off', - }, -}; diff --git a/packages/angular/.oxlintrc.json b/packages/angular/.oxlintrc.json new file mode 100644 index 000000000000..f87f394ed3b6 --- /dev/null +++ b/packages/angular/.oxlintrc.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "env": { + "browser": true + }, + "overrides": [ + { + "files": ["**/src/**"], + "rules": { + "sdk/no-class-field-initializers": "off" + } + } + ], + "ignorePatterns": ["setup-test.ts", "patch-vitest.ts"] +} diff --git a/packages/angular/package.json b/packages/angular/package.json index 2785c18d8c69..c2d4b1168863 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -51,8 +51,8 @@ "build:tarball": "npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", "clean": "rimraf build coverage sentry-angular-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2020 ./build/{esm2020,fesm2015,fesm2020}/*.mjs --module", "test": "yarn test:unit", "test:unit": "vitest run", diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index ceb05c0b9e9f..ccd918667f00 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -26,6 +26,7 @@ export interface ErrorHandlerOptions { function tryToUnwrapZonejsError(error: unknown): unknown | Error { // TODO: once Angular14 is the minimum requirement ERROR_ORIGINAL_ERROR and // getOriginalError from error.ts can be used directly. + // oxlint-disable-next-line typescript/prefer-optional-chain return error && (error as { ngOriginalError: Error }).ngOriginalError ? (error as { ngOriginalError: Error }).ngOriginalError : error; @@ -39,6 +40,7 @@ function extractHttpModuleError(error: HttpErrorResponse): string | Error { // ... or an`ErrorEvent`, which can provide us with the message but no stack... // guarding `ErrorEvent` against `undefined` as it's not defined in Node environments + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof ErrorEvent !== 'undefined' && error.error instanceof ErrorEvent && error.error.message) { return error.error.message; } diff --git a/packages/angular/src/zone.ts b/packages/angular/src/zone.ts index 22f56e4c3871..fb4db2ed8ac2 100644 --- a/packages/angular/src/zone.ts +++ b/packages/angular/src/zone.ts @@ -7,7 +7,7 @@ declare const Zone: any; // In Angular 17 and future versions, zoneless support is forthcoming. // Therefore, it's advisable to safely check whether the `run` function is // available in the `` context. -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access typescript/prefer-optional-chain const isNgZoneEnabled = typeof Zone !== 'undefined' && Zone.root?.run; /** diff --git a/packages/astro/.eslintrc.cjs b/packages/astro/.eslintrc.cjs deleted file mode 100644 index 3be941649fcf..000000000000 --- a/packages/astro/.eslintrc.cjs +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - env: { - browser: true, - node: true, - }, - extends: ['../../.eslintrc.js'], - overrides: [ - { - files: ['vite.config.ts'], - parserOptions: { - project: ['tsconfig.vite.json'], - }, - }, - ], -}; diff --git a/packages/astro/.oxlintrc.json b/packages/astro/.oxlintrc.json new file mode 100644 index 000000000000..28d9e2d390f2 --- /dev/null +++ b/packages/astro/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "env": { + "browser": true, + "node": true + } +} diff --git a/packages/astro/package.json b/packages/astro/package.json index 4d18ee6f7300..48384978c4e9 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -76,8 +76,8 @@ "build:tarball": "npm pack", "circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts", "clean": "rimraf build coverage sentry-astro-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2020 ./build/cjs/*.js && es-check es2020 ./build/esm/*.js --module", "test": "yarn test:unit", "test:unit": "vitest run", diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts index 82278da28925..c97ca2fd1ed0 100644 --- a/packages/astro/src/integration/snippets.ts +++ b/packages/astro/src/integration/snippets.ts @@ -59,6 +59,7 @@ const buildClientIntegrations = (options: SentryOptions): string => { integrations.push('Sentry.browserTracingIntegration()'); } + /* oxlint-disable typescript/prefer-optional-chain */ if ( options.replaysSessionSampleRate == null || options.replaysSessionSampleRate || @@ -67,6 +68,7 @@ const buildClientIntegrations = (options: SentryOptions): string => { ) { integrations.push('Sentry.replayIntegration()'); } + /* oxlint-enable typescript/prefer-optional-chain */ return integrations.join(', '); }; diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index a12c25ff6045..b42be72ae846 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -423,9 +423,10 @@ function getParametrizedRoute( // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const routesFromManifest = ctx?.[Symbol.for('context.routes')]?.manifest?.routes; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + // oxlint-disable-next-line typescript/no-unsafe-member-access const matchedRouteSegmentsFromManifest = routesFromManifest?.find( (route: { routeData?: { route?: string } }) => route?.routeData?.route === rawRoutePattern, + // oxlint-disable-next-line typescript/no-unsafe-member-access )?.routeData?.segments; return ( diff --git a/packages/aws-serverless/.eslintrc.js b/packages/aws-serverless/.eslintrc.js deleted file mode 100644 index d1d4c4e12aa0..000000000000 --- a/packages/aws-serverless/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - env: { - node: true, - }, - extends: ['../../.eslintrc.js'], - overrides: [ - { - files: ['scripts/**/*.ts'], - parserOptions: { - project: ['../../tsconfig.dev.json'], - }, - }, - { - files: ['test/**'], - parserOptions: { - sourceType: 'module', - }, - }, - ], -}; diff --git a/packages/aws-serverless/.oxlintrc.json b/packages/aws-serverless/.oxlintrc.json new file mode 100644 index 000000000000..8ca250cb7e99 --- /dev/null +++ b/packages/aws-serverless/.oxlintrc.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "env": { + "node": true + } +} diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index de4d12881a01..bb0564f610bb 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -92,8 +92,8 @@ "build:tarball": "npm pack", "circularDepCheck": "madge --circular src/index.ts", "clean": "rimraf build dist-awslambda-layer coverage sentry-serverless-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2022 ./build/npm/cjs/*.js && es-check es2022 ./build/npm/esm/*.js --module", "test": "vitest run", "test:watch": "vitest --watch", diff --git a/packages/browser-utils/.eslintrc.js b/packages/browser-utils/.eslintrc.js deleted file mode 100644 index 607e5d1b7d43..000000000000 --- a/packages/browser-utils/.eslintrc.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.js'], - env: { - browser: true, - }, - overrides: [ - { - files: ['src/**'], - rules: {}, - }, - { - files: ['src/metrics/**'], - rules: { - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - }, - }, - ], -}; diff --git a/packages/browser-utils/.oxlintrc.json b/packages/browser-utils/.oxlintrc.json new file mode 100644 index 000000000000..220599004174 --- /dev/null +++ b/packages/browser-utils/.oxlintrc.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "env": { + "browser": true + }, + "overrides": [ + { + "files": ["src/metrics/**"], + "rules": { + "typescript/explicit-function-return-type": "off", + "typescript/no-non-null-assertion": "off" + } + } + ] +} diff --git a/packages/browser-utils/package.json b/packages/browser-utils/package.json index 8498b5d2f72b..54d89fea3f07 100644 --- a/packages/browser-utils/package.json +++ b/packages/browser-utils/package.json @@ -53,8 +53,8 @@ "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch", "build:tarball": "npm pack", "clean": "rimraf build coverage sentry-internal-browser-utils-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2020 ./build/cjs/*.js && es-check es2020 ./build/esm/*.js --module", "test:unit": "vitest run", "test": "vitest run", diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/InteractionManager.ts b/packages/browser-utils/src/metrics/web-vitals/lib/InteractionManager.ts index d4aea1683606..726699bc2010 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/InteractionManager.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/InteractionManager.ts @@ -51,14 +51,14 @@ export class InteractionManager { * longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER * long. */ - // eslint-disable-next-line @sentry-internal/sdk/no-class-field-initializers, @typescript-eslint/explicit-member-accessibility + // oxlint-disable-next-line sdk/no-class-field-initializers _longestInteractionList: Interaction[] = []; /** * A mapping of longest interactions by their interaction ID. * This is used for faster lookup. */ - // eslint-disable-next-line @sentry-internal/sdk/no-class-field-initializers, @typescript-eslint/explicit-member-accessibility + // oxlint-disable-next-line sdk/no-class-field-initializers _longestInteractionMap: Map = new Map(); // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/LayoutShiftManager.ts b/packages/browser-utils/src/metrics/web-vitals/lib/LayoutShiftManager.ts index c9171b56ef0c..47d329162915 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/LayoutShiftManager.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/LayoutShiftManager.ts @@ -19,9 +19,9 @@ export class LayoutShiftManager { // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility _onAfterProcessingUnexpectedShift?: (entry: LayoutShift) => void; - // eslint-disable-next-line @sentry-internal/sdk/no-class-field-initializers, @typescript-eslint/explicit-member-accessibility + // oxlint-disable-next-line sdk/no-class-field-initializers _sessionValue = 0; - // eslint-disable-next-line @sentry-internal/sdk/no-class-field-initializers, @typescript-eslint/explicit-member-accessibility + // oxlint-disable-next-line sdk/no-class-field-initializers _sessionEntries: LayoutShift[] = []; // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility diff --git a/packages/browser/.eslintignore b/packages/browser/.eslintignore deleted file mode 100644 index 81c6b54e0be2..000000000000 --- a/packages/browser/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -tmp.js diff --git a/packages/browser/.eslintrc.js b/packages/browser/.eslintrc.js deleted file mode 100644 index fec08079889a..000000000000 --- a/packages/browser/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - env: { - browser: true, - }, - ignorePatterns: ['test/integration/**', 'test/loader.js'], - extends: ['../../.eslintrc.js'], -}; diff --git a/packages/browser/.oxlintrc.json b/packages/browser/.oxlintrc.json new file mode 100644 index 000000000000..a17777df77bf --- /dev/null +++ b/packages/browser/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "env": { + "browser": true + }, + "ignorePatterns": ["test/integration/**", "test/loader.js"] +} diff --git a/packages/browser/package.json b/packages/browser/package.json index 4b827760784b..9d57d64c4cb4 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -69,8 +69,8 @@ "build:tarball": "npm pack", "circularDepCheck": "madge --circular src/index.ts", "clean": "rimraf build coverage .rpt2_cache sentry-browser-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", + "fix": "oxlint . --fix", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2020 ./build/{bundles,npm/cjs/prod}/*.js && es-check es2020 ./build/npm/esm/prod/*.js --module", "size:check": "cat build/bundles/bundle.min.js | gzip -9 | wc -c | awk '{$1=$1/1024; print \"ES2017: \",$1,\"kB\";}'", "test": "vitest run", diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index 9823d596a502..798a068b5adf 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -165,6 +165,7 @@ function getPopFirstTopFrames(ex: Error & { framesToPop?: unknown }): number { function isWebAssemblyException(exception: unknown): exception is WebAssembly.Exception { // Check for support // @ts-expect-error - WebAssembly.Exception is a valid class + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof WebAssembly !== 'undefined' && typeof WebAssembly.Exception !== 'undefined') { // @ts-expect-error - WebAssembly.Exception is a valid class return exception instanceof WebAssembly.Exception; diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 02c3a1f66af3..cb74bc1e6ce6 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -88,7 +88,7 @@ const chromeStackParserFn: StackLineParserFn = line => { const parts = chromeRegex.exec(line) as null | [string, string, string, string, string]; if (parts) { - const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line + const isEval = parts[2]?.indexOf('eval') === 0; // start of line if (isEval) { const subMatch = chromeEvalRegex.exec(parts[2]) as null | [string, string, string, string]; diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index c71acf106258..dbcc57a6d982 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -503,8 +503,7 @@ export const browserTracingIntegration = ((options: Partial { throw _makeDoNotSendEventError('An event processor returned `null`, will not send event.'); } + // oxlint-disable-next-line typescript/prefer-optional-chain const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; if (isInternalException) { return prepared; diff --git a/packages/core/src/integrations/mcp-server/correlation.ts b/packages/core/src/integrations/mcp-server/correlation.ts index 068e4d4432d1..b47f0f9b4a69 100644 --- a/packages/core/src/integrations/mcp-server/correlation.ts +++ b/packages/core/src/integrations/mcp-server/correlation.ts @@ -70,7 +70,7 @@ export function storeSpanForRequest(transport: MCPTransport, requestId: RequestI spanMap.set(requestId, { span, method, - // eslint-disable-next-line @sentry-internal/sdk/no-unsafe-random-apis + // oxlint-disable-next-line sdk/no-unsafe-random-apis startTime: Date.now(), }); } diff --git a/packages/core/src/integrations/mcp-server/transport.ts b/packages/core/src/integrations/mcp-server/transport.ts index 5e4fd6e75c23..065fb44ab17d 100644 --- a/packages/core/src/integrations/mcp-server/transport.ts +++ b/packages/core/src/integrations/mcp-server/transport.ts @@ -105,6 +105,7 @@ export function wrapTransportSend(transport: MCPTransport, options: ResolvedMcpO } if (isJsonRpcResponse(message)) { + // oxlint-disable-next-line typescript/prefer-optional-chain if (message.id !== null && message.id !== undefined) { if (message.error) { captureJsonRpcErrorResponse(message.error); diff --git a/packages/core/src/tracing/google-genai/index.ts b/packages/core/src/tracing/google-genai/index.ts index 7781b67d6db0..369fb7701bd9 100644 --- a/packages/core/src/tracing/google-genai/index.ts +++ b/packages/core/src/tracing/google-genai/index.ts @@ -143,6 +143,7 @@ function addPrivateRequestAttributes(span: Span, params: Record // config.systemInstruction: ContentUnion if ( + // oxlint-disable-next-line typescript/prefer-optional-chain 'config' in params && params.config && typeof params.config === 'object' && diff --git a/packages/core/src/tracing/openai/utils.ts b/packages/core/src/tracing/openai/utils.ts index 82494f7ae018..3338d4524d75 100644 --- a/packages/core/src/tracing/openai/utils.ts +++ b/packages/core/src/tracing/openai/utils.ts @@ -222,6 +222,7 @@ export function addResponsesApiAttributes(span: Span, response: OpenAIResponseOb // Filter for function_call type objects in the output array const functionCalls = responseWithOutput.output.filter( (item): unknown => + // oxlint-disable-next-line typescript/prefer-optional-chain typeof item === 'object' && item !== null && (item as Record).type === 'function_call', ); diff --git a/packages/core/src/tracing/vercel-ai/index.ts b/packages/core/src/tracing/vercel-ai/index.ts index d3c4b036e228..1360d66b6166 100644 --- a/packages/core/src/tracing/vercel-ai/index.ts +++ b/packages/core/src/tracing/vercel-ai/index.ts @@ -131,7 +131,7 @@ function vercelAiEventProcessor(event: Event): Event { // Also apply to root when it is the invoke_agent pipeline const trace = event.contexts?.trace; - if (trace && trace.op === 'gen_ai.invoke_agent') { + if (trace?.op === 'gen_ai.invoke_agent') { applyAccumulatedTokens(trace, tokenAccumulator); } } diff --git a/packages/core/src/utils/normalize.ts b/packages/core/src/utils/normalize.ts index d70033d65672..1c25d937cfe4 100644 --- a/packages/core/src/utils/normalize.ts +++ b/packages/core/src/utils/normalize.ts @@ -303,7 +303,7 @@ export function normalizeUrlToBase(url: string, basePath: string): string { newUrl .replace(/\\/g, '/') .replace(/webpack:\/?/g, '') // Remove intermediate base path - // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor + // oxlint-disable-next-line sdk/no-regexp-constructor .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///') ); } diff --git a/packages/core/src/utils/prepareEvent.ts b/packages/core/src/utils/prepareEvent.ts index 6528873c3dee..95e244df2092 100644 --- a/packages/core/src/utils/prepareEvent.ts +++ b/packages/core/src/utils/prepareEvent.ts @@ -95,6 +95,7 @@ export function prepareEvent( ]; // Skip event processors for internal exceptions to prevent recursion + // oxlint-disable-next-line typescript/prefer-optional-chain const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; const result = isInternalException ? resolvedSyncPromise(prepared) diff --git a/packages/core/src/utils/string.ts b/packages/core/src/utils/string.ts index b74f9559f9cf..fe28ef24c46a 100644 --- a/packages/core/src/utils/string.ts +++ b/packages/core/src/utils/string.ts @@ -72,7 +72,7 @@ export function safeJoin(input: unknown[], delimiter?: string): string { } const output = []; - // eslint-disable-next-line @typescript-eslint/prefer-for-of + // eslint-disable-next-line typescript/prefer-for-of for (let i = 0; i < input.length; i++) { const value = input[i]; try { diff --git a/packages/core/src/utils/tracing.ts b/packages/core/src/utils/tracing.ts index 25e3295118f8..c3c5e5d91ae1 100644 --- a/packages/core/src/utils/tracing.ts +++ b/packages/core/src/utils/tracing.ts @@ -9,7 +9,7 @@ import { parseSampleRate } from './parseSampleRate'; import { generateSpanId, generateTraceId } from './propagationContext'; import { safeMathRandom } from './randomSafeContext'; -// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here +// oxlint-disable-next-line sdk/no-regexp-constructor -- RegExp is used for readability here export const TRACEPARENT_REGEXP = new RegExp( '^[ \\t]*' + // whitespace '([0-9a-f]{32})?' + // trace_id diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index 35438866c6c2..e7335f0de7e0 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2817,7 +2817,7 @@ describe('Client', () => { // would affect the entire test suite. // Maybe this can be re-enabled when switching to vitest. // - // eslint-disable-next-line @sentry-internal/sdk/no-skipped-tests + // eslint-disable-next-line jest/no-disabled-tests test.skip('handles asynchronous errors', async () => { const error = new Error('Test error'); const callback = vi.fn().mockRejectedValue(error); diff --git a/packages/deno/.eslintrc.js b/packages/deno/.eslintrc.js deleted file mode 100644 index 5a8ccd2be035..000000000000 --- a/packages/deno/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.js'], - ignorePatterns: ['lib.deno.d.ts', 'scripts/*.mjs', 'build-types/**', 'build-test/**', 'build/**'], - rules: { - '@sentry-internal/sdk/no-class-field-initializers': 'off', - }, -}; diff --git a/packages/deno/.oxlintrc.json b/packages/deno/.oxlintrc.json new file mode 100644 index 000000000000..75164516b719 --- /dev/null +++ b/packages/deno/.oxlintrc.json @@ -0,0 +1,13 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "overrides": [ + { + "files": ["**/src/**"], + "rules": { + "sdk/no-class-field-initializers": "off" + } + } + ], + "ignorePatterns": ["lib.deno.d.ts", "scripts/*.mjs", "build-types/**", "build-test/**", "build/**"] +} diff --git a/packages/deno/package.json b/packages/deno/package.json index fb3f17c74bd1..374348f904c1 100644 --- a/packages/deno/package.json +++ b/packages/deno/package.json @@ -37,9 +37,9 @@ "circularDepCheck": "madge --circular src/index.ts", "clean": "rimraf build build-types build-test coverage node_modules/.deno sentry-deno-*.tgz", "prefix": "yarn deno-types", - "fix": "eslint . --format stylish --fix", + "fix": "oxlint . --fix", "prelint": "yarn deno-types", - "lint": "eslint . --format stylish", + "lint": "oxlint .", "lint:es-compatibility": "es-check es2022 ./build/esm/*.js --module", "install:deno": "node ./scripts/install-deno.mjs", "test": "run-s install:deno deno-types test:unit", diff --git a/packages/deno/src/utils/streaming.ts b/packages/deno/src/utils/streaming.ts index b999af39bf49..4f6f4654af68 100644 --- a/packages/deno/src/utils/streaming.ts +++ b/packages/deno/src/utils/streaming.ts @@ -81,6 +81,7 @@ function monitorStream( onDone: () => void, ): ReadableStream> { const reader = stream.getReader(); + // oxlint-disable-next-line typescript/no-floating-promises reader.closed.finally(() => onDone()); return new ReadableStream({ async start(controller) { diff --git a/packages/ember/.eslintignore b/packages/ember/.eslintignore deleted file mode 100644 index ef6a9cb20ac9..000000000000 --- a/packages/ember/.eslintignore +++ /dev/null @@ -1,30 +0,0 @@ -# unconventional js -/blueprints/*/files/ - -# compiled output -/dist/ -/tmp/ - -# dependencies -/bower_components/ -/node_modules/ - -# misc -/coverage/ -!.* -.*/ -.eslintcache - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/npm-shrinkwrap.json.ember-try -/package.json.ember-try -/package-lock.json.ember-try -/yarn.lock.ember-try - -# Random compiledd types -index.d.ts -runloop.d.ts -types.d.ts -/instance-initializers/ diff --git a/packages/ember/.eslintrc.js b/packages/ember/.eslintrc.js deleted file mode 100644 index d626d24fce6c..000000000000 --- a/packages/ember/.eslintrc.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; - -module.exports = { - extends: ['../../.eslintrc.js'], - - overrides: [ - { - // Vendor scripts are injected as inline