eslint-plugin-react-web-api 1.26.3-next.5 → 1.26.3-next.7

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.mts CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- type MessageID$3 = "noLeakedTimeoutInEffect" | "noLeakedTimeoutInLifecycle" | "noLeakedTimeoutNoTimeoutId";
3
+ type MessageID$3 = "expectedClearTimeoutInCleanup" | "expectedClearTimeoutInUnmount" | "expectedTimeoutId";
4
4
 
5
- type MessageID$2 = "noLeakedResizeObserver" | "noLeakedResizeObserverInControlFlow" | "noLeakedResizeObserverNoFloatingInstance";
5
+ type MessageID$2 = "expectedDisconnectInControlFlow" | "expectedDisconnectOrUnobserveInCleanup" | "unexpectedFloatingInstance";
6
6
 
7
- type MessageID$1 = "noLeakedIntervalInEffect" | "noLeakedIntervalInLifecycle" | "noLeakedIntervalNoIntervalId";
7
+ type MessageID$1 = "expectedClearIntervalInCleanup" | "expectedClearIntervalInUnmount" | "expectedIntervalId";
8
8
 
9
- type MessageID = "noLeakedEventListenerInEffect" | "noLeakedEventListenerInLifecycle" | "noLeakedEventListenerOfInlineFunction";
9
+ type MessageID = "expectedRemoveEventListenerInCleanup" | "expectedRemoveEventListenerInUnmount" | "unexpectedInlineFunction";
10
10
 
11
11
  declare const _default: {
12
12
  meta: {
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- type MessageID$3 = "noLeakedTimeoutInEffect" | "noLeakedTimeoutInLifecycle" | "noLeakedTimeoutNoTimeoutId";
3
+ type MessageID$3 = "expectedClearTimeoutInCleanup" | "expectedClearTimeoutInUnmount" | "expectedTimeoutId";
4
4
 
5
- type MessageID$2 = "noLeakedResizeObserver" | "noLeakedResizeObserverInControlFlow" | "noLeakedResizeObserverNoFloatingInstance";
5
+ type MessageID$2 = "expectedDisconnectInControlFlow" | "expectedDisconnectOrUnobserveInCleanup" | "unexpectedFloatingInstance";
6
6
 
7
- type MessageID$1 = "noLeakedIntervalInEffect" | "noLeakedIntervalInLifecycle" | "noLeakedIntervalNoIntervalId";
7
+ type MessageID$1 = "expectedClearIntervalInCleanup" | "expectedClearIntervalInUnmount" | "expectedIntervalId";
8
8
 
9
- type MessageID = "noLeakedEventListenerInEffect" | "noLeakedEventListenerInLifecycle" | "noLeakedEventListenerOfInlineFunction";
9
+ type MessageID = "expectedRemoveEventListenerInCleanup" | "expectedRemoveEventListenerInUnmount" | "unexpectedInlineFunction";
10
10
 
11
11
  declare const _default: {
12
12
  meta: {
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var VAR2__namespace = /*#__PURE__*/_interopNamespace(VAR2);
32
32
 
33
33
  // package.json
34
34
  var name = "eslint-plugin-react-web-api";
35
- var version = "1.26.3-next.5";
35
+ var version = "1.26.3-next.7";
36
36
  var createRule = shared.createRuleForPlugin("web-api");
37
37
  function getInstanceID(node, prev) {
38
38
  switch (true) {
@@ -148,9 +148,9 @@ var no_leaked_event_listener_default = createRule({
148
148
  [Symbol.for("rule_features")]: RULE_FEATURES
149
149
  },
150
150
  messages: {
151
- noLeakedEventListenerInEffect: "An 'addEventListener' in '{{effectMethodKind}}' should have a corresponding 'removeEventListener' in its cleanup function.",
152
- noLeakedEventListenerInLifecycle: "An 'addEventListener' in 'componentDidMount' should have a corresponding 'removeEventListener' in 'componentWillUnmount' method.",
153
- noLeakedEventListenerOfInlineFunction: "A/an '{{eventMethodKind}}' should not have an inline listener function."
151
+ expectedRemoveEventListenerInCleanup: "An 'addEventListener' in '{{effectMethodKind}}' should have a corresponding 'removeEventListener' in its cleanup function.",
152
+ expectedRemoveEventListenerInUnmount: "An 'addEventListener' in 'componentDidMount' should have a corresponding 'removeEventListener' in 'componentWillUnmount' method.",
153
+ unexpectedInlineFunction: "A/an '{{eventMethodKind}}' should not have an inline listener function."
154
154
  },
155
155
  schema: []
156
156
  },
@@ -195,7 +195,7 @@ var no_leaked_event_listener_default = createRule({
195
195
  return;
196
196
  }
197
197
  context.report({
198
- messageId: "noLeakedEventListenerOfInlineFunction",
198
+ messageId: "unexpectedInlineFunction",
199
199
  node: listener,
200
200
  data: { eventMethodKind: callKind }
201
201
  });
@@ -267,7 +267,7 @@ var no_leaked_event_listener_default = createRule({
267
267
  case "setup":
268
268
  case "cleanup":
269
269
  context.report({
270
- messageId: "noLeakedEventListenerInEffect",
270
+ messageId: "expectedRemoveEventListenerInCleanup",
271
271
  node: aEntry.node,
272
272
  data: {
273
273
  effectMethodKind: "useEffect"
@@ -277,7 +277,7 @@ var no_leaked_event_listener_default = createRule({
277
277
  case "mount":
278
278
  case "unmount":
279
279
  context.report({
280
- messageId: "noLeakedEventListenerInLifecycle",
280
+ messageId: "expectedRemoveEventListenerInUnmount",
281
281
  node: aEntry.node
282
282
  });
283
283
  continue;
@@ -310,9 +310,9 @@ var no_leaked_interval_default = createRule({
310
310
  [Symbol.for("rule_features")]: RULE_FEATURES2
311
311
  },
312
312
  messages: {
313
- noLeakedIntervalInEffect: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the cleanup function.",
314
- noLeakedIntervalInLifecycle: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the 'componentWillUnmount' method.",
315
- noLeakedIntervalNoIntervalId: "A 'setInterval' must be assigned to a variable for proper cleanup."
313
+ expectedClearIntervalInCleanup: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the cleanup function.",
314
+ expectedClearIntervalInUnmount: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the 'componentWillUnmount' method.",
315
+ expectedIntervalId: "A 'setInterval' must be assigned to a variable for proper cleanup."
316
316
  },
317
317
  schema: []
318
318
  },
@@ -348,7 +348,7 @@ var no_leaked_interval_default = createRule({
348
348
  const intervalIdNode = VAR2__namespace.getVariableDeclaratorId(node);
349
349
  if (intervalIdNode == null) {
350
350
  context.report({
351
- messageId: "noLeakedIntervalNoIntervalId",
351
+ messageId: "expectedIntervalId",
352
352
  node
353
353
  });
354
354
  break;
@@ -394,7 +394,7 @@ var no_leaked_interval_default = createRule({
394
394
  case "setup":
395
395
  case "cleanup":
396
396
  context.report({
397
- messageId: "noLeakedIntervalInEffect",
397
+ messageId: "expectedClearIntervalInCleanup",
398
398
  node: sEntry.node,
399
399
  data: {
400
400
  kind: "useEffect"
@@ -404,7 +404,7 @@ var no_leaked_interval_default = createRule({
404
404
  case "mount":
405
405
  case "unmount":
406
406
  context.report({
407
- messageId: "noLeakedIntervalInLifecycle",
407
+ messageId: "expectedClearIntervalInUnmount",
408
408
  node: sEntry.node,
409
409
  data: {
410
410
  kind: "componentDidMount"
@@ -459,9 +459,9 @@ var no_leaked_resize_observer_default = createRule({
459
459
  [Symbol.for("rule_features")]: RULE_FEATURES3
460
460
  },
461
461
  messages: {
462
- noLeakedResizeObserver: "A 'ResizeObserver' instance created in 'useEffect' must be disconnected in the cleanup function.",
463
- noLeakedResizeObserverInControlFlow: "Dynamically added 'ResizeObserver.observe' should be cleared all at once using 'ResizeObserver.disconnect' in the cleanup function.",
464
- noLeakedResizeObserverNoFloatingInstance: "A 'ResizeObserver' instance created in component or custom Hook must be assigned to a variable for proper cleanup."
462
+ expectedDisconnectInControlFlow: "Dynamically added 'ResizeObserver.observe' should be cleared all at once using 'ResizeObserver.disconnect' in the cleanup function.",
463
+ expectedDisconnectOrUnobserveInCleanup: "A 'ResizeObserver' instance created in 'useEffect' must be disconnected in the cleanup function.",
464
+ unexpectedFloatingInstance: "A 'ResizeObserver' instance created in component or custom Hook must be assigned to a variable for proper cleanup."
465
465
  },
466
466
  schema: []
467
467
  },
@@ -543,7 +543,7 @@ var no_leaked_resize_observer_default = createRule({
543
543
  const id = getInstanceID(node);
544
544
  if (id == null) {
545
545
  context.report({
546
- messageId: "noLeakedResizeObserverNoFloatingInstance",
546
+ messageId: "unexpectedFloatingInstance",
547
547
  node
548
548
  });
549
549
  return;
@@ -566,14 +566,14 @@ var no_leaked_resize_observer_default = createRule({
566
566
  const isPhaseNode = (node2) => node2 === phaseNode;
567
567
  const hasDynamicallyAdded = oentries.some((e) => !isPhaseNode(AST2__namespace.findParentNode(e.node, eff.or(isDynamic, isPhaseNode))));
568
568
  if (hasDynamicallyAdded) {
569
- context.report({ messageId: "noLeakedResizeObserverInControlFlow", node });
569
+ context.report({ messageId: "expectedDisconnectInControlFlow", node });
570
570
  continue;
571
571
  }
572
572
  for (const oEntry of oentries) {
573
573
  if (uentries.some((uEntry) => isInstanceIDEqual(uEntry.element, oEntry.element, context))) {
574
574
  continue;
575
575
  }
576
- context.report({ messageId: "noLeakedResizeObserver", node: oEntry.node });
576
+ context.report({ messageId: "expectedDisconnectOrUnobserveInCleanup", node: oEntry.node });
577
577
  }
578
578
  }
579
579
  }
@@ -603,9 +603,9 @@ var no_leaked_timeout_default = createRule({
603
603
  [Symbol.for("rule_features")]: RULE_FEATURES4
604
604
  },
605
605
  messages: {
606
- noLeakedTimeoutInEffect: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the cleanup function.",
607
- noLeakedTimeoutInLifecycle: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the 'componentWillUnmount' method.",
608
- noLeakedTimeoutNoTimeoutId: "A 'setTimeout' must be assigned to a variable for proper cleanup."
606
+ expectedClearTimeoutInCleanup: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the cleanup function.",
607
+ expectedClearTimeoutInUnmount: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the 'componentWillUnmount' method.",
608
+ expectedTimeoutId: "A 'setTimeout' must be assigned to a variable for proper cleanup."
609
609
  },
610
610
  schema: []
611
611
  },
@@ -638,7 +638,7 @@ var no_leaked_timeout_default = createRule({
638
638
  const timeoutIdNode = VAR2__namespace.getVariableDeclaratorId(node);
639
639
  if (timeoutIdNode == null) {
640
640
  context.report({
641
- messageId: "noLeakedTimeoutNoTimeoutId",
641
+ messageId: "expectedTimeoutId",
642
642
  node
643
643
  });
644
644
  break;
@@ -677,7 +677,7 @@ var no_leaked_timeout_default = createRule({
677
677
  case "setup":
678
678
  case "cleanup":
679
679
  context.report({
680
- messageId: "noLeakedTimeoutInEffect",
680
+ messageId: "expectedClearTimeoutInCleanup",
681
681
  node: sEntry.node,
682
682
  data: {
683
683
  kind: "useEffect"
@@ -687,7 +687,7 @@ var no_leaked_timeout_default = createRule({
687
687
  case "mount":
688
688
  case "unmount":
689
689
  context.report({
690
- messageId: "noLeakedTimeoutInLifecycle",
690
+ messageId: "expectedClearTimeoutInUnmount",
691
691
  node: sEntry.node,
692
692
  data: {
693
693
  kind: "componentDidMount"
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import { AST_NODE_TYPES as AST_NODE_TYPES$1 } from '@typescript-eslint/types';
9
9
 
10
10
  // package.json
11
11
  var name = "eslint-plugin-react-web-api";
12
- var version = "1.26.3-next.5";
12
+ var version = "1.26.3-next.7";
13
13
  var createRule = createRuleForPlugin("web-api");
14
14
  function getInstanceID(node, prev) {
15
15
  switch (true) {
@@ -125,9 +125,9 @@ var no_leaked_event_listener_default = createRule({
125
125
  [Symbol.for("rule_features")]: RULE_FEATURES
126
126
  },
127
127
  messages: {
128
- noLeakedEventListenerInEffect: "An 'addEventListener' in '{{effectMethodKind}}' should have a corresponding 'removeEventListener' in its cleanup function.",
129
- noLeakedEventListenerInLifecycle: "An 'addEventListener' in 'componentDidMount' should have a corresponding 'removeEventListener' in 'componentWillUnmount' method.",
130
- noLeakedEventListenerOfInlineFunction: "A/an '{{eventMethodKind}}' should not have an inline listener function."
128
+ expectedRemoveEventListenerInCleanup: "An 'addEventListener' in '{{effectMethodKind}}' should have a corresponding 'removeEventListener' in its cleanup function.",
129
+ expectedRemoveEventListenerInUnmount: "An 'addEventListener' in 'componentDidMount' should have a corresponding 'removeEventListener' in 'componentWillUnmount' method.",
130
+ unexpectedInlineFunction: "A/an '{{eventMethodKind}}' should not have an inline listener function."
131
131
  },
132
132
  schema: []
133
133
  },
@@ -172,7 +172,7 @@ var no_leaked_event_listener_default = createRule({
172
172
  return;
173
173
  }
174
174
  context.report({
175
- messageId: "noLeakedEventListenerOfInlineFunction",
175
+ messageId: "unexpectedInlineFunction",
176
176
  node: listener,
177
177
  data: { eventMethodKind: callKind }
178
178
  });
@@ -244,7 +244,7 @@ var no_leaked_event_listener_default = createRule({
244
244
  case "setup":
245
245
  case "cleanup":
246
246
  context.report({
247
- messageId: "noLeakedEventListenerInEffect",
247
+ messageId: "expectedRemoveEventListenerInCleanup",
248
248
  node: aEntry.node,
249
249
  data: {
250
250
  effectMethodKind: "useEffect"
@@ -254,7 +254,7 @@ var no_leaked_event_listener_default = createRule({
254
254
  case "mount":
255
255
  case "unmount":
256
256
  context.report({
257
- messageId: "noLeakedEventListenerInLifecycle",
257
+ messageId: "expectedRemoveEventListenerInUnmount",
258
258
  node: aEntry.node
259
259
  });
260
260
  continue;
@@ -287,9 +287,9 @@ var no_leaked_interval_default = createRule({
287
287
  [Symbol.for("rule_features")]: RULE_FEATURES2
288
288
  },
289
289
  messages: {
290
- noLeakedIntervalInEffect: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the cleanup function.",
291
- noLeakedIntervalInLifecycle: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the 'componentWillUnmount' method.",
292
- noLeakedIntervalNoIntervalId: "A 'setInterval' must be assigned to a variable for proper cleanup."
290
+ expectedClearIntervalInCleanup: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the cleanup function.",
291
+ expectedClearIntervalInUnmount: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the 'componentWillUnmount' method.",
292
+ expectedIntervalId: "A 'setInterval' must be assigned to a variable for proper cleanup."
293
293
  },
294
294
  schema: []
295
295
  },
@@ -325,7 +325,7 @@ var no_leaked_interval_default = createRule({
325
325
  const intervalIdNode = VAR2.getVariableDeclaratorId(node);
326
326
  if (intervalIdNode == null) {
327
327
  context.report({
328
- messageId: "noLeakedIntervalNoIntervalId",
328
+ messageId: "expectedIntervalId",
329
329
  node
330
330
  });
331
331
  break;
@@ -371,7 +371,7 @@ var no_leaked_interval_default = createRule({
371
371
  case "setup":
372
372
  case "cleanup":
373
373
  context.report({
374
- messageId: "noLeakedIntervalInEffect",
374
+ messageId: "expectedClearIntervalInCleanup",
375
375
  node: sEntry.node,
376
376
  data: {
377
377
  kind: "useEffect"
@@ -381,7 +381,7 @@ var no_leaked_interval_default = createRule({
381
381
  case "mount":
382
382
  case "unmount":
383
383
  context.report({
384
- messageId: "noLeakedIntervalInLifecycle",
384
+ messageId: "expectedClearIntervalInUnmount",
385
385
  node: sEntry.node,
386
386
  data: {
387
387
  kind: "componentDidMount"
@@ -436,9 +436,9 @@ var no_leaked_resize_observer_default = createRule({
436
436
  [Symbol.for("rule_features")]: RULE_FEATURES3
437
437
  },
438
438
  messages: {
439
- noLeakedResizeObserver: "A 'ResizeObserver' instance created in 'useEffect' must be disconnected in the cleanup function.",
440
- noLeakedResizeObserverInControlFlow: "Dynamically added 'ResizeObserver.observe' should be cleared all at once using 'ResizeObserver.disconnect' in the cleanup function.",
441
- noLeakedResizeObserverNoFloatingInstance: "A 'ResizeObserver' instance created in component or custom Hook must be assigned to a variable for proper cleanup."
439
+ expectedDisconnectInControlFlow: "Dynamically added 'ResizeObserver.observe' should be cleared all at once using 'ResizeObserver.disconnect' in the cleanup function.",
440
+ expectedDisconnectOrUnobserveInCleanup: "A 'ResizeObserver' instance created in 'useEffect' must be disconnected in the cleanup function.",
441
+ unexpectedFloatingInstance: "A 'ResizeObserver' instance created in component or custom Hook must be assigned to a variable for proper cleanup."
442
442
  },
443
443
  schema: []
444
444
  },
@@ -520,7 +520,7 @@ var no_leaked_resize_observer_default = createRule({
520
520
  const id = getInstanceID(node);
521
521
  if (id == null) {
522
522
  context.report({
523
- messageId: "noLeakedResizeObserverNoFloatingInstance",
523
+ messageId: "unexpectedFloatingInstance",
524
524
  node
525
525
  });
526
526
  return;
@@ -543,14 +543,14 @@ var no_leaked_resize_observer_default = createRule({
543
543
  const isPhaseNode = (node2) => node2 === phaseNode;
544
544
  const hasDynamicallyAdded = oentries.some((e) => !isPhaseNode(AST2.findParentNode(e.node, or(isDynamic, isPhaseNode))));
545
545
  if (hasDynamicallyAdded) {
546
- context.report({ messageId: "noLeakedResizeObserverInControlFlow", node });
546
+ context.report({ messageId: "expectedDisconnectInControlFlow", node });
547
547
  continue;
548
548
  }
549
549
  for (const oEntry of oentries) {
550
550
  if (uentries.some((uEntry) => isInstanceIDEqual(uEntry.element, oEntry.element, context))) {
551
551
  continue;
552
552
  }
553
- context.report({ messageId: "noLeakedResizeObserver", node: oEntry.node });
553
+ context.report({ messageId: "expectedDisconnectOrUnobserveInCleanup", node: oEntry.node });
554
554
  }
555
555
  }
556
556
  }
@@ -580,9 +580,9 @@ var no_leaked_timeout_default = createRule({
580
580
  [Symbol.for("rule_features")]: RULE_FEATURES4
581
581
  },
582
582
  messages: {
583
- noLeakedTimeoutInEffect: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the cleanup function.",
584
- noLeakedTimeoutInLifecycle: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the 'componentWillUnmount' method.",
585
- noLeakedTimeoutNoTimeoutId: "A 'setTimeout' must be assigned to a variable for proper cleanup."
583
+ expectedClearTimeoutInCleanup: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the cleanup function.",
584
+ expectedClearTimeoutInUnmount: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the 'componentWillUnmount' method.",
585
+ expectedTimeoutId: "A 'setTimeout' must be assigned to a variable for proper cleanup."
586
586
  },
587
587
  schema: []
588
588
  },
@@ -615,7 +615,7 @@ var no_leaked_timeout_default = createRule({
615
615
  const timeoutIdNode = VAR2.getVariableDeclaratorId(node);
616
616
  if (timeoutIdNode == null) {
617
617
  context.report({
618
- messageId: "noLeakedTimeoutNoTimeoutId",
618
+ messageId: "expectedTimeoutId",
619
619
  node
620
620
  });
621
621
  break;
@@ -654,7 +654,7 @@ var no_leaked_timeout_default = createRule({
654
654
  case "setup":
655
655
  case "cleanup":
656
656
  context.report({
657
- messageId: "noLeakedTimeoutInEffect",
657
+ messageId: "expectedClearTimeoutInCleanup",
658
658
  node: sEntry.node,
659
659
  data: {
660
660
  kind: "useEffect"
@@ -664,7 +664,7 @@ var no_leaked_timeout_default = createRule({
664
664
  case "mount":
665
665
  case "unmount":
666
666
  context.report({
667
- messageId: "noLeakedTimeoutInLifecycle",
667
+ messageId: "expectedClearTimeoutInUnmount",
668
668
  node: sEntry.node,
669
669
  data: {
670
670
  kind: "componentDidMount"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-web-api",
3
- "version": "1.26.3-next.5",
3
+ "version": "1.26.3-next.7",
4
4
  "description": "ESLint React's ESLint plugin for interacting with Web APIs",
5
5
  "keywords": [
6
6
  "react",
@@ -48,12 +48,12 @@
48
48
  "@typescript-eslint/utils": "^8.23.0",
49
49
  "string-ts": "^2.2.1",
50
50
  "ts-pattern": "^5.6.2",
51
- "@eslint-react/ast": "1.26.3-next.5",
52
- "@eslint-react/eff": "1.26.3-next.5",
53
- "@eslint-react/jsx": "1.26.3-next.5",
54
- "@eslint-react/shared": "1.26.3-next.5",
55
- "@eslint-react/core": "1.26.3-next.5",
56
- "@eslint-react/var": "1.26.3-next.5"
51
+ "@eslint-react/ast": "1.26.3-next.7",
52
+ "@eslint-react/core": "1.26.3-next.7",
53
+ "@eslint-react/eff": "1.26.3-next.7",
54
+ "@eslint-react/jsx": "1.26.3-next.7",
55
+ "@eslint-react/shared": "1.26.3-next.7",
56
+ "@eslint-react/var": "1.26.3-next.7"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/react": "^19.0.8",