diff --git a/.changeset/complexity-lint-warning.md b/.changeset/complexity-lint-warning.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/complexity-lint-warning.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.claude/skills/clerk-monorepo/SKILL.md b/.claude/skills/clerk-monorepo/SKILL.md index e94e35f3480..7ee23dab002 100644 --- a/.claude/skills/clerk-monorepo/SKILL.md +++ b/.claude/skills/clerk-monorepo/SKILL.md @@ -85,6 +85,10 @@ pnpm --filter @clerk/backend test:node path/to/file.test.ts pnpm lint pnpm format # workspace packages plus root files, docs/, integration/, scripts/ pnpm prettier --write '.claude/**/*.md' # pnpm format does not cover .claude/; format skill files this way +# Cognitive complexity (`sonarjs/cognitive-complexity`, max 15) is an error. Existing violations are +# grandfathered in each package's eslint-suppressions.json. After simplifying one of those functions, drop its +# stale entry (lint fails until you do) from inside that package: +pnpm eslint src --prune-suppressions # Changesets — write the file, don't run the CLI (both scripts are interactive prompts) pnpm changeset status --since=origin/main # what CI checks; run this to verify diff --git a/.prettierignore b/.prettierignore index 933efe001d3..e1f3a7dfd10 100644 --- a/.prettierignore +++ b/.prettierignore @@ -27,3 +27,5 @@ renovate.json5 # Frozen snapshots of TypeDoc-generated MDX; must match raw `extract-methods.mjs` output. .typedoc/__tests__/__snapshots__/ CLAUDE.md +# Written by `eslint --suppress-rule` / `--prune-suppressions`; ESLint owns the formatting. +/**/eslint-suppressions.json diff --git a/eslint.config.mjs b/eslint.config.mjs index 325bcc948d7..49e2a779ea8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,6 +9,7 @@ import pluginReact from 'eslint-plugin-react'; import pluginReactHooks from 'eslint-plugin-react-hooks'; import pluginStylex from '@stylexjs/eslint-plugin'; import pluginSimpleImportSort from 'eslint-plugin-simple-import-sort'; +import pluginSonarjs from 'eslint-plugin-sonarjs'; import pluginTurbo from 'eslint-plugin-turbo'; import pluginUnusedImports from 'eslint-plugin-unused-imports'; import pluginYml from 'eslint-plugin-yml'; @@ -330,6 +331,7 @@ export default tseslint.config([ }, }, 'simple-import-sort': pluginSimpleImportSort, + sonarjs: pluginSonarjs, 'unused-imports': pluginUnusedImports, turbo: pluginTurbo, }, @@ -398,6 +400,7 @@ export default tseslint.config([ 'sort-imports': 'off', ...pluginTurbo.configs['flat/recommended'].rules, 'unused-imports/no-unused-imports': 'error', + 'sonarjs/cognitive-complexity': ['error', 15], // TYPESCRIPT RULE DISABLES '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-unsafe-argument': 'off', diff --git a/package.json b/package.json index 836fd3ad975..1bb554441e9 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "eslint-plugin-react": "7.37.5", "eslint-plugin-react-hooks": "5.2.0", "eslint-plugin-simple-import-sort": "12.1.1", + "eslint-plugin-sonarjs": "4.2.0", "eslint-plugin-turbo": "2.5.5", "eslint-plugin-unused-imports": "4.4.1", "eslint-plugin-yml": "1.18.0", diff --git a/packages/backend/eslint-suppressions.json b/packages/backend/eslint-suppressions.json new file mode 100644 index 00000000000..9d3ae0fcdf0 --- /dev/null +++ b/packages/backend/eslint-suppressions.json @@ -0,0 +1,22 @@ +{ + "src/api/request.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/proxy.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/tokens/authenticateContext.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/tokens/request.ts": { + "sonarjs/cognitive-complexity": { + "count": 2 + } + } +} \ No newline at end of file diff --git a/packages/clerk-js/eslint-suppressions.json b/packages/clerk-js/eslint-suppressions.json new file mode 100644 index 00000000000..9f84f8c22c8 --- /dev/null +++ b/packages/clerk-js/eslint-suppressions.json @@ -0,0 +1,52 @@ +{ + "src/core/clerk.ts": { + "sonarjs/cognitive-complexity": { + "count": 7 + } + }, + "src/core/fapiClient.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/core/fraudProtection.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/core/protect.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/core/protectSession.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/core/resources/Base.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/core/tokenCache.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/billing.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/captcha/turnstile.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/mergePatch.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/electron/eslint-suppressions.json b/packages/electron/eslint-suppressions.json new file mode 100644 index 00000000000..2c5a0e3536b --- /dev/null +++ b/packages/electron/eslint-suppressions.json @@ -0,0 +1,12 @@ +{ + "src/main/create-clerk-bridge.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/storage/index.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/eslint-plugin/eslint-suppressions.json b/packages/eslint-plugin/eslint-suppressions.json new file mode 100644 index 00000000000..5270fb7bb67 --- /dev/null +++ b/packages/eslint-plugin/eslint-suppressions.json @@ -0,0 +1,27 @@ +{ + "src/next/fix-auth-protection.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/next/lib/exports.ts": { + "sonarjs/cognitive-complexity": { + "count": 3 + } + }, + "src/next/lib/fixers.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/next/lib/match-folders.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/next/lib/protection-checks.ts": { + "sonarjs/cognitive-complexity": { + "count": 2 + } + } +} \ No newline at end of file diff --git a/packages/expo/eslint-suppressions.json b/packages/expo/eslint-suppressions.json new file mode 100644 index 00000000000..a6794abf176 --- /dev/null +++ b/packages/expo/eslint-suppressions.json @@ -0,0 +1,12 @@ +{ + "src/hooks/useSignInWithApple.ios.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/provider/nativeClientSync.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/express/eslint-suppressions.json b/packages/express/eslint-suppressions.json new file mode 100644 index 00000000000..4f44c757bd2 --- /dev/null +++ b/packages/express/eslint-suppressions.json @@ -0,0 +1,7 @@ +{ + "src/authenticateRequest.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/fastify/eslint-suppressions.json b/packages/fastify/eslint-suppressions.json new file mode 100644 index 00000000000..faae7dda847 --- /dev/null +++ b/packages/fastify/eslint-suppressions.json @@ -0,0 +1,7 @@ +{ + "src/withClerkMiddleware.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/headless/eslint-suppressions.json b/packages/headless/eslint-suppressions.json new file mode 100644 index 00000000000..fe3050d1db7 --- /dev/null +++ b/packages/headless/eslint-suppressions.json @@ -0,0 +1,22 @@ +{ + "src/primitives/drawer/use-drawer-drag.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/primitives/drawer/use-snap-points.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/primitives/otp/otp-input.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/use-render.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/hono/eslint-suppressions.json b/packages/hono/eslint-suppressions.json new file mode 100644 index 00000000000..430d5419109 --- /dev/null +++ b/packages/hono/eslint-suppressions.json @@ -0,0 +1,7 @@ +{ + "src/clerkMiddleware.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/react/eslint-suppressions.json b/packages/react/eslint-suppressions.json new file mode 100644 index 00000000000..197c8786e40 --- /dev/null +++ b/packages/react/eslint-suppressions.json @@ -0,0 +1,12 @@ +{ + "src/isomorphicClerk.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/useCustomMenuItems.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/shared/eslint-suppressions.json b/packages/shared/eslint-suppressions.json new file mode 100644 index 00000000000..359658dfe79 --- /dev/null +++ b/packages/shared/eslint-suppressions.json @@ -0,0 +1,32 @@ +{ + "src/authorization.ts": { + "sonarjs/cognitive-complexity": { + "count": 3 + } + }, + "src/internal/clerk-js/completeSignUpFlow.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/internal/clerk-js/url.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/internal/clerk-js/web3.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/keys.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/loadClerkJsScript.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/testing/eslint-suppressions.json b/packages/testing/eslint-suppressions.json new file mode 100644 index 00000000000..59eb3126151 --- /dev/null +++ b/packages/testing/eslint-suppressions.json @@ -0,0 +1,12 @@ +{ + "src/common/helpers-utils.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/playwright/setupClerkTestingToken.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/ui/eslint-suppressions.json b/packages/ui/eslint-suppressions.json new file mode 100644 index 00000000000..2c97a39112e --- /dev/null +++ b/packages/ui/eslint-suppressions.json @@ -0,0 +1,112 @@ +{ + "src/components/Checkout/CheckoutComplete.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/Checkout/CheckoutForm.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/ConfigureDirectorySync/SecurityDirectorySyncSection.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/ConfigureSSO/elements/Wizard/reducer.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/OAuthConsent/OAuthConsent.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/OrganizationProfile/InviteMembersForm.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/PricingTable/PricingTableDefault.tsx": { + "sonarjs/cognitive-complexity": { + "count": 2 + } + }, + "src/components/SignIn/SignInFactorOne.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/SignIn/SignInStart.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/SignUp/SignUpStart.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/SignUp/signUpFormHelpers.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/SubscriptionDetails/index.tsx": { + "sonarjs/cognitive-complexity": { + "count": 2 + } + }, + "src/components/Subscriptions/SubscriptionsList.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/devPrompts/EnableOrganizationsPrompt/index.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/components/devPrompts/KeylessPrompt/index.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/contexts/components/Plans.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/hooks/useProtectCheckRunner.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/mosaic/user-button/user-button.view.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/mosaic/user-profile/user-profile-security-panel.view.tsx": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/router/pathToRegexp.ts": { + "sonarjs/cognitive-complexity": { + "count": 4 + } + }, + "src/utils/colors/legacy.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/utils/detectClerkStylesheetUsage.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/upgrade/eslint-suppressions.json b/packages/upgrade/eslint-suppressions.json new file mode 100644 index 00000000000..34e54bf2fd2 --- /dev/null +++ b/packages/upgrade/eslint-suppressions.json @@ -0,0 +1,47 @@ +{ + "src/cli.js": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/codemods/transform-align-experimental-unstable-prefixes.cjs": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/codemods/transform-protect-to-show-vue.cjs": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/codemods/transform-protect-to-show.cjs": { + "sonarjs/cognitive-complexity": { + "count": 3 + } + }, + "src/codemods/transform-remove-deprecated-props.cjs": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/config.js": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/runner.js": { + "sonarjs/cognitive-complexity": { + "count": 2 + } + }, + "src/util/detect-sdk.js": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + }, + "src/util/package-manager.js": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/packages/vue/eslint-suppressions.json b/packages/vue/eslint-suppressions.json new file mode 100644 index 00000000000..cbf59b3b1fc --- /dev/null +++ b/packages/vue/eslint-suppressions.json @@ -0,0 +1,7 @@ +{ + "src/utils/useCustomMenuItems.ts": { + "sonarjs/cognitive-complexity": { + "count": 1 + } + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3ecba5aa74..1fa42fc70ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -242,6 +242,9 @@ importers: eslint-plugin-simple-import-sort: specifier: 12.1.1 version: 12.1.1(eslint@9.31.0(jiti@2.7.0)) + eslint-plugin-sonarjs: + specifier: 4.2.0 + version: 4.2.0(eslint@9.31.0(jiti@2.7.0)) eslint-plugin-turbo: specifier: 2.5.5 version: 2.5.5(eslint@9.31.0(jiti@2.7.0))(turbo@2.10.12) @@ -7603,6 +7606,10 @@ packages: resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} engines: {node: '>=6.14.2'} + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -9016,6 +9023,11 @@ packages: peerDependencies: eslint: '>=5.0.0' + eslint-plugin-sonarjs@4.2.0: + resolution: {integrity: sha512-bqADfuNtTL7VK6RU29eoiFTtaaBKIpVPuX3bOl+rBpWSBa0zIBVZlqZNZQjfP6s4iXkAJokv5IsD8OsACkwApg==} + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 + eslint-plugin-turbo@2.5.5: resolution: {integrity: sha512-IlN65X6W7rgK88u5xl1xC+7FIGKA7eyaca0yxZQ9CBNV6keAaqtjZQLw8ZfXdv7T+MzTLYkYOeOHAv8yCRUx4Q==} peerDependencies: @@ -9637,6 +9649,9 @@ packages: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -9793,6 +9808,10 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} + globals@17.12.0: + resolution: {integrity: sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==} + engines: {node: '>=18'} + globals@17.4.0: resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} engines: {node: '>=18'} @@ -10724,6 +10743,10 @@ packages: resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} engines: {'0': node >=0.6.0} + jsx-ast-utils-x@0.1.0: + resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -13102,6 +13125,10 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -13131,6 +13158,10 @@ packages: regex@6.1.0: resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} @@ -13427,6 +13458,10 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} @@ -22066,7 +22101,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 5.0.0(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@22.20.1)(@vitest/coverage-v8@5.0.0)(happy-dom@20.10.2(bufferutil@4.1.0)(utf-8-validate@5.0.10))(jsdom@27.0.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(msw@2.15.0(@types/node@22.20.1)(typescript@6.0.3))(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.46.1)(tsx@4.20.6)(yaml@2.9.0)) + vitest: 5.0.0(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@22.20.1)(@vitest/coverage-v8@5.0.0)(happy-dom@20.10.2(bufferutil@4.1.0)(utf-8-validate@5.0.10))(jsdom@27.0.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(msw@2.15.0(@types/node@22.20.1)(typescript@6.0.3))(vite@8.2.2(@types/node@22.20.1)(esbuild@0.27.7)(jiti@2.7.0)(terser@5.46.1)(tsx@4.20.6)(yaml@2.9.0)) '@vitest/istanbul-lib-coverage@1.0.1': {} @@ -23296,6 +23331,8 @@ snapshots: node-gyp-build: 4.8.4 optional: true + builtin-modules@3.3.0: {} + bundle-name@4.1.0: dependencies: run-applescript: 7.1.0 @@ -24903,6 +24940,23 @@ snapshots: dependencies: eslint: 9.31.0(jiti@2.7.0) + eslint-plugin-sonarjs@4.2.0(eslint@9.31.0(jiti@2.7.0)): + dependencies: + '@eslint-community/regexpp': 4.12.2 + builtin-modules: 3.3.0 + bytes: 3.1.2 + eslint: 9.31.0(jiti@2.7.0) + functional-red-black-tree: 1.0.1 + globals: 17.12.0 + jsx-ast-utils-x: 0.1.0 + lodash.merge: 4.6.2 + minimatch: 10.2.6 + scslre: 0.3.0 + semver: 7.8.5 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + yaml: 2.9.0 + eslint-plugin-turbo@2.5.5(eslint@9.31.0(jiti@2.7.0))(turbo@2.10.12): dependencies: dotenv: 16.0.3 @@ -25780,6 +25834,8 @@ snapshots: hasown: 2.0.2 is-callable: 1.2.7 + functional-red-black-tree@1.0.1: {} + functions-have-names@1.2.3: {} fuse.js@7.5.0: {} @@ -25939,6 +25995,8 @@ snapshots: globals@15.15.0: {} + globals@17.12.0: {} + globals@17.4.0: {} globalthis@1.0.4: @@ -26996,6 +27054,8 @@ snapshots: json-schema: 0.4.0 verror: 1.10.0 + jsx-ast-utils-x@0.1.0: {} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.9 @@ -30059,6 +30119,10 @@ snapshots: dependencies: redis-errors: 1.2.0 + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.12.2 + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -30097,6 +30161,11 @@ snapshots: dependencies: regex-utilities: 2.3.0 + regexp-ast-analysis@0.7.1: + dependencies: + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -30496,6 +30565,12 @@ snapshots: ajv-keywords: 5.1.0(ajv@8.20.0) optional: true + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scule@1.3.0: {} section-matter@1.0.0: