chore: standardised the eslint config structure accross the project (#11814)

This commit is contained in:
Mridang Agarwalla
2026-03-12 11:02:52 +01:00
committed by GitHub
parent 621fd9bdec
commit 7cdee1703f
61 changed files with 1025 additions and 2011 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ export default async function Layout(props: { children: ReactNode; params: Promi
}
});
let tree = source.pageTree;
let tree: typeof source.pageTree;
if (currentVersion !== 'latest') {
// Hoist the version folder to root to flatten sidebar
// versionSource.pageTree -> [ v4.10 folder, v4.9 folder ... ]
+2 -2
View File
@@ -2,14 +2,14 @@
import { RootProvider } from 'fumadocs-ui/provider/next';
import dynamic from "next/dynamic";
import { ThemeProvider } from 'next-themes';
import { ReactNode } from 'react';
import MixpanelProvider from '@/components/mixpanel-provider';
import PlausibleProvider from '@/components/plausible-provider';
const SearchDialog = dynamic(() => import("@/components/inkeep-search"));
export function Providers({ children }: { children: React.ReactNode }) {
export function Providers({ children }: { children: ReactNode }) {
return (
<RootProvider
search={{
@@ -1,10 +1,6 @@
import React, { useMemo } from 'react';
import yaml from 'js-yaml';
import { Check, X } from 'lucide-react';
import { cn } from '@/utils/cn'; // Assuming utils/cn exists, or I'll use clsx/tailwind-merge directly if not sure
// Fallback utility if generic cn doesn't exist, checking imports first is safer, but I'll inline a simple merge if needed
// Checking package.json I saw clsx and tailwind-merge are dependencies.
import { Check } from 'lucide-react';
function classNames(...classes) {
return classes.filter(Boolean).join(' ');
+1 -1
View File
@@ -1,6 +1,6 @@
'use client';
import { initMixpanel, mixpanelClient, optInTracking, optOutTracking } from '@/utils/mixpanel';
import { initMixpanel, optInTracking, optOutTracking } from '@/utils/mixpanel';
import React, { useEffect } from 'react';
export default function MixpanelProvider({ children }: { children: React.ReactNode }) {
+90 -96
View File
@@ -1,101 +1,58 @@
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const mdx = require('eslint-plugin-mdx');
const mdxParser = require('eslint-mdx');
const tsParser = require('@typescript-eslint/parser');
const tsPlugin = require('@typescript-eslint/eslint-plugin');
import globals from 'globals';
import js from '@eslint/js';
// import { FlatCompat } from '@eslint/eslintrc';
// import path from 'path';
// import { fileURLToPath } from 'url';
// const __filename = fileURLToPath(import.meta.url);
// const __dirname = path.dirname(__filename);
// const compat = new FlatCompat({
// baseDirectory: __dirname,
// });
import js from "@eslint/js";
import tsPlugin from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
import prettierConfig from "eslint-config-prettier/flat";
import importPlugin from "eslint-plugin-import";
import * as mdx from "eslint-plugin-mdx";
import globals from "globals";
export default [
// 1. Base JS Rules
{
ignores: [
"node_modules/",
".next/",
"out/",
"build/",
".source/",
"next-env.d.ts",
],
},
js.configs.recommended,
// 2. Import Next.js Core Web Vitals (via compat because it doesn't support Flat Config natively yet)
// ...compat.extends('next/core-web-vitals'),
// ...compat.extends('next', 'next/typescript'), // Causes circular JSON error
// ...
// 3. MDX Configuration
{
files: ['*.mdx'],
...mdx.flat,
processor: mdx.createRemarkProcessor({
lintCodeBlocks: false,
}),
languageOptions: {
globals: {
...globals.browser,
...globals.node,
props: 'readonly',
},
parser: mdxParser,
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
'react/no-unescaped-entities': 'off',
'no-unused-vars': 'off',
'no-irregular-whitespace': 'off',
'no-useless-escape': 'off',
},
},
// ...
// 4. Code Blocks inside MDX (virtual files)
{
files: ['*.mdx/*.{js,jsx,ts,tsx}'],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
props: 'readonly', // common in MDX
}
},
rules: {
'no-unused-vars': 'off',
'import/no-anonymous-default-export': 'off',
},
},
// 5. Global Ignores
{
ignores: ["node_modules/", ".next/", "out/", "build/", ".source/", "next-env.d.ts"],
},
// 6. Global options for JS files
{
files: ['**/*.{js,mjs,cjs}'],
files: ["**/*.{js,mjs,cjs}"],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
}
},
},
// 7. Manual TypeScript Configuration
{
files: ['**/*.{ts,tsx}'],
files: ["**/*.jsx"],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
parserOptions: {
ecmaFeatures: { jsx: true },
},
},
rules: {
"no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^React$" }],
},
},
{
files: ["**/*.{ts,tsx}"],
plugins: {
'@typescript-eslint': tsPlugin,
"@typescript-eslint": tsPlugin,
import: importPlugin,
},
languageOptions: {
parser: tsParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: { jsx: true },
},
globals: {
@@ -103,24 +60,61 @@ export default [
...globals.node,
},
},
settings: {
"import/resolver": {
typescript: true,
},
},
rules: {
...tsPlugin.configs.recommended.rules,
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'off', // Disable for legacy code
'@typescript-eslint/ban-ts-comment': 'off',
...importPlugin.configs.recommended.rules,
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_" },
],
"no-undef": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
},
},
// 8. Scripts Config
{
files: ['scripts/**/*.{js,mjs,ts}'],
files: ["**/*.mdx"],
...mdx.flat,
processor: mdx.createRemarkProcessor({
lintCodeBlocks: false,
}),
languageOptions: {
...mdx.flat.languageOptions,
globals: {
...globals.browser,
...globals.node,
props: "readonly",
},
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'no-undef': 'off',
'no-useless-escape': 'off',
'no-empty': 'off',
'no-async-promise-executor': 'off',
}
}
"no-unused-vars": "off",
"no-irregular-whitespace": "off",
"no-useless-escape": "off",
},
},
{
files: ["**/*.mdx/*.{js,jsx,ts,tsx}"],
plugins: {
import: importPlugin,
},
languageOptions: {
globals: {
...globals.browser,
...globals.node,
props: "readonly",
},
},
rules: {
"no-unused-vars": "off",
},
},
prettierConfig,
];
+9 -8
View File
@@ -7,8 +7,8 @@
"generate:index-pages": "tsx scripts/generate-index-pages.ts",
"fetch:remote-content": "node scripts/fetch-remote-content.mjs",
"generate:proto-docs": "node scripts/generate-proto-docs.mjs",
"generate:api-reference": "tsx scripts/generate-api-reference.mts --only-generate",
"fix:api-links": "tsx scripts/generate-api-reference.mts --only-fix",
"generate:api-reference": "tsx scripts/generate-api-reference.ts --only-generate",
"fix:api-links": "tsx scripts/generate-api-reference.ts --only-fix",
"build:mdx-source": "fumadocs-mdx",
"build": "next build",
"dev": "next dev",
@@ -16,7 +16,7 @@
"start": "next start",
"clean": "node scripts/clean.mjs",
"check:types": "fumadocs-mdx && next typegen && tsc --noEmit",
"check:links": "tsx scripts/check-links.mts",
"check:links": "tsx scripts/check-links.ts",
"test:scripts": "node --test scripts/*.test.mjs",
"postinstall": "fumadocs-mdx",
"lint": "eslint ."
@@ -49,7 +49,6 @@
"zod": "^4.3.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^10.0.1",
"@tailwindcss/postcss": "^4.1.18",
"@tailwindcss/typography": "^0.5.19",
@@ -57,11 +56,13 @@
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.56.0",
"@typescript-eslint/parser": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.57.0",
"eslint": "^10.0.0",
"eslint-config-next": "16.1.6",
"eslint-plugin-mdx": "^3.6.2",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-mdx": "^3.7.0",
"glob": "^13.0.5",
"globals": "^17.3.0",
"next-validate-link": "^1.6.4",
@@ -10,7 +10,6 @@ register('fumadocs-mdx/node/loader', import.meta.url);
import {
type FileObject,
printErrors,
scanURLs,
validateFiles,
} from 'next-validate-link';
@@ -1,6 +1,5 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import yaml from 'js-yaml';
const V1_BASE_PATHS: Record<string, string> = {
'admin.openapi.json': '/admin/v1',
+1 -1
View File
@@ -32,7 +32,7 @@ async function run() {
}
// Versioned content and protos
const cleanVersioned = (dir, pattern) => {
const cleanVersioned = (dir) => {
if (!fs.existsSync(dir)) return;
const files = fs.readdirSync(dir);
for (const file of files) {
+6 -6
View File
@@ -71,7 +71,7 @@ function getCurrentRef() {
cachedRef = branch;
return cachedRef;
}
} catch (e) {
} catch {
// Ignore git errors
}
console.log(`[ref] Defaulting to ${FALLBACK_BRANCH}`);
@@ -143,7 +143,7 @@ function copyDirectorySafely(src, dest) {
if (versionDirPattern.test(item) && fs.statSync(join(src, item)).isDirectory()) {
isVersionDir = true;
}
} catch (e) {
} catch {
// Ignore stat errors
}
@@ -281,7 +281,7 @@ async function downloadFileContent(tagOrBranch, repoPath) {
let decodedRepoPath;
try {
decodedRepoPath = decodeURIComponent(repoPath.replace(/\\/g, '/'));
} catch (e) {
} catch {
// If decoding fails (malformed escape sequences), fall back to original
decodedRepoPath = repoPath;
}
@@ -370,7 +370,7 @@ async function fixRelativeImports(versionDir, tagOrBranch) {
});
// 2. Markdown Images: ![alt](src)
const mdImgRegex = /(!\[.*?\]\()([^\)]+)(\))/g;
const mdImgRegex = /(!\[.*?\]\()([^)]+)(\))/g;
content = content.replace(mdImgRegex, (match, p1, p2, p3) => {
if (!p2.startsWith('.')) return match;
const rewritten = rewritePath(filePath, p2);
@@ -452,7 +452,7 @@ function getLocalVersion() {
if (!branch) {
try {
branch = execSync('git branch --show-current').toString().trim();
} catch (e) {}
} catch { /* ignore git errors */ }
}
if (branch && branch !== 'main' && branch !== 'master') {
@@ -467,7 +467,7 @@ function getLocalVersion() {
if (semver.valid(tag) && semver.gt(tag, CUTOFF)) {
return { label: tag, isUnreleased: false };
}
} catch (e) { }
} catch { /* ignore git errors */ }
return { label: 'v4.11.0', isUnreleased: true };
}
@@ -4,7 +4,6 @@ import { writeFileSync, mkdirSync, readdirSync, lstatSync, readFileSync, existsS
import path, { join, dirname, basename } from 'path';
import { fileURLToPath } from 'url';
import { glob } from 'glob';
import yaml from 'js-yaml';
// Suppress "Generated: ..." logs to avoid Vercel log limits
const originalLog = console.log;
@@ -147,7 +146,7 @@ async function fixAllGeneratedLinks() {
const versionMap = fileIndex.get(version);
// [Text](apis/resources/service_name/file_name.api.mdx)
const linkRegex = /\[([^\]]+)\]\(([\/]?apis\/resources\/([^\/]+)\/([^\/)]+)\.api\.mdx)\)/g;
const linkRegex = /\[([^\]]+)\]\(([/]?apis\/resources\/([^/]+)\/([^/)]+)\.api\.mdx)\)/g;
let modified = false;
let newContent = content.replace(linkRegex, (match, text, fullLink, serviceSlug, fileSlug) => {
@@ -178,7 +177,7 @@ async function fixAllGeneratedLinks() {
// Fix v2beta links that were likely in the source proto comments
// and also remove potential double /docs prefixing from source comments
const internalLinkRegex = /\[([^\]]+)\]\(([\/]?docs\/)?reference\/api\/([^\/]+)\/([^\s)]+)\)/g;
const internalLinkRegex = /\[([^\]]+)\]\(([/]?docs\/)?reference\/api\/([^/]+)\/([^\s)]+)\)/g;
newContent = newContent.replace(internalLinkRegex, (match, text, docsPrefix, service, fileSlug) => {
let targetFileSlug = fileSlug;
let isV2Beta = fileSlug.includes('.v2beta.');
@@ -87,6 +87,7 @@ async function run() {
// Use spawn (async) instead of spawnSync to avoid blocking the event loop
// eslint-disable-next-line no-async-promise-executor
await new Promise(async (resolvePromise, rejectPromise) => {
// Dynamic discovery of excluded paths
const getExcludedPaths = async () => {
-4
View File
@@ -43,10 +43,6 @@ walk(CONTENT_DIR, (filepath) => {
// Replaces /docs/img/ -> correctPrefix + img/
// Replaces /docs/vX.Y/ -> correctPrefix + vX.Y/
const PUBLIC_PREFIX = '/docs/img/';
const VERSION_PREFIXES = ['/docs/v4.10/', '/docs/v4.9/', '/docs/v4.8/'];
const TARGET_PATHS = [PUBLIC_PREFIX, ...VERSION_PREFIXES];
// Pattern: (!\[.*?\]\(|src=["'])(/docs/(?:img|v\d+\.\d+)/.*?)(\)|["'])
const pattern = /(!\[.*?\]\(|src=["'])\/docs\/((?:img|v\d+\.\d+)\/.*?)(\)|["'])/g;
-2
View File
@@ -1,5 +1,4 @@
import fs from 'fs';
import path from 'path';
const REDIRECTS_PATH = '/home/ffo/git/zitadel/zitadel/apps/docs/redirects.json';
@@ -37,7 +36,6 @@ function validateRedirects() {
});
// 2. Circular & Chains
const checked = new Set();
sources.forEach((value, source) => {
let currentSource = source;
const path = [currentSource];