Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
117
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 1633c1f95c0f9e73ae15585320dc103a06b6c960 311 lines 9.7 kB view raw
1// @ts-check 2import js from '@eslint/js' 3import tseslint from 'typescript-eslint' 4import { defineConfig } from 'eslint/config'; 5import react from 'eslint-plugin-react' 6import reactHooks from 'eslint-plugin-react-hooks' 7// @ts-expect-error no types 8import reactNative from 'eslint-plugin-react-native' 9// @ts-expect-error no types 10import reactNativeA11y from 'eslint-plugin-react-native-a11y' 11import simpleImportSort from 'eslint-plugin-simple-import-sort' 12import importX from 'eslint-plugin-import-x' 13import lingui from 'eslint-plugin-lingui' 14import reactCompiler from 'eslint-plugin-react-compiler' 15import bskyInternal from 'eslint-plugin-bsky-internal' 16import globals from 'globals' 17import tsParser from '@typescript-eslint/parser' 18 19export default defineConfig( 20 /** 21 * Global ignores 22 */ 23 { 24 ignores: [ 25 '**/__mocks__/*.ts', 26 'ios/**', 27 'android/**', 28 'coverage/**', 29 '*.lock', 30 '.husky/**', 31 'patches/**', 32 '*.html', 33 'bskyweb/**', 34 'bskyembed/**', 35 'src/locale/locales/_build/**', 36 'src/locale/locales/**/*.js', 37 '*.e2e.ts', 38 '*.e2e.tsx', 39 'eslint.config.mjs', 40 'svgo.config.mjs', 41 '.jscodeshift/**', 42 'rspack.config.ts', 43 'scripts/post-web-build.js', 44 ], 45 }, 46 47 /** 48 * Base configurations 49 */ 50 js.configs.recommended, 51 tseslint.configs.recommendedTypeChecked, 52 reactHooks.configs.flat.recommended, 53 importX.flatConfigs.recommended, 54 importX.flatConfigs.typescript, 55 importX.flatConfigs['react-native'], 56 57 /** 58 * Main configuration for all JS/TS/JSX/TSX files 59 */ 60 { 61 files: ['**/*.{js,jsx,ts,tsx}'], 62 plugins: { 63 react, 64 'react-native': reactNative, 65 'react-native-a11y': reactNativeA11y, 66 'simple-import-sort': simpleImportSort, 67 // @ts-expect-error - not sure why 68 lingui, 69 'react-compiler': reactCompiler, 70 'bsky-internal': bskyInternal, 71 }, 72 languageOptions: { 73 ecmaVersion: 'latest', 74 sourceType: 'module', 75 globals: { 76 ...globals.browser, 77 ...globals.node, 78 }, 79 parserOptions: { 80 parser: tsParser, 81 projectService: true, 82 tsconfigRootDir: import.meta.dirname, 83 ecmaFeatures: { 84 jsx: true, 85 }, 86 }, 87 }, 88 settings: { 89 react: { 90 version: 'detect', 91 }, 92 componentWrapperFunctions: ['observer'], 93 }, 94 rules: { 95 /** 96 * Custom rules 97 */ 98 'bsky-internal/avoid-unwrapped-text': [ 99 'error', 100 { 101 impliedTextComponents: [ 102 'H1', 103 'H2', 104 'H3', 105 'H4', 106 'H5', 107 'H6', 108 'P', 109 'Admonition', 110 'Admonition.Admonition', 111 'Toast.Action', 112 'AgeAssuranceAdmonition', 113 'Span', 114 'StackedButton', 115 ], 116 impliedTextProps: [], 117 suggestedTextWrappers: { 118 Button: 'ButtonText', 119 'ToggleButton.Button': 'ToggleButton.ButtonText', 120 'SegmentedControl.Item': 'SegmentedControl.ItemText', 121 }, 122 }, 123 ], 124 'bsky-internal/use-exact-imports': 'error', 125 'bsky-internal/use-prefixed-imports': 'error', 126 'bsky-internal/lingui-msg-rule': 'error', 127 128 /** 129 * React & React Native 130 */ 131 ...react.configs.recommended.rules, 132 ...react.configs['jsx-runtime'].rules, 133 'react/hook-use-state': 'warn', 134 'react/no-unescaped-entities': 'off', 135 'react/prop-types': 'off', 136 'react-native/no-inline-styles': 'off', 137 ...reactNativeA11y.configs.all.rules, 138 'react-compiler/react-compiler': 'warn', 139 // TODO: Fix these and set to error 140 'react-hooks/set-state-in-effect': 'warn', 141 'react-hooks/purity': 'warn', 142 'react-hooks/refs': 'warn', 143 'react-hooks/immutability': 'warn', 144 145 /** 146 * Import sorting 147 */ 148 'simple-import-sort/imports': [ 149 'error', 150 { 151 groups: [ 152 // Side effect imports. 153 ['^\\u0000'], 154 // Node.js builtins prefixed with `node:`. 155 ['^node:'], 156 // Packages. 157 // Things that start with a letter (or digit or underscore), or `@` followed by a letter. 158 // React/React Native prioritized, followed by expo 159 // Followed by all packages excluding unprefixed relative ones 160 [ 161 '^(react\\/(.*)$)|^(react$)|^(react-native(.*)$)', 162 '^(expo(.*)$)|^(expo$)', 163 '^(?!(?:alf|components|lib|locale|logger|platform|screens|state|view)(?:$|\\/))@?\\w', 164 ], 165 // Relative imports. 166 // Ideally, anything that starts with a dot or # 167 // due to unprefixed relative imports being used, we whitelist the relative paths we use 168 // (?:$|\\/) matches end of string or / 169 [ 170 '^(?:#\\/)?(?:lib|state|logger|platform|locale)(?:$|\\/)', 171 '^(?:#\\/)?view(?:$|\\/)', 172 '^(?:#\\/)?screens(?:$|\\/)', 173 '^(?:#\\/)?alf(?:$|\\/)', 174 '^(?:#\\/)?components(?:$|\\/)', 175 '^#\\/', 176 '^\\.', 177 ], 178 // anything else - hopefully we don't have any of these 179 ['^'], 180 ], 181 }, 182 ], 183 'simple-import-sort/exports': 'error', 184 185 /** 186 * Import linting 187 */ 188 'import-x/consistent-type-specifier-style': ['warn', 'prefer-inline'], 189 'import-x/no-unresolved': ['error', { 190 /* 191 * The `postinstall` hook runs `compile-if-needed` locally, but not in 192 * CI. For CI-sake, ignore this. 193 */ 194 ignore: ['^#\/locale\/locales\/.+\/messages'], 195 }], 196 'import-x/no-extraneous-dependencies': ['error', { 197 'whitelist': [ 198 // test files only 199 '@jest/globals', 200 // we only use a really simple util from this, and we know it will be present 201 'expo-modules-core', 202 // this is a dep for @atproto/api, but we absolutely need them in sync, so just 203 // rely on the transient version 204 '@atproto/common-web', 205 ] 206 }], 207 'import-x/no-nodejs-modules': 'error', 208 209 /** 210 * TypeScript-specific rules 211 */ 212 'no-unused-vars': 'off', // off, we use TS-specific rule below 213 '@typescript-eslint/no-unused-vars': [ 214 'error', 215 { 216 argsIgnorePattern: '^_', 217 varsIgnorePattern: '^_.+', 218 caughtErrors: 'none', 219 ignoreRestSiblings: true, 220 }, 221 ], 222 '@typescript-eslint/consistent-type-imports': [ 223 'warn', 224 {prefer: 'type-imports', fixStyle: 'inline-type-imports'}, 225 ], 226 '@typescript-eslint/no-require-imports': 'off', 227 '@typescript-eslint/no-unused-expressions': ['error', { 228 allowTernary: true, 229 }], 230 /** 231 * Maintain previous behavior - these are stricter in typescript-eslint 232 * v8 `warn` ones are probably worth fixing. `off` ones are a bit too 233 * nit-picky 234 */ 235 '@typescript-eslint/no-explicit-any': 'off', 236 '@typescript-eslint/ban-ts-comment': 'off', 237 '@typescript-eslint/no-empty-object-type': 'off', 238 '@typescript-eslint/no-unsafe-function-type': 'off', 239 '@typescript-eslint/no-unsafe-assignment': 'off', 240 '@typescript-eslint/unbound-method': 'off', 241 '@typescript-eslint/no-unsafe-argument': 'off', 242 '@typescript-eslint/no-unsafe-return': 'off', 243 '@typescript-eslint/no-unsafe-member-access': 'warn', 244 '@typescript-eslint/no-unsafe-call': 'warn', 245 '@typescript-eslint/no-floating-promises': 'warn', 246 '@typescript-eslint/no-misused-promises': 'warn', 247 '@typescript-eslint/require-await': 'warn', 248 '@typescript-eslint/no-unsafe-enum-comparison': 'warn', 249 '@typescript-eslint/no-unnecessary-type-assertion': 'warn', 250 '@typescript-eslint/no-redundant-type-constituents': 'warn', 251 '@typescript-eslint/no-duplicate-type-constituents': 'warn', 252 '@typescript-eslint/no-base-to-string': 'warn', 253 '@typescript-eslint/prefer-promise-reject-errors': 'warn', 254 '@typescript-eslint/await-thenable': 'warn', 255 256 "no-restricted-imports": ["error", { 257 "paths": [{ 258 "name": "react", 259 "importNames": ["React", "default"], 260 "message": "React is already in the global type namespace. Use named imports for runtime modules." 261 }] 262 }], 263 264 /** 265 * Turn off rules that we haven't enforced thus far 266 */ 267 'no-empty-pattern': 'off', 268 'no-async-promise-executor': 'off', 269 'no-constant-binary-expression': 'warn', 270 'prefer-const': 'off', 271 'no-empty': 'off', 272 'no-unsafe-optional-chaining': 'off', 273 'no-prototype-builtins': 'off', 274 'no-var': 'off', 275 'prefer-rest-params': 'off', 276 'no-case-declarations': 'off', 277 'no-irregular-whitespace': 'off', 278 'no-useless-escape': 'off', 279 'no-sparse-arrays': 'off', 280 'no-fallthrough': 'off', 281 'no-control-regex': 'off', 282 }, 283 }, 284 285 /** 286 * Test files configuration 287 */ 288 { 289 files: ['**/__tests__/**/*.{js,jsx,ts,tsx}', '**/*.test.{js,jsx,ts,tsx}'], 290 languageOptions: { 291 globals: { 292 ...globals.jest, 293 } 294 }, 295 }, 296 297 /** 298 * Expo config plugins run in Node during prebuild, not in the app runtime. 299 */ 300 { 301 files: ['plugins/**/*.{js,jsx,ts,tsx}'], 302 rules: { 303 'import-x/no-nodejs-modules': 'off', 304 'import-x/no-extraneous-dependencies': ['error', { 305 whitelist: [ 306 '@expo/plist', 307 ], 308 }], 309 }, 310 }, 311)