Files
librechat.ai/eslint.config.mjs
Danny Avila a0a74501c9 chore: bump dev packages, linting, logos (#521)
* chore: upgrade eslint to v9

* chore: update package dependencies in package.json and pnpm-lock.yaml

- Added `minimatch` and `serialize-javascript` dependencies with updated versions.
- Upgraded `ajv` to version 6.14.0.
- Removed outdated dependencies from pnpm-lock.yaml for better package management.

* feat: add Stripe logos to Companies section

- Introduced new company entry for Stripe in the Companies component, including both light and dark logo variants.
- Updated the Companies array to display 10 logos instead of 8.
- Adjusted TypeScript environment reference to point to the development types directory.
2026-03-02 18:18:50 -05:00

196 lines
7.2 KiB
JavaScript

import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { includeIgnoreFile } from '@eslint/compat';
import js from '@eslint/js';
import nextPlugin from '@next/eslint-plugin-next';
import eslintConfigPrettier from 'eslint-config-prettier';
import importPlugin from 'eslint-plugin-import';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import tailwindcss from 'eslint-plugin-tailwindcss';
import unicorn from 'eslint-plugin-unicorn';
import globals from 'globals';
import tseslint from 'typescript-eslint';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default tseslint.config(
// ── 1. Global ignores ──────────────────────────────────────────────
includeIgnoreFile(path.resolve(__dirname, '.gitignore')),
{ ignores: ['content/**', '.source/**'] },
// ── 2. Base configs ────────────────────────────────────────────────
js.configs.recommended,
...tseslint.configs.recommended,
// ── 3. All JS / TS files — shared rules ────────────────────────────
{
files: ['**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts}'],
plugins: {
import: importPlugin,
unicorn,
},
rules: {
'prefer-object-has-own': 'error',
'logical-assignment-operators': ['error', 'always', { enforceForIfStatements: true }],
'no-else-return': ['error', { allowElseIf: false }],
'no-lonely-if': 'error',
'prefer-destructuring': ['error', { VariableDeclarator: { object: true } }],
'import/no-duplicates': 'error',
'no-negated-condition': 'off',
'unicorn/no-negated-condition': 'error',
'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
'object-shorthand': ['error', 'always'],
'unicorn/prefer-regexp-test': 'error',
'unicorn/no-array-for-each': 'error',
'unicorn/prefer-string-replace-all': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_' },
],
// todo: enable
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-require-imports': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
},
},
// ── 4. React files ─────────────────────────────────────────────────
{
files: ['app/**/*.{tsx,jsx}', 'components/**/*.{tsx,jsx}', 'lib/**/*.{tsx,jsx}'],
...react.configs.flat.recommended,
...react.configs.flat['jsx-runtime'],
plugins: {
...react.configs.flat.recommended.plugins,
'react-hooks': reactHooks,
},
settings: { react: { version: 'detect' } },
rules: {
...react.configs.flat.recommended.rules,
...react.configs.flat['jsx-runtime'].rules,
...reactHooks.configs['recommended-latest'].rules,
'react/prop-types': 'off',
'react/no-unknown-property': ['error', { ignore: ['jsx'] }],
'react-hooks/exhaustive-deps': 'error',
'react/self-closing-comp': 'error',
'no-restricted-syntax': [
'error',
{
selector:
'CallExpression[callee.name=useMemo][arguments.1.type=ArrayExpression][arguments.1.elements.length=0]',
message:
"`useMemo` with an empty dependency array can't provide a stable reference, use `useRef` instead.",
},
{
selector: 'MemberExpression[object.name=z] > .property[name=object]',
message: 'Use z.strictObject is more safe.',
},
],
'react/jsx-filename-extension': [
'error',
{ extensions: ['.tsx', '.jsx'], allow: 'as-needed' },
],
'react/jsx-curly-brace-presence': 'error',
'react/jsx-boolean-value': 'error',
},
},
// ── 5. Next.js rules ───────────────────────────────────────────────
{
files: ['app/**/*.{tsx,jsx}', 'components/**/*.{tsx,jsx}', 'lib/**/*.{tsx,jsx}'],
plugins: { '@next/next': nextPlugin },
rules: {
...nextPlugin.configs.recommended.rules,
...nextPlugin.configs['core-web-vitals'].rules,
},
},
// ── 6. TypeScript type-checked ─────────────────────────────────────
{
files: ['**/*.{ts,tsx,cts,mts}'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: __dirname,
},
},
rules: {
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
},
},
// ── 7. Tailwind CSS ────────────────────────────────────────────────
{
files: ['app/**/*.{tsx,jsx}', 'components/**/*.{tsx,jsx}', 'lib/**/*.{tsx,jsx}'],
...tailwindcss.configs['flat/recommended'][0],
settings: {
tailwindcss: {
callees: ['cn'],
whitelist: [
'dash-ring',
'theme-\\d+',
'nextra-[\\w-]+',
'blog-card',
'glide(__.+)?',
'credentials-\\w+',
'input-container',
'copy-button',
'generate-button',
'tooltip',
'card',
'cards',
'file',
'file-tree',
'folder',
'carousel',
'frame',
'btn(-.+)?',
'rounded-box',
'rounded-square',
'bg-blackish',
'clickhouse-highlight',
'text-base-content\\/\\d+',
'origin-\\(.+\\)',
'max-h-\\(.+\\)',
'subheading-\\w*',
'post-item(-.+)?',
],
},
},
rules: {
'tailwindcss/classnames-order': 'off',
'tailwindcss/enforces-negative-arbitrary-values': 'error',
'tailwindcss/enforces-shorthand': 'error',
'tailwindcss/migration-from-tailwind-2': 'error',
'tailwindcss/no-custom-classname': 'error',
},
},
// ── 8. Node / CJS config files ─────────────────────────────────────
{
files: [
'*.config.{js,cjs,mjs,ts}',
'postcss.config.*',
'prettier.config.*',
'.prettierrc.{js,cjs}',
'**/*.cjs',
],
languageOptions: {
globals: globals.node,
},
},
// ── 9. Declaration files ───────────────────────────────────────────
{
files: ['**/*.d.ts'],
rules: { 'no-var': 'off' },
},
// ── 10. Prettier (must be last) ────────────────────────────────────
eslintConfigPrettier,
);