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

Configure Feed

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

at a876aae44ea07494ebea9727350aa060b81f317b 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)