@eslint-react/shared 2.0.0-next.9 → 2.0.1-beta.0
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 +115 -1037
- package/dist/index.js +163 -237
- package/package.json +11 -12
package/dist/index.js
CHANGED
|
@@ -1,256 +1,182 @@
|
|
|
1
|
-
import module from
|
|
2
|
-
import path from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
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 "@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-config-adapters.ts
|
|
39
|
+
function getConfigAdapters(pluginName, plugin) {
|
|
40
|
+
function toFlatConfig(config) {
|
|
41
|
+
return {
|
|
42
|
+
...config,
|
|
43
|
+
plugins: { [pluginName]: plugin }
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function toLegacyConfig({ rules }) {
|
|
47
|
+
return {
|
|
48
|
+
plugins: [pluginName],
|
|
49
|
+
rules
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
toFlatConfig,
|
|
54
|
+
toLegacyConfig
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/get-doc-url.ts
|
|
60
|
+
/**
|
|
61
|
+
* Get the URL for the documentation of a rule in a plugin.
|
|
62
|
+
* @internal
|
|
63
|
+
* @param pluginName The name of the plugin.
|
|
64
|
+
* @returns The URL for the documentation of a rule.
|
|
65
|
+
*/
|
|
66
|
+
const getDocsUrl = (pluginName) => (ruleName) => {
|
|
67
|
+
if (pluginName === "x") return `${WEBSITE_URL}/docs/rules/${ruleName}`;
|
|
68
|
+
return `${WEBSITE_URL}/docs/rules/${pluginName}-${ruleName}`;
|
|
24
69
|
};
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/get-react-version.ts
|
|
25
73
|
function getReactVersion(fallback) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
74
|
+
try {
|
|
75
|
+
return match(_require("react")).with({ version: P.select(P.string) }, identity).otherwise(() => fallback);
|
|
76
|
+
} catch {
|
|
77
|
+
return fallback;
|
|
78
|
+
}
|
|
31
79
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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())
|
|
58
|
-
});
|
|
59
|
-
var CustomComponentSchema = z.object({
|
|
60
|
-
/**
|
|
61
|
-
* The name of the user-defined component.
|
|
62
|
-
* @example
|
|
63
|
-
* "Link"
|
|
64
|
-
*/
|
|
65
|
-
name: z.string(),
|
|
66
|
-
/**
|
|
67
|
-
* The name of the host component that the user-defined component represents.
|
|
68
|
-
* @example
|
|
69
|
-
* "a"
|
|
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())
|
|
85
|
-
});
|
|
86
|
-
var CustomHooksSchema = z.object({
|
|
87
|
-
use: z.optional(z.array(z.string())),
|
|
88
|
-
useActionState: z.optional(z.array(z.string())),
|
|
89
|
-
useCallback: z.optional(z.array(z.string())),
|
|
90
|
-
useContext: z.optional(z.array(z.string())),
|
|
91
|
-
useDebugValue: z.optional(z.array(z.string())),
|
|
92
|
-
useDeferredValue: z.optional(z.array(z.string())),
|
|
93
|
-
useEffect: z.optional(z.array(z.string())),
|
|
94
|
-
useFormStatus: z.optional(z.array(z.string())),
|
|
95
|
-
useId: z.optional(z.array(z.string())),
|
|
96
|
-
useImperativeHandle: z.optional(z.array(z.string())),
|
|
97
|
-
useInsertionEffect: z.optional(z.array(z.string())),
|
|
98
|
-
useLayoutEffect: z.optional(z.array(z.string())),
|
|
99
|
-
useMemo: z.optional(z.array(z.string())),
|
|
100
|
-
useOptimistic: z.optional(z.array(z.string())),
|
|
101
|
-
useReducer: z.optional(z.array(z.string())),
|
|
102
|
-
useRef: z.optional(z.array(z.string())),
|
|
103
|
-
useState: z.optional(z.array(z.string())),
|
|
104
|
-
useSyncExternalStore: z.optional(z.array(z.string())),
|
|
105
|
-
useTransition: z.optional(z.array(z.string()))
|
|
106
|
-
});
|
|
107
|
-
var ESLintReactSettingsSchema = z.object({
|
|
108
|
-
/**
|
|
109
|
-
* The source where React is imported from.
|
|
110
|
-
* @description This allows to specify a custom import location for React when not using the official distribution.
|
|
111
|
-
* @default `"react"`
|
|
112
|
-
* @example `"@pika/react"`
|
|
113
|
-
*/
|
|
114
|
-
importSource: z.optional(z.string()),
|
|
115
|
-
/**
|
|
116
|
-
* The identifier that's used for JSX Element creation.
|
|
117
|
-
* @default `"createElement"`
|
|
118
|
-
* @deprecated
|
|
119
|
-
*/
|
|
120
|
-
jsxPragma: z.optional(z.string()),
|
|
121
|
-
/**
|
|
122
|
-
* The identifier that's used for JSX fragment elements.
|
|
123
|
-
* @description This should not be a member expression (i.e. use "Fragment" instead of "React.Fragment").
|
|
124
|
-
* @default `"Fragment"`
|
|
125
|
-
* @deprecated
|
|
126
|
-
*/
|
|
127
|
-
jsxPragmaFrag: z.optional(z.string()),
|
|
128
|
-
/**
|
|
129
|
-
* The name of the prop that is used for polymorphic components.
|
|
130
|
-
* @description This is used to determine the type of the component.
|
|
131
|
-
* @example `"as"`
|
|
132
|
-
*/
|
|
133
|
-
polymorphicPropName: z.optional(z.string()),
|
|
134
|
-
/**
|
|
135
|
-
* @default `true`
|
|
136
|
-
* @internal
|
|
137
|
-
*/
|
|
138
|
-
strict: z.optional(z.boolean()),
|
|
139
|
-
/**
|
|
140
|
-
* Check both the shape and the import to determine if an API is from React.
|
|
141
|
-
* @default `true`
|
|
142
|
-
* @internal
|
|
143
|
-
*/
|
|
144
|
-
skipImportCheck: z.optional(z.boolean()),
|
|
145
|
-
/**
|
|
146
|
-
* React version to use, "detect" means auto detect React version from the project's dependencies.
|
|
147
|
-
* If `importSource` is specified, an equivalent version of React should be provided here.
|
|
148
|
-
* @example `"18.3.1"`
|
|
149
|
-
* @default `"detect"`
|
|
150
|
-
*/
|
|
151
|
-
version: z.optional(z.string()),
|
|
152
|
-
/**
|
|
153
|
-
* A object to define additional hooks that are equivalent to the built-in React Hooks.
|
|
154
|
-
* @description ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules.
|
|
155
|
-
* @example `{ useEffect: ["useIsomorphicLayoutEffect"] }`
|
|
156
|
-
*/
|
|
157
|
-
additionalHooks: z.optional(CustomHooksSchema),
|
|
158
|
-
/**
|
|
159
|
-
* An array of user-defined components
|
|
160
|
-
* @description This is used to inform the ESLint React plugins how to treat these components during checks.
|
|
161
|
-
* @example `[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]`
|
|
162
|
-
*/
|
|
163
|
-
additionalComponents: z.optional(z.array(CustomComponentSchema))
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/settings.ts
|
|
83
|
+
/**
|
|
84
|
+
* Schema for ESLint React settings configuration
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
const ESLintReactSettingsSchema = z.object({
|
|
88
|
+
importSource: z.optional(z.string()),
|
|
89
|
+
polymorphicPropName: z.optional(z.string()),
|
|
90
|
+
version: z.optional(z.string())
|
|
164
91
|
});
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Schema for ESLint settings
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
const ESLintSettingsSchema = z.optional(z.object({ "react-x": z.optional(z.unknown()) }));
|
|
97
|
+
/**
|
|
98
|
+
* Default ESLint React settings
|
|
99
|
+
*/
|
|
100
|
+
const DEFAULT_ESLINT_REACT_SETTINGS = {
|
|
101
|
+
version: "detect",
|
|
102
|
+
importSource: "react",
|
|
103
|
+
polymorphicPropName: "as"
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Default ESLint settings with React settings included
|
|
107
|
+
*/
|
|
108
|
+
const DEFAULT_ESLINT_SETTINGS = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };
|
|
109
|
+
/**
|
|
110
|
+
* Checks if the provided settings conform to ESLintSettings schema
|
|
111
|
+
* @param settings The settings object to validate
|
|
112
|
+
*/
|
|
171
113
|
function isESLintSettings(settings) {
|
|
172
|
-
|
|
114
|
+
return ESLintSettingsSchema.safeParse(settings).success;
|
|
173
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Checks if the provided settings conform to ESLintReactSettings schema
|
|
118
|
+
* @param settings The settings object to validate
|
|
119
|
+
*/
|
|
174
120
|
function isESLintReactSettings(settings) {
|
|
175
|
-
|
|
121
|
+
return ESLintReactSettingsSchema.safeParse(settings).success;
|
|
176
122
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
additionalComponents: [],
|
|
184
|
-
additionalHooks: {
|
|
185
|
-
useEffect: ["useIsomorphicLayoutEffect"],
|
|
186
|
-
useLayoutEffect: ["useIsomorphicLayoutEffect"]
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
var DEFAULT_ESLINT_SETTINGS = {
|
|
190
|
-
"react-x": DEFAULT_ESLINT_REACT_SETTINGS
|
|
191
|
-
};
|
|
192
|
-
var coerceESLintSettings = (settings) => {
|
|
193
|
-
return settings;
|
|
123
|
+
/**
|
|
124
|
+
* Coerces unknown input to ESLintSettings type
|
|
125
|
+
* @param settings The settings object to coerce
|
|
126
|
+
*/
|
|
127
|
+
const coerceESLintSettings = (settings) => {
|
|
128
|
+
return settings;
|
|
194
129
|
};
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Decodes and validates ESLint settings, using defaults if invalid
|
|
132
|
+
* @param settings The settings object to decode
|
|
133
|
+
*/
|
|
134
|
+
const decodeESLintSettings = (settings) => {
|
|
135
|
+
if (isESLintSettings(settings)) return settings;
|
|
136
|
+
return DEFAULT_ESLINT_SETTINGS;
|
|
200
137
|
};
|
|
201
|
-
|
|
202
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Coerces unknown input to ESLintReactSettings type
|
|
140
|
+
* @param settings The settings object to coerce
|
|
141
|
+
*/
|
|
142
|
+
const coerceSettings = (settings) => {
|
|
143
|
+
return settings;
|
|
203
144
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
145
|
+
/**
|
|
146
|
+
* Decodes and validates ESLint React settings, using defaults if invalid
|
|
147
|
+
* @param settings The settings object to decode
|
|
148
|
+
*/
|
|
149
|
+
const decodeSettings = (settings) => {
|
|
150
|
+
if (isESLintReactSettings(settings)) return settings;
|
|
151
|
+
return DEFAULT_ESLINT_REACT_SETTINGS;
|
|
209
152
|
};
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
...rest,
|
|
222
|
-
components: additionalComponents.map((component) => {
|
|
223
|
-
const { name, as = name, attributes = [], ...rest2 } = component;
|
|
224
|
-
const re = RegExp.toRegExp(name);
|
|
225
|
-
return {
|
|
226
|
-
...rest2,
|
|
227
|
-
name,
|
|
228
|
-
re,
|
|
229
|
-
as,
|
|
230
|
-
attributes: attributes.map(({ name: name2, as: as2 = name2, ...rest3 }) => ({
|
|
231
|
-
...rest3,
|
|
232
|
-
name: name2,
|
|
233
|
-
as: as2
|
|
234
|
-
}))
|
|
235
|
-
};
|
|
236
|
-
}),
|
|
237
|
-
additionalHooks,
|
|
238
|
-
importSource,
|
|
239
|
-
polymorphicPropName,
|
|
240
|
-
skipImportCheck,
|
|
241
|
-
strict,
|
|
242
|
-
version: match(version).with(P.union(P.nullish, "", "detect"), () => getReactVersion("19.1.0")).otherwise(identity)
|
|
243
|
-
};
|
|
153
|
+
/**
|
|
154
|
+
* Normalizes ESLint React settings to a consistent internal format
|
|
155
|
+
* Transforms component definitions and resolves version information
|
|
156
|
+
*/
|
|
157
|
+
const normalizeSettings = ({ importSource = "react", polymorphicPropName = "as", version,...rest }) => {
|
|
158
|
+
return {
|
|
159
|
+
...rest,
|
|
160
|
+
importSource,
|
|
161
|
+
polymorphicPropName,
|
|
162
|
+
version: match(version).with(P.union(P.nullish, "", "detect"), () => getReactVersion("19.1.0")).otherwise(identity)
|
|
163
|
+
};
|
|
244
164
|
};
|
|
245
|
-
|
|
165
|
+
const cache = /* @__PURE__ */ new Map();
|
|
166
|
+
/**
|
|
167
|
+
* Retrieves normalized ESLint React settings from the rule context
|
|
168
|
+
* Uses caching for performance optimization
|
|
169
|
+
* @param context The ESLint rule context
|
|
170
|
+
*/
|
|
246
171
|
function getSettingsFromContext(context) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
cache,
|
|
250
|
-
settings["react-x"],
|
|
251
|
-
() => normalizeSettings(decodeSettings(settings["react-x"]))
|
|
252
|
-
);
|
|
172
|
+
const settings = context.settings;
|
|
173
|
+
return getOrElseUpdate(cache, settings["react-x"], () => normalizeSettings(decodeSettings(settings["react-x"])));
|
|
253
174
|
}
|
|
254
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Helper function for defining typed settings for "react-x" in JavaScript files
|
|
177
|
+
* Provides type checking without runtime transformation
|
|
178
|
+
*/
|
|
179
|
+
const defineSettings = identity;
|
|
255
180
|
|
|
256
|
-
|
|
181
|
+
//#endregion
|
|
182
|
+
export { DEFAULT_ESLINT_REACT_SETTINGS, DEFAULT_ESLINT_SETTINGS, ESLintReactSettingsSchema, ESLintSettingsSchema, GITHUB_URL, NPM_SCOPE, WEBSITE_URL, _require, coerceESLintSettings, coerceSettings, decodeESLintSettings, decodeSettings, defineSettings, getConfigAdapters, 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.
|
|
3
|
+
"version": "2.0.1-beta.0",
|
|
4
4
|
"description": "ESLint React's Shared constants and functions.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -27,25 +27,24 @@
|
|
|
27
27
|
"./package.json"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@typescript-eslint/utils": "^8.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"@eslint-react/eff": "2.0.
|
|
34
|
-
"@eslint-react/kit": "2.0.
|
|
30
|
+
"@typescript-eslint/utils": "^8.44.1",
|
|
31
|
+
"ts-pattern": "^5.8.0",
|
|
32
|
+
"zod": "^4.1.11",
|
|
33
|
+
"@eslint-react/eff": "2.0.1-beta.0",
|
|
34
|
+
"@eslint-react/kit": "2.0.1-beta.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@tsconfig/node22": "^22.0.
|
|
38
|
-
"@types/picomatch": "^4.0.
|
|
39
|
-
"
|
|
40
|
-
"type-fest": "^
|
|
37
|
+
"@tsconfig/node22": "^22.0.2",
|
|
38
|
+
"@types/picomatch": "^4.0.2",
|
|
39
|
+
"tsdown": "^0.15.4",
|
|
40
|
+
"type-fest": "^5.0.1",
|
|
41
41
|
"@local/configs": "0.0.0"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
|
-
"bun": ">=1.0.15",
|
|
45
44
|
"node": ">=20.19.0"
|
|
46
45
|
},
|
|
47
46
|
"scripts": {
|
|
48
|
-
"build": "
|
|
47
|
+
"build": "tsdown --dts-resolve",
|
|
49
48
|
"build:docs": "typedoc",
|
|
50
49
|
"lint:publish": "publint",
|
|
51
50
|
"lint:ts": "tsc --noEmit"
|