@forthtilliath/eslint-config 0.3.0 → 0.4.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/README.md CHANGED
@@ -63,19 +63,25 @@ import { angularConfig } from "@forthtilliath/eslint-config/angular";
63
63
  export default angularConfig;
64
64
  ```
65
65
 
66
- All five are **named** exports — a default import (`import config from "..."`)
66
+ ```ts
67
+ // A React Native / Expo app
68
+ import { reactNativeConfig } from "@forthtilliath/eslint-config/react-native";
69
+ export default reactNativeConfig;
70
+ ```
71
+
72
+ All six are **named** exports — a default import (`import config from "..."`)
67
73
  resolves to the whole module namespace object instead of the config array and
68
74
  crashes ESLint's flat-config loader outright. Two of the five variants had
69
75
  exactly this bug at one point; use the named-import form above.
70
76
 
71
77
  Each variant is additive: `reactConfig`/`angularConfig` extend `baseConfig`,
72
- `nextJsConfig`/`storybookConfig` extend `reactConfig`.
78
+ `nextJsConfig`/`storybookConfig`/`reactNativeConfig` extend `reactConfig`.
73
79
 
74
80
  ### Customizing a variant
75
81
 
76
82
  Each variant is also exported as a factory (`createBaseConfig`,
77
83
  `createReactConfig`, `createNextJsConfig`, `createStorybookConfig`,
78
- `createAngularConfig`) taking an options object — the plain `baseConfig`,
84
+ `createAngularConfig`, `createReactNativeConfig`) taking an options object — the plain `baseConfig`,
79
85
  `reactConfig`, etc. exports above are just that factory called with no
80
86
  arguments. Pass options to opt out of a default:
81
87
 
@@ -93,18 +99,26 @@ import { createBaseConfig } from "@forthtilliath/eslint-config";
93
99
  export default createBaseConfig({ strict: false, turbo: false });
94
100
  ```
95
101
 
96
- | Option | Default | Effect |
97
- | ---------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
98
- | `prettier` | `true` | Append `eslint-config-prettier` at the end. |
99
- | `strict` | `true` | Use `strictTypeChecked`/`stylisticTypeChecked` instead of plain `recommended`. |
100
- | `turbo` | `true` | Enable `eslint-plugin-turbo`'s `no-undeclared-env-vars` rule. |
101
- | `a11y` | `true` | _(react/nextjs/storybook)_ Enable `eslint-plugin-jsx-a11y`'s recommended rules. |
102
- | `i18n` | `false` | _(react/nextjs/storybook)_ Enable `eslint-plugin-i18next`'s `no-literal-string` rule. |
103
- | `testingLibrary` | `false` | _(react/nextjs/storybook)_ Enable `eslint-plugin-testing-library` + `eslint-plugin-jest-dom` on test files. |
102
+ | Option | Default | Effect |
103
+ | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
104
+ | `prettier` | `true` | Append `eslint-config-prettier` at the end. |
105
+ | `strict` | `true` | Use `strictTypeChecked`/`stylisticTypeChecked` instead of plain `recommended`. |
106
+ | `turbo` | `true` | Enable `eslint-plugin-turbo`'s `no-undeclared-env-vars` rule. |
107
+ | `a11y` | `true`\* | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-jsx-a11y`'s recommended rules. \*Defaults to `false` in `createReactNativeConfig` (jsx-a11y targets DOM semantics, which RN doesn't have). |
108
+ | `i18n` | `false` | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-i18next`'s `no-literal-string` rule. |
109
+ | `testingLibrary` | `false` | _(react/nextjs/storybook/react-native)_ Enable `eslint-plugin-testing-library` + `eslint-plugin-jest-dom` on test files. |
104
110
 
105
111
  Options are forwarded down the chain, so `createNextJsConfig({ prettier: false })`
106
112
  also disables Prettier in the `reactConfig`/`baseConfig` layers it builds on.
107
113
 
114
+ `createReactNativeConfig` also always adds `eslint-plugin-react-native`
115
+ (`split-platform-components`, `no-raw-text`) and the RN/Metro-injected
116
+ `__DEV__` global — these aren't behind an option, unlike the toggles above.
117
+ `no-inline-styles` and `sort-styles` stay off (stylistic, not correctness);
118
+ `no-unused-styles` and `no-single-element-style-arrays` also stay off —
119
+ `eslint-plugin-react-native@5.0.0` crashes running them under ESLint 10
120
+ (`context.getSourceCode is not a function`, an API ESLint 10 removed).
121
+
108
122
  ```ts
109
123
  // Full i18n project (next-intl, react-intl...): forbid hardcoded JSX strings
110
124
  import { createNextJsConfig } from "@forthtilliath/eslint-config/nextjs";
@@ -112,9 +126,11 @@ export default createNextJsConfig({ i18n: true });
112
126
  ```
113
127
 
114
128
  ```ts
115
- // React Native / Expo: jsx-a11y targets DOM semantics and doesn't apply
116
- import { createReactConfig } from "@forthtilliath/eslint-config/react";
117
- export default createReactConfig({ a11y: false });
129
+ // React Native / Expo, customized: same options as createReactConfig, plus
130
+ // eslint-plugin-react-native's rules (a11y is off by default here, since
131
+ // jsx-a11y targets DOM semantics and doesn't apply to RN)
132
+ import { createReactNativeConfig } from "@forthtilliath/eslint-config/react-native";
133
+ export default createReactNativeConfig({ testingLibrary: true });
118
134
  ```
119
135
 
120
136
  ### Typed linting and non-project files
@@ -0,0 +1,20 @@
1
+ /**
2
+ * eslint-plugin-react-native only ships a legacy (eslintrc) `configs.all`
3
+ * export, no flat-config preset — so the plugin and its rules are wired by
4
+ * hand here instead of spreading a ready-made flat config like storybook.js
5
+ * does.
6
+ */
7
+ /**
8
+ * A custom ESLint configuration for React Native / Expo apps.
9
+ *
10
+ * @param {import("./base.js").BaseConfigOptions & import("./react.js").ReactConfigOptions} [options]
11
+ * @returns {import("eslint").Linter.Config[]} */
12
+ export function createReactNativeConfig({ a11y, ...options }?: import("./base.js").BaseConfigOptions & import("./react.js").ReactConfigOptions): import("eslint").Linter.Config[];
13
+ /**
14
+ * A custom ESLint configuration for React Native / Expo apps, with the
15
+ * default options. Use `createReactNativeConfig(options)` instead to
16
+ * customize it.
17
+ *
18
+ * @type {import("eslint").Linter.Config[]} */
19
+ export const reactNativeConfig: import("eslint").Linter.Config[];
20
+ //# sourceMappingURL=react-native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../src/react-native.js"],"names":[],"mappings":"AAKA;;;;;GAKG;AAEH;;;;iDAIiD;AACjD,+DAFW,OAAO,WAAW,EAAE,iBAAiB,GAAG,OAAO,YAAY,EAAE,kBAAkB,GAC7E,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAoC5C;AAED;;;;;8CAK8C;AAC9C,gCADU,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CACiB"}
@@ -0,0 +1,57 @@
1
+ import { defineConfig } from "eslint/config";
2
+ import pluginReactNative from "eslint-plugin-react-native";
3
+ import { createReactConfig } from "./react.js";
4
+ /**
5
+ * eslint-plugin-react-native only ships a legacy (eslintrc) `configs.all`
6
+ * export, no flat-config preset — so the plugin and its rules are wired by
7
+ * hand here instead of spreading a ready-made flat config like storybook.js
8
+ * does.
9
+ */
10
+ /**
11
+ * A custom ESLint configuration for React Native / Expo apps.
12
+ *
13
+ * @param {import("./base.js").BaseConfigOptions & import("./react.js").ReactConfigOptions} [options]
14
+ * @returns {import("eslint").Linter.Config[]} */
15
+ export function createReactNativeConfig({ a11y = false, ...options } = {}) {
16
+ return defineConfig([
17
+ ...createReactConfig({ a11y, ...options }),
18
+ {
19
+ languageOptions: {
20
+ globals: {
21
+ // Injected by Metro/React Native at build time, dead-code-eliminated
22
+ // in release builds — not part of globals.node or globals.browser.
23
+ __DEV__: "readonly",
24
+ },
25
+ },
26
+ },
27
+ {
28
+ plugins: {
29
+ "react-native": pluginReactNative,
30
+ },
31
+ rules: {
32
+ "react-native/split-platform-components": "error",
33
+ "react-native/no-raw-text": "error",
34
+ // Off by default: both are stylistic preferences rather than
35
+ // correctness checks, and inline styles in particular are a common,
36
+ // legitimate RN pattern (one-off layout tweaks) that Prettier already
37
+ // keeps readable.
38
+ "react-native/no-inline-styles": "off",
39
+ // Off: crashes outright under ESLint 10 ("context.getSourceCode is
40
+ // not a function") — eslint-plugin-react-native@5.0.0 still calls the
41
+ // API ESLint 10 removed, in the util shared by no-unused-styles/
42
+ // no-color-literals and in sort-styles/no-single-element-style-arrays
43
+ // directly. Re-enable once the plugin ships a fix.
44
+ "react-native/no-unused-styles": "off",
45
+ "react-native/no-single-element-style-arrays": "off",
46
+ "react-native/sort-styles": "off",
47
+ },
48
+ },
49
+ ]);
50
+ }
51
+ /**
52
+ * A custom ESLint configuration for React Native / Expo apps, with the
53
+ * default options. Use `createReactNativeConfig(options)` instead to
54
+ * customize it.
55
+ *
56
+ * @type {import("eslint").Linter.Config[]} */
57
+ export const reactNativeConfig = createReactNativeConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forthtilliath/eslint-config",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -31,6 +31,7 @@
31
31
  "eslint-plugin-jsx-a11y": "^6.10.2",
32
32
  "eslint-plugin-react": "^7.37.5",
33
33
  "eslint-plugin-react-hooks": "^7.1.1",
34
+ "eslint-plugin-react-native": "^5.0.0",
34
35
  "eslint-plugin-react-refresh": "^0.5.4",
35
36
  "eslint-plugin-simple-import-sort": "^13.0.0",
36
37
  "eslint-plugin-storybook": "^9.1.20",