@eslint-react/core 5.16.1 → 5.17.1

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.d.ts +130 -131
  2. package/dist/index.js +477 -130
  3. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -9,28 +9,124 @@ import { P, isMatching, match } from "ts-pattern";
9
9
 
10
10
  //#region ../../.pkgs/eff/dist/index.js
11
11
  /**
12
- * Creates a function that can be used in a data-last (aka `pipe`able) or
13
- * data-first style.
12
+ * Applies a `pipe` method's variadic arguments to an initial value from left
13
+ * to right.
14
14
  *
15
- * The first parameter to `dual` is either the arity of the uncurried function
16
- * or a predicate that determines if the function is being used in a data-first
17
- * or data-last style.
15
+ * **When to use**
18
16
  *
19
- * Using the arity is the most common use case, but there are some cases where
20
- * you may want to use a predicate. For example, if you have a function that
21
- * takes an optional argument, you can use a predicate to determine if the
22
- * function is being used in a data-first or data-last style.
17
+ * Use to implement a custom `.pipe(...)` method from JavaScript's `arguments`
18
+ * object.
23
19
  *
24
- * You can pass either the arity of the uncurried function or a predicate
25
- * which determines if the function is being used in a data-first or
26
- * data-last style.
20
+ * **Details**
27
21
  *
28
- * **Example** (Using arity to determine data-first or data-last style)
22
+ * This helper is intended for implementing `Pipeable.pipe` methods that
23
+ * receive JavaScript's `arguments` object. With no functions it returns the
24
+ * original value; otherwise it feeds each result into the next function.
25
+ *
26
+ * **Example** (Implementing a pipe method)
29
27
  *
30
28
  * ```ts
31
- * import { dual, pipe } from "effect/Function"
29
+ * import { Pipeable } from "effect"
30
+ *
31
+ * class NumberBox {
32
+ * constructor(readonly value: number) {}
33
+ *
34
+ * pipe(..._fns: ReadonlyArray<(value: number) => number>): number {
35
+ * return Pipeable.pipeArguments(this.value, arguments) as number
36
+ * }
37
+ * }
38
+ *
39
+ * const result = new NumberBox(5).pipe(
40
+ * (n) => n + 2,
41
+ * (n) => n * 3
42
+ * )
43
+ * console.log(result) // 21
44
+ * ```
45
+ *
46
+ * @category combinators
47
+ * @since 2.0.0
48
+ */
49
+ const pipeArguments = (self, args) => {
50
+ switch (args.length) {
51
+ case 0: return self;
52
+ case 1: return args[0](self);
53
+ case 2: return args[1](args[0](self));
54
+ case 3: return args[2](args[1](args[0](self)));
55
+ case 4: return args[3](args[2](args[1](args[0](self))));
56
+ case 5: return args[4](args[3](args[2](args[1](args[0](self)))));
57
+ case 6: return args[5](args[4](args[3](args[2](args[1](args[0](self))))));
58
+ case 7: return args[6](args[5](args[4](args[3](args[2](args[1](args[0](self)))))));
59
+ case 8: return args[7](args[6](args[5](args[4](args[3](args[2](args[1](args[0](self))))))));
60
+ case 9: return args[8](args[7](args[6](args[5](args[4](args[3](args[2](args[1](args[0](self)))))))));
61
+ default: {
62
+ let ret = self;
63
+ for (let i = 0, len = args.length; i < len; i++) ret = args[i](ret);
64
+ return ret;
65
+ }
66
+ }
67
+ };
68
+ /**
69
+ * Reusable prototype that implements `Pipeable.pipe`.
70
+ *
71
+ * **When to use**
32
72
  *
33
- * const sum = dual<
73
+ * Use when classes or object prototypes can reuse this value when they need the
74
+ * standard pipe implementation backed by `pipeArguments`.
75
+ *
76
+ * @category prototypes
77
+ * @since 3.15.0
78
+ */
79
+ const Prototype = { pipe() {
80
+ return pipeArguments(this, arguments);
81
+ } };
82
+ /**
83
+ * Provides a base constructor whose instances implement the standard `Pipeable.pipe`
84
+ * method.
85
+ *
86
+ * **When to use**
87
+ *
88
+ * Use when you need to define a class that supports Effect-style method
89
+ * chaining through `.pipe(...)`.
90
+ *
91
+ * @category constructors
92
+ * @since 3.15.0
93
+ */
94
+ const Class = (function() {
95
+ function PipeableBase() {}
96
+ PipeableBase.prototype = Prototype;
97
+ return PipeableBase;
98
+ })();
99
+ /**
100
+ * Provides small helpers for defining and reusing TypeScript functions.
101
+ *
102
+ * The main helpers are `pipe` and `flow` for left-to-right composition and
103
+ * `dual` for APIs that support both direct and pipe-friendly call styles. The
104
+ * module also contains small identity, constant, tuple, type-level, and
105
+ * memoization helpers used across the library.
106
+ *
107
+ * @since 2.0.0
108
+ */
109
+ /**
110
+ * Creates a function that can be called in data-first style or data-last
111
+ * (`pipe`-friendly) style.
112
+ *
113
+ * **When to use**
114
+ *
115
+ * Use to expose one implementation through both direct and `pipe`-friendly
116
+ * call styles.
117
+ *
118
+ * **Details**
119
+ *
120
+ * Pass either the arity of the uncurried function or a predicate that decides
121
+ * whether the current call is data-first. Arity is the common case. Use a
122
+ * predicate when optional arguments make arity ambiguous.
123
+ *
124
+ * **Example** (Selecting data-first or data-last style by arity)
125
+ *
126
+ * ```ts
127
+ * import { Function, pipe } from "effect"
128
+ *
129
+ * const sum = Function.dual<
34
130
  * (that: number) => (self: number) => number,
35
131
  * (self: number, that: number) => number
36
132
  * >(2, (self, that) => self + that)
@@ -39,26 +135,26 @@ import { P, isMatching, match } from "ts-pattern";
39
135
  * console.log(pipe(2, sum(3))) // 5
40
136
  * ```
41
137
  *
42
- * **Example** (Using call signatures to define the overloads)
138
+ * **Example** (Defining overloads with call signatures)
43
139
  *
44
140
  * ```ts
45
- * import { dual, pipe } from "effect/Function"
141
+ * import { Function, pipe } from "effect"
46
142
  *
47
143
  * const sum: {
48
144
  * (that: number): (self: number) => number
49
145
  * (self: number, that: number): number
50
- * } = dual(2, (self: number, that: number): number => self + that)
146
+ * } = Function.dual(2, (self: number, that: number): number => self + that)
51
147
  *
52
148
  * console.log(sum(2, 3)) // 5
53
149
  * console.log(pipe(2, sum(3))) // 5
54
150
  * ```
55
151
  *
56
- * **Example** (Using a predicate to determine data-first or data-last style)
152
+ * **Example** (Selecting data-first or data-last style with a predicate)
57
153
  *
58
154
  * ```ts
59
- * import { dual, pipe } from "effect/Function"
155
+ * import { Function, pipe } from "effect"
60
156
  *
61
- * const sum = dual<
157
+ * const sum = Function.dual<
62
158
  * (that: number) => (self: number) => number,
63
159
  * (self: number, that: number) => number
64
160
  * >(
@@ -70,9 +166,8 @@ import { P, isMatching, match } from "ts-pattern";
70
166
  * console.log(pipe(2, sum(3))) // 5
71
167
  * ```
72
168
  *
73
- * @param arity - The arity of the uncurried function or a predicate that determines if the function is being used in a data-first or data-last style.
74
- * @param body - The function to be curried.
75
- * @since 1.0.0
169
+ * @category combinators
170
+ * @since 2.0.0
76
171
  */
77
172
  const dual = function(arity, body) {
78
173
  if (typeof arity === "function") return function() {
@@ -103,41 +198,294 @@ const dual = function(arity, body) {
103
198
  }
104
199
  };
105
200
  /**
106
- * Do nothing and return `false`.
201
+ * Returns its input argument unchanged.
202
+ *
203
+ * **When to use**
204
+ *
205
+ * Use to return a value unchanged where a function is required.
206
+ *
207
+ * **Example** (Returning the same value)
208
+ *
209
+ * ```ts
210
+ * import { identity } from "effect"
211
+ * import * as assert from "node:assert"
107
212
  *
108
- * @returns false
213
+ * assert.deepStrictEqual(identity(5), 5)
214
+ * ```
215
+ *
216
+ * @category combinators
217
+ * @since 2.0.0
109
218
  */
110
- function constFalse() {
111
- return false;
112
- }
219
+ const identity = (a) => a;
220
+ /**
221
+ * Returns the input value with a different static type.
222
+ *
223
+ * **When to use**
224
+ *
225
+ * Use when you need an explicit type-level cast and accept that the value is
226
+ * returned unchanged at runtime.
227
+ *
228
+ * **Gotchas**
229
+ *
230
+ * This is a type-level cast only; it performs no runtime validation or
231
+ * conversion.
232
+ *
233
+ * @see {@link satisfies} for checking assignability without changing the resulting type
234
+ *
235
+ * @category utility types
236
+ * @since 4.0.0
237
+ */
238
+ const cast = identity;
239
+ /**
240
+ * Creates a zero-argument function that always returns the provided value.
241
+ *
242
+ * **When to use**
243
+ *
244
+ * Use when you need a thunk or callback that returns the same value on every
245
+ * invocation.
246
+ *
247
+ * **Example** (Creating a constant thunk)
248
+ *
249
+ * ```ts
250
+ * import { Function } from "effect"
251
+ * import * as assert from "node:assert"
252
+ *
253
+ * const constNull = Function.constant(null)
254
+ *
255
+ * assert.deepStrictEqual(constNull(), null)
256
+ * assert.deepStrictEqual(constNull(), null)
257
+ * ```
258
+ *
259
+ * @category constructors
260
+ * @since 2.0.0
261
+ */
262
+ const constant = (value) => () => value;
263
+ /**
264
+ * Returns `true` when called.
265
+ *
266
+ * **When to use**
267
+ *
268
+ * Use when you need a thunk that returns `true` on every invocation.
269
+ *
270
+ * **Example** (Returning true from a thunk)
271
+ *
272
+ * ```ts
273
+ * import { Function } from "effect"
274
+ * import * as assert from "node:assert"
275
+ *
276
+ * assert.deepStrictEqual(Function.constTrue(), true)
277
+ * ```
278
+ *
279
+ * @category constants
280
+ * @since 2.0.0
281
+ */
282
+ const constTrue = constant(true);
283
+ /**
284
+ * Returns `false` when called.
285
+ *
286
+ * **When to use**
287
+ *
288
+ * Use when you need a thunk that returns `false` on every invocation.
289
+ *
290
+ * **Example** (Returning false from a thunk)
291
+ *
292
+ * ```ts
293
+ * import { Function } from "effect"
294
+ * import * as assert from "node:assert"
295
+ *
296
+ * assert.deepStrictEqual(Function.constFalse(), false)
297
+ * ```
298
+ *
299
+ * @category constants
300
+ * @since 2.0.0
301
+ */
302
+ const constFalse = constant(false);
303
+ /**
304
+ * Returns `null` when called.
305
+ *
306
+ * **When to use**
307
+ *
308
+ * Use when you need a thunk that returns `null` on every invocation.
309
+ *
310
+ * **Example** (Returning null from a thunk)
311
+ *
312
+ * ```ts
313
+ * import { Function } from "effect"
314
+ * import * as assert from "node:assert"
315
+ *
316
+ * assert.deepStrictEqual(Function.constNull(), null)
317
+ * ```
318
+ *
319
+ * @category constants
320
+ * @since 2.0.0
321
+ */
322
+ const constNull = constant(null);
323
+ /**
324
+ * Returns `undefined` when called.
325
+ *
326
+ * **When to use**
327
+ *
328
+ * Use when you need a thunk that returns `undefined` on every invocation.
329
+ *
330
+ * **Example** (Returning undefined from a thunk)
331
+ *
332
+ * ```ts
333
+ * import { Function } from "effect"
334
+ * import * as assert from "node:assert"
335
+ *
336
+ * assert.deepStrictEqual(Function.constUndefined(), undefined)
337
+ * ```
338
+ *
339
+ * @category constants
340
+ * @since 2.0.0
341
+ */
342
+ const constUndefined = constant(void 0);
113
343
  /**
114
344
  * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
115
345
  * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
116
346
  *
117
- * @param self - The first function to apply (or the composed function in data-last style).
118
- * @param bc - The second function to apply.
119
- * @returns A composed function that applies both functions in sequence.
120
- * @example
347
+ * **When to use**
348
+ *
349
+ * Use to compose exactly two unary functions into a reusable unary function.
350
+ *
351
+ * **Example** (Composing two functions)
352
+ *
121
353
  * ```ts
354
+ * import { Function } from "effect"
122
355
  * import * as assert from "node:assert"
123
- * import { compose } from "effect/Function"
124
356
  *
125
- * const increment = (n: number) => n + 1;
126
- * const square = (n: number) => n * n;
357
+ * const increment = (n: number) => n + 1
358
+ * const square = (n: number) => n * n
127
359
  *
128
- * assert.strictEqual(compose(increment, square)(2), 9);
360
+ * assert.strictEqual(Function.compose(increment, square)(2), 9)
129
361
  * ```
130
362
  *
131
- * @since 1.0.0
363
+ * @see {@link flow} for composing a left-to-right sequence of functions
364
+ * @see {@link pipe} for applying a value through a left-to-right sequence immediately
365
+ *
366
+ * @category combinators
367
+ * @since 2.0.0
132
368
  */
133
369
  const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
370
+ /**
371
+ * Marks an impossible branch by accepting a `never` value and returning any
372
+ * type.
373
+ *
374
+ * **When to use**
375
+ *
376
+ * Use when you need a return value in a branch that exhaustive checks prove
377
+ * cannot be reached.
378
+ *
379
+ * **Gotchas**
380
+ *
381
+ * Calling `absurd` throws, because a value of type `never` should be
382
+ * impossible at runtime.
383
+ *
384
+ * **Example** (Handling impossible values)
385
+ *
386
+ * ```ts
387
+ * import { absurd } from "effect"
388
+ *
389
+ * const handleNever = (value: never) => {
390
+ * return absurd(value) // This will throw an error if called
391
+ * }
392
+ * ```
393
+ *
394
+ * @category utility types
395
+ * @since 2.0.0
396
+ */
397
+ const absurd = (_) => {
398
+ throw new Error("Called `absurd` function which should be uncallable");
399
+ };
400
+ /**
401
+ * Creates a compile-time placeholder for a value of any type.
402
+ *
403
+ * **When to use**
404
+ *
405
+ * Use as a temporary typed placeholder while developing incomplete code.
406
+ *
407
+ * **Gotchas**
408
+ *
409
+ * `hole` is intended for temporary development use. If the placeholder is
410
+ * evaluated at runtime, it throws.
411
+ *
412
+ * **Example** (Creating a development placeholder)
413
+ *
414
+ * ```ts
415
+ * import { hole } from "effect"
416
+ *
417
+ * // Intentionally not called: `hole` throws if the placeholder is evaluated.
418
+ * const buildUser = (id: number): { readonly id: number; readonly name: string } => ({
419
+ * id,
420
+ * name: hole<string>()
421
+ * })
422
+ *
423
+ * console.log(typeof buildUser) // "function"
424
+ * ```
425
+ *
426
+ * @category utility types
427
+ * @since 2.0.0
428
+ */
429
+ const hole = cast(absurd);
430
+ /**
431
+ * Drops the longest prefix of elements from an array that satisfy the given predicate.
432
+ *
433
+ * Supports both data-first and data-last (`pipe`-friendly) call styles.
434
+ *
435
+ * @param pred - The predicate to test each element with.
436
+ * @returns A new array without the matching prefix.
437
+ * @example
438
+ * ```ts
439
+ * import * as assert from "node:assert"
440
+ * import { dropWhile, pipe } from "@local/eff"
441
+ *
442
+ * // data-first
443
+ * assert.deepStrictEqual(dropWhile([1, 2, 3, 2, 1], (n: number) => n < 3), [3, 2, 1])
444
+ *
445
+ * // data-last
446
+ * assert.deepStrictEqual(pipe([1, 2, 3, 2, 1], dropWhile((n: number) => n < 3)), [3, 2, 1])
447
+ * ```
448
+ * @category array
449
+ */
450
+ const dropWhile = dual(2, (xs, pred) => {
451
+ const len = xs.length;
452
+ let idx = 0;
453
+ while (idx < len && pred(xs[idx])) idx++;
454
+ return xs.slice(idx);
455
+ });
456
+ /**
457
+ * Takes the longest prefix of elements from an array that satisfy the given predicate.
458
+ *
459
+ * Supports both data-first and data-last (`pipe`-friendly) call styles.
460
+ *
461
+ * @param pred - The predicate to test each element with.
462
+ * @returns A new array containing only the matching prefix.
463
+ * @example
464
+ * ```ts
465
+ * import * as assert from "node:assert"
466
+ * import { pipe, takeWhile } from "@local/eff"
467
+ *
468
+ * // data-first
469
+ * assert.deepStrictEqual(takeWhile([1, 2, 3, 2, 1], (n: number) => n < 3), [1, 2])
470
+ *
471
+ * // data-last
472
+ * assert.deepStrictEqual(pipe([1, 2, 3, 2, 1], takeWhile((n: number) => n < 3)), [1, 2])
473
+ * ```
474
+ * @category array
475
+ */
476
+ const takeWhile = dual(2, (xs, pred) => {
477
+ const len = xs.length;
478
+ let idx = 0;
479
+ while (idx < len && pred(xs[idx])) idx++;
480
+ return xs.slice(0, idx);
481
+ });
134
482
 
135
483
  //#endregion
136
484
  //#region src/api.ts
137
485
  /**
138
- * Check if the node is a React API identifier or member expression
139
- * @param api The React API name to check against (ex: "useState", "React.memo")
140
- * @returns A predicate function to check if a node matches the API
486
+ * Check if the node is a React API identifier or member expression.
487
+ * @param api The React API name to check against (ex: "useState", "React.memo").
488
+ * @returns A predicate function to check if a node matches the API.
141
489
  */
142
490
  function isAPI(api) {
143
491
  const func = (context, node) => {
@@ -152,9 +500,9 @@ function isAPI(api) {
152
500
  return dual(2, func);
153
501
  }
154
502
  /**
155
- * Check if the node is a call expression to a specific React API
156
- * @param api The React API name to check against
157
- * @returns A predicate function to check if a node is a call to the API
503
+ * Check if the node is a call expression to a specific React API.
504
+ * @param api The React API name to check against.
505
+ * @returns A predicate function to check if a node is a call to the API.
158
506
  */
159
507
  function isAPICall(api) {
160
508
  const func = (context, node) => {
@@ -232,9 +580,9 @@ const isUseTransitionCall = isAPICall("useTransition");
232
580
  //#endregion
233
581
  //#region src/class.ts
234
582
  /**
235
- * Get the class identifier of a class node
236
- * @param node The class node to get the identifier from
237
- * @returns The class identifier or null if not found
583
+ * Get the class identifier of a class node.
584
+ * @param node The class node to get the identifier from.
585
+ * @returns The class identifier or null if not found.
238
586
  */
239
587
  function getClassId(node) {
240
588
  if (node.id != null) return node.id;
@@ -393,7 +741,7 @@ function getClassComponentCollector(context) {
393
741
  *
394
742
  * Ported from {@link https://github.com/facebook/react/blob/bb8a76c6cc77ea2976d690ea09f5a1b3d9b1792a/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts#L860 | RulesOfHooks.ts}
395
743
  *
396
- * @param node - The function node to analyze.
744
+ * @param node The function node to analyze.
397
745
  * @returns The identifier node if found, `null` otherwise.
398
746
  */
399
747
  function getFunctionId(node) {
@@ -412,7 +760,7 @@ function getFunctionId(node) {
412
760
  /**
413
761
  * Identifies the initialization path of a function node in the AST.
414
762
  *
415
- * @param node - The function node to analyze.
763
+ * @param node The function node to analyze.
416
764
  * @returns The function initialization path or `null` if not identifiable.
417
765
  */
418
766
  function getFunctionInitPath(node) {
@@ -463,8 +811,8 @@ function getFunctionInitPath(node) {
463
811
  /**
464
812
  * Checks if a specific function call exists in the function initialization path.
465
813
  *
466
- * @param callName - The name of the call to check for (e.g., "memo", "forwardRef").
467
- * @param initPath - The function initialization path to search in.
814
+ * @param callName The name of the call to check for (e.g., "memo", "forwardRef").
815
+ * @param initPath The function initialization path to search in.
468
816
  * @returns `true` if the call exists in the path, `false` otherwise.
469
817
  */
470
818
  function isFunctionHasCallInInitPath(callName, initPath) {
@@ -479,7 +827,7 @@ function isFunctionHasCallInInitPath(callName, initPath) {
479
827
  /**
480
828
  * Checks if a function is empty.
481
829
  *
482
- * @param node - The function node to check.
830
+ * @param node The function node to check.
483
831
  * @returns `true` if the function is empty, `false` otherwise.
484
832
  */
485
833
  function isFunctionEmpty(node) {
@@ -500,8 +848,8 @@ function getFunctionDirectives(node) {
500
848
  /**
501
849
  * Checks if a directive with the given name exists in the function directives.
502
850
  *
503
- * @param node - The function AST node.
504
- * @param name - The directive name to check (e.g., "use memo", "use no memo").
851
+ * @param node The function AST node.
852
+ * @param name The directive name to check (e.g., "use memo", "use no memo").
505
853
  * @returns `true` if the directive exists, `false` otherwise.
506
854
  */
507
855
  function isFunctionHasDirective(node, name) {
@@ -517,24 +865,24 @@ const SEL_FUNCTION_DISPLAY_NAME_ASSIGNMENT = [
517
865
  //#endregion
518
866
  //#region src/function-component.ts
519
867
  /**
520
- * Component flag constants
868
+ * Component flag constants.
521
869
  */
522
870
  const FunctionComponentFlag = {
523
- /** No flags set */
871
+ /** No flags set. */
524
872
  None: 0n,
525
- /** Indicates the component is a pure component (ex: extends PureComponent) */
873
+ /** Indicates the component is a pure component (ex: extends PureComponent). */
526
874
  PureComponent: 1n << 0n,
527
- /** Indicates the component creates elements using `createElement` instead of JSX */
875
+ /** Indicates the component creates elements using `createElement` instead of JSX. */
528
876
  CreateElement: 1n << 1n,
529
- /** Indicates the component is memoized (ex: React.memo) */
877
+ /** Indicates the component is memoized (ex: React.memo). */
530
878
  Memo: 1n << 2n,
531
- /** Indicates the component forwards a ref (ex: React.forwardRef) */
879
+ /** Indicates the component forwards a ref (ex: React.forwardRef). */
532
880
  ForwardRef: 1n << 3n
533
881
  };
534
882
  /**
535
- * Get component flag from init path
536
- * @param initPath The init path of the function component
537
- * @returns The component flag
883
+ * Get component flag from init path.
884
+ * @param initPath The init path of the function component.
885
+ * @returns The component flag.
538
886
  * @internal
539
887
  */
540
888
  function getFunctionComponentFlagFromInitPath(initPath) {
@@ -544,20 +892,20 @@ function getFunctionComponentFlagFromInitPath(initPath) {
544
892
  return flag;
545
893
  }
546
894
  /**
547
- * Check if the node is a call expression for a component wrapper
548
- * @param context The ESLint rule context
549
- * @param node The node to check
550
- * @returns `true` if the node is a call expression for a component wrapper
895
+ * Check if the node is a call expression for a component wrapper.
896
+ * @param context The ESLint rule context.
897
+ * @param node The node to check.
898
+ * @returns `true` if the node is a call expression for a component wrapper.
551
899
  */
552
900
  function isFunctionComponentWrapperCall(context, node) {
553
901
  if (node.type !== AST_NODE_TYPES.CallExpression) return false;
554
902
  return isMemoCall(context, node) || isForwardRefCall(context, node);
555
903
  }
556
904
  /**
557
- * Check if the node is a callback function passed to a component wrapper
558
- * @param context The ESLint rule context
559
- * @param node The node to check
560
- * @returns `true` if the node is a callback function passed to a component wrapper
905
+ * Check if the node is a callback function passed to a component wrapper.
906
+ * @param context The ESLint rule context.
907
+ * @param node The node to check.
908
+ * @returns `true` if the node is a callback function passed to a component wrapper.
561
909
  */
562
910
  function isFunctionComponentWrapperCallback(context, node) {
563
911
  if (!Check.isFunction(node)) return false;
@@ -567,9 +915,9 @@ function isFunctionComponentWrapperCallback(context, node) {
567
915
  return isFunctionComponentWrapperCall(context, parent);
568
916
  }
569
917
  /**
570
- * Get function component identifier from `const Component = memo(() => {});`
571
- * @param context The rule context
572
- * @param node The AST node to get the function component identifier from
918
+ * Get function component identifier from `const Component = memo(() => {});`.
919
+ * @param context The rule context.
920
+ * @param node The AST node to get the function component identifier from.
573
921
  * @internal
574
922
  */
575
923
  function getFunctionComponentId(context, node) {
@@ -584,25 +932,25 @@ function getFunctionComponentId(context, node) {
584
932
  }
585
933
  }
586
934
  /**
587
- * Check if a string matches the strict component name pattern
588
- * @param name The name to check
935
+ * Check if a string matches the strict component name pattern.
936
+ * @param name The name to check.
589
937
  */
590
938
  function isFunctionComponentName(name) {
591
939
  return RE_COMPONENT_NAME.test(name);
592
940
  }
593
941
  /**
594
- * Check if a string matches the loose component name pattern
595
- * @param name The name to check
942
+ * Check if a string matches the loose component name pattern.
943
+ * @param name The name to check.
596
944
  */
597
945
  function isFunctionComponentNameLoose(name) {
598
946
  return RE_COMPONENT_NAME_LOOSE.test(name);
599
947
  }
600
948
  /**
601
- * Check if a function has a loose component name
602
- * @param context The rule context
603
- * @param fn The function to check
604
- * @param allowNone Whether to allow no name
605
- * @returns Whether the function has a loose component name
949
+ * Check if a function has a loose component name.
950
+ * @param context The rule context.
951
+ * @param fn The function to check.
952
+ * @param allowNone Whether to allow no name.
953
+ * @returns Whether the function has a loose component name.
606
954
  */
607
955
  function isFunctionWithLooseComponentName(context, fn, allowNone = false) {
608
956
  const id = getFunctionComponentId(context, fn);
@@ -612,7 +960,7 @@ function isFunctionWithLooseComponentName(context, fn, allowNone = false) {
612
960
  return false;
613
961
  }
614
962
  /**
615
- * Hints for component collector
963
+ * Hints for component collector.
616
964
  */
617
965
  const FunctionComponentDetectionHint = {
618
966
  ...JsxDetectionHint,
@@ -626,16 +974,16 @@ const FunctionComponentDetectionHint = {
626
974
  DoNotIncludeFunctionDefinedAsArbitraryCallExpressionCallback: 1n << 18n
627
975
  };
628
976
  /**
629
- * Default component detection hint
977
+ * Default component detection hint.
630
978
  */
631
979
  const DEFAULT_COMPONENT_DETECTION_HINT = 0n | FunctionComponentDetectionHint.DoNotIncludeJsxWithBigIntValue | FunctionComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | FunctionComponentDetectionHint.DoNotIncludeJsxWithNumberValue | FunctionComponentDetectionHint.DoNotIncludeJsxWithStringValue | FunctionComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArbitraryCallExpressionCallback | FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayExpressionElement | FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayFlatMapCallback | FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback | FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayPatternElement | FunctionComponentDetectionHint.RequireAllArrayElementsToBeJsx | FunctionComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | FunctionComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx;
632
980
  /**
633
- * Determine if a function node represents a valid React component definition
981
+ * Determine if a function node represents a valid React component definition.
634
982
  *
635
- * @param context The rule context
636
- * @param node The function node to analyze
637
- * @param hint Component detection hints (bit flags) to customize detection logic
638
- * @returns `true` if the node is considered a component definition
983
+ * @param context The rule context.
984
+ * @param node The function node to analyze.
985
+ * @param hint Component detection hints (bit flags) to customize detection logic.
986
+ * @returns `true` if the node is considered a component definition.
639
987
  */
640
988
  function isFunctionComponentDefinition(context, node, hint) {
641
989
  if (!isFunctionWithLooseComponentName(context, node, true)) return false;
@@ -724,9 +1072,9 @@ function isHookName(name) {
724
1072
  return name === "use" || /^use[A-Z0-9]/.test(name);
725
1073
  }
726
1074
  /**
727
- * Checks if the given node is a hook identifier
728
- * @param id The AST node to check
729
- * @returns `true` if the node is a hook identifier or member expression with hook name, `false` otherwise
1075
+ * Checks if the given node is a hook identifier.
1076
+ * @param id The AST node to check.
1077
+ * @returns `true` if the node is a hook identifier or member expression with hook name, `false` otherwise.
730
1078
  */
731
1079
  function isHookId(id) {
732
1080
  switch (id.type) {
@@ -737,8 +1085,8 @@ function isHookId(id) {
737
1085
  }
738
1086
  /**
739
1087
  * Checks if the given expression is a hook tag (callee / tagged template tag).
740
- * @param tag The expression node to check
741
- * @returns `true` if the expression is a hook identifier or member expression with hook name, `false` otherwise
1088
+ * @param tag The expression node to check.
1089
+ * @returns `true` if the expression is a hook identifier or member expression with hook name, `false` otherwise.
742
1090
  */
743
1091
  function isHookTag(tag) {
744
1092
  if (tag == null) return false;
@@ -746,8 +1094,8 @@ function isHookTag(tag) {
746
1094
  }
747
1095
  /**
748
1096
  * Determine if a function node is a React Hook based on its name.
749
- * @param node The function node to check
750
- * @returns True if the function is a React Hook, false otherwise
1097
+ * @param node The function node to check.
1098
+ * @returns True if the function is a React Hook, false otherwise.
751
1099
  */
752
1100
  function isHookDefinition(node) {
753
1101
  if (node == null) return false;
@@ -771,10 +1119,10 @@ function isHookCall(node) {
771
1119
  return isHookName(name);
772
1120
  }
773
1121
  /**
774
- * Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
775
- * @param node The AST node to check
776
- * @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks
777
- * @returns True if the node is a useEffect-like call
1122
+ * Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern.
1123
+ * @param node The AST node to check.
1124
+ * @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks.
1125
+ * @returns True if the node is a useEffect-like call.
778
1126
  */
779
1127
  function isUseEffectLikeCall(node, additionalEffectHooks = { test: constFalse }) {
780
1128
  if (node == null) return false;
@@ -784,10 +1132,10 @@ function isUseEffectLikeCall(node, additionalEffectHooks = { test: constFalse })
784
1132
  return /^use\w*Effect$/u.test(name) || additionalEffectHooks.test(name);
785
1133
  }
786
1134
  /**
787
- * Detect useState calls and variations using a regex pattern
788
- * @param node The AST node to check
789
- * @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks
790
- * @returns True if the node is a useState-like call
1135
+ * Detect useState calls and variations using a regex pattern.
1136
+ * @param node The AST node to check.
1137
+ * @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks.
1138
+ * @returns True if the node is a useState-like call.
791
1139
  */
792
1140
  function isUseStateLikeCall(node, additionalStateHooks = { test: constFalse }) {
793
1141
  if (node == null) return false;
@@ -797,8 +1145,8 @@ function isUseStateLikeCall(node, additionalStateHooks = { test: constFalse }) {
797
1145
  return name === "useState" || additionalStateHooks.test(name);
798
1146
  }
799
1147
  /**
800
- * Determine if a node is the setup function passed to a useEffect-like hook
801
- * @param node The AST node to check
1148
+ * Determine if a node is the setup function passed to a useEffect-like hook.
1149
+ * @param node The AST node to check.
802
1150
  */
803
1151
  function isUseEffectSetupCallback(node) {
804
1152
  if (node == null) return false;
@@ -806,8 +1154,8 @@ function isUseEffectSetupCallback(node) {
806
1154
  return expr.parent?.type === AST_NODE_TYPES.CallExpression && expr.parent.arguments.at(0) === expr && isUseEffectLikeCall(expr.parent);
807
1155
  }
808
1156
  /**
809
- * Determine if a node is the cleanup function returned by a useEffect-like hook's setup function
810
- * @param node The AST node to check
1157
+ * Determine if a node is the cleanup function returned by a useEffect-like hook's setup function.
1158
+ * @param node The AST node to check.
811
1159
  */
812
1160
  function isUseEffectCleanupCallback(node) {
813
1161
  if (node == null) return false;
@@ -830,10 +1178,9 @@ function isUseEffectCleanupCallback(node) {
830
1178
  * circular definitions (e.g. `var a = b; var b = a;`) are detected and
831
1179
  * treated as not JSX-like instead of recursing indefinitely.
832
1180
  *
833
- * @param context - The ESLint rule context (needed for variable resolution).
834
- * @param node - The AST node to analyse.
835
- * @param hint - Optional bit-flags to adjust detection behaviour.
836
- * Defaults to {@link DEFAULT_JSX_DETECTION_HINT}.
1181
+ * @param context The ESLint rule context (needed for variable resolution).
1182
+ * @param node The AST node to analyse.
1183
+ * @param hint Optional bit-flags to adjust detection behaviour. Defaults to {@link DEFAULT_JSX_DETECTION_HINT}.
837
1184
  * @returns Whether the node is considered JSX-like.
838
1185
  *
839
1186
  * @example
@@ -887,10 +1234,10 @@ function isJsxLike(context, node, hint = DEFAULT_JSX_DETECTION_HINT) {
887
1234
  //#endregion
888
1235
  //#region src/function-component-collector.ts
889
1236
  /**
890
- * Get an api and visitor object for the rule to collect function components
891
- * @param context The ESLint rule context
892
- * @param options The options to use
893
- * @returns The api and visitor of the collector
1237
+ * Get an api and visitor object for the rule to collect function components.
1238
+ * @param context The ESLint rule context.
1239
+ * @param options The options to use.
1240
+ * @returns The api and visitor of the collector.
894
1241
  */
895
1242
  function getFunctionComponentCollector(context, options = {}) {
896
1243
  const { collectDisplayName = false, hint = DEFAULT_COMPONENT_DETECTION_HINT } = options;
@@ -988,9 +1335,9 @@ function getFunctionComponentCollector(context, options = {}) {
988
1335
  //#endregion
989
1336
  //#region src/hook-collector.ts
990
1337
  /**
991
- * Get an api and visitor object for the rule to collect hooks
992
- * @param context The ESLint rule context
993
- * @returns The api and visitor of the collector
1338
+ * Get an api and visitor object for the rule to collect hooks.
1339
+ * @param context The ESLint rule context.
1340
+ * @returns The api and visitor of the collector.
994
1341
  */
995
1342
  function getHookCollector(context) {
996
1343
  const hooks = /* @__PURE__ */ new Map();
@@ -1073,7 +1420,7 @@ const mergedCache = /* @__PURE__ */ new WeakMap();
1073
1420
  * Falls back to sensible React defaults when no compiler options are
1074
1421
  * available (e.g. when the file is parsed without type information).
1075
1422
  *
1076
- * @param context - The ESLint rule context.
1423
+ * @param context The ESLint rule context.
1077
1424
  * @returns Fully‑populated `JsxConfig` derived from compiler options.
1078
1425
  */
1079
1426
  function getJsxConfigFromCompilerOptions(context) {
@@ -1092,7 +1439,7 @@ function getJsxConfigFromCompilerOptions(context) {
1092
1439
  * The result is cached per `sourceCode` instance via a `WeakMap` so that
1093
1440
  * repeated calls from different rules analysing the same file are free.
1094
1441
  *
1095
- * @param context - The ESLint rule context.
1442
+ * @param context The ESLint rule context.
1096
1443
  * @returns Partial `JsxConfig` containing only the values found in pragmas.
1097
1444
  */
1098
1445
  function getJsxConfigFromAnnotation(context) {
@@ -1126,7 +1473,7 @@ function getJsxConfigFromAnnotation(context) {
1126
1473
  *
1127
1474
  * This is the main entry‑point most consumers should use.
1128
1475
  *
1129
- * @param context - The ESLint rule context.
1476
+ * @param context The ESLint rule context.
1130
1477
  * @returns Fully‑populated, merged `JsxConfig`.
1131
1478
  */
1132
1479
  function getJsxConfig(context) {
@@ -1192,10 +1539,10 @@ const isUnknownType = (type) => isTypeFlagSet(type, ts.TypeFlags.Unknown);
1192
1539
  //#endregion
1193
1540
  //#region src/type-name.ts
1194
1541
  /**
1195
- * An enhanced version of getFullyQualifiedName that handles cases that original function does not handle
1196
- * @param checker TypeScript type checker
1197
- * @param symbol Symbol to get fully qualified name for
1198
- * @returns Fully qualified name of the symbol
1542
+ * An enhanced version of getFullyQualifiedName that handles cases that original function does not handle.
1543
+ * @param checker The TypeScript type checker.
1544
+ * @param symbol The symbol to get fully qualified name for.
1545
+ * @returns The fully qualified name of the symbol.
1199
1546
  */
1200
1547
  function getFullyQualifiedNameEx(checker, symbol) {
1201
1548
  let name = symbol.name;
@@ -1245,10 +1592,10 @@ function getFullyQualifiedNameEx(checker, symbol) {
1245
1592
  //#endregion
1246
1593
  //#region src/type-variant.ts
1247
1594
  /**
1248
- * Ported from https://github.com/typescript-eslint/typescript-eslint/blob/eb736bbfc22554694400e6a4f97051d845d32e0b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts#L826 with some enhancements
1595
+ * Ported from https://github.com/typescript-eslint/typescript-eslint/blob/eb736bbfc22554694400e6a4f97051d845d32e0b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts#L826 with some enhancements.
1249
1596
  * Get the variants of an array of types.
1250
- * @param types The types to get the variants of
1251
- * @returns The variants of the types
1597
+ * @param types The types to get the variants of.
1598
+ * @returns The variants of the types.
1252
1599
  * @internal
1253
1600
  */
1254
1601
  function getTypeVariants(types) {