eslint-plugin-react-dom 2.0.0-next.14 → 2.0.0-next.141
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 +21 -6
- package/dist/index.js +224 -150
- package/package.json +15 -16
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
import { CamelCase } from 'string-ts';
|
|
1
2
|
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
|
|
2
3
|
import { RulePreset } from '@eslint-react/kit';
|
|
3
4
|
|
|
5
|
+
declare const RULE_NAME$2 = "no-unsafe-target-blank";
|
|
6
|
+
type MessageID$2 = CamelCase<typeof RULE_NAME$2> | RuleSuggestMessageID$2;
|
|
7
|
+
type RuleSuggestMessageID$2 = "addRelNoreferrerNoopener";
|
|
8
|
+
|
|
9
|
+
declare const RULE_NAME$1 = "no-missing-iframe-sandbox";
|
|
10
|
+
type MessageID$1 = CamelCase<typeof RULE_NAME$1> | RuleSuggestMessageID$1;
|
|
11
|
+
type RuleSuggestMessageID$1 = "addIframeSandbox";
|
|
12
|
+
|
|
13
|
+
declare const RULE_NAME = "no-missing-button-type";
|
|
14
|
+
type MessageID = CamelCase<typeof RULE_NAME> | RuleSuggestMessageID;
|
|
15
|
+
type RuleSuggestMessageID = "addButtonType";
|
|
16
|
+
|
|
4
17
|
declare const _default: {
|
|
5
18
|
configs: {
|
|
6
19
|
recommended: {
|
|
@@ -16,15 +29,16 @@ declare const _default: {
|
|
|
16
29
|
readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
17
30
|
readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
18
31
|
readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
19
|
-
readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
20
|
-
readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
32
|
+
readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
33
|
+
readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
21
34
|
readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
22
35
|
readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
23
36
|
readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
24
37
|
readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
38
|
+
readonly "no-string-style-prop": _typescript_eslint_utils_ts_eslint.RuleModule<"noStringStyleProp", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
25
39
|
readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
26
40
|
readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
27
|
-
readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
41
|
+
readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$2, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
28
42
|
readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
29
43
|
readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
30
44
|
};
|
|
@@ -48,15 +62,16 @@ declare const _default: {
|
|
|
48
62
|
readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
49
63
|
readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
50
64
|
readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
51
|
-
readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
52
|
-
readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
65
|
+
readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
66
|
+
readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$1, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
53
67
|
readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
54
68
|
readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
55
69
|
readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
56
70
|
readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
71
|
+
readonly "no-string-style-prop": _typescript_eslint_utils_ts_eslint.RuleModule<"noStringStyleProp", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
57
72
|
readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
58
73
|
readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
59
|
-
readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<
|
|
74
|
+
readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<MessageID$2, [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
60
75
|
readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
61
76
|
readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
62
77
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { getDocsUrl, getSettingsFromContext, DEFAULT_ESLINT_REACT_SETTINGS } from '@eslint-react/shared';
|
|
2
2
|
import * as ER from '@eslint-react/core';
|
|
3
3
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
4
|
-
import
|
|
4
|
+
import { unit } from '@eslint-react/eff';
|
|
5
5
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
6
6
|
import { compare } from 'compare-versions';
|
|
7
7
|
import { RegExp, Reporter } from '@eslint-react/kit';
|
|
8
|
-
import { _ } from '@eslint-react/eff';
|
|
9
8
|
|
|
10
9
|
var __defProp = Object.defineProperty;
|
|
11
10
|
var __export = (target, all) => {
|
|
@@ -33,6 +32,7 @@ var rules = {
|
|
|
33
32
|
"react-dom/no-render": "error",
|
|
34
33
|
"react-dom/no-render-return-value": "error",
|
|
35
34
|
"react-dom/no-script-url": "warn",
|
|
35
|
+
"react-dom/no-string-style-prop": "error",
|
|
36
36
|
"react-dom/no-unsafe-iframe-sandbox": "warn",
|
|
37
37
|
"react-dom/no-unsafe-target-blank": "warn",
|
|
38
38
|
"react-dom/no-use-form-state": "error",
|
|
@@ -44,7 +44,7 @@ var settings = {
|
|
|
44
44
|
|
|
45
45
|
// package.json
|
|
46
46
|
var name2 = "eslint-plugin-react-dom";
|
|
47
|
-
var version = "2.0.0-next.
|
|
47
|
+
var version = "2.0.0-next.141";
|
|
48
48
|
function createJsxElementResolver(context) {
|
|
49
49
|
const { components, polymorphicPropName } = getSettingsFromContext(context);
|
|
50
50
|
return {
|
|
@@ -89,6 +89,39 @@ var createRule = ESLintUtils.RuleCreator(getDocsUrl("dom"));
|
|
|
89
89
|
function findCustomComponentProp(name3, props) {
|
|
90
90
|
return props.findLast((a) => a.as === name3);
|
|
91
91
|
}
|
|
92
|
+
function resolveAttribute(context, attributes, elementNode, attributeName) {
|
|
93
|
+
const customComponentProp = findCustomComponentProp(attributeName, attributes);
|
|
94
|
+
const propNameOnJsx = customComponentProp?.name ?? attributeName;
|
|
95
|
+
const attribute = ER.getAttribute(
|
|
96
|
+
context,
|
|
97
|
+
propNameOnJsx,
|
|
98
|
+
elementNode.openingElement.attributes,
|
|
99
|
+
context.sourceCode.getScope(elementNode)
|
|
100
|
+
);
|
|
101
|
+
if (attribute == null) {
|
|
102
|
+
return {
|
|
103
|
+
attribute: unit,
|
|
104
|
+
attributeName: propNameOnJsx,
|
|
105
|
+
attributeValue: unit,
|
|
106
|
+
attributeValueString: customComponentProp?.defaultValue
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const attributeValue = ER.getAttributeValue(context, attribute, propNameOnJsx);
|
|
110
|
+
if (attributeValue.kind === "some" && typeof attributeValue.value === "string") {
|
|
111
|
+
return {
|
|
112
|
+
attribute,
|
|
113
|
+
attributeName: propNameOnJsx,
|
|
114
|
+
attributeValue,
|
|
115
|
+
attributeValueString: attributeValue.value
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
attribute,
|
|
120
|
+
attributeName: propNameOnJsx,
|
|
121
|
+
attributeValue: unit,
|
|
122
|
+
attributeValueString: customComponentProp?.defaultValue ?? unit
|
|
123
|
+
};
|
|
124
|
+
}
|
|
92
125
|
|
|
93
126
|
// src/rules/no-dangerously-set-innerhtml.ts
|
|
94
127
|
var RULE_NAME = "no-dangerously-set-innerhtml";
|
|
@@ -153,7 +186,7 @@ function create2(context) {
|
|
|
153
186
|
JSXElement(node) {
|
|
154
187
|
const attributes = node.openingElement.attributes;
|
|
155
188
|
const initialScope = context.sourceCode.getScope(node);
|
|
156
|
-
const hasChildren =
|
|
189
|
+
const hasChildren = node.children.some(isSignificantChildren) || ER.hasAttribute(context, "children", attributes, initialScope);
|
|
157
190
|
if (hasChildren && ER.hasAttribute(context, dangerouslySetInnerHTML2, attributes, initialScope)) {
|
|
158
191
|
context.report({
|
|
159
192
|
messageId: "noDangerouslySetInnerhtmlWithChildren",
|
|
@@ -163,8 +196,14 @@ function create2(context) {
|
|
|
163
196
|
}
|
|
164
197
|
};
|
|
165
198
|
}
|
|
166
|
-
function
|
|
167
|
-
return node.
|
|
199
|
+
function isWhiteSpace(node) {
|
|
200
|
+
return typeof node.value === "string" && node.raw.trim() === "";
|
|
201
|
+
}
|
|
202
|
+
function isPaddingSpaces(node) {
|
|
203
|
+
return ER.isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n");
|
|
204
|
+
}
|
|
205
|
+
function isSignificantChildren(node) {
|
|
206
|
+
return node.type !== AST_NODE_TYPES.JSXText || !isPaddingSpaces(node);
|
|
168
207
|
}
|
|
169
208
|
var RULE_NAME3 = "no-find-dom-node";
|
|
170
209
|
var RULE_FEATURES3 = [];
|
|
@@ -322,8 +361,13 @@ function getFix(context, node) {
|
|
|
322
361
|
];
|
|
323
362
|
};
|
|
324
363
|
}
|
|
364
|
+
|
|
365
|
+
// src/rules/no-missing-button-type.ts
|
|
325
366
|
var RULE_NAME6 = "no-missing-button-type";
|
|
326
|
-
var RULE_FEATURES6 = [
|
|
367
|
+
var RULE_FEATURES6 = [
|
|
368
|
+
"FIX"
|
|
369
|
+
];
|
|
370
|
+
var BUTTON_TYPES = ["button", "submit", "reset"];
|
|
327
371
|
var no_missing_button_type_default = createRule({
|
|
328
372
|
meta: {
|
|
329
373
|
type: "problem",
|
|
@@ -331,7 +375,9 @@ var no_missing_button_type_default = createRule({
|
|
|
331
375
|
description: "Enforces explicit `type` attribute for `button` elements.",
|
|
332
376
|
[Symbol.for("rule_features")]: RULE_FEATURES6
|
|
333
377
|
},
|
|
378
|
+
hasSuggestions: true,
|
|
334
379
|
messages: {
|
|
380
|
+
addButtonType: "Add 'type' attribute with value '{{type}}'.",
|
|
335
381
|
noMissingButtonType: "Add missing 'type' attribute on 'button' component."
|
|
336
382
|
},
|
|
337
383
|
schema: []
|
|
@@ -346,60 +392,42 @@ function create6(context) {
|
|
|
346
392
|
JSXElement(node) {
|
|
347
393
|
const { attributes, domElementType } = resolver.resolve(node);
|
|
348
394
|
if (domElementType !== "button") return;
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
context,
|
|
353
|
-
propNameOnJsx,
|
|
354
|
-
node.openingElement.attributes,
|
|
355
|
-
context.sourceCode.getScope(node)
|
|
356
|
-
);
|
|
357
|
-
if (attributeNode != null) {
|
|
358
|
-
const attributeValue = ER.getAttributeValue(
|
|
359
|
-
context,
|
|
360
|
-
attributeNode,
|
|
361
|
-
propNameOnJsx
|
|
362
|
-
);
|
|
363
|
-
if (attributeValue.kind === "some" && typeof attributeValue.value !== "string") {
|
|
364
|
-
context.report({
|
|
365
|
-
messageId: "noMissingButtonType",
|
|
366
|
-
node: attributeNode
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (typeof customComponentProp?.defaultValue !== "string") {
|
|
395
|
+
const typeAttribute = resolveAttribute(context, attributes, node, "type");
|
|
396
|
+
if (typeAttribute.attributeValueString != null) return;
|
|
397
|
+
if (typeAttribute.attribute == null) {
|
|
372
398
|
context.report({
|
|
373
399
|
messageId: "noMissingButtonType",
|
|
374
|
-
node
|
|
400
|
+
node: node.openingElement,
|
|
401
|
+
suggest: getSuggest((type) => (fixer) => {
|
|
402
|
+
return fixer.insertTextAfter(node.openingElement.name, ` ${typeAttribute.attributeName}="${type}"`);
|
|
403
|
+
})
|
|
375
404
|
});
|
|
405
|
+
return;
|
|
376
406
|
}
|
|
407
|
+
context.report({
|
|
408
|
+
messageId: "noMissingButtonType",
|
|
409
|
+
node: typeAttribute.attributeValue?.node ?? typeAttribute.attribute,
|
|
410
|
+
suggest: getSuggest((type) => (fixer) => {
|
|
411
|
+
if (typeAttribute.attribute == null) return null;
|
|
412
|
+
return fixer.replaceText(typeAttribute.attribute, `${typeAttribute.attributeName}="${type}"`);
|
|
413
|
+
})
|
|
414
|
+
});
|
|
377
415
|
}
|
|
378
416
|
};
|
|
379
417
|
}
|
|
418
|
+
function getSuggest(getFix4) {
|
|
419
|
+
return BUTTON_TYPES.map((type) => ({
|
|
420
|
+
messageId: "addButtonType",
|
|
421
|
+
data: { type },
|
|
422
|
+
fix: getFix4(type)
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/rules/no-missing-iframe-sandbox.ts
|
|
380
427
|
var RULE_NAME7 = "no-missing-iframe-sandbox";
|
|
381
|
-
var RULE_FEATURES7 = [
|
|
382
|
-
|
|
383
|
-
"",
|
|
384
|
-
"allow-downloads",
|
|
385
|
-
"allow-downloads-without-user-activation",
|
|
386
|
-
"allow-forms",
|
|
387
|
-
"allow-modals",
|
|
388
|
-
"allow-orientation-lock",
|
|
389
|
-
"allow-pointer-lock",
|
|
390
|
-
"allow-popups",
|
|
391
|
-
"allow-popups-to-escape-sandbox",
|
|
392
|
-
"allow-presentation",
|
|
393
|
-
"allow-same-origin",
|
|
394
|
-
"allow-scripts",
|
|
395
|
-
"allow-storage-access-by-user-activation",
|
|
396
|
-
"allow-top-navigation",
|
|
397
|
-
"allow-top-navigation-by-user-activation",
|
|
398
|
-
"allow-top-navigation-to-custom-protocols"
|
|
428
|
+
var RULE_FEATURES7 = [
|
|
429
|
+
"FIX"
|
|
399
430
|
];
|
|
400
|
-
function hasValidSandBox(value) {
|
|
401
|
-
return typeof value === "string" && value.split(" ").every((value2) => validTypes.some((valid) => valid === value2));
|
|
402
|
-
}
|
|
403
431
|
var no_missing_iframe_sandbox_default = createRule({
|
|
404
432
|
meta: {
|
|
405
433
|
type: "problem",
|
|
@@ -407,7 +435,10 @@ var no_missing_iframe_sandbox_default = createRule({
|
|
|
407
435
|
description: "Enforces explicit `sandbox` attribute for `iframe` elements.",
|
|
408
436
|
[Symbol.for("rule_features")]: RULE_FEATURES7
|
|
409
437
|
},
|
|
438
|
+
fixable: "code",
|
|
439
|
+
hasSuggestions: true,
|
|
410
440
|
messages: {
|
|
441
|
+
addIframeSandbox: "Add 'sandbox' attribute with value '{{value}}'.",
|
|
411
442
|
noMissingIframeSandbox: "Add missing 'sandbox' attribute on 'iframe' component."
|
|
412
443
|
},
|
|
413
444
|
schema: []
|
|
@@ -422,33 +453,34 @@ function create7(context) {
|
|
|
422
453
|
JSXElement(node) {
|
|
423
454
|
const { attributes, domElementType } = resolver.resolve(node);
|
|
424
455
|
if (domElementType !== "iframe") return;
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
context,
|
|
429
|
-
propNameOnJsx,
|
|
430
|
-
node.openingElement.attributes,
|
|
431
|
-
context.sourceCode.getScope(node)
|
|
432
|
-
);
|
|
433
|
-
if (attributeNode != null) {
|
|
434
|
-
const attributeValue = ER.getAttributeValue(
|
|
435
|
-
context,
|
|
436
|
-
attributeNode,
|
|
437
|
-
propNameOnJsx
|
|
438
|
-
);
|
|
439
|
-
if (attributeValue.kind === "some" && hasValidSandBox(attributeValue.value)) return;
|
|
456
|
+
const sandboxAttribute = resolveAttribute(context, attributes, node, "sandbox");
|
|
457
|
+
if (sandboxAttribute.attributeValueString != null) return;
|
|
458
|
+
if (sandboxAttribute.attribute == null) {
|
|
440
459
|
context.report({
|
|
441
460
|
messageId: "noMissingIframeSandbox",
|
|
442
|
-
node:
|
|
461
|
+
node: node.openingElement,
|
|
462
|
+
suggest: [{
|
|
463
|
+
messageId: "addIframeSandbox",
|
|
464
|
+
data: { value: "" },
|
|
465
|
+
fix(fixer) {
|
|
466
|
+
return fixer.insertTextAfter(node.openingElement.name, ` ${sandboxAttribute.attributeName}=""`);
|
|
467
|
+
}
|
|
468
|
+
}]
|
|
443
469
|
});
|
|
444
470
|
return;
|
|
445
471
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
472
|
+
context.report({
|
|
473
|
+
messageId: "noMissingIframeSandbox",
|
|
474
|
+
node: sandboxAttribute.attributeValue?.node ?? sandboxAttribute.attribute,
|
|
475
|
+
suggest: [{
|
|
476
|
+
messageId: "addIframeSandbox",
|
|
477
|
+
data: { value: "" },
|
|
478
|
+
fix(fixer) {
|
|
479
|
+
if (sandboxAttribute.attribute == null) return null;
|
|
480
|
+
return fixer.replaceText(sandboxAttribute.attribute, `${sandboxAttribute.attributeName}=""`);
|
|
481
|
+
}
|
|
482
|
+
}]
|
|
483
|
+
});
|
|
452
484
|
}
|
|
453
485
|
};
|
|
454
486
|
}
|
|
@@ -664,7 +696,51 @@ function create11(context) {
|
|
|
664
696
|
}
|
|
665
697
|
};
|
|
666
698
|
}
|
|
667
|
-
var RULE_NAME12 = "no-
|
|
699
|
+
var RULE_NAME12 = "no-string-style-prop";
|
|
700
|
+
var RULE_FEATURES12 = [];
|
|
701
|
+
var no_string_style_prop_default = createRule({
|
|
702
|
+
meta: {
|
|
703
|
+
type: "problem",
|
|
704
|
+
docs: {
|
|
705
|
+
description: "Disallows the use of string style prop.",
|
|
706
|
+
[Symbol.for("rule_features")]: RULE_FEATURES12
|
|
707
|
+
},
|
|
708
|
+
messages: {
|
|
709
|
+
noStringStyleProp: "Do not use string style prop. Use an object instead."
|
|
710
|
+
},
|
|
711
|
+
schema: []
|
|
712
|
+
},
|
|
713
|
+
name: RULE_NAME12,
|
|
714
|
+
create: create12,
|
|
715
|
+
defaultOptions: []
|
|
716
|
+
});
|
|
717
|
+
function create12(context) {
|
|
718
|
+
return {
|
|
719
|
+
JSXAttribute(node) {
|
|
720
|
+
if (node.name.name !== "style") return;
|
|
721
|
+
const styleText = getAttributeValueText(context, node.value);
|
|
722
|
+
if (styleText == null) return;
|
|
723
|
+
context.report({
|
|
724
|
+
messageId: "noStringStyleProp",
|
|
725
|
+
node
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
function getAttributeValueText(context, node) {
|
|
731
|
+
if (node == null) return null;
|
|
732
|
+
switch (true) {
|
|
733
|
+
case (node.type === AST_NODE_TYPES.Literal && typeof node.value === "string"):
|
|
734
|
+
return context.sourceCode.getText(node);
|
|
735
|
+
case (node.type === AST_NODE_TYPES.JSXExpressionContainer && node.expression.type === AST_NODE_TYPES.Literal && typeof node.expression.value === "string"):
|
|
736
|
+
return context.sourceCode.getText(node.expression);
|
|
737
|
+
case (node.type === AST_NODE_TYPES.JSXExpressionContainer && node.expression.type === AST_NODE_TYPES.TemplateLiteral):
|
|
738
|
+
return context.sourceCode.getText(node.expression);
|
|
739
|
+
default:
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
var RULE_NAME13 = "no-unknown-property";
|
|
668
744
|
var DEFAULTS = {
|
|
669
745
|
ignore: [],
|
|
670
746
|
requireDataLowercase: false
|
|
@@ -1627,11 +1703,11 @@ var no_unknown_property_default = createRule({
|
|
|
1627
1703
|
}
|
|
1628
1704
|
}]
|
|
1629
1705
|
},
|
|
1630
|
-
name:
|
|
1631
|
-
create:
|
|
1706
|
+
name: RULE_NAME13,
|
|
1707
|
+
create: create13,
|
|
1632
1708
|
defaultOptions: []
|
|
1633
1709
|
});
|
|
1634
|
-
function
|
|
1710
|
+
function create13(context) {
|
|
1635
1711
|
const report = Reporter.make(context);
|
|
1636
1712
|
function getIgnoreConfig() {
|
|
1637
1713
|
return context.options[0]?.ignore || DEFAULTS.ignore;
|
|
@@ -1722,12 +1798,14 @@ function testReactVersion(context, comparator, version2) {
|
|
|
1722
1798
|
const { version: localVersion } = getSettingsFromContext(context);
|
|
1723
1799
|
return compare(localVersion, version2, comparator);
|
|
1724
1800
|
}
|
|
1725
|
-
|
|
1726
|
-
|
|
1801
|
+
|
|
1802
|
+
// src/rules/no-unsafe-iframe-sandbox.ts
|
|
1803
|
+
var RULE_NAME14 = "no-unsafe-iframe-sandbox";
|
|
1804
|
+
var RULE_FEATURES13 = [];
|
|
1727
1805
|
var unsafeSandboxValues = [
|
|
1728
1806
|
["allow-scripts", "allow-same-origin"]
|
|
1729
1807
|
];
|
|
1730
|
-
function
|
|
1808
|
+
function isSafeSandbox(value) {
|
|
1731
1809
|
if (typeof value !== "string") return false;
|
|
1732
1810
|
return !unsafeSandboxValues.some((values) => {
|
|
1733
1811
|
return values.every((v) => value.includes(v));
|
|
@@ -1738,57 +1816,39 @@ var no_unsafe_iframe_sandbox_default = createRule({
|
|
|
1738
1816
|
type: "problem",
|
|
1739
1817
|
docs: {
|
|
1740
1818
|
description: "Enforces `sandbox` attribute for `iframe` elements is not set to unsafe combinations.",
|
|
1741
|
-
[Symbol.for("rule_features")]:
|
|
1819
|
+
[Symbol.for("rule_features")]: RULE_FEATURES13
|
|
1742
1820
|
},
|
|
1743
1821
|
messages: {
|
|
1744
1822
|
noUnsafeIframeSandbox: "Unsafe 'sandbox' attribute value on 'iframe' component."
|
|
1745
1823
|
},
|
|
1746
1824
|
schema: []
|
|
1747
1825
|
},
|
|
1748
|
-
name:
|
|
1749
|
-
create:
|
|
1826
|
+
name: RULE_NAME14,
|
|
1827
|
+
create: create14,
|
|
1750
1828
|
defaultOptions: []
|
|
1751
1829
|
});
|
|
1752
|
-
function
|
|
1830
|
+
function create14(context) {
|
|
1753
1831
|
const resolver = createJsxElementResolver(context);
|
|
1754
1832
|
return {
|
|
1755
1833
|
JSXElement(node) {
|
|
1756
1834
|
const { attributes, domElementType } = resolver.resolve(node);
|
|
1757
1835
|
if (domElementType !== "iframe") return;
|
|
1758
|
-
const
|
|
1759
|
-
|
|
1760
|
-
const attributeNode = ER.getAttribute(
|
|
1761
|
-
context,
|
|
1762
|
-
propNameOnJsx,
|
|
1763
|
-
node.openingElement.attributes,
|
|
1764
|
-
context.sourceCode.getScope(node)
|
|
1765
|
-
);
|
|
1766
|
-
if (attributeNode != null) {
|
|
1767
|
-
const attributeValue = ER.getAttributeValue(
|
|
1768
|
-
context,
|
|
1769
|
-
attributeNode,
|
|
1770
|
-
propNameOnJsx
|
|
1771
|
-
);
|
|
1772
|
-
if (attributeValue.kind === "some" && !hasSafeSandbox(attributeValue.value)) {
|
|
1773
|
-
context.report({
|
|
1774
|
-
messageId: "noUnsafeIframeSandbox",
|
|
1775
|
-
node: attributeNode
|
|
1776
|
-
});
|
|
1777
|
-
return;
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
if (customComponentProp?.defaultValue == null) return;
|
|
1781
|
-
if (!hasSafeSandbox(customComponentProp.defaultValue)) {
|
|
1836
|
+
const sandboxAttribute = resolveAttribute(context, attributes, node, "sandbox");
|
|
1837
|
+
if (!isSafeSandbox(sandboxAttribute.attributeValueString)) {
|
|
1782
1838
|
context.report({
|
|
1783
1839
|
messageId: "noUnsafeIframeSandbox",
|
|
1784
|
-
node
|
|
1840
|
+
node: sandboxAttribute.attributeValue?.node ?? sandboxAttribute.attribute ?? node
|
|
1785
1841
|
});
|
|
1786
1842
|
}
|
|
1787
1843
|
}
|
|
1788
1844
|
};
|
|
1789
1845
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1846
|
+
|
|
1847
|
+
// src/rules/no-unsafe-target-blank.ts
|
|
1848
|
+
var RULE_NAME15 = "no-unsafe-target-blank";
|
|
1849
|
+
var RULE_FEATURES14 = [
|
|
1850
|
+
"FIX"
|
|
1851
|
+
];
|
|
1792
1852
|
function isExternalLinkLike(value) {
|
|
1793
1853
|
if (value == null) return false;
|
|
1794
1854
|
return value.startsWith("https://") || /^(?:\w+:|\/\/)/u.test(value);
|
|
@@ -1802,58 +1862,70 @@ var no_unsafe_target_blank_default = createRule({
|
|
|
1802
1862
|
type: "problem",
|
|
1803
1863
|
docs: {
|
|
1804
1864
|
description: 'Disallow `target="_blank"` without `rel="noreferrer noopener"`.',
|
|
1805
|
-
[Symbol.for("rule_features")]:
|
|
1865
|
+
[Symbol.for("rule_features")]: RULE_FEATURES14
|
|
1806
1866
|
},
|
|
1867
|
+
fixable: "code",
|
|
1868
|
+
hasSuggestions: true,
|
|
1807
1869
|
messages: {
|
|
1870
|
+
addRelNoreferrerNoopener: `Add 'rel="noreferrer noopener"' to the link to prevent security risks.`,
|
|
1808
1871
|
noUnsafeTargetBlank: `Using 'target="_blank"' on an external link without 'rel="noreferrer noopener"' is a security risk.`
|
|
1809
1872
|
},
|
|
1810
1873
|
schema: []
|
|
1811
1874
|
},
|
|
1812
|
-
name:
|
|
1813
|
-
create:
|
|
1875
|
+
name: RULE_NAME15,
|
|
1876
|
+
create: create15,
|
|
1814
1877
|
defaultOptions: []
|
|
1815
1878
|
});
|
|
1816
|
-
function
|
|
1879
|
+
function create15(context) {
|
|
1817
1880
|
const resolver = createJsxElementResolver(context);
|
|
1818
1881
|
return {
|
|
1819
1882
|
JSXElement(node) {
|
|
1820
1883
|
const { attributes, domElementType } = resolver.resolve(node);
|
|
1821
1884
|
if (domElementType !== "a") return;
|
|
1822
|
-
const
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
propNameOnJsx,
|
|
1829
|
-
node.openingElement.attributes,
|
|
1830
|
-
elementScope
|
|
1831
|
-
);
|
|
1832
|
-
if (attributeNode == null) return customComponentProp?.defaultValue;
|
|
1833
|
-
const attributeValue = ER.getAttributeValue(context, attributeNode, propNameOnJsx);
|
|
1834
|
-
if (attributeValue.kind === "some" && typeof attributeValue.value === "string") {
|
|
1835
|
-
return attributeValue.value;
|
|
1836
|
-
}
|
|
1837
|
-
return _;
|
|
1838
|
-
};
|
|
1839
|
-
if (getAttributeStringValue("target") !== "_blank") {
|
|
1885
|
+
const targetAttribute = resolveAttribute(context, attributes, node, "target");
|
|
1886
|
+
if (targetAttribute.attributeValueString !== "_blank") {
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
const hrefAttribute = resolveAttribute(context, attributes, node, "href");
|
|
1890
|
+
if (!isExternalLinkLike(hrefAttribute.attributeValueString)) {
|
|
1840
1891
|
return;
|
|
1841
1892
|
}
|
|
1842
|
-
|
|
1893
|
+
const relAttribute = resolveAttribute(context, attributes, node, "rel");
|
|
1894
|
+
if (isSafeRel(relAttribute.attributeValueString)) {
|
|
1843
1895
|
return;
|
|
1844
1896
|
}
|
|
1845
|
-
if (
|
|
1897
|
+
if (relAttribute.attribute == null) {
|
|
1898
|
+
context.report({
|
|
1899
|
+
messageId: "noUnsafeTargetBlank",
|
|
1900
|
+
node: node.openingElement,
|
|
1901
|
+
suggest: [{
|
|
1902
|
+
messageId: "addRelNoreferrerNoopener",
|
|
1903
|
+
fix(fixer) {
|
|
1904
|
+
return fixer.insertTextAfter(
|
|
1905
|
+
node.openingElement.name,
|
|
1906
|
+
` ${relAttribute.attributeName}="noreferrer noopener"`
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
}]
|
|
1910
|
+
});
|
|
1846
1911
|
return;
|
|
1847
1912
|
}
|
|
1848
1913
|
context.report({
|
|
1849
1914
|
messageId: "noUnsafeTargetBlank",
|
|
1850
|
-
node
|
|
1915
|
+
node: relAttribute.attributeValue?.node ?? relAttribute.attribute,
|
|
1916
|
+
suggest: [{
|
|
1917
|
+
messageId: "addRelNoreferrerNoopener",
|
|
1918
|
+
fix(fixer) {
|
|
1919
|
+
if (relAttribute.attribute == null) return null;
|
|
1920
|
+
return fixer.replaceText(relAttribute.attribute, `${relAttribute.attributeName}="noreferrer noopener"`);
|
|
1921
|
+
}
|
|
1922
|
+
}]
|
|
1851
1923
|
});
|
|
1852
1924
|
}
|
|
1853
1925
|
};
|
|
1854
1926
|
}
|
|
1855
|
-
var
|
|
1856
|
-
var
|
|
1927
|
+
var RULE_NAME16 = "no-use-form-state";
|
|
1928
|
+
var RULE_FEATURES15 = [
|
|
1857
1929
|
"MOD"
|
|
1858
1930
|
];
|
|
1859
1931
|
var no_use_form_state_default = createRule({
|
|
@@ -1861,7 +1933,7 @@ var no_use_form_state_default = createRule({
|
|
|
1861
1933
|
type: "problem",
|
|
1862
1934
|
docs: {
|
|
1863
1935
|
description: "Replaces usages of `useFormState` with `useActionState`.",
|
|
1864
|
-
[Symbol.for("rule_features")]:
|
|
1936
|
+
[Symbol.for("rule_features")]: RULE_FEATURES15
|
|
1865
1937
|
},
|
|
1866
1938
|
fixable: "code",
|
|
1867
1939
|
messages: {
|
|
@@ -1869,11 +1941,11 @@ var no_use_form_state_default = createRule({
|
|
|
1869
1941
|
},
|
|
1870
1942
|
schema: []
|
|
1871
1943
|
},
|
|
1872
|
-
name:
|
|
1873
|
-
create:
|
|
1944
|
+
name: RULE_NAME16,
|
|
1945
|
+
create: create16,
|
|
1874
1946
|
defaultOptions: []
|
|
1875
1947
|
});
|
|
1876
|
-
function
|
|
1948
|
+
function create16(context) {
|
|
1877
1949
|
if (!context.sourceCode.text.includes("useFormState")) return {};
|
|
1878
1950
|
const settings2 = getSettingsFromContext(context);
|
|
1879
1951
|
if (compare(settings2.version, "19.0.0", "<")) return {};
|
|
@@ -1928,8 +2000,8 @@ function getFix3(context, node) {
|
|
|
1928
2000
|
];
|
|
1929
2001
|
};
|
|
1930
2002
|
}
|
|
1931
|
-
var
|
|
1932
|
-
var
|
|
2003
|
+
var RULE_NAME17 = "no-void-elements-with-children";
|
|
2004
|
+
var RULE_FEATURES16 = [];
|
|
1933
2005
|
var voidElements = /* @__PURE__ */ new Set([
|
|
1934
2006
|
"area",
|
|
1935
2007
|
"base",
|
|
@@ -1953,21 +2025,22 @@ var no_void_elements_with_children_default = createRule({
|
|
|
1953
2025
|
type: "problem",
|
|
1954
2026
|
docs: {
|
|
1955
2027
|
description: "Disallow `children` in void DOM elements.",
|
|
1956
|
-
[Symbol.for("rule_features")]:
|
|
2028
|
+
[Symbol.for("rule_features")]: RULE_FEATURES16
|
|
1957
2029
|
},
|
|
1958
2030
|
messages: {
|
|
1959
2031
|
noVoidElementsWithChildren: "'{{element}}' is a void element tag and must not have children."
|
|
1960
2032
|
},
|
|
1961
2033
|
schema: []
|
|
1962
2034
|
},
|
|
1963
|
-
name:
|
|
1964
|
-
create:
|
|
2035
|
+
name: RULE_NAME17,
|
|
2036
|
+
create: create17,
|
|
1965
2037
|
defaultOptions: []
|
|
1966
2038
|
});
|
|
1967
|
-
function
|
|
2039
|
+
function create17(context) {
|
|
2040
|
+
const resolver = createJsxElementResolver(context);
|
|
1968
2041
|
return {
|
|
1969
2042
|
JSXElement(node) {
|
|
1970
|
-
const elementName =
|
|
2043
|
+
const { domElementType: elementName } = resolver.resolve(node);
|
|
1971
2044
|
if (elementName.length === 0 || !voidElements.has(elementName)) {
|
|
1972
2045
|
return;
|
|
1973
2046
|
}
|
|
@@ -2014,6 +2087,7 @@ var plugin = {
|
|
|
2014
2087
|
"no-render": no_render_default,
|
|
2015
2088
|
"no-render-return-value": no_render_return_value_default,
|
|
2016
2089
|
"no-script-url": no_script_url_default,
|
|
2090
|
+
"no-string-style-prop": no_string_style_prop_default,
|
|
2017
2091
|
"no-unknown-property": no_unknown_property_default,
|
|
2018
2092
|
"no-unsafe-iframe-sandbox": no_unsafe_iframe_sandbox_default,
|
|
2019
2093
|
"no-unsafe-target-blank": no_unsafe_target_blank_default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-dom",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.141",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React DOM related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -35,27 +35,27 @@
|
|
|
35
35
|
"./package.json"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@typescript-eslint/scope-manager": "^8.
|
|
39
|
-
"@typescript-eslint/types": "^8.
|
|
40
|
-
"@typescript-eslint/utils": "^8.
|
|
38
|
+
"@typescript-eslint/scope-manager": "^8.40.0",
|
|
39
|
+
"@typescript-eslint/types": "^8.40.0",
|
|
40
|
+
"@typescript-eslint/utils": "^8.40.0",
|
|
41
41
|
"compare-versions": "^6.1.1",
|
|
42
42
|
"string-ts": "^2.2.1",
|
|
43
|
-
"ts-pattern": "^5.
|
|
44
|
-
"@eslint-react/
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/eff": "2.0.0-next.
|
|
49
|
-
"@eslint-react/
|
|
43
|
+
"ts-pattern": "^5.8.0",
|
|
44
|
+
"@eslint-react/ast": "2.0.0-next.141",
|
|
45
|
+
"@eslint-react/core": "2.0.0-next.141",
|
|
46
|
+
"@eslint-react/kit": "2.0.0-next.141",
|
|
47
|
+
"@eslint-react/var": "2.0.0-next.141",
|
|
48
|
+
"@eslint-react/eff": "2.0.0-next.141",
|
|
49
|
+
"@eslint-react/shared": "2.0.0-next.141"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@types/react": "^19.1.
|
|
53
|
-
"@types/react-dom": "^19.1.
|
|
54
|
-
"tsup": "^8.
|
|
52
|
+
"@types/react": "^19.1.11",
|
|
53
|
+
"@types/react-dom": "^19.1.7",
|
|
54
|
+
"tsup": "^8.5.0",
|
|
55
55
|
"@local/configs": "0.0.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"eslint": "^9.
|
|
58
|
+
"eslint": "^9.33.0",
|
|
59
59
|
"typescript": "^4.9.5 || ^5.4.5"
|
|
60
60
|
},
|
|
61
61
|
"peerDependenciesMeta": {
|
|
@@ -67,7 +67,6 @@
|
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
69
|
"engines": {
|
|
70
|
-
"bun": ">=1.0.15",
|
|
71
70
|
"node": ">=20.19.0"
|
|
72
71
|
},
|
|
73
72
|
"publishConfig": {
|