@eslint-react/shared 2.0.0-next.146 → 2.0.0-next.148
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 +154 -826
- package/dist/index.js +169 -219
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,242 +1,192 @@
|
|
|
1
|
-
import module from
|
|
2
|
-
import path from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { RegExp } from
|
|
6
|
-
import { z } from
|
|
1
|
+
import module from "node:module";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getOrElseUpdate, identity } from "@eslint-react/eff";
|
|
4
|
+
import { P, match } from "ts-pattern";
|
|
5
|
+
import { RegExp } from "@eslint-react/kit";
|
|
6
|
+
import { z } from "zod/v4";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
//#region src/_id.ts
|
|
9
|
+
let id = 0n;
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
const getId = () => (id++).toString();
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/_require.ts
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
const _require = module.createRequire(process.cwd() + path.sep);
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/constants.ts
|
|
24
|
+
/**
|
|
25
|
+
* The NPM scope for this project.
|
|
26
|
+
*/
|
|
27
|
+
const NPM_SCOPE = "@eslint-react";
|
|
28
|
+
/**
|
|
29
|
+
* The GitHub repository for this project.
|
|
30
|
+
*/
|
|
31
|
+
const GITHUB_URL = "https://github.com/Rel1cx/eslint-react";
|
|
32
|
+
/**
|
|
33
|
+
* The URL to the project's website.
|
|
34
|
+
*/
|
|
35
|
+
const WEBSITE_URL = "https://eslint-react.xyz";
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/get-doc-url.ts
|
|
39
|
+
/**
|
|
40
|
+
* Get the URL for the documentation of a rule in a plugin.
|
|
41
|
+
* @internal
|
|
42
|
+
* @param pluginName The name of the plugin.
|
|
43
|
+
* @returns The URL for the documentation of a rule.
|
|
44
|
+
*/
|
|
45
|
+
const getDocsUrl = (pluginName) => (ruleName) => {
|
|
46
|
+
if (pluginName === "x") return `${WEBSITE_URL}/docs/rules/${ruleName}`;
|
|
47
|
+
return `${WEBSITE_URL}/docs/rules/${pluginName}-${ruleName}`;
|
|
24
48
|
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/get-react-version.ts
|
|
25
52
|
function getReactVersion(fallback) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
53
|
+
try {
|
|
54
|
+
return match(_require("react")).with({ version: P.select(P.string) }, identity).otherwise(() => fallback);
|
|
55
|
+
} catch {
|
|
56
|
+
return fallback;
|
|
57
|
+
}
|
|
31
58
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* The name of the prop in the host component.
|
|
41
|
-
* @example
|
|
42
|
-
* "href"
|
|
43
|
-
*/
|
|
44
|
-
as: z.optional(z.string()),
|
|
45
|
-
/**
|
|
46
|
-
* Whether the prop is controlled or not in the user-defined component.
|
|
47
|
-
* @internal
|
|
48
|
-
* @example
|
|
49
|
-
* `true`
|
|
50
|
-
*/
|
|
51
|
-
controlled: z.optional(z.boolean()),
|
|
52
|
-
/**
|
|
53
|
-
* The default value of the prop in the user-defined component.
|
|
54
|
-
* @example
|
|
55
|
-
* `"/"`
|
|
56
|
-
*/
|
|
57
|
-
defaultValue: z.optional(z.string())
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/settings.ts
|
|
62
|
+
const CustomComponentPropSchema = z.object({
|
|
63
|
+
name: z.string(),
|
|
64
|
+
as: z.optional(z.string()),
|
|
65
|
+
controlled: z.optional(z.boolean()),
|
|
66
|
+
defaultValue: z.optional(z.string())
|
|
58
67
|
});
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
*/
|
|
71
|
-
as: z.optional(z.string()),
|
|
72
|
-
/**
|
|
73
|
-
* Attributes mapping between the user-defined component and the host component.
|
|
74
|
-
* @example
|
|
75
|
-
* `Link` component has a `to` attribute that represents the `href` attribute in the built-in `a` element with a default value of `"/"`.
|
|
76
|
-
*/
|
|
77
|
-
attributes: z.optional(z.array(CustomComponentPropSchema)),
|
|
78
|
-
/**
|
|
79
|
-
* The ESQuery selector to select the component precisely.
|
|
80
|
-
* @internal
|
|
81
|
-
* @example
|
|
82
|
-
* `JSXElement:has(JSXAttribute[name.name='component'][value.value='a'])`
|
|
83
|
-
*/
|
|
84
|
-
selector: z.optional(z.string())
|
|
68
|
+
/**
|
|
69
|
+
* @description
|
|
70
|
+
* This will provide some key information to the rule before checking for user-defined components.
|
|
71
|
+
* For example:
|
|
72
|
+
* Which prop is used as the `href` prop for the user-defined `Link` component that represents the built-in `a` element.
|
|
73
|
+
*/
|
|
74
|
+
const CustomComponentSchema = z.object({
|
|
75
|
+
name: z.string(),
|
|
76
|
+
as: z.optional(z.string()),
|
|
77
|
+
attributes: z.optional(z.array(CustomComponentPropSchema)),
|
|
78
|
+
selector: z.optional(z.string())
|
|
85
79
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
80
|
+
const CustomHooksSchema = z.object({
|
|
81
|
+
use: z.optional(z.array(z.string())),
|
|
82
|
+
useActionState: z.optional(z.array(z.string())),
|
|
83
|
+
useCallback: z.optional(z.array(z.string())),
|
|
84
|
+
useContext: z.optional(z.array(z.string())),
|
|
85
|
+
useDebugValue: z.optional(z.array(z.string())),
|
|
86
|
+
useDeferredValue: z.optional(z.array(z.string())),
|
|
87
|
+
useEffect: z.optional(z.array(z.string())),
|
|
88
|
+
useFormStatus: z.optional(z.array(z.string())),
|
|
89
|
+
useId: z.optional(z.array(z.string())),
|
|
90
|
+
useImperativeHandle: z.optional(z.array(z.string())),
|
|
91
|
+
useInsertionEffect: z.optional(z.array(z.string())),
|
|
92
|
+
useLayoutEffect: z.optional(z.array(z.string())),
|
|
93
|
+
useMemo: z.optional(z.array(z.string())),
|
|
94
|
+
useOptimistic: z.optional(z.array(z.string())),
|
|
95
|
+
useReducer: z.optional(z.array(z.string())),
|
|
96
|
+
useRef: z.optional(z.array(z.string())),
|
|
97
|
+
useState: z.optional(z.array(z.string())),
|
|
98
|
+
useSyncExternalStore: z.optional(z.array(z.string())),
|
|
99
|
+
useTransition: z.optional(z.array(z.string()))
|
|
106
100
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
* @example `"as"`
|
|
119
|
-
*/
|
|
120
|
-
polymorphicPropName: z.optional(z.string()),
|
|
121
|
-
/**
|
|
122
|
-
* @default `true`
|
|
123
|
-
* @internal
|
|
124
|
-
*/
|
|
125
|
-
strict: z.optional(z.boolean()),
|
|
126
|
-
/**
|
|
127
|
-
* Check both the shape and the import to determine if an API is from React.
|
|
128
|
-
* @default `true`
|
|
129
|
-
* @internal
|
|
130
|
-
*/
|
|
131
|
-
skipImportCheck: z.optional(z.boolean()),
|
|
132
|
-
/**
|
|
133
|
-
* React version to use, "detect" means auto detect React version from the project's dependencies.
|
|
134
|
-
* If `importSource` is specified, an equivalent version of React should be provided here.
|
|
135
|
-
* @example `"18.3.1"`
|
|
136
|
-
* @default `"detect"`
|
|
137
|
-
*/
|
|
138
|
-
version: z.optional(z.string()),
|
|
139
|
-
/**
|
|
140
|
-
* A object to define additional hooks that are equivalent to the built-in React Hooks.
|
|
141
|
-
* @description ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules.
|
|
142
|
-
* @example `{ useEffect: ["useIsomorphicLayoutEffect"] }`
|
|
143
|
-
*/
|
|
144
|
-
additionalHooks: z.optional(CustomHooksSchema),
|
|
145
|
-
/**
|
|
146
|
-
* An array of user-defined components
|
|
147
|
-
* @description This is used to inform the ESLint React plugins how to treat these components during checks.
|
|
148
|
-
* @example `[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]`
|
|
149
|
-
*/
|
|
150
|
-
additionalComponents: z.optional(z.array(CustomComponentSchema))
|
|
101
|
+
/**
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
const ESLintReactSettingsSchema = z.object({
|
|
105
|
+
importSource: z.optional(z.string()),
|
|
106
|
+
polymorphicPropName: z.optional(z.string()),
|
|
107
|
+
strict: z.optional(z.boolean()),
|
|
108
|
+
skipImportCheck: z.optional(z.boolean()),
|
|
109
|
+
version: z.optional(z.string()),
|
|
110
|
+
additionalHooks: z.optional(CustomHooksSchema),
|
|
111
|
+
additionalComponents: z.optional(z.array(CustomComponentSchema))
|
|
151
112
|
});
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
113
|
+
/**
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
const ESLintSettingsSchema = z.optional(z.object({ "react-x": z.optional(z.unknown()) }));
|
|
157
117
|
function isESLintSettings(settings) {
|
|
158
|
-
|
|
118
|
+
return ESLintSettingsSchema.safeParse(settings).success;
|
|
159
119
|
}
|
|
160
120
|
function isESLintReactSettings(settings) {
|
|
161
|
-
|
|
121
|
+
return ESLintReactSettingsSchema.safeParse(settings).success;
|
|
162
122
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
123
|
+
/**
|
|
124
|
+
* The default ESLint settings for "react-x".
|
|
125
|
+
*/
|
|
126
|
+
const DEFAULT_ESLINT_REACT_SETTINGS = {
|
|
127
|
+
version: "detect",
|
|
128
|
+
importSource: "react",
|
|
129
|
+
strict: true,
|
|
130
|
+
skipImportCheck: true,
|
|
131
|
+
polymorphicPropName: "as",
|
|
132
|
+
additionalComponents: [],
|
|
133
|
+
additionalHooks: {
|
|
134
|
+
useEffect: ["useIsomorphicLayoutEffect"],
|
|
135
|
+
useLayoutEffect: ["useIsomorphicLayoutEffect"]
|
|
136
|
+
}
|
|
177
137
|
};
|
|
178
|
-
|
|
179
|
-
|
|
138
|
+
const DEFAULT_ESLINT_SETTINGS = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };
|
|
139
|
+
const coerceESLintSettings = (settings) => {
|
|
140
|
+
return settings;
|
|
180
141
|
};
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
return DEFAULT_ESLINT_SETTINGS;
|
|
142
|
+
const decodeESLintSettings = (settings) => {
|
|
143
|
+
if (isESLintSettings(settings)) return settings;
|
|
144
|
+
return DEFAULT_ESLINT_SETTINGS;
|
|
186
145
|
};
|
|
187
|
-
|
|
188
|
-
|
|
146
|
+
const coerceSettings = (settings) => {
|
|
147
|
+
return settings;
|
|
189
148
|
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
return DEFAULT_ESLINT_REACT_SETTINGS;
|
|
149
|
+
const decodeSettings = (settings) => {
|
|
150
|
+
if (isESLintReactSettings(settings)) return settings;
|
|
151
|
+
return DEFAULT_ESLINT_REACT_SETTINGS;
|
|
195
152
|
};
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
};
|
|
222
|
-
}),
|
|
223
|
-
additionalHooks,
|
|
224
|
-
importSource,
|
|
225
|
-
polymorphicPropName,
|
|
226
|
-
skipImportCheck,
|
|
227
|
-
strict,
|
|
228
|
-
version: match(version).with(P.union(P.nullish, "", "detect"), () => getReactVersion("19.1.0")).otherwise(identity)
|
|
229
|
-
};
|
|
153
|
+
const normalizeSettings = ({ additionalComponents = [], additionalHooks = {}, importSource = "react", polymorphicPropName = "as", skipImportCheck = true, strict = true, version,...rest }) => {
|
|
154
|
+
return {
|
|
155
|
+
...rest,
|
|
156
|
+
components: additionalComponents.map((component) => {
|
|
157
|
+
const { name, as = name, attributes = [],...rest$1 } = component;
|
|
158
|
+
const re = RegExp.toRegExp(name);
|
|
159
|
+
return {
|
|
160
|
+
...rest$1,
|
|
161
|
+
name,
|
|
162
|
+
re,
|
|
163
|
+
as,
|
|
164
|
+
attributes: attributes.map(({ name: name$1, as: as$1 = name$1,...rest$2 }) => ({
|
|
165
|
+
...rest$2,
|
|
166
|
+
name: name$1,
|
|
167
|
+
as: as$1
|
|
168
|
+
}))
|
|
169
|
+
};
|
|
170
|
+
}),
|
|
171
|
+
additionalHooks,
|
|
172
|
+
importSource,
|
|
173
|
+
polymorphicPropName,
|
|
174
|
+
skipImportCheck,
|
|
175
|
+
strict,
|
|
176
|
+
version: match(version).with(P.union(P.nullish, "", "detect"), () => getReactVersion("19.1.0")).otherwise(identity)
|
|
177
|
+
};
|
|
230
178
|
};
|
|
231
|
-
|
|
179
|
+
const cache = /* @__PURE__ */ new Map();
|
|
232
180
|
function getSettingsFromContext(context) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
cache,
|
|
236
|
-
settings["react-x"],
|
|
237
|
-
() => normalizeSettings(decodeSettings(settings["react-x"]))
|
|
238
|
-
);
|
|
181
|
+
const settings = context.settings;
|
|
182
|
+
return getOrElseUpdate(cache, settings["react-x"], () => normalizeSettings(decodeSettings(settings["react-x"])));
|
|
239
183
|
}
|
|
240
|
-
|
|
184
|
+
/**
|
|
185
|
+
* A helper function to define settings for "react-x" with type checking in JavaScript files.
|
|
186
|
+
* @param settings The settings.
|
|
187
|
+
* @returns The settings.
|
|
188
|
+
*/
|
|
189
|
+
const defineSettings = identity;
|
|
241
190
|
|
|
242
|
-
|
|
191
|
+
//#endregion
|
|
192
|
+
export { CustomComponentPropSchema, CustomComponentSchema, CustomHooksSchema, DEFAULT_ESLINT_REACT_SETTINGS, DEFAULT_ESLINT_SETTINGS, ESLintReactSettingsSchema, ESLintSettingsSchema, GITHUB_URL, NPM_SCOPE, WEBSITE_URL, _require, coerceESLintSettings, coerceSettings, decodeESLintSettings, decodeSettings, defineSettings, getDocsUrl, getId, getReactVersion, getSettingsFromContext, isESLintReactSettings, isESLintSettings, normalizeSettings };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/shared",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.148",
|
|
4
4
|
"description": "ESLint React's Shared constants and functions.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"./package.json"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@typescript-eslint/utils": "^8.
|
|
30
|
+
"@typescript-eslint/utils": "^8.41.0",
|
|
31
31
|
"ts-pattern": "^5.8.0",
|
|
32
|
-
"zod": "^4.1.
|
|
33
|
-
"@eslint-react/eff": "2.0.0-next.
|
|
34
|
-
"@eslint-react/kit": "2.0.0-next.
|
|
32
|
+
"zod": "^4.1.3",
|
|
33
|
+
"@eslint-react/eff": "2.0.0-next.148",
|
|
34
|
+
"@eslint-react/kit": "2.0.0-next.148"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@tsconfig/node22": "^22.0.2",
|
|
38
38
|
"@types/picomatch": "^4.0.2",
|
|
39
|
-
"
|
|
39
|
+
"tsdown": "^0.14.2",
|
|
40
40
|
"type-fest": "^4.41.0",
|
|
41
41
|
"@local/configs": "0.0.0"
|
|
42
42
|
},
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"node": ">=20.19.0"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
|
-
"build": "
|
|
47
|
+
"build": "tsdown --dts-resolve",
|
|
48
48
|
"build:docs": "typedoc",
|
|
49
49
|
"lint:publish": "publint",
|
|
50
50
|
"lint:ts": "tsc --noEmit"
|