eslint-plugin-react-dom 1.24.0-next.9 → 1.24.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.
Files changed (3) hide show
  1. package/dist/index.js +155 -103
  2. package/dist/index.mjs +154 -101
  3. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -1,13 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var JSX3 = require('@eslint-react/jsx');
4
- var eff = require('@eslint-react/eff');
3
+ var JSX = require('@eslint-react/jsx');
5
4
  var shared = require('@eslint-react/shared');
6
5
  var types = require('@typescript-eslint/types');
7
- var core = require('@eslint-react/core');
8
6
  var AST = require('@eslint-react/ast');
9
- var VAR = require('@eslint-react/var');
10
7
  var compareVersions = require('compare-versions');
8
+ var eff = require('@eslint-react/eff');
11
9
 
12
10
  function _interopNamespace(e) {
13
11
  if (e && e.__esModule) return e;
@@ -27,47 +25,40 @@ function _interopNamespace(e) {
27
25
  return Object.freeze(n);
28
26
  }
29
27
 
30
- var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
28
+ var JSX__namespace = /*#__PURE__*/_interopNamespace(JSX);
31
29
  var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
32
- var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
33
30
 
34
31
  // package.json
35
32
  var name = "eslint-plugin-react-dom";
36
- var version = "1.24.0-next.9";
37
- function getAdditionalAttributes(componentName, additionalComponents) {
38
- return additionalComponents.findLast((c) => c.name === componentName || c.re.test(componentName))?.attributes ?? [];
33
+ var version = "1.24.0";
34
+ var createRule = shared.createRuleForPlugin("dom");
35
+
36
+ // src/utils/find-custom-component.ts
37
+ function findCustomComponent(name2, components) {
38
+ return components.findLast((c) => c.name === name2 || c.re.test(name2));
39
39
  }
40
- function getAttributeMetaData(name2, attributes) {
41
- const settings = attributes.findLast((a) => a.as === name2);
42
- return {
43
- name: settings?.name ?? name2,
44
- controlled: settings?.controlled ?? false,
45
- defaultValue: settings?.defaultValue
46
- };
40
+ function findCustomComponentProp(name2, props) {
41
+ return props.findLast((a) => a.as === name2);
47
42
  }
48
- function getAttributeNodeAndStringValue(name2, element, context, additionalAttributes) {
49
- const attributeMetaData = getAttributeMetaData(name2, additionalAttributes);
50
- const attributeNameOnElement = attributeMetaData.name;
51
- const attributeNode = JSX3__namespace.getAttributeNode(
52
- attributeNameOnElement,
53
- context.sourceCode.getScope(element),
54
- element.openingElement.attributes
43
+ function getElementNameOnJsxAndDom(node, context, polymorphicPropName, additionalComponents = []) {
44
+ const name2 = JSX__namespace.getElementName(node);
45
+ if (name2 === name2.toLowerCase()) return [name2, name2];
46
+ const component = additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2));
47
+ if (component != null) return [name2, component.as];
48
+ if (polymorphicPropName == null) return [name2, name2];
49
+ const initialScope = context.sourceCode.getScope(node);
50
+ const attributeNode = JSX__namespace.getAttribute(
51
+ polymorphicPropName,
52
+ node.openingElement.attributes,
53
+ initialScope
55
54
  );
56
- if (attributeNode == null) {
57
- return {
58
- attributeNode: eff._,
59
- attributeValue: attributeMetaData.defaultValue
60
- };
55
+ if (attributeNode == null) return [name2, name2];
56
+ const polymorphicPropValue = JSX__namespace.getAttributeValue(attributeNode, polymorphicPropName, initialScope);
57
+ if (polymorphicPropValue.kind === "some" && typeof polymorphicPropValue.value === "string") {
58
+ return [name2, polymorphicPropValue.value];
61
59
  }
62
- const attributeScope = context.sourceCode.getScope(attributeNode);
63
- const attributeValue = JSX3__namespace.getAttributeStringValue(
64
- attributeNameOnElement,
65
- attributeNode,
66
- attributeScope
67
- );
68
- return { attributeNode, attributeValue };
60
+ return [name2, name2];
69
61
  }
70
- var createRule = shared.createRuleForPlugin("dom");
71
62
 
72
63
  // src/rules/no-dangerously-set-innerhtml.ts
73
64
  var RULE_NAME = "no-dangerously-set-innerhtml";
@@ -92,10 +83,10 @@ var no_dangerously_set_innerhtml_default = createRule({
92
83
  return {
93
84
  JSXElement(node) {
94
85
  const attributes = node.openingElement.attributes;
95
- const attribute = JSX3__namespace.getAttributeNode(
86
+ const attribute = JSX__namespace.getAttribute(
96
87
  "dangerouslySetInnerHTML",
97
- context.sourceCode.getScope(node),
98
- attributes
88
+ attributes,
89
+ context.sourceCode.getScope(node)
99
90
  );
100
91
  if (attribute == null) return;
101
92
  context.report({
@@ -130,8 +121,8 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
130
121
  JSXElement(node) {
131
122
  const attributes = node.openingElement.attributes;
132
123
  const initialScope = context.sourceCode.getScope(node);
133
- const hasChildren = hasChildrenWithin(node) || JSX3__namespace.hasAttribute("children", initialScope, attributes);
134
- if (hasChildren && JSX3__namespace.hasAttribute("dangerouslySetInnerHTML", initialScope, attributes)) {
124
+ const hasChildren = hasChildrenWithin(node) || JSX__namespace.hasAttribute("children", attributes, initialScope);
125
+ if (hasChildren && JSX__namespace.hasAttribute("dangerouslySetInnerHTML", attributes, initialScope)) {
135
126
  context.report({
136
127
  messageId: "noDangerouslySetInnerhtmlWithChildren",
137
128
  node
@@ -143,7 +134,7 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
143
134
  defaultOptions: []
144
135
  });
145
136
  function hasChildrenWithin(node) {
146
- return node.children.length > 0 && node.children[0] != null && !JSX3__namespace.isLineBreak(node.children[0]);
137
+ return node.children.length > 0 && node.children[0] != null && !JSX__namespace.isLineBreak(node.children[0]);
147
138
  }
148
139
  var RULE_NAME3 = "no-find-dom-node";
149
140
  var RULE_FEATURES3 = [
@@ -207,23 +198,37 @@ var no_missing_button_type_default = createRule({
207
198
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
208
199
  return {
209
200
  JSXElement(node) {
210
- const [elementNameOnJsx, elementNameOnHtml] = core.getElementNameOnJsxAndHtml(
211
- node.openingElement,
201
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
202
+ node,
212
203
  context,
213
204
  polymorphicPropName,
214
205
  additionalComponents
215
206
  );
216
- if (elementNameOnHtml !== "button") return;
217
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
218
- "type",
219
- node,
220
- context,
221
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
207
+ if (elementNameOnDom !== "button") return;
208
+ const elementScope = context.sourceCode.getScope(node);
209
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
210
+ const customComponentProp = findCustomComponentProp("type", customComponent?.attributes ?? []);
211
+ const propNameOnJsx = customComponentProp?.name ?? "type";
212
+ const attributeNode = JSX__namespace.getAttribute(
213
+ propNameOnJsx,
214
+ node.openingElement.attributes,
215
+ elementScope
222
216
  );
223
- if (typeof attributeValue !== "string") {
217
+ if (attributeNode != null) {
218
+ const attributeScope = context.sourceCode.getScope(attributeNode);
219
+ const attributeValue = JSX__namespace.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
220
+ if (attributeValue.kind === "some" && typeof attributeValue.value !== "string") {
221
+ context.report({
222
+ messageId: "noMissingButtonType",
223
+ node: attributeNode
224
+ });
225
+ }
226
+ return;
227
+ }
228
+ if (typeof customComponentProp?.defaultValue !== "string") {
224
229
  context.report({
225
230
  messageId: "noMissingButtonType",
226
- node: attributeNode ?? node
231
+ node
227
232
  });
228
233
  }
229
234
  }
@@ -253,6 +258,9 @@ var validTypes = [
253
258
  "allow-top-navigation-by-user-activation",
254
259
  "allow-top-navigation-to-custom-protocols"
255
260
  ];
261
+ function hasValidSandBox(value) {
262
+ return typeof value === "string" && value.split(" ").every((value2) => validTypes.some((valid) => valid === value2));
263
+ }
256
264
  var no_missing_iframe_sandbox_default = createRule({
257
265
  meta: {
258
266
  type: "problem",
@@ -272,25 +280,38 @@ var no_missing_iframe_sandbox_default = createRule({
272
280
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
273
281
  return {
274
282
  JSXElement(node) {
275
- const [elementNameOnJsx, elementNameOnHtml] = core.getElementNameOnJsxAndHtml(
276
- node.openingElement,
283
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
284
+ node,
277
285
  context,
278
286
  polymorphicPropName,
279
287
  additionalComponents
280
288
  );
281
- if (elementNameOnHtml !== "iframe") return;
282
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
283
- "sandbox",
284
- node,
285
- context,
286
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
289
+ if (elementNameOnDom !== "iframe") return;
290
+ const elementScope = context.sourceCode.getScope(node);
291
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
292
+ const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
293
+ const propNameOnJsx = customComponentProp?.name ?? "sandbox";
294
+ const attributeNode = JSX__namespace.getAttribute(
295
+ propNameOnJsx,
296
+ node.openingElement.attributes,
297
+ elementScope
287
298
  );
288
- const hasValidSandboxValue = typeof attributeValue === "string" && attributeValue.split(" ").every((value) => validTypes.some((valid) => valid === value));
289
- if (hasValidSandboxValue) return;
290
- context.report({
291
- messageId: "noMissingIframeSandbox",
292
- node: attributeNode ?? node.openingElement
293
- });
299
+ if (attributeNode != null) {
300
+ const attributeScope = context.sourceCode.getScope(attributeNode);
301
+ const attributeValue = JSX__namespace.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
302
+ if (attributeValue.kind === "some" && hasValidSandBox(attributeValue.value)) return;
303
+ context.report({
304
+ messageId: "noMissingIframeSandbox",
305
+ node: attributeNode
306
+ });
307
+ return;
308
+ }
309
+ if (!hasValidSandBox(customComponentProp?.defaultValue)) {
310
+ context.report({
311
+ messageId: "noMissingIframeSandbox",
312
+ node
313
+ });
314
+ }
294
315
  }
295
316
  };
296
317
  },
@@ -315,14 +336,14 @@ var no_namespace_default = createRule({
315
336
  name: RULE_NAME6,
316
337
  create(context) {
317
338
  return {
318
- JSXOpeningElement(node) {
319
- const name2 = JSX3__namespace.getElementName(node);
339
+ JSXElement(node) {
340
+ const name2 = JSX__namespace.getElementName(node);
320
341
  if (typeof name2 !== "string" || !name2.includes(":")) {
321
342
  return;
322
343
  }
323
344
  context.report({
324
345
  messageId: "noNamespace",
325
- node,
346
+ node: node.openingElement.name,
326
347
  data: {
327
348
  name: name2
328
349
  }
@@ -409,10 +430,10 @@ var no_script_url_default = createRule({
409
430
  return;
410
431
  }
411
432
  const attributeScope = context.sourceCode.getScope(node);
412
- const attributeValue = JSX3__namespace.getAttributeStaticValue(node, attributeScope);
413
- const attributeValueResolved = VAR__namespace.toResolved(attributeValue).value;
414
- if (typeof attributeValueResolved !== "string") return;
415
- if (shared.RE_JAVASCRIPT_PROTOCOL.test(attributeValueResolved)) {
433
+ const attributeName = JSX__namespace.getAttributeName(node);
434
+ const attributeValue = JSX__namespace.getAttributeValue(node, attributeName, attributeScope);
435
+ if (attributeValue.kind === "none" || typeof attributeValue.value !== "string") return;
436
+ if (shared.RE_JAVASCRIPT_PROTOCOL.test(attributeValue.value)) {
416
437
  context.report({
417
438
  messageId: "noScriptUrl",
418
439
  node: node.value
@@ -1484,9 +1505,15 @@ var RULE_NAME10 = "no-unsafe-iframe-sandbox";
1484
1505
  var RULE_FEATURES9 = [
1485
1506
  "CHK"
1486
1507
  ];
1487
- var unsafeCombinations = [
1508
+ var unsafeSandboxValues = [
1488
1509
  ["allow-scripts", "allow-same-origin"]
1489
1510
  ];
1511
+ function hasSafeSandbox(value) {
1512
+ if (typeof value !== "string") return false;
1513
+ return !unsafeSandboxValues.some((values) => {
1514
+ return values.every((v) => value.includes(v));
1515
+ });
1516
+ }
1490
1517
  var no_unsafe_iframe_sandbox_default = createRule({
1491
1518
  meta: {
1492
1519
  type: "problem",
@@ -1506,25 +1533,40 @@ var no_unsafe_iframe_sandbox_default = createRule({
1506
1533
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
1507
1534
  return {
1508
1535
  JSXElement(node) {
1509
- const [elementNameOnJsx, elementNameOnHtml] = core.getElementNameOnJsxAndHtml(
1510
- node.openingElement,
1536
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
1537
+ node,
1511
1538
  context,
1512
1539
  polymorphicPropName,
1513
1540
  additionalComponents
1514
1541
  );
1515
- if (elementNameOnHtml !== "iframe") return;
1516
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
1517
- "sandbox",
1518
- node,
1519
- context,
1520
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
1542
+ if (elementNameOnDom !== "iframe") return;
1543
+ const elementScope = context.sourceCode.getScope(node);
1544
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
1545
+ const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
1546
+ const propNameOnJsx = customComponentProp?.name ?? "sandbox";
1547
+ const attributeNode = JSX__namespace.getAttribute(
1548
+ propNameOnJsx,
1549
+ node.openingElement.attributes,
1550
+ elementScope
1521
1551
  );
1522
- if (attributeValue == null) return;
1523
- if (!unsafeCombinations.some((c) => c.every((v) => attributeValue.includes(v)))) return;
1524
- context.report({
1525
- messageId: "noUnsafeIframeSandbox",
1526
- node: attributeNode ?? node.openingElement
1527
- });
1552
+ if (attributeNode != null) {
1553
+ const attributeScope = context.sourceCode.getScope(attributeNode);
1554
+ const attributeValue = JSX__namespace.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
1555
+ if (attributeValue.kind === "some" && !hasSafeSandbox(attributeValue.value)) {
1556
+ context.report({
1557
+ messageId: "noUnsafeIframeSandbox",
1558
+ node: attributeNode
1559
+ });
1560
+ return;
1561
+ }
1562
+ }
1563
+ if (customComponentProp?.defaultValue == null) return;
1564
+ if (!hasSafeSandbox(customComponentProp.defaultValue)) {
1565
+ context.report({
1566
+ messageId: "noUnsafeIframeSandbox",
1567
+ node
1568
+ });
1569
+ }
1528
1570
  }
1529
1571
  };
1530
1572
  },
@@ -1561,28 +1603,38 @@ var no_unsafe_target_blank_default = createRule({
1561
1603
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
1562
1604
  return {
1563
1605
  JSXElement(node) {
1564
- const [elementNameOnJsx, elementNameOnHtml] = core.getElementNameOnJsxAndHtml(
1565
- node.openingElement,
1606
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
1607
+ node,
1566
1608
  context,
1567
1609
  polymorphicPropName,
1568
1610
  additionalComponents
1569
1611
  );
1570
- if (elementNameOnHtml !== "a") return;
1571
- const getAttributeValue = (name2) => {
1572
- return getAttributeNodeAndStringValue(
1573
- name2,
1574
- node,
1575
- context,
1576
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
1577
- ).attributeValue;
1612
+ if (elementNameOnDom !== "a") return;
1613
+ const elementScope = context.sourceCode.getScope(node);
1614
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
1615
+ const getAttributeStringValue = (name2) => {
1616
+ const customComponentProp = findCustomComponentProp(name2, customComponent?.attributes ?? []);
1617
+ const propNameOnJsx = customComponentProp?.name ?? name2;
1618
+ const attributeNode = JSX__namespace.getAttribute(
1619
+ propNameOnJsx,
1620
+ node.openingElement.attributes,
1621
+ elementScope
1622
+ );
1623
+ if (attributeNode == null) return customComponentProp?.defaultValue;
1624
+ const attributeScope = context.sourceCode.getScope(attributeNode);
1625
+ const attributeValue = JSX__namespace.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
1626
+ if (attributeValue.kind === "some" && typeof attributeValue.value === "string") {
1627
+ return attributeValue.value;
1628
+ }
1629
+ return eff._;
1578
1630
  };
1579
- if (getAttributeValue("target") !== "_blank") {
1631
+ if (getAttributeStringValue("target") !== "_blank") {
1580
1632
  return;
1581
1633
  }
1582
- if (!isExternalLinkLike(getAttributeValue("href"))) {
1634
+ if (!isExternalLinkLike(getAttributeStringValue("href"))) {
1583
1635
  return;
1584
1636
  }
1585
- if (isSafeRel(getAttributeValue("rel"))) {
1637
+ if (isSafeRel(getAttributeStringValue("rel"))) {
1586
1638
  return;
1587
1639
  }
1588
1640
  context.report({
@@ -1632,7 +1684,7 @@ var no_void_elements_with_children_default = createRule({
1632
1684
  create(context) {
1633
1685
  return {
1634
1686
  JSXElement(node) {
1635
- const elementName = JSX3__namespace.getElementName(node.openingElement);
1687
+ const elementName = JSX__namespace.getElementName(node);
1636
1688
  if (elementName.length === 0 || !voidElements.has(elementName)) {
1637
1689
  return;
1638
1690
  }
@@ -1647,7 +1699,7 @@ var no_void_elements_with_children_default = createRule({
1647
1699
  }
1648
1700
  const { attributes } = node.openingElement;
1649
1701
  const initialScope = context.sourceCode.getScope(node);
1650
- const hasAttribute3 = (name2) => JSX3__namespace.hasAttribute(name2, initialScope, attributes);
1702
+ const hasAttribute3 = (name2) => JSX__namespace.hasAttribute(name2, attributes, initialScope);
1651
1703
  if (hasAttribute3("children") || hasAttribute3("dangerouslySetInnerHTML")) {
1652
1704
  context.report({
1653
1705
  messageId: "noVoidElementsWithChildren",
package/dist/index.mjs CHANGED
@@ -1,49 +1,41 @@
1
- import * as JSX3 from '@eslint-react/jsx';
2
- import { _ } from '@eslint-react/eff';
1
+ import * as JSX from '@eslint-react/jsx';
3
2
  import { createRuleForPlugin, getSettingsFromContext, RE_JAVASCRIPT_PROTOCOL } from '@eslint-react/shared';
4
3
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
5
- import { getElementNameOnJsxAndHtml } from '@eslint-react/core';
6
4
  import * as AST from '@eslint-react/ast';
7
- import * as VAR from '@eslint-react/var';
8
5
  import { compare } from 'compare-versions';
6
+ import { _ } from '@eslint-react/eff';
9
7
 
10
8
  // package.json
11
9
  var name = "eslint-plugin-react-dom";
12
- var version = "1.24.0-next.9";
13
- function getAdditionalAttributes(componentName, additionalComponents) {
14
- return additionalComponents.findLast((c) => c.name === componentName || c.re.test(componentName))?.attributes ?? [];
10
+ var version = "1.24.0";
11
+ var createRule = createRuleForPlugin("dom");
12
+
13
+ // src/utils/find-custom-component.ts
14
+ function findCustomComponent(name2, components) {
15
+ return components.findLast((c) => c.name === name2 || c.re.test(name2));
15
16
  }
16
- function getAttributeMetaData(name2, attributes) {
17
- const settings = attributes.findLast((a) => a.as === name2);
18
- return {
19
- name: settings?.name ?? name2,
20
- controlled: settings?.controlled ?? false,
21
- defaultValue: settings?.defaultValue
22
- };
17
+ function findCustomComponentProp(name2, props) {
18
+ return props.findLast((a) => a.as === name2);
23
19
  }
24
- function getAttributeNodeAndStringValue(name2, element, context, additionalAttributes) {
25
- const attributeMetaData = getAttributeMetaData(name2, additionalAttributes);
26
- const attributeNameOnElement = attributeMetaData.name;
27
- const attributeNode = JSX3.getAttributeNode(
28
- attributeNameOnElement,
29
- context.sourceCode.getScope(element),
30
- element.openingElement.attributes
20
+ function getElementNameOnJsxAndDom(node, context, polymorphicPropName, additionalComponents = []) {
21
+ const name2 = JSX.getElementName(node);
22
+ if (name2 === name2.toLowerCase()) return [name2, name2];
23
+ const component = additionalComponents.findLast((c) => c.name === name2 || c.re.test(name2));
24
+ if (component != null) return [name2, component.as];
25
+ if (polymorphicPropName == null) return [name2, name2];
26
+ const initialScope = context.sourceCode.getScope(node);
27
+ const attributeNode = JSX.getAttribute(
28
+ polymorphicPropName,
29
+ node.openingElement.attributes,
30
+ initialScope
31
31
  );
32
- if (attributeNode == null) {
33
- return {
34
- attributeNode: _,
35
- attributeValue: attributeMetaData.defaultValue
36
- };
32
+ if (attributeNode == null) return [name2, name2];
33
+ const polymorphicPropValue = JSX.getAttributeValue(attributeNode, polymorphicPropName, initialScope);
34
+ if (polymorphicPropValue.kind === "some" && typeof polymorphicPropValue.value === "string") {
35
+ return [name2, polymorphicPropValue.value];
37
36
  }
38
- const attributeScope = context.sourceCode.getScope(attributeNode);
39
- const attributeValue = JSX3.getAttributeStringValue(
40
- attributeNameOnElement,
41
- attributeNode,
42
- attributeScope
43
- );
44
- return { attributeNode, attributeValue };
37
+ return [name2, name2];
45
38
  }
46
- var createRule = createRuleForPlugin("dom");
47
39
 
48
40
  // src/rules/no-dangerously-set-innerhtml.ts
49
41
  var RULE_NAME = "no-dangerously-set-innerhtml";
@@ -68,10 +60,10 @@ var no_dangerously_set_innerhtml_default = createRule({
68
60
  return {
69
61
  JSXElement(node) {
70
62
  const attributes = node.openingElement.attributes;
71
- const attribute = JSX3.getAttributeNode(
63
+ const attribute = JSX.getAttribute(
72
64
  "dangerouslySetInnerHTML",
73
- context.sourceCode.getScope(node),
74
- attributes
65
+ attributes,
66
+ context.sourceCode.getScope(node)
75
67
  );
76
68
  if (attribute == null) return;
77
69
  context.report({
@@ -106,8 +98,8 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
106
98
  JSXElement(node) {
107
99
  const attributes = node.openingElement.attributes;
108
100
  const initialScope = context.sourceCode.getScope(node);
109
- const hasChildren = hasChildrenWithin(node) || JSX3.hasAttribute("children", initialScope, attributes);
110
- if (hasChildren && JSX3.hasAttribute("dangerouslySetInnerHTML", initialScope, attributes)) {
101
+ const hasChildren = hasChildrenWithin(node) || JSX.hasAttribute("children", attributes, initialScope);
102
+ if (hasChildren && JSX.hasAttribute("dangerouslySetInnerHTML", attributes, initialScope)) {
111
103
  context.report({
112
104
  messageId: "noDangerouslySetInnerhtmlWithChildren",
113
105
  node
@@ -119,7 +111,7 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
119
111
  defaultOptions: []
120
112
  });
121
113
  function hasChildrenWithin(node) {
122
- return node.children.length > 0 && node.children[0] != null && !JSX3.isLineBreak(node.children[0]);
114
+ return node.children.length > 0 && node.children[0] != null && !JSX.isLineBreak(node.children[0]);
123
115
  }
124
116
  var RULE_NAME3 = "no-find-dom-node";
125
117
  var RULE_FEATURES3 = [
@@ -183,23 +175,37 @@ var no_missing_button_type_default = createRule({
183
175
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "button");
184
176
  return {
185
177
  JSXElement(node) {
186
- const [elementNameOnJsx, elementNameOnHtml] = getElementNameOnJsxAndHtml(
187
- node.openingElement,
178
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
179
+ node,
188
180
  context,
189
181
  polymorphicPropName,
190
182
  additionalComponents
191
183
  );
192
- if (elementNameOnHtml !== "button") return;
193
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
194
- "type",
195
- node,
196
- context,
197
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
184
+ if (elementNameOnDom !== "button") return;
185
+ const elementScope = context.sourceCode.getScope(node);
186
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
187
+ const customComponentProp = findCustomComponentProp("type", customComponent?.attributes ?? []);
188
+ const propNameOnJsx = customComponentProp?.name ?? "type";
189
+ const attributeNode = JSX.getAttribute(
190
+ propNameOnJsx,
191
+ node.openingElement.attributes,
192
+ elementScope
198
193
  );
199
- if (typeof attributeValue !== "string") {
194
+ if (attributeNode != null) {
195
+ const attributeScope = context.sourceCode.getScope(attributeNode);
196
+ const attributeValue = JSX.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
197
+ if (attributeValue.kind === "some" && typeof attributeValue.value !== "string") {
198
+ context.report({
199
+ messageId: "noMissingButtonType",
200
+ node: attributeNode
201
+ });
202
+ }
203
+ return;
204
+ }
205
+ if (typeof customComponentProp?.defaultValue !== "string") {
200
206
  context.report({
201
207
  messageId: "noMissingButtonType",
202
- node: attributeNode ?? node
208
+ node
203
209
  });
204
210
  }
205
211
  }
@@ -229,6 +235,9 @@ var validTypes = [
229
235
  "allow-top-navigation-by-user-activation",
230
236
  "allow-top-navigation-to-custom-protocols"
231
237
  ];
238
+ function hasValidSandBox(value) {
239
+ return typeof value === "string" && value.split(" ").every((value2) => validTypes.some((valid) => valid === value2));
240
+ }
232
241
  var no_missing_iframe_sandbox_default = createRule({
233
242
  meta: {
234
243
  type: "problem",
@@ -248,25 +257,38 @@ var no_missing_iframe_sandbox_default = createRule({
248
257
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
249
258
  return {
250
259
  JSXElement(node) {
251
- const [elementNameOnJsx, elementNameOnHtml] = getElementNameOnJsxAndHtml(
252
- node.openingElement,
260
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
261
+ node,
253
262
  context,
254
263
  polymorphicPropName,
255
264
  additionalComponents
256
265
  );
257
- if (elementNameOnHtml !== "iframe") return;
258
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
259
- "sandbox",
260
- node,
261
- context,
262
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
266
+ if (elementNameOnDom !== "iframe") return;
267
+ const elementScope = context.sourceCode.getScope(node);
268
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
269
+ const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
270
+ const propNameOnJsx = customComponentProp?.name ?? "sandbox";
271
+ const attributeNode = JSX.getAttribute(
272
+ propNameOnJsx,
273
+ node.openingElement.attributes,
274
+ elementScope
263
275
  );
264
- const hasValidSandboxValue = typeof attributeValue === "string" && attributeValue.split(" ").every((value) => validTypes.some((valid) => valid === value));
265
- if (hasValidSandboxValue) return;
266
- context.report({
267
- messageId: "noMissingIframeSandbox",
268
- node: attributeNode ?? node.openingElement
269
- });
276
+ if (attributeNode != null) {
277
+ const attributeScope = context.sourceCode.getScope(attributeNode);
278
+ const attributeValue = JSX.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
279
+ if (attributeValue.kind === "some" && hasValidSandBox(attributeValue.value)) return;
280
+ context.report({
281
+ messageId: "noMissingIframeSandbox",
282
+ node: attributeNode
283
+ });
284
+ return;
285
+ }
286
+ if (!hasValidSandBox(customComponentProp?.defaultValue)) {
287
+ context.report({
288
+ messageId: "noMissingIframeSandbox",
289
+ node
290
+ });
291
+ }
270
292
  }
271
293
  };
272
294
  },
@@ -291,14 +313,14 @@ var no_namespace_default = createRule({
291
313
  name: RULE_NAME6,
292
314
  create(context) {
293
315
  return {
294
- JSXOpeningElement(node) {
295
- const name2 = JSX3.getElementName(node);
316
+ JSXElement(node) {
317
+ const name2 = JSX.getElementName(node);
296
318
  if (typeof name2 !== "string" || !name2.includes(":")) {
297
319
  return;
298
320
  }
299
321
  context.report({
300
322
  messageId: "noNamespace",
301
- node,
323
+ node: node.openingElement.name,
302
324
  data: {
303
325
  name: name2
304
326
  }
@@ -385,10 +407,10 @@ var no_script_url_default = createRule({
385
407
  return;
386
408
  }
387
409
  const attributeScope = context.sourceCode.getScope(node);
388
- const attributeValue = JSX3.getAttributeStaticValue(node, attributeScope);
389
- const attributeValueResolved = VAR.toResolved(attributeValue).value;
390
- if (typeof attributeValueResolved !== "string") return;
391
- if (RE_JAVASCRIPT_PROTOCOL.test(attributeValueResolved)) {
410
+ const attributeName = JSX.getAttributeName(node);
411
+ const attributeValue = JSX.getAttributeValue(node, attributeName, attributeScope);
412
+ if (attributeValue.kind === "none" || typeof attributeValue.value !== "string") return;
413
+ if (RE_JAVASCRIPT_PROTOCOL.test(attributeValue.value)) {
392
414
  context.report({
393
415
  messageId: "noScriptUrl",
394
416
  node: node.value
@@ -1460,9 +1482,15 @@ var RULE_NAME10 = "no-unsafe-iframe-sandbox";
1460
1482
  var RULE_FEATURES9 = [
1461
1483
  "CHK"
1462
1484
  ];
1463
- var unsafeCombinations = [
1485
+ var unsafeSandboxValues = [
1464
1486
  ["allow-scripts", "allow-same-origin"]
1465
1487
  ];
1488
+ function hasSafeSandbox(value) {
1489
+ if (typeof value !== "string") return false;
1490
+ return !unsafeSandboxValues.some((values) => {
1491
+ return values.every((v) => value.includes(v));
1492
+ });
1493
+ }
1466
1494
  var no_unsafe_iframe_sandbox_default = createRule({
1467
1495
  meta: {
1468
1496
  type: "problem",
@@ -1482,25 +1510,40 @@ var no_unsafe_iframe_sandbox_default = createRule({
1482
1510
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "iframe");
1483
1511
  return {
1484
1512
  JSXElement(node) {
1485
- const [elementNameOnJsx, elementNameOnHtml] = getElementNameOnJsxAndHtml(
1486
- node.openingElement,
1513
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
1514
+ node,
1487
1515
  context,
1488
1516
  polymorphicPropName,
1489
1517
  additionalComponents
1490
1518
  );
1491
- if (elementNameOnHtml !== "iframe") return;
1492
- const { attributeNode, attributeValue } = getAttributeNodeAndStringValue(
1493
- "sandbox",
1494
- node,
1495
- context,
1496
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
1519
+ if (elementNameOnDom !== "iframe") return;
1520
+ const elementScope = context.sourceCode.getScope(node);
1521
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
1522
+ const customComponentProp = findCustomComponentProp("sandbox", customComponent?.attributes ?? []);
1523
+ const propNameOnJsx = customComponentProp?.name ?? "sandbox";
1524
+ const attributeNode = JSX.getAttribute(
1525
+ propNameOnJsx,
1526
+ node.openingElement.attributes,
1527
+ elementScope
1497
1528
  );
1498
- if (attributeValue == null) return;
1499
- if (!unsafeCombinations.some((c) => c.every((v) => attributeValue.includes(v)))) return;
1500
- context.report({
1501
- messageId: "noUnsafeIframeSandbox",
1502
- node: attributeNode ?? node.openingElement
1503
- });
1529
+ if (attributeNode != null) {
1530
+ const attributeScope = context.sourceCode.getScope(attributeNode);
1531
+ const attributeValue = JSX.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
1532
+ if (attributeValue.kind === "some" && !hasSafeSandbox(attributeValue.value)) {
1533
+ context.report({
1534
+ messageId: "noUnsafeIframeSandbox",
1535
+ node: attributeNode
1536
+ });
1537
+ return;
1538
+ }
1539
+ }
1540
+ if (customComponentProp?.defaultValue == null) return;
1541
+ if (!hasSafeSandbox(customComponentProp.defaultValue)) {
1542
+ context.report({
1543
+ messageId: "noUnsafeIframeSandbox",
1544
+ node
1545
+ });
1546
+ }
1504
1547
  }
1505
1548
  };
1506
1549
  },
@@ -1537,28 +1580,38 @@ var no_unsafe_target_blank_default = createRule({
1537
1580
  const additionalComponents = settings.additionalComponents.filter((c) => c.as === "a");
1538
1581
  return {
1539
1582
  JSXElement(node) {
1540
- const [elementNameOnJsx, elementNameOnHtml] = getElementNameOnJsxAndHtml(
1541
- node.openingElement,
1583
+ const [elementNameOnJsx, elementNameOnDom] = getElementNameOnJsxAndDom(
1584
+ node,
1542
1585
  context,
1543
1586
  polymorphicPropName,
1544
1587
  additionalComponents
1545
1588
  );
1546
- if (elementNameOnHtml !== "a") return;
1547
- const getAttributeValue = (name2) => {
1548
- return getAttributeNodeAndStringValue(
1549
- name2,
1550
- node,
1551
- context,
1552
- getAdditionalAttributes(elementNameOnJsx, additionalComponents)
1553
- ).attributeValue;
1589
+ if (elementNameOnDom !== "a") return;
1590
+ const elementScope = context.sourceCode.getScope(node);
1591
+ const customComponent = findCustomComponent(elementNameOnJsx, additionalComponents);
1592
+ const getAttributeStringValue = (name2) => {
1593
+ const customComponentProp = findCustomComponentProp(name2, customComponent?.attributes ?? []);
1594
+ const propNameOnJsx = customComponentProp?.name ?? name2;
1595
+ const attributeNode = JSX.getAttribute(
1596
+ propNameOnJsx,
1597
+ node.openingElement.attributes,
1598
+ elementScope
1599
+ );
1600
+ if (attributeNode == null) return customComponentProp?.defaultValue;
1601
+ const attributeScope = context.sourceCode.getScope(attributeNode);
1602
+ const attributeValue = JSX.getAttributeValue(attributeNode, propNameOnJsx, attributeScope);
1603
+ if (attributeValue.kind === "some" && typeof attributeValue.value === "string") {
1604
+ return attributeValue.value;
1605
+ }
1606
+ return _;
1554
1607
  };
1555
- if (getAttributeValue("target") !== "_blank") {
1608
+ if (getAttributeStringValue("target") !== "_blank") {
1556
1609
  return;
1557
1610
  }
1558
- if (!isExternalLinkLike(getAttributeValue("href"))) {
1611
+ if (!isExternalLinkLike(getAttributeStringValue("href"))) {
1559
1612
  return;
1560
1613
  }
1561
- if (isSafeRel(getAttributeValue("rel"))) {
1614
+ if (isSafeRel(getAttributeStringValue("rel"))) {
1562
1615
  return;
1563
1616
  }
1564
1617
  context.report({
@@ -1608,7 +1661,7 @@ var no_void_elements_with_children_default = createRule({
1608
1661
  create(context) {
1609
1662
  return {
1610
1663
  JSXElement(node) {
1611
- const elementName = JSX3.getElementName(node.openingElement);
1664
+ const elementName = JSX.getElementName(node);
1612
1665
  if (elementName.length === 0 || !voidElements.has(elementName)) {
1613
1666
  return;
1614
1667
  }
@@ -1623,7 +1676,7 @@ var no_void_elements_with_children_default = createRule({
1623
1676
  }
1624
1677
  const { attributes } = node.openingElement;
1625
1678
  const initialScope = context.sourceCode.getScope(node);
1626
- const hasAttribute3 = (name2) => JSX3.hasAttribute(name2, initialScope, attributes);
1679
+ const hasAttribute3 = (name2) => JSX.hasAttribute(name2, attributes, initialScope);
1627
1680
  if (hasAttribute3("children") || hasAttribute3("dangerouslySetInnerHTML")) {
1628
1681
  context.report({
1629
1682
  messageId: "noVoidElementsWithChildren",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-dom",
3
- "version": "1.24.0-next.9",
3
+ "version": "1.24.0",
4
4
  "description": "ESLint React's ESLint plugin for React DOM related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -46,13 +46,13 @@
46
46
  "@typescript-eslint/utils": "^8.20.0",
47
47
  "compare-versions": "^6.1.1",
48
48
  "string-ts": "^2.2.0",
49
- "ts-pattern": "^5.6.0",
50
- "@eslint-react/ast": "1.24.0-next.9",
51
- "@eslint-react/core": "1.24.0-next.9",
52
- "@eslint-react/jsx": "1.24.0-next.9",
53
- "@eslint-react/eff": "1.24.0-next.9",
54
- "@eslint-react/var": "1.24.0-next.9",
55
- "@eslint-react/shared": "1.24.0-next.9"
49
+ "ts-pattern": "^5.6.1",
50
+ "@eslint-react/ast": "1.24.0",
51
+ "@eslint-react/core": "1.24.0",
52
+ "@eslint-react/eff": "1.24.0",
53
+ "@eslint-react/shared": "1.24.0",
54
+ "@eslint-react/jsx": "1.24.0",
55
+ "@eslint-react/var": "1.24.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/react": "^19.0.7",