Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

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