A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules
1import eslint from "@eslint/js";
2import stylistic from "@stylistic/eslint-plugin";
3import prettier from "eslint-config-prettier";
4import importPlugin from "eslint-plugin-import";
5import { defineConfig } from "eslint/config";
6import tseslint from "typescript-eslint";
7
8export default defineConfig(
9 eslint.configs.recommended,
10 ...tseslint.configs.strictTypeChecked,
11 prettier,
12 {
13 languageOptions: {
14 parserOptions: {
15 project: "./tsconfig.json",
16 tsconfigRootDir: import.meta.dirname,
17 },
18 },
19 },
20 {
21 plugins: {
22 "@stylistic": stylistic,
23 import: importPlugin,
24 },
25 rules: {
26 // TypeScript specific rules
27 "@typescript-eslint/no-unused-vars": [
28 "warn",
29 { argsIgnorePattern: "^_" },
30 ],
31 "@typescript-eslint/no-explicit-any": "warn",
32 "@typescript-eslint/no-unsafe-assignment": "error",
33 "@typescript-eslint/no-unsafe-member-access": "error",
34 "@typescript-eslint/no-unsafe-call": "error",
35 "@typescript-eslint/no-unsafe-return": "error",
36 "@typescript-eslint/no-unsafe-argument": "error",
37 "@typescript-eslint/prefer-nullish-coalescing": "warn",
38 "@typescript-eslint/prefer-optional-chain": "warn",
39 "@typescript-eslint/no-non-null-assertion": "error",
40 "@typescript-eslint/consistent-type-imports": "error",
41 "@typescript-eslint/consistent-type-exports": "error",
42 "@typescript-eslint/no-import-type-side-effects": "error",
43
44 // General code quality
45 "no-console": "warn",
46 "no-debugger": "error",
47 "no-var": "error",
48 "prefer-const": "warn",
49 "prefer-template": "warn",
50 "object-shorthand": "warn",
51 "prefer-destructuring": ["warn", { object: true, array: false }],
52
53 // Import rules
54 "import/order": [
55 "warn",
56 {
57 groups: [
58 "builtin",
59 "external",
60 "internal",
61 "parent",
62 "sibling",
63 "index",
64 ],
65 pathGroups: [
66 {
67 pattern: "@atproto/**",
68 group: "external",
69 position: "after",
70 },
71 {
72 pattern: "@skyware/**",
73 group: "external",
74 position: "after",
75 },
76 {
77 pattern: "@clavata/**",
78 group: "external",
79 position: "after",
80 },
81 ],
82 pathGroupsExcludedImportTypes: ["builtin"],
83 "newlines-between": "never",
84 alphabetize: { order: "asc", caseInsensitive: true },
85 },
86 ],
87 "import/no-duplicates": "warn",
88 "import/no-unresolved": "off", // TypeScript handles this
89
90 // Security-focused rules
91 "no-eval": "error",
92 "no-implied-eval": "error",
93 "no-new-func": "error",
94 "no-script-url": "error",
95
96 // Error handling
97 "no-empty-pattern": "error",
98 "no-fallthrough": "error",
99 "no-unreachable": "error",
100 "no-unreachable-loop": "error",
101
102 // Style preferences (prettier handles these)
103 "@stylistic/indent": "off",
104 "@stylistic/quotes": "off",
105 "@stylistic/semi": "off",
106 "@stylistic/object-curly-spacing": "off",
107 "@stylistic/array-bracket-spacing": "off",
108 "@stylistic/space-before-function-paren": "off",
109 },
110 },
111 {
112 files: ["**/*.js", "**/*.mjs"],
113 ...tseslint.configs.disableTypeChecked,
114 },
115 {
116 ignores: [
117 "node_modules/",
118 "dist/",
119 "build/",
120 "*.config.js",
121 "*.config.mjs",
122 "coverage/",
123 "rules/",
124 ],
125 },
126 // Test file overrides
127 {
128 files: ["**/*.test.ts", "**/*.test.tsx"],
129 rules: {
130 "@typescript-eslint/unbound-method": "off",
131 "@typescript-eslint/no-unsafe-argument": "off",
132 "@typescript-eslint/no-unsafe-assignment": "off",
133 "@typescript-eslint/no-unsafe-call": "off",
134 "@typescript-eslint/no-unsafe-member-access": "off",
135 "@typescript-eslint/no-unsafe-return": "off",
136 "@typescript-eslint/no-explicit-any": "off",
137 "@typescript-eslint/require-await": "off",
138 "@typescript-eslint/await-thenable": "off",
139 "@typescript-eslint/no-confusing-void-expression": "off",
140 "@typescript-eslint/restrict-template-expressions": "off",
141 "@typescript-eslint/no-unnecessary-type-conversion": "off",
142 "@typescript-eslint/no-deprecated": "off",
143 },
144 },
145);