eslint-plugin-react-web-api 4.2.5-beta.0 → 5.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +127 -157
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -26,138 +26,13 @@ var __exportAll = (all, no_symbols) => {
|
|
|
26
26
|
//#endregion
|
|
27
27
|
//#region package.json
|
|
28
28
|
var name$1 = "eslint-plugin-react-web-api";
|
|
29
|
-
var version = "
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region ../../../.pkgs/eff/dist/index.js
|
|
33
|
-
function or(a, b) {
|
|
34
|
-
return (data) => a(data) || b(data);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Creates a function that can be used in a data-last (aka `pipe`able) or
|
|
38
|
-
* data-first style.
|
|
39
|
-
*
|
|
40
|
-
* The first parameter to `dual` is either the arity of the uncurried function
|
|
41
|
-
* or a predicate that determines if the function is being used in a data-first
|
|
42
|
-
* or data-last style.
|
|
43
|
-
*
|
|
44
|
-
* Using the arity is the most common use case, but there are some cases where
|
|
45
|
-
* you may want to use a predicate. For example, if you have a function that
|
|
46
|
-
* takes an optional argument, you can use a predicate to determine if the
|
|
47
|
-
* function is being used in a data-first or data-last style.
|
|
48
|
-
*
|
|
49
|
-
* You can pass either the arity of the uncurried function or a predicate
|
|
50
|
-
* which determines if the function is being used in a data-first or
|
|
51
|
-
* data-last style.
|
|
52
|
-
*
|
|
53
|
-
* **Example** (Using arity to determine data-first or data-last style)
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* import { dual, pipe } from "effect/Function"
|
|
57
|
-
*
|
|
58
|
-
* const sum = dual<
|
|
59
|
-
* (that: number) => (self: number) => number,
|
|
60
|
-
* (self: number, that: number) => number
|
|
61
|
-
* >(2, (self, that) => self + that)
|
|
62
|
-
*
|
|
63
|
-
* console.log(sum(2, 3)) // 5
|
|
64
|
-
* console.log(pipe(2, sum(3))) // 5
|
|
65
|
-
* ```
|
|
66
|
-
*
|
|
67
|
-
* **Example** (Using call signatures to define the overloads)
|
|
68
|
-
*
|
|
69
|
-
* ```ts
|
|
70
|
-
* import { dual, pipe } from "effect/Function"
|
|
71
|
-
*
|
|
72
|
-
* const sum: {
|
|
73
|
-
* (that: number): (self: number) => number
|
|
74
|
-
* (self: number, that: number): number
|
|
75
|
-
* } = dual(2, (self: number, that: number): number => self + that)
|
|
76
|
-
*
|
|
77
|
-
* console.log(sum(2, 3)) // 5
|
|
78
|
-
* console.log(pipe(2, sum(3))) // 5
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* **Example** (Using a predicate to determine data-first or data-last style)
|
|
82
|
-
*
|
|
83
|
-
* ```ts
|
|
84
|
-
* import { dual, pipe } from "effect/Function"
|
|
85
|
-
*
|
|
86
|
-
* const sum = dual<
|
|
87
|
-
* (that: number) => (self: number) => number,
|
|
88
|
-
* (self: number, that: number) => number
|
|
89
|
-
* >(
|
|
90
|
-
* (args) => args.length === 2,
|
|
91
|
-
* (self, that) => self + that
|
|
92
|
-
* )
|
|
93
|
-
*
|
|
94
|
-
* console.log(sum(2, 3)) // 5
|
|
95
|
-
* console.log(pipe(2, sum(3))) // 5
|
|
96
|
-
* ```
|
|
97
|
-
*
|
|
98
|
-
* @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.
|
|
99
|
-
* @param body - The function to be curried.
|
|
100
|
-
* @since 1.0.0
|
|
101
|
-
*/
|
|
102
|
-
const dual = function(arity, body) {
|
|
103
|
-
if (typeof arity === "function") return function() {
|
|
104
|
-
return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
|
|
105
|
-
};
|
|
106
|
-
switch (arity) {
|
|
107
|
-
case 0:
|
|
108
|
-
case 1: throw new RangeError(`Invalid arity ${arity}`);
|
|
109
|
-
case 2: return function(a, b) {
|
|
110
|
-
if (arguments.length >= 2) return body(a, b);
|
|
111
|
-
return function(self) {
|
|
112
|
-
return body(self, a);
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
case 3: return function(a, b, c) {
|
|
116
|
-
if (arguments.length >= 3) return body(a, b, c);
|
|
117
|
-
return function(self) {
|
|
118
|
-
return body(self, a, b);
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
default: return function() {
|
|
122
|
-
if (arguments.length >= arity) return body.apply(this, arguments);
|
|
123
|
-
const args = arguments;
|
|
124
|
-
return function(self) {
|
|
125
|
-
return body(self, ...args);
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
/**
|
|
131
|
-
* 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`.
|
|
132
|
-
* The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
|
|
133
|
-
*
|
|
134
|
-
* @param self - The first function to apply (or the composed function in data-last style).
|
|
135
|
-
* @param bc - The second function to apply.
|
|
136
|
-
* @returns A composed function that applies both functions in sequence.
|
|
137
|
-
* @example
|
|
138
|
-
* ```ts
|
|
139
|
-
* import * as assert from "node:assert"
|
|
140
|
-
* import { compose } from "effect/Function"
|
|
141
|
-
*
|
|
142
|
-
* const increment = (n: number) => n + 1;
|
|
143
|
-
* const square = (n: number) => n * n;
|
|
144
|
-
*
|
|
145
|
-
* assert.strictEqual(compose(increment, square)(2), 9);
|
|
146
|
-
* ```
|
|
147
|
-
*
|
|
148
|
-
* @since 1.0.0
|
|
149
|
-
*/
|
|
150
|
-
const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
|
|
29
|
+
var version = "5.0.0-next.0";
|
|
151
30
|
|
|
152
31
|
//#endregion
|
|
153
32
|
//#region src/types/component-phase.ts
|
|
154
|
-
const ComponentPhaseRelevance = birecord({
|
|
155
|
-
mount: "unmount",
|
|
156
|
-
setup: "cleanup"
|
|
157
|
-
});
|
|
158
|
-
const isInversePhase = dual(2, (a, b) => ComponentPhaseRelevance.get(a) === b);
|
|
33
|
+
const ComponentPhaseRelevance = birecord({ setup: "cleanup" });
|
|
159
34
|
function getPhaseKindOfFunction(node) {
|
|
160
|
-
return match(node).when(core.isUseEffectSetupCallback, () => "setup").when(core.isUseEffectCleanupCallback, () => "cleanup").
|
|
35
|
+
return match(node).when(core.isUseEffectSetupCallback, () => "setup").when(core.isUseEffectCleanupCallback, () => "cleanup").otherwise(() => null);
|
|
161
36
|
}
|
|
162
37
|
|
|
163
38
|
//#endregion
|
|
@@ -234,7 +109,6 @@ var no_leaked_event_listener_default = createRule({
|
|
|
234
109
|
docs: { description: "Enforces that every 'addEventListener' in a component or custom hook has a corresponding 'removeEventListener'." },
|
|
235
110
|
messages: {
|
|
236
111
|
expectedRemoveEventListenerInCleanup: "An 'addEventListener' in '{{effectMethodKind}}' should have a corresponding 'removeEventListener' in its cleanup function.",
|
|
237
|
-
expectedRemoveEventListenerInUnmount: "An 'addEventListener' in 'componentDidMount' should have a corresponding 'removeEventListener' in 'componentWillUnmount' method.",
|
|
238
112
|
unexpectedInlineFunction: "A/an '{{eventMethodKind}}' should not have an inline listener function."
|
|
239
113
|
},
|
|
240
114
|
schema: []
|
|
@@ -245,7 +119,7 @@ var no_leaked_event_listener_default = createRule({
|
|
|
245
119
|
});
|
|
246
120
|
function create$3(context) {
|
|
247
121
|
if (!context.sourceCode.text.includes("addEventListener")) return {};
|
|
248
|
-
if (!/use\w*Effect
|
|
122
|
+
if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
|
|
249
123
|
const fEntries = [];
|
|
250
124
|
const aEntries = [];
|
|
251
125
|
const rEntries = [];
|
|
@@ -259,7 +133,7 @@ function create$3(context) {
|
|
|
259
133
|
function isInverseEntry(aEntry, rEntry) {
|
|
260
134
|
const { type: aType, callee: aCallee, capture: aCapture, listener: aListener, phase: aPhase } = aEntry;
|
|
261
135
|
const { type: rType, callee: rCallee, capture: rCapture, listener: rListener, phase: rPhase } = rEntry;
|
|
262
|
-
if (
|
|
136
|
+
if (ComponentPhaseRelevance.get(aPhase) !== rPhase) return false;
|
|
263
137
|
return isSameObject(aCallee, rCallee) && ast.isNodeEqual(aListener, rListener) && isValueEqual(context, aType, rType) && aCapture === rCapture;
|
|
264
138
|
}
|
|
265
139
|
function checkInlineFunction(node, callKind, options) {
|
|
@@ -288,7 +162,7 @@ function create$3(context) {
|
|
|
288
162
|
if (fKind == null) return;
|
|
289
163
|
if (!ComponentPhaseRelevance.has(fKind)) return;
|
|
290
164
|
match(getCallKind$3(node)).with("addEventListener", (callKind) => {
|
|
291
|
-
if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.object.type === AST_NODE_TYPES.Identifier && core.
|
|
165
|
+
if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.object.type === AST_NODE_TYPES.Identifier && core.isAPIFromReactNative(node.callee.object.name, context.sourceCode.getScope(node))) return;
|
|
292
166
|
const [type, listener, options] = node.arguments;
|
|
293
167
|
if (type == null || listener == null) return;
|
|
294
168
|
const opts = options == null ? defaultOptions : getOptions(context, options);
|
|
@@ -335,13 +209,6 @@ function create$3(context) {
|
|
|
335
209
|
node: aEntry.node
|
|
336
210
|
});
|
|
337
211
|
continue;
|
|
338
|
-
case "mount":
|
|
339
|
-
case "unmount":
|
|
340
|
-
context.report({
|
|
341
|
-
messageId: "expectedRemoveEventListenerInUnmount",
|
|
342
|
-
node: aEntry.node
|
|
343
|
-
});
|
|
344
|
-
continue;
|
|
345
212
|
}
|
|
346
213
|
}
|
|
347
214
|
}
|
|
@@ -364,7 +231,6 @@ var no_leaked_interval_default = createRule({
|
|
|
364
231
|
docs: { description: "Enforces that every 'setInterval' in a component or custom hook has a corresponding 'clearInterval'." },
|
|
365
232
|
messages: {
|
|
366
233
|
expectedClearIntervalInCleanup: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the cleanup function.",
|
|
367
|
-
expectedClearIntervalInUnmount: "A 'setInterval' created in '{{ kind }}' must be cleared with 'clearInterval' in the 'componentWillUnmount' method.",
|
|
368
234
|
expectedIntervalId: "A 'setInterval' must be assigned to a variable for proper cleanup."
|
|
369
235
|
},
|
|
370
236
|
schema: []
|
|
@@ -444,20 +310,133 @@ function create$2(context) {
|
|
|
444
310
|
node: sEntry.node
|
|
445
311
|
});
|
|
446
312
|
continue;
|
|
447
|
-
case "mount":
|
|
448
|
-
case "unmount":
|
|
449
|
-
context.report({
|
|
450
|
-
data: { kind: "componentDidMount" },
|
|
451
|
-
messageId: "expectedClearIntervalInUnmount",
|
|
452
|
-
node: sEntry.node
|
|
453
|
-
});
|
|
454
|
-
continue;
|
|
455
313
|
}
|
|
456
314
|
}
|
|
457
315
|
}
|
|
458
316
|
});
|
|
459
317
|
}
|
|
460
318
|
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region ../../../.pkgs/eff/dist/index.js
|
|
321
|
+
function or(a, b) {
|
|
322
|
+
return (data) => a(data) || b(data);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Creates a function that can be used in a data-last (aka `pipe`able) or
|
|
326
|
+
* data-first style.
|
|
327
|
+
*
|
|
328
|
+
* The first parameter to `dual` is either the arity of the uncurried function
|
|
329
|
+
* or a predicate that determines if the function is being used in a data-first
|
|
330
|
+
* or data-last style.
|
|
331
|
+
*
|
|
332
|
+
* Using the arity is the most common use case, but there are some cases where
|
|
333
|
+
* you may want to use a predicate. For example, if you have a function that
|
|
334
|
+
* takes an optional argument, you can use a predicate to determine if the
|
|
335
|
+
* function is being used in a data-first or data-last style.
|
|
336
|
+
*
|
|
337
|
+
* You can pass either the arity of the uncurried function or a predicate
|
|
338
|
+
* which determines if the function is being used in a data-first or
|
|
339
|
+
* data-last style.
|
|
340
|
+
*
|
|
341
|
+
* **Example** (Using arity to determine data-first or data-last style)
|
|
342
|
+
*
|
|
343
|
+
* ```ts
|
|
344
|
+
* import { dual, pipe } from "effect/Function"
|
|
345
|
+
*
|
|
346
|
+
* const sum = dual<
|
|
347
|
+
* (that: number) => (self: number) => number,
|
|
348
|
+
* (self: number, that: number) => number
|
|
349
|
+
* >(2, (self, that) => self + that)
|
|
350
|
+
*
|
|
351
|
+
* console.log(sum(2, 3)) // 5
|
|
352
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
353
|
+
* ```
|
|
354
|
+
*
|
|
355
|
+
* **Example** (Using call signatures to define the overloads)
|
|
356
|
+
*
|
|
357
|
+
* ```ts
|
|
358
|
+
* import { dual, pipe } from "effect/Function"
|
|
359
|
+
*
|
|
360
|
+
* const sum: {
|
|
361
|
+
* (that: number): (self: number) => number
|
|
362
|
+
* (self: number, that: number): number
|
|
363
|
+
* } = dual(2, (self: number, that: number): number => self + that)
|
|
364
|
+
*
|
|
365
|
+
* console.log(sum(2, 3)) // 5
|
|
366
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
367
|
+
* ```
|
|
368
|
+
*
|
|
369
|
+
* **Example** (Using a predicate to determine data-first or data-last style)
|
|
370
|
+
*
|
|
371
|
+
* ```ts
|
|
372
|
+
* import { dual, pipe } from "effect/Function"
|
|
373
|
+
*
|
|
374
|
+
* const sum = dual<
|
|
375
|
+
* (that: number) => (self: number) => number,
|
|
376
|
+
* (self: number, that: number) => number
|
|
377
|
+
* >(
|
|
378
|
+
* (args) => args.length === 2,
|
|
379
|
+
* (self, that) => self + that
|
|
380
|
+
* )
|
|
381
|
+
*
|
|
382
|
+
* console.log(sum(2, 3)) // 5
|
|
383
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
384
|
+
* ```
|
|
385
|
+
*
|
|
386
|
+
* @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.
|
|
387
|
+
* @param body - The function to be curried.
|
|
388
|
+
* @since 1.0.0
|
|
389
|
+
*/
|
|
390
|
+
const dual = function(arity, body) {
|
|
391
|
+
if (typeof arity === "function") return function() {
|
|
392
|
+
return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
|
|
393
|
+
};
|
|
394
|
+
switch (arity) {
|
|
395
|
+
case 0:
|
|
396
|
+
case 1: throw new RangeError(`Invalid arity ${arity}`);
|
|
397
|
+
case 2: return function(a, b) {
|
|
398
|
+
if (arguments.length >= 2) return body(a, b);
|
|
399
|
+
return function(self) {
|
|
400
|
+
return body(self, a);
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
case 3: return function(a, b, c) {
|
|
404
|
+
if (arguments.length >= 3) return body(a, b, c);
|
|
405
|
+
return function(self) {
|
|
406
|
+
return body(self, a, b);
|
|
407
|
+
};
|
|
408
|
+
};
|
|
409
|
+
default: return function() {
|
|
410
|
+
if (arguments.length >= arity) return body.apply(this, arguments);
|
|
411
|
+
const args = arguments;
|
|
412
|
+
return function(self) {
|
|
413
|
+
return body(self, ...args);
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* 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`.
|
|
420
|
+
* The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
|
|
421
|
+
*
|
|
422
|
+
* @param self - The first function to apply (or the composed function in data-last style).
|
|
423
|
+
* @param bc - The second function to apply.
|
|
424
|
+
* @returns A composed function that applies both functions in sequence.
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* import * as assert from "node:assert"
|
|
428
|
+
* import { compose } from "effect/Function"
|
|
429
|
+
*
|
|
430
|
+
* const increment = (n: number) => n + 1;
|
|
431
|
+
* const square = (n: number) => n * n;
|
|
432
|
+
*
|
|
433
|
+
* assert.strictEqual(compose(increment, square)(2), 9);
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* @since 1.0.0
|
|
437
|
+
*/
|
|
438
|
+
const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
|
|
439
|
+
|
|
461
440
|
//#endregion
|
|
462
441
|
//#region src/rules/no-leaked-resize-observer/no-leaked-resize-observer.ts
|
|
463
442
|
const RULE_NAME$1 = "no-leaked-resize-observer";
|
|
@@ -616,7 +595,6 @@ var no_leaked_timeout_default = createRule({
|
|
|
616
595
|
docs: { description: "Enforces that every 'setTimeout' in a component or custom hook has a corresponding 'clearTimeout'." },
|
|
617
596
|
messages: {
|
|
618
597
|
expectedClearTimeoutInCleanup: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the cleanup function.",
|
|
619
|
-
expectedClearTimeoutInUnmount: "A 'setTimeout' created in '{{ kind }}' must be cleared with 'clearTimeout' in the 'componentWillUnmount' method.",
|
|
620
598
|
expectedTimeoutId: "A 'setTimeout' must be assigned to a variable for proper cleanup."
|
|
621
599
|
},
|
|
622
600
|
schema: []
|
|
@@ -692,14 +670,6 @@ function create(context) {
|
|
|
692
670
|
node: sEntry.node
|
|
693
671
|
});
|
|
694
672
|
continue;
|
|
695
|
-
case "mount":
|
|
696
|
-
case "unmount":
|
|
697
|
-
context.report({
|
|
698
|
-
data: { kind: "componentDidMount" },
|
|
699
|
-
messageId: "expectedClearTimeoutInUnmount",
|
|
700
|
-
node: sEntry.node
|
|
701
|
-
});
|
|
702
|
-
continue;
|
|
703
673
|
}
|
|
704
674
|
}
|
|
705
675
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-web-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-next.0",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for interacting with Web APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"@typescript-eslint/utils": "^8.58.0",
|
|
44
44
|
"birecord": "^0.1.1",
|
|
45
45
|
"ts-pattern": "^5.9.0",
|
|
46
|
-
"@eslint-react/ast": "
|
|
47
|
-
"@eslint-react/core": "
|
|
48
|
-
"@eslint-react/shared": "
|
|
49
|
-
"@eslint-react/var": "
|
|
46
|
+
"@eslint-react/ast": "5.0.0-next.0",
|
|
47
|
+
"@eslint-react/core": "5.0.0-next.0",
|
|
48
|
+
"@eslint-react/shared": "5.0.0-next.0",
|
|
49
|
+
"@eslint-react/var": "5.0.0-next.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/react": "^19.2.14",
|
|
53
53
|
"@types/react-dom": "^19.2.3",
|
|
54
|
-
"eslint": "^10.
|
|
54
|
+
"eslint": "^10.2.0",
|
|
55
55
|
"tsdown": "^0.21.7",
|
|
56
56
|
"@local/configs": "0.0.0",
|
|
57
57
|
"@local/eff": "3.0.0-beta.72"
|