@ghettoddos/eslint-config 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2750,6 +2750,24 @@ interface RuleOptions {
2750
2750
  * @see https://eslint-react.xyz/docs/rules/naming-convention-use-state
2751
2751
  */
2752
2752
  'react-naming-convention/use-state'?: Linter.RuleEntry<[]>;
2753
+ 'react-native-community/no-color-literals'?: Linter.RuleEntry<[]>;
2754
+ 'react-native-community/no-inline-styles'?: Linter.RuleEntry<[]>;
2755
+ 'react-native-community/no-raw-text'?: Linter.RuleEntry<ReactNativeCommunityNoRawText>;
2756
+ /**
2757
+ * Disallow single element style arrays. These cause unnecessary re-renders as the identity of the array always changes
2758
+ */
2759
+ 'react-native-community/no-single-element-style-arrays'?: Linter.RuleEntry<[]>;
2760
+ 'react-native-community/no-unused-styles'?: Linter.RuleEntry<[]>;
2761
+ 'react-native-community/sort-styles'?: Linter.RuleEntry<ReactNativeCommunitySortStyles>;
2762
+ 'react-native-community/split-platform-components'?: Linter.RuleEntry<ReactNativeCommunitySplitPlatformComponents>;
2763
+ /**
2764
+ * Disallow deep imports from react native
2765
+ */
2766
+ 'react-native/no-deep-imports'?: Linter.RuleEntry<[]>;
2767
+ /**
2768
+ * Ensure that PlatformColor() and DynamicColorIOS() are passed literals of the expected shape.
2769
+ */
2770
+ 'react-native/platform-colors'?: Linter.RuleEntry<[]>;
2753
2771
  'react-refresh/only-export-components'?: Linter.RuleEntry<ReactRefreshOnlyExportComponents>;
2754
2772
  /**
2755
2773
  * Prevents leaked `addEventListener` in a component or custom Hook.
@@ -10961,6 +10979,20 @@ type ReactNamingConventionFilenameExtension = [] | [(("always" | "as-needed") |
10961
10979
  extensions?: string[];
10962
10980
  ignoreFilesWithoutCode?: boolean;
10963
10981
  })];
10982
+ // ----- react-native-community/no-raw-text -----
10983
+ type ReactNativeCommunityNoRawText = [] | [{
10984
+ skip?: string[];
10985
+ }];
10986
+ // ----- react-native-community/sort-styles -----
10987
+ type ReactNativeCommunitySortStyles = [] | [("asc" | "desc")] | [("asc" | "desc"), {
10988
+ ignoreClassNames?: boolean;
10989
+ ignoreStyleProperties?: boolean;
10990
+ }];
10991
+ // ----- react-native-community/split-platform-components -----
10992
+ type ReactNativeCommunitySplitPlatformComponents = [] | [{
10993
+ androidPathRegex?: string;
10994
+ iosPathRegex?: string;
10995
+ }];
10964
10996
  // ----- react-refresh/only-export-components -----
10965
10997
  type ReactRefreshOnlyExportComponents = [] | [{
10966
10998
  allowExportNames?: string[];
@@ -15080,7 +15112,7 @@ type Yoda = [] | [("always" | "never")] | [("always" | "never"), {
15080
15112
  onlyEquality?: boolean;
15081
15113
  }];
15082
15114
  // Names of all the configs
15083
- type ConfigNames = 'eslint-comments/rules' | 'formatter/setup' | 'imports/rules' | 'javascript/setup' | 'javascript/rules' | 'jsx/setup' | 'jsonc/setup' | 'jsonc/rules' | 'markdown/setup' | 'markdown/processor' | 'markdown/parser' | 'markdown/disables' | 'node/rules' | 'perfectionist/setup' | 'pnpm/package-json' | 'pnpm/pnpm-workspace-yaml' | 'react/setup' | 'react/rules' | 'sort/package-json' | 'stylistic/rules' | 'toml/setup' | 'toml/rules' | 'regexp/rules' | 'typescript/setup' | 'typescript/parser' | 'typescript/rules' | 'unicorn/rules' | 'unocss' | 'antfu/vue/setup' | 'antfu/vue/rules' | 'yaml/setup' | 'yaml/rules' | 'yaml/pnpm-workspace' | 'next/setup' | 'next/rules' | 'jsx-a11y/rules' | 'effector/setup' | 'effector/rules';
15115
+ type ConfigNames = 'eslint-comments/rules' | 'formatter/setup' | 'imports/rules' | 'javascript/setup' | 'javascript/rules' | 'jsx/setup' | 'jsonc/setup' | 'jsonc/rules' | 'markdown/setup' | 'markdown/processor' | 'markdown/parser' | 'markdown/disables' | 'node/rules' | 'perfectionist/setup' | 'pnpm/package-json' | 'pnpm/pnpm-workspace-yaml' | 'react/setup' | 'react/rules' | 'react-native/setup' | 'react-native/rules' | 'sort/package-json' | 'stylistic/rules' | 'toml/setup' | 'toml/rules' | 'regexp/rules' | 'typescript/setup' | 'typescript/parser' | 'typescript/rules' | 'unicorn/rules' | 'unocss' | 'vue/setup' | 'vue/rules' | 'yaml/setup' | 'yaml/rules' | 'yaml/pnpm-workspace' | 'next/setup' | 'next/rules' | 'jsx-a11y/rules' | 'effector/setup' | 'effector/rules';
15084
15116
  //#endregion
15085
15117
  //#region src/vendor/prettier-types.d.ts
15086
15118
  /**
@@ -15327,6 +15359,17 @@ interface OptionsEffector extends OptionsOverrides {
15327
15359
  */
15328
15360
  scope?: boolean;
15329
15361
  }
15362
+ interface OptionsReactNative extends OptionsOverrides {
15363
+ /**
15364
+ * Enable expo rules.
15365
+ *
15366
+ * Requires installing:
15367
+ * - `eslint-plugin-expo`
15368
+ *
15369
+ * @default auto-detect based on the dependencies
15370
+ */
15371
+ expo?: boolean;
15372
+ }
15330
15373
  interface OptionsTypeScriptParserOptions {
15331
15374
  /**
15332
15375
  * Additional parser options for TypeScript.
@@ -15499,6 +15542,16 @@ interface OptionsConfig extends OptionsComponentExts, OptionsProjectType {
15499
15542
  * @default auto-detect based on the dependencies
15500
15543
  */
15501
15544
  next?: boolean | OptionsOverrides;
15545
+ /**
15546
+ * Enable react-native rules.
15547
+ *
15548
+ * Requires installing:
15549
+ * - `@react-native/eslint-plugin`
15550
+ * - `eslint-plugin-react-native`
15551
+ *
15552
+ * @default auto-detect based on the dependencies
15553
+ */
15554
+ reactNative?: boolean | OptionsReactNative;
15502
15555
  /**
15503
15556
  * Enable effector rules.
15504
15557
  *
@@ -15645,6 +15698,9 @@ declare function pnpm(): Promise<TypedFlatConfigItem[]>;
15645
15698
  //#region src/configs/react.d.ts
15646
15699
  declare function react(options?: OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes & OptionsOverrides & OptionsFiles): Promise<TypedFlatConfigItem[]>;
15647
15700
  //#endregion
15701
+ //#region src/configs/react-native.d.ts
15702
+ declare function reactNative(options?: OptionsReactNative & OptionsFiles): Promise<TypedFlatConfigItem[]>;
15703
+ //#endregion
15648
15704
  //#region src/configs/regexp.d.ts
15649
15705
  declare function regexp(options?: OptionsRegExp & OptionsOverrides): Promise<TypedFlatConfigItem[]>;
15650
15706
  //#endregion
@@ -15771,4 +15827,4 @@ type ResolvedOptions<T> = T extends boolean ? never : NonNullable<T>;
15771
15827
  declare function resolveSubOptions<C extends Record<string, any>, K extends keyof C>(options: C, key: K): ResolvedOptions<C[K]>;
15772
15828
  declare function getOverrides<C extends Record<string, any>, K extends keyof C>(options: C, key: K): Partial<Linter.RulesRecord & RuleOptions>;
15773
15829
  //#endregion
15774
- export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsEffector, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsRegExp, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, StylisticOptions, TypedFlatConfigItem, combine, comments, config, config as default, defaultPluginRenaming, disables, effector, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsonc, jsx, jsxA11y, markdown, next, node, parserPlain, perfectionist, pnpm, react, regexp, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, toml, typescript, unicorn, unocss, vue, yaml };
15830
+ export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsEffector, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsReactNative, OptionsRegExp, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, StylisticOptions, TypedFlatConfigItem, combine, comments, config, config as default, defaultPluginRenaming, disables, effector, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsonc, jsx, jsxA11y, markdown, next, node, parserPlain, perfectionist, pnpm, react, reactNative, regexp, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, toml, typescript, unicorn, unocss, vue, yaml };
package/dist/index.js CHANGED
@@ -143,6 +143,7 @@ const VuePackages = [
143
143
  "vitepress",
144
144
  "@slidev/cli"
145
145
  ];
146
+ const ReactNativePackages = ["react-native", "expo"];
146
147
 
147
148
  //#endregion
148
149
  //#region src/utils.ts
@@ -1058,6 +1059,10 @@ async function react(options = {}) {
1058
1059
  "react/no-unused-state": "warn",
1059
1060
  "react/no-use-context": "warn",
1060
1061
  "react/no-useless-forward-ref": "warn",
1062
+ "react/prefer-shorthand-boolean": "warn",
1063
+ "react/prefer-destructuring-assignment": "warn",
1064
+ "react/no-missing-context-display-name": "warn",
1065
+ "react/no-missing-component-display-name": "warn",
1061
1066
  "react-dom/no-dangerously-set-innerhtml": "warn",
1062
1067
  "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1063
1068
  "react-dom/no-find-dom-node": "error",
@@ -1082,6 +1087,8 @@ async function react(options = {}) {
1082
1087
  "react-web-api/no-leaked-interval": "warn",
1083
1088
  "react-web-api/no-leaked-resize-observer": "warn",
1084
1089
  "react-web-api/no-leaked-timeout": "warn",
1090
+ "react-naming-convention/context-name": "warn",
1091
+ "react-naming-convention/use-state": "warn",
1085
1092
  "react-refresh/only-export-components": ["warn", {
1086
1093
  allowConstantExport: isAllowConstantExport,
1087
1094
  allowExportNames: [...isUsingNext ? [
@@ -1122,6 +1129,71 @@ async function react(options = {}) {
1122
1129
  ];
1123
1130
  }
1124
1131
 
1132
+ //#endregion
1133
+ //#region src/configs/react-native.ts
1134
+ async function reactNative(options = {}) {
1135
+ const { expo = isPackageExists("expo"), files = [GLOB_SRC], overrides = {} } = options;
1136
+ await ensurePackages([
1137
+ "@react-native/eslint-plugin",
1138
+ "eslint-plugin-react-native",
1139
+ ...expo ? ["eslint-plugin-expo"] : []
1140
+ ]);
1141
+ const [pluginReactNative, pluginReactNativeCommunity, pluginExpo] = await Promise.all([
1142
+ interopDefault(import("@react-native/eslint-plugin")),
1143
+ interopDefault(import("eslint-plugin-react-native")),
1144
+ ...expo ? [interopDefault(import("eslint-plugin-expo"))] : []
1145
+ ]);
1146
+ return [{
1147
+ name: "react-native/setup",
1148
+ plugins: {
1149
+ "react-native": pluginReactNative,
1150
+ "react-native-community": pluginReactNativeCommunity,
1151
+ ...expo ? { expo: pluginExpo } : {}
1152
+ }
1153
+ }, {
1154
+ files,
1155
+ languageOptions: {
1156
+ globals: {
1157
+ "__DEV__": "readonly",
1158
+ "__fbBatchedBridgeConfig": false,
1159
+ "Blob": true,
1160
+ "clearImmediate": true,
1161
+ "document": false,
1162
+ "ErrorUtils": false,
1163
+ "exports": false,
1164
+ "File": true,
1165
+ "Map": true,
1166
+ "navigator": false,
1167
+ "Promise": true,
1168
+ "queueMicrotask": true,
1169
+ "requestAnimationFrame": true,
1170
+ "requestIdleCallback": true,
1171
+ "Set": true,
1172
+ "setImmediate": true,
1173
+ "shared-node-browser": true,
1174
+ "WebSocket": true,
1175
+ "window": false
1176
+ },
1177
+ parserOptions: { ecmaFeatures: { jsx: true } },
1178
+ sourceType: "module"
1179
+ },
1180
+ name: "react-native/rules",
1181
+ rules: {
1182
+ "react-native-community/no-inline-styles": "warn",
1183
+ "react-native-community/no-raw-text": "warn",
1184
+ "react-native-community/no-single-element-style-arrays": "warn",
1185
+ "react-native-community/no-unused-styles": "warn",
1186
+ "react-native/no-deep-imports": "error",
1187
+ ...expo ? {
1188
+ "expo/no-dynamic-env-var": "error",
1189
+ "expo/no-env-var-destructuring": "error"
1190
+ } : {},
1191
+ ...overrides
1192
+ },
1193
+ settings: { react: { version: "detect" } }
1194
+ }];
1195
+ }
1196
+
1125
1197
  //#endregion
1126
1198
  //#region src/configs/regexp.ts
1127
1199
  async function regexp(options = {}) {
@@ -1618,7 +1690,7 @@ async function vue(options = {}) {
1618
1690
  watch: "readonly",
1619
1691
  watchEffect: "readonly"
1620
1692
  } },
1621
- name: "antfu/vue/setup",
1693
+ name: "vue/setup",
1622
1694
  plugins: {
1623
1695
  vue: pluginVue,
1624
1696
  ...a11y ? { "vue-a11y": pluginVueA11y } : {}
@@ -1634,7 +1706,7 @@ async function vue(options = {}) {
1634
1706
  sourceType: "module"
1635
1707
  }
1636
1708
  },
1637
- name: "antfu/vue/rules",
1709
+ name: "vue/rules",
1638
1710
  processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors([pluginVue.processors[".vue"], processorVueBlocks({
1639
1711
  ...sfcBlocks,
1640
1712
  blocks: {
@@ -1907,7 +1979,7 @@ const defaultPluginRenaming = {
1907
1979
  */
1908
1980
  function config(options = {}, ...userConfigs) {
1909
1981
  const isUsingReact = ReactPackages.some((i) => isPackageExists(i));
1910
- const { autoRenamePlugins = true, componentExts = [], effector: enableEffector = isPackageExists("effector"), gitignore: enableGitignore = true, imports: enableImports = true, jsx: enableJsx = true, jsxA11y: enableJsxA11y = isUsingReact, next: enableNext = NextJsPackages.some((i) => isPackageExists(i)), pnpm: enableCatalogs = false, react: enableReact = isUsingReact, regexp: enableRegexp = true, typescript: enableTypeScript = isPackageExists("typescript"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => isPackageExists(i)) } = options;
1982
+ const { autoRenamePlugins = true, componentExts = [], effector: enableEffector = isPackageExists("effector"), gitignore: enableGitignore = true, imports: enableImports = true, jsx: enableJsx = true, jsxA11y: enableJsxA11y = isUsingReact, next: enableNext = NextJsPackages.some((i) => isPackageExists(i)), pnpm: enableCatalogs = false, react: enableReact = isUsingReact, reactNative: enableReactNative = ReactNativePackages.some((i) => isPackageExists(i)), regexp: enableRegexp = true, typescript: enableTypeScript = isPackageExists("typescript"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => isPackageExists(i)) } = options;
1911
1983
  let isInEditor = options.isInEditor;
1912
1984
  if (isInEditor == null) {
1913
1985
  isInEditor = isInEditorEnv();
@@ -1959,6 +2031,10 @@ function config(options = {}, ...userConfigs) {
1959
2031
  overrides: getOverrides(options, "react"),
1960
2032
  tsconfigPath
1961
2033
  }));
2034
+ if (enableReactNative) configs$1.push(reactNative({
2035
+ ...resolveSubOptions(options, "reactNative"),
2036
+ overrides: getOverrides(options, "reactNative")
2037
+ }));
1962
2038
  if (enableJsxA11y) configs$1.push(jsxA11y({ overrides: getOverrides(options, "jsxA11y") }));
1963
2039
  if (enableNext) configs$1.push(next({ overrides: getOverrides(options, "next") }));
1964
2040
  if (enableEffector) configs$1.push(effector({
@@ -2006,4 +2082,4 @@ function config(options = {}, ...userConfigs) {
2006
2082
  var src_default = config;
2007
2083
 
2008
2084
  //#endregion
2009
- export { GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, config, src_default as default, defaultPluginRenaming, disables, effector, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsonc, jsx, jsxA11y, markdown, next, node, parserPlain, perfectionist, pnpm, react, regexp, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, toml, typescript, unicorn, unocss, vue, yaml };
2085
+ export { GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, StylisticConfigDefaults, combine, comments, config, src_default as default, defaultPluginRenaming, disables, effector, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsonc, jsx, jsxA11y, markdown, next, node, parserPlain, perfectionist, pnpm, react, reactNative, regexp, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, toml, typescript, unicorn, unocss, vue, yaml };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ghettoddos/eslint-config",
3
3
  "type": "module",
4
- "version": "1.7.0",
4
+ "version": "1.8.1",
5
5
  "description": "ghettoDdOS ESLint config",
6
6
  "author": "ghettoDdOS <pen.egor2002@gamil.com> (https://github.com/ghettoDdOS/)",
7
7
  "license": "MIT",
@@ -27,11 +27,14 @@
27
27
  "peerDependencies": {
28
28
  "@next/eslint-plugin-next": "^15.4.3",
29
29
  "@prettier/plugin-xml": "^3.4.2",
30
+ "@react-native/eslint-plugin": "^0.80.1",
30
31
  "@unocss/eslint-plugin": ">=0.50.0",
31
32
  "eslint": "^9.10.0",
32
33
  "eslint-plugin-effector": "^0.15.0",
34
+ "eslint-plugin-expo": "^0.1.4",
33
35
  "eslint-plugin-format": ">=0.1.0",
34
36
  "eslint-plugin-jsx-a11y": "^6.10.2",
37
+ "eslint-plugin-react-native": "^5.0.0",
35
38
  "eslint-plugin-vuejs-accessibility": "^2.4.1"
36
39
  },
37
40
  "peerDependenciesMeta": {
@@ -41,18 +44,27 @@
41
44
  "@prettier/plugin-xml": {
42
45
  "optional": true
43
46
  },
47
+ "@react-native/eslint-plugin": {
48
+ "optional": true
49
+ },
44
50
  "@unocss/eslint-plugin": {
45
51
  "optional": true
46
52
  },
47
53
  "eslint-plugin-effector": {
48
54
  "optional": true
49
55
  },
56
+ "eslint-plugin-expo": {
57
+ "optional": true
58
+ },
50
59
  "eslint-plugin-format": {
51
60
  "optional": true
52
61
  },
53
62
  "eslint-plugin-jsx-a11y": {
54
63
  "optional": true
55
64
  },
65
+ "eslint-plugin-react-native": {
66
+ "optional": true
67
+ },
56
68
  "eslint-plugin-vuejs-accessibility": {
57
69
  "optional": true
58
70
  }
@@ -98,13 +110,16 @@
98
110
  "@eslint/config-inspector": "^1.1.0",
99
111
  "@next/eslint-plugin-next": "^15.4.3",
100
112
  "@prettier/plugin-xml": "^3.4.2",
113
+ "@react-native/eslint-plugin": "^0.80.1",
101
114
  "@types/node": "^24.1.0",
102
115
  "@unocss/eslint-plugin": "^66.3.3",
103
116
  "bumpp": "^10.2.0",
104
117
  "eslint": "^9.31.0",
105
118
  "eslint-plugin-effector": "^0.15.0",
119
+ "eslint-plugin-expo": "^0.1.4",
106
120
  "eslint-plugin-format": "^1.0.1",
107
121
  "eslint-plugin-jsx-a11y": "^6.10.2",
122
+ "eslint-plugin-react-native": "^5.0.0",
108
123
  "eslint-plugin-vuejs-accessibility": "^2.4.1",
109
124
  "eslint-typegen": "^2.2.1",
110
125
  "lint-staged": "^16.1.2",