mirror of
https://github.com/zen-browser/www.git
synced 2025-07-07 08:55:32 +02:00
feat(eslint): add eslint flat config
This commit is contained in:
parent
1937be58a6
commit
01f4dac75d
16 changed files with 4607 additions and 2125 deletions
28
.eslint/astro.ts
Normal file
28
.eslint/astro.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
// @ts-expect-error - no types available
|
||||||
|
import jsxA11y from "eslint-plugin-jsx-a11y";
|
||||||
|
import { astroFiles } from "./shared";
|
||||||
|
|
||||||
|
export const astroConfig: Linter.Config = {
|
||||||
|
name: "eslint/astro",
|
||||||
|
files: astroFiles,
|
||||||
|
plugins: {
|
||||||
|
"jsx-a11y": jsxA11y,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// Astro specific adjustments
|
||||||
|
"@typescript-eslint/no-unused-vars": "off", // Astro components can have unused props
|
||||||
|
"import/no-unresolved": "off",
|
||||||
|
"no-undef": "off", // Astro has global variables like Astro
|
||||||
|
|
||||||
|
// A11y rules for Astro
|
||||||
|
"jsx-a11y/alt-text": "error",
|
||||||
|
"jsx-a11y/anchor-has-content": "error",
|
||||||
|
"jsx-a11y/anchor-is-valid": "error",
|
||||||
|
"jsx-a11y/click-events-have-key-events": "error",
|
||||||
|
"jsx-a11y/interactive-supports-focus": "error",
|
||||||
|
"jsx-a11y/no-redundant-roles": "error",
|
||||||
|
"jsx-a11y/img-redundant-alt": "error",
|
||||||
|
"jsx-a11y/no-access-key": "error",
|
||||||
|
},
|
||||||
|
};
|
72
.eslint/base.ts
Normal file
72
.eslint/base.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import { sharedFiles } from "./shared";
|
||||||
|
|
||||||
|
export const baseConfig: Linter.Config = {
|
||||||
|
name: "eslint/base",
|
||||||
|
files: sharedFiles,
|
||||||
|
rules: {
|
||||||
|
"constructor-super": "error",
|
||||||
|
"for-direction": "error",
|
||||||
|
"getter-return": "error",
|
||||||
|
"no-async-promise-executor": "error",
|
||||||
|
"no-case-declarations": "error",
|
||||||
|
"no-class-assign": "error",
|
||||||
|
"no-compare-neg-zero": "error",
|
||||||
|
"no-cond-assign": "error",
|
||||||
|
"no-const-assign": "error",
|
||||||
|
"no-constant-binary-expression": "error",
|
||||||
|
"no-constant-condition": "error",
|
||||||
|
"no-control-regex": "error",
|
||||||
|
"no-debugger": "error",
|
||||||
|
"no-delete-var": "error",
|
||||||
|
"no-dupe-args": "error",
|
||||||
|
"no-dupe-class-members": "error",
|
||||||
|
"no-dupe-else-if": "error",
|
||||||
|
"no-dupe-keys": "error",
|
||||||
|
"no-duplicate-case": "error",
|
||||||
|
"no-empty-character-class": "error",
|
||||||
|
"no-empty-pattern": "error",
|
||||||
|
"no-empty-static-block": "error",
|
||||||
|
"no-ex-assign": "error",
|
||||||
|
"no-fallthrough": "error",
|
||||||
|
"no-func-assign": "error",
|
||||||
|
"no-global-assign": "error",
|
||||||
|
"no-import-assign": "error",
|
||||||
|
"no-invalid-regexp": "error",
|
||||||
|
"no-loss-of-precision": "error",
|
||||||
|
"no-misleading-character-class": "error",
|
||||||
|
"no-new-native-nonconstructor": "error",
|
||||||
|
"no-nonoctal-decimal-escape": "error",
|
||||||
|
"no-obj-calls": "error",
|
||||||
|
"no-octal": "error",
|
||||||
|
"no-redeclare": "error",
|
||||||
|
"no-regex-spaces": "error",
|
||||||
|
"no-self-assign": "error",
|
||||||
|
"no-setter-return": "error",
|
||||||
|
"no-this-before-super": "error",
|
||||||
|
"no-undef": "error",
|
||||||
|
"no-unexpected-multiline": "error",
|
||||||
|
"no-unreachable": "error",
|
||||||
|
"no-unsafe-finally": "error",
|
||||||
|
"no-unsafe-negation": "error",
|
||||||
|
"no-unsafe-optional-chaining": "error",
|
||||||
|
"no-unused-labels": "error",
|
||||||
|
"no-unused-private-class-members": "error",
|
||||||
|
"no-useless-backreference": "error",
|
||||||
|
"no-useless-catch": "error",
|
||||||
|
"no-var": "error",
|
||||||
|
"no-with": "error",
|
||||||
|
"require-yield": "error",
|
||||||
|
"use-isnan": "error",
|
||||||
|
"valid-typeof": "error",
|
||||||
|
|
||||||
|
// Additional base rules
|
||||||
|
"no-console": ["warn", { allow: ["warn", "error"] }],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"object-shorthand": "error",
|
||||||
|
"prefer-template": "error",
|
||||||
|
curly: ["error", "all"],
|
||||||
|
eqeqeq: ["error", "always"],
|
||||||
|
"no-implicit-coercion": "error",
|
||||||
|
},
|
||||||
|
};
|
19
.eslint/config-files.ts
Normal file
19
.eslint/config-files.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import { configFiles } from "./shared";
|
||||||
|
|
||||||
|
export const configFilesConfig: Linter.Config = {
|
||||||
|
name: "eslint/config-files",
|
||||||
|
files: configFiles,
|
||||||
|
rules: {
|
||||||
|
"no-console": "off",
|
||||||
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
|
"import/no-default-export": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-return": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-argument": "off",
|
||||||
|
"prefer-const": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
},
|
||||||
|
};
|
63
.eslint/import.ts
Normal file
63
.eslint/import.ts
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
// @ts-expect-error - no types available
|
||||||
|
import importPlugin from "eslint-plugin-import";
|
||||||
|
import { sharedFiles } from "./shared";
|
||||||
|
|
||||||
|
export const importConfigArray: Linter.Config[] = [
|
||||||
|
{
|
||||||
|
name: "eslint/import",
|
||||||
|
files: sharedFiles,
|
||||||
|
plugins: {
|
||||||
|
import: importPlugin,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...importPlugin.configs.recommended.rules,
|
||||||
|
...importPlugin.configs.typescript.rules,
|
||||||
|
|
||||||
|
"import/order": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
groups: [
|
||||||
|
"builtin",
|
||||||
|
"external",
|
||||||
|
"internal",
|
||||||
|
["parent", "sibling"],
|
||||||
|
"index",
|
||||||
|
"object",
|
||||||
|
"type",
|
||||||
|
],
|
||||||
|
"newlines-between": "always",
|
||||||
|
alphabetize: {
|
||||||
|
order: "asc",
|
||||||
|
caseInsensitive: true,
|
||||||
|
},
|
||||||
|
pathGroups: [
|
||||||
|
{
|
||||||
|
pattern: "@/**",
|
||||||
|
group: "internal",
|
||||||
|
position: "before",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pathGroupsExcludedImportTypes: ["builtin"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"import/no-unresolved": "off", // TypeScript handles this
|
||||||
|
"import/no-duplicates": ["error", { "prefer-inline": true }],
|
||||||
|
"import/consistent-type-specifier-style": ["error", "prefer-inline"],
|
||||||
|
"import/first": "error",
|
||||||
|
"import/newline-after-import": "error",
|
||||||
|
"import/no-default-export": "off", // Allow default exports
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
"import/resolver": {
|
||||||
|
typescript: {
|
||||||
|
alwaysTryTypes: true,
|
||||||
|
},
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
"import/parsers": {
|
||||||
|
"@typescript-eslint/parser": [".ts", ".tsx"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
35
.eslint/javascript.ts
Normal file
35
.eslint/javascript.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import { javascriptFiles } from "./shared";
|
||||||
|
|
||||||
|
export const javascriptConfig: Linter.Config = {
|
||||||
|
name: "eslint/javascript",
|
||||||
|
files: javascriptFiles,
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
sourceType: "module",
|
||||||
|
parserOptions: {
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
argsIgnorePattern: "^_",
|
||||||
|
varsIgnorePattern: "^_",
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"no-console": ["warn", { allow: ["warn", "error"] }],
|
||||||
|
"no-debugger": "error",
|
||||||
|
"prefer-const": "error",
|
||||||
|
"no-var": "error",
|
||||||
|
"object-shorthand": "error",
|
||||||
|
"prefer-template": "error",
|
||||||
|
curly: ["error", "all"],
|
||||||
|
eqeqeq: ["error", "always"],
|
||||||
|
"no-implicit-coercion": "error",
|
||||||
|
},
|
||||||
|
};
|
31
.eslint/jsx-a11y.ts
Normal file
31
.eslint/jsx-a11y.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
// @ts-expect-error - no types available
|
||||||
|
import jsxA11y from "eslint-plugin-jsx-a11y";
|
||||||
|
import { astroFiles, javascriptFiles, typescriptFiles } from "./shared";
|
||||||
|
|
||||||
|
export const jsxA11yConfig: Linter.Config = {
|
||||||
|
name: "eslint/jsx-a11y",
|
||||||
|
files: [
|
||||||
|
...astroFiles,
|
||||||
|
...typescriptFiles.filter((f) => f.includes("tsx")),
|
||||||
|
...javascriptFiles.filter((f) => f.includes("jsx")),
|
||||||
|
],
|
||||||
|
plugins: {
|
||||||
|
"jsx-a11y": jsxA11y,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...jsxA11y.configs.recommended.rules,
|
||||||
|
|
||||||
|
// Additional a11y rules
|
||||||
|
"jsx-a11y/alt-text": "error",
|
||||||
|
"jsx-a11y/anchor-has-content": "error",
|
||||||
|
"jsx-a11y/anchor-is-valid": "error",
|
||||||
|
"jsx-a11y/click-events-have-key-events": "error",
|
||||||
|
"jsx-a11y/interactive-supports-focus": "error",
|
||||||
|
"jsx-a11y/no-redundant-roles": "error",
|
||||||
|
"jsx-a11y/img-redundant-alt": "error",
|
||||||
|
"jsx-a11y/no-access-key": "error",
|
||||||
|
"jsx-a11y/label-has-associated-control": "error",
|
||||||
|
"jsx-a11y/no-autofocus": "warn",
|
||||||
|
},
|
||||||
|
};
|
59
.eslint/react.ts
Normal file
59
.eslint/react.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import react from "eslint-plugin-react";
|
||||||
|
import { javascriptFiles, typescriptFiles } from "./shared";
|
||||||
|
|
||||||
|
export const reactConfig: Linter.Config = {
|
||||||
|
name: "eslint/react",
|
||||||
|
files: [
|
||||||
|
...typescriptFiles.filter((f) => f.includes("tsx")),
|
||||||
|
...javascriptFiles.filter((f) => f.includes("jsx")),
|
||||||
|
],
|
||||||
|
plugins: {
|
||||||
|
react,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...react.configs.recommended.rules,
|
||||||
|
|
||||||
|
"react/react-in-jsx-scope": "off", // Not needed in modern React/Preact
|
||||||
|
"react/prop-types": "off", // Using TypeScript
|
||||||
|
"react/jsx-uses-react": "off",
|
||||||
|
"react/jsx-uses-vars": "error",
|
||||||
|
"react/no-unescaped-entities": "off",
|
||||||
|
"react/jsx-key": "error",
|
||||||
|
"react/jsx-no-useless-fragment": "error",
|
||||||
|
"react/self-closing-comp": "error",
|
||||||
|
"react/jsx-boolean-value": ["error", "never"],
|
||||||
|
"react/jsx-curly-brace-presence": [
|
||||||
|
"error",
|
||||||
|
{ props: "never", children: "never" },
|
||||||
|
],
|
||||||
|
"react/function-component-definition": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
namedComponents: "arrow-function",
|
||||||
|
unnamedComponents: "arrow-function",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: "detect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
import reactHooks from "eslint-plugin-react-hooks";
|
||||||
|
|
||||||
|
export const reactHooksConfig: Linter.Config = {
|
||||||
|
name: "eslint/react-hooks",
|
||||||
|
files: [
|
||||||
|
...typescriptFiles.filter((f) => f.includes("tsx")),
|
||||||
|
...javascriptFiles.filter((f) => f.includes("jsx")),
|
||||||
|
],
|
||||||
|
plugins: {
|
||||||
|
"react-hooks": reactHooks,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...reactHooks.configs.recommended.rules,
|
||||||
|
},
|
||||||
|
};
|
41
.eslint/shared.ts
Normal file
41
.eslint/shared.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
export const sharedFiles = [
|
||||||
|
"**/*.js",
|
||||||
|
"**/*.cjs",
|
||||||
|
"**/*.mjs",
|
||||||
|
"**/*.jsx",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.cts",
|
||||||
|
"**/*.mts",
|
||||||
|
"**/*.tsx",
|
||||||
|
"**/*.d.ts",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const sharedTestFiles = [
|
||||||
|
"**/*.test.{ts,tsx,js,jsx}",
|
||||||
|
"**/*.spec.{ts,tsx,js,jsx}",
|
||||||
|
"**/tests/**/*.{ts,tsx,js,jsx}",
|
||||||
|
"**/__tests__/**/*.{ts,tsx,js,jsx}",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const astroFiles = ["**/*.astro"];
|
||||||
|
|
||||||
|
export const typescriptFiles = [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
"**/*.mts",
|
||||||
|
"**/*.cts",
|
||||||
|
"**/*.d.ts",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const javascriptFiles = ["**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"];
|
||||||
|
|
||||||
|
export const configFiles = [
|
||||||
|
"*.config.{ts,js,mjs}",
|
||||||
|
"**/*.config.{ts,js,mjs}",
|
||||||
|
"**/vite.config.*",
|
||||||
|
"**/vitest.config.*",
|
||||||
|
"**/playwright.config.*",
|
||||||
|
"**/astro.config.*",
|
||||||
|
"**/tailwind.config.*",
|
||||||
|
"**/eslint.config.*",
|
||||||
|
];
|
19
.eslint/test.ts
Normal file
19
.eslint/test.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import { sharedTestFiles } from "./shared";
|
||||||
|
|
||||||
|
export const testConfig: Linter.Config = {
|
||||||
|
name: "eslint/test",
|
||||||
|
files: sharedTestFiles,
|
||||||
|
rules: {
|
||||||
|
"no-console": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-return": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-argument": "off",
|
||||||
|
"@typescript-eslint/unbound-method": "off",
|
||||||
|
"import/no-extraneous-dependencies": "off",
|
||||||
|
},
|
||||||
|
};
|
44
.eslint/typescript.ts
Normal file
44
.eslint/typescript.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import type { Linter } from "eslint";
|
||||||
|
import { typescriptFiles } from "./shared";
|
||||||
|
|
||||||
|
export function createTypescriptConfig(tsConfigPath: string): Linter.Config {
|
||||||
|
return {
|
||||||
|
name: "eslint/typescript",
|
||||||
|
files: typescriptFiles,
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
sourceType: "module",
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
project: tsConfigPath,
|
||||||
|
tsconfigRootDir: process.cwd(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// Basic TypeScript rules that work without type information
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
argsIgnorePattern: "^_",
|
||||||
|
varsIgnorePattern: "^_",
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "warn",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
|
"@typescript-eslint/consistent-type-imports": [
|
||||||
|
"error",
|
||||||
|
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
|
||||||
|
],
|
||||||
|
"@typescript-eslint/consistent-type-definitions": ["error", "type"],
|
||||||
|
|
||||||
|
// Override base rules for TypeScript
|
||||||
|
"no-unused-vars": "off", // Handled by TypeScript
|
||||||
|
"no-undef": "off", // TypeScript handles this
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
47
.prettierignore
Normal file
47
.prettierignore
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# Build outputs
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.astro/
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
# Test outputs
|
||||||
|
playwright-report/
|
||||||
|
test-results/
|
||||||
|
|
||||||
|
# Package files
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
# Config files that should maintain their format
|
||||||
|
wrangler.toml
|
||||||
|
|
||||||
|
# Binary files
|
||||||
|
*.png
|
||||||
|
*.jpg
|
||||||
|
*.jpeg
|
||||||
|
*.gif
|
||||||
|
*.svg
|
||||||
|
*.ico
|
||||||
|
*.woff
|
||||||
|
*.woff2
|
||||||
|
*.ttf
|
||||||
|
*.eot
|
||||||
|
|
||||||
|
# IDE and OS
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Static assets
|
||||||
|
public/fonts/
|
||||||
|
public/favicon.ico
|
||||||
|
public/favicon.svg
|
44
.vscode/settings.json
vendored
Normal file
44
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": "explicit",
|
||||||
|
"source.organizeImports": "explicit"
|
||||||
|
},
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"astro"
|
||||||
|
],
|
||||||
|
"eslint.format.enable": false,
|
||||||
|
"prettier.requireConfig": true,
|
||||||
|
"[astro]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[typescriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[jsonc]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[markdown]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"*.astro": "astro"
|
||||||
|
}
|
||||||
|
}
|
93
eslint.config.ts
Normal file
93
eslint.config.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
import { includeIgnoreFile } from "@eslint/compat";
|
||||||
|
import type { TSESLint } from "@typescript-eslint/utils";
|
||||||
|
import prettierConfig from "eslint-config-prettier";
|
||||||
|
import astro from "eslint-plugin-astro";
|
||||||
|
import { dirname, resolve } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
|
// Import modular configurations
|
||||||
|
import { astroConfig } from "./.eslint/astro";
|
||||||
|
import { baseConfig } from "./.eslint/base";
|
||||||
|
import { configFilesConfig } from "./.eslint/config-files";
|
||||||
|
import { importConfigArray } from "./.eslint/import";
|
||||||
|
import { javascriptConfig } from "./.eslint/javascript";
|
||||||
|
import { jsxA11yConfig } from "./.eslint/jsx-a11y";
|
||||||
|
import { reactConfig, reactHooksConfig } from "./.eslint/react";
|
||||||
|
import { testConfig } from "./.eslint/test";
|
||||||
|
import { createTypescriptConfig } from "./.eslint/typescript";
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
const tsConfigPath = resolve(__dirname, "./tsconfig.json");
|
||||||
|
|
||||||
|
const ignoresConfig = {
|
||||||
|
name: "eslint/ignores",
|
||||||
|
ignores: [
|
||||||
|
// Build outputs
|
||||||
|
"**/dist/**",
|
||||||
|
"**/build/**",
|
||||||
|
"**/.astro/**",
|
||||||
|
"**/node_modules/**",
|
||||||
|
|
||||||
|
// Test outputs
|
||||||
|
"**/coverage/**",
|
||||||
|
"**/playwright-report/**",
|
||||||
|
"**/test-results/**",
|
||||||
|
|
||||||
|
// Config files that don't need linting
|
||||||
|
"**/*.config.js",
|
||||||
|
"**/*.config.mjs",
|
||||||
|
"**/wrangler.toml",
|
||||||
|
|
||||||
|
// Other common ignores
|
||||||
|
"**/.next/**",
|
||||||
|
"**/.nuxt/**",
|
||||||
|
"**/.output/**",
|
||||||
|
"**/.vercel/**",
|
||||||
|
"**/.netlify/**",
|
||||||
|
"**/public/**",
|
||||||
|
"**/*.min.js",
|
||||||
|
"**/*.d.ts",
|
||||||
|
"**/CHANGELOG.md",
|
||||||
|
"**/README.md",
|
||||||
|
],
|
||||||
|
} satisfies TSESLint.FlatConfig.Config;
|
||||||
|
|
||||||
|
const config: TSESLint.FlatConfig.ConfigArray = tseslint.config(
|
||||||
|
// Include .gitignore patterns
|
||||||
|
includeIgnoreFile(resolve(__dirname, ".gitignore")),
|
||||||
|
|
||||||
|
// Core configurations
|
||||||
|
ignoresConfig,
|
||||||
|
baseConfig,
|
||||||
|
// TypeScript ecosystem
|
||||||
|
...tseslint.configs.strict,
|
||||||
|
...tseslint.configs.stylistic,
|
||||||
|
createTypescriptConfig(tsConfigPath),
|
||||||
|
|
||||||
|
// Import management
|
||||||
|
...importConfigArray,
|
||||||
|
|
||||||
|
// Framework specific
|
||||||
|
reactConfig,
|
||||||
|
reactHooksConfig,
|
||||||
|
jsxA11yConfig,
|
||||||
|
|
||||||
|
// Astro specific
|
||||||
|
...astro.configs.recommended,
|
||||||
|
astroConfig,
|
||||||
|
|
||||||
|
// Language specific
|
||||||
|
javascriptConfig,
|
||||||
|
|
||||||
|
// Special cases
|
||||||
|
testConfig,
|
||||||
|
configFilesConfig,
|
||||||
|
|
||||||
|
// Prettier integration (must be last)
|
||||||
|
prettierConfig,
|
||||||
|
);
|
||||||
|
|
||||||
|
export default config;
|
6041
package-lock.json
generated
6041
package-lock.json
generated
File diff suppressed because it is too large
Load diff
37
package.json
37
package.json
|
@ -9,8 +9,12 @@
|
||||||
"preview": "astro preview --port 3000",
|
"preview": "astro preview --port 3000",
|
||||||
"wrangler": "wrangler",
|
"wrangler": "wrangler",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"lint": "biome lint ./src",
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.astro",
|
||||||
"format": "biome format ./src",
|
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx,.astro --fix",
|
||||||
|
"format": "prettier --write .",
|
||||||
|
"format:check": "prettier --check .",
|
||||||
|
"biome:lint": "biome lint ./src",
|
||||||
|
"biome:format": "biome format ./src",
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"test": "npx vitest run",
|
"test": "npx vitest run",
|
||||||
"test:coverage": "npx vitest --coverage",
|
"test:coverage": "npx vitest --coverage",
|
||||||
|
@ -33,6 +37,7 @@
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"free-astro-components": "^1.2.0",
|
"free-astro-components": "^1.2.0",
|
||||||
|
"jiti": "^2.4.2",
|
||||||
"lucide-astro": "^0.460.0",
|
"lucide-astro": "^0.460.0",
|
||||||
"lucide-react": "^0.475.0",
|
"lucide-react": "^0.475.0",
|
||||||
"motion": "^11.13.5",
|
"motion": "^11.13.5",
|
||||||
|
@ -45,20 +50,44 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
|
"@eslint/compat": "^1.2.9",
|
||||||
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.27.0",
|
||||||
"@playwright/test": "^1.52.0",
|
"@playwright/test": "^1.52.0",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.6.3",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/jsdom": "^21.1.7",
|
"@types/jsdom": "^21.1.7",
|
||||||
"@types/node": "^22.15.18",
|
"@types/node": "^22.15.18",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||||
|
"@typescript-eslint/parser": "^8.33.0",
|
||||||
|
"@typescript-eslint/utils": "^8.33.0",
|
||||||
"@vitest/coverage-istanbul": "^3.1.3",
|
"@vitest/coverage-istanbul": "^3.1.3",
|
||||||
|
"eslint": "^9.27.0",
|
||||||
|
"eslint-config-prettier": "^10.1.5",
|
||||||
|
"eslint-import-resolver-typescript": "^4.4.1",
|
||||||
|
"eslint-plugin-astro": "^1.3.1",
|
||||||
|
"eslint-plugin-import": "^2.31.0",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||||
|
"eslint-plugin-react": "^7.37.5",
|
||||||
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^26.1.0",
|
||||||
"lint-staged": "^15.2.7",
|
"lint-staged": "^15.2.7",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||||
|
"typescript-eslint": "^8.33.0",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^3.1.3",
|
"vitest": "^3.1.3",
|
||||||
"wrangler": "^3.114.8"
|
"wrangler": "^4.17.0"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"src/**/*.{ts,tsx,astro,js,jsx}": ["biome check --write ."]
|
"src/**/*.{ts,tsx,astro,js,jsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"src/**/*.{json,md,css}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
57
prettier.config.js
Normal file
57
prettier.config.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* @type {import('prettier').Config}
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
// Basic formatting
|
||||||
|
printWidth: 100,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: false,
|
||||||
|
singleQuote: true,
|
||||||
|
quoteProps: "as-needed",
|
||||||
|
trailingComma: "es5",
|
||||||
|
bracketSpacing: true,
|
||||||
|
bracketSameLine: false,
|
||||||
|
arrowParens: "avoid",
|
||||||
|
|
||||||
|
// Language-specific formatting
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: "*.astro",
|
||||||
|
options: {
|
||||||
|
parser: "astro",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ["*.json", "*.jsonc"],
|
||||||
|
options: {
|
||||||
|
trailingComma: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ["*.md", "*.mdx"],
|
||||||
|
options: {
|
||||||
|
printWidth: 80,
|
||||||
|
proseWrap: "always",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ["*.yml", "*.yaml"],
|
||||||
|
options: {
|
||||||
|
singleQuote: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
plugins: [
|
||||||
|
"prettier-plugin-astro",
|
||||||
|
"prettier-plugin-tailwindcss", // Must be last
|
||||||
|
],
|
||||||
|
|
||||||
|
// Plugin-specific options
|
||||||
|
tailwindFunctions: ["clsx", "cn", "twMerge"],
|
||||||
|
|
||||||
|
// Astro-specific options
|
||||||
|
astroAllowShorthand: false,
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue