@blumintinc/eslint-plugin-blumint 1.20.125 → 1.20.126
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/lib/index.js
CHANGED
|
@@ -9,6 +9,33 @@ const createRule_1 = require("../utils/createRule");
|
|
|
9
9
|
function hasPseudoElementSelector(selector) {
|
|
10
10
|
return /::?(before|after)\b/i.test(selector);
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* The four expression assertions state a type about the expression they wrap and
|
|
14
|
+
* contribute no value of their own, so `'none' as const`, `'none' satisfies
|
|
15
|
+
* string`, `('none')!` and `<const>'none'` all denote the same string as
|
|
16
|
+
* `'none'`. A read that classifies the value a property holds must look through
|
|
17
|
+
* every one of them alike, or the verdict turns on which type syntax an author
|
|
18
|
+
* reached for.
|
|
19
|
+
*/
|
|
20
|
+
const ASSERTION_TYPES = new Set([
|
|
21
|
+
utils_1.AST_NODE_TYPES.TSAsExpression,
|
|
22
|
+
utils_1.AST_NODE_TYPES.TSSatisfiesExpression,
|
|
23
|
+
utils_1.AST_NODE_TYPES.TSNonNullExpression,
|
|
24
|
+
utils_1.AST_NODE_TYPES.TSTypeAssertion,
|
|
25
|
+
]);
|
|
26
|
+
const isAssertion = (node) => ASSERTION_TYPES.has(node.type);
|
|
27
|
+
/**
|
|
28
|
+
* Peels every assertion off a node. Assertions nest — `'none' as const
|
|
29
|
+
* satisfies string` is a satisfies over an as — so a single unwrap would still
|
|
30
|
+
* hand back a wrapper.
|
|
31
|
+
*/
|
|
32
|
+
function unwrapAssertions(node) {
|
|
33
|
+
let target = node;
|
|
34
|
+
while (isAssertion(target)) {
|
|
35
|
+
target = target.expression;
|
|
36
|
+
}
|
|
37
|
+
return target;
|
|
38
|
+
}
|
|
12
39
|
/**
|
|
13
40
|
* Reads the static string a node denotes, so a property name or value carries
|
|
14
41
|
* the same meaning however it is spelled. A no-substitution template literal is
|
|
@@ -21,19 +48,22 @@ function hasPseudoElementSelector(selector) {
|
|
|
21
48
|
* literal with duplicate keys does not compile.
|
|
22
49
|
*
|
|
23
50
|
* An interpolated template stays opaque: its text is not known statically, so
|
|
24
|
-
* the rule keeps its conservative silence there.
|
|
51
|
+
* the rule keeps its conservative silence there. An assertion around an opaque
|
|
52
|
+
* value is equally opaque: unwrapping reaches the expression underneath, and
|
|
53
|
+
* that expression still decides whether anything can be read.
|
|
25
54
|
*/
|
|
26
55
|
function staticStringOf(node) {
|
|
27
|
-
|
|
28
|
-
|
|
56
|
+
const target = unwrapAssertions(node);
|
|
57
|
+
if (target.type === utils_1.AST_NODE_TYPES.Literal) {
|
|
58
|
+
return String(target.value);
|
|
29
59
|
}
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
60
|
+
if (target.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
61
|
+
return target.name;
|
|
32
62
|
}
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return
|
|
63
|
+
if (target.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
|
|
64
|
+
target.expressions.length === 0 &&
|
|
65
|
+
target.quasis.length === 1) {
|
|
66
|
+
return target.quasis[0].value.cooked ?? target.quasis[0].value.raw;
|
|
37
67
|
}
|
|
38
68
|
return undefined;
|
|
39
69
|
}
|
|
@@ -110,7 +140,11 @@ function classifyOffsetComponents(raw) {
|
|
|
110
140
|
* classified; variables, member expressions, and calls are treated as unknown
|
|
111
141
|
* and never counted toward the hit-slop exemption.
|
|
112
142
|
*/
|
|
113
|
-
function classifyOffsetValue(
|
|
143
|
+
function classifyOffsetValue(node) {
|
|
144
|
+
// An assertion states a type, not a length. Reading the position through one
|
|
145
|
+
// while leaving the offsets opaque would strip an assertion-written hit-slop
|
|
146
|
+
// overlay of its carve-out and hand it the tap-target-shrinking autofix.
|
|
147
|
+
const value = unwrapAssertions(node);
|
|
114
148
|
if (value.type === utils_1.AST_NODE_TYPES.Literal) {
|
|
115
149
|
if (typeof value.value === 'number') {
|
|
116
150
|
if (value.value === 0)
|
|
@@ -421,6 +421,21 @@ exports.default = (0, createRule_1.createRule)({
|
|
|
421
421
|
if (!declaredVariable) {
|
|
422
422
|
return null;
|
|
423
423
|
}
|
|
424
|
+
// The conversion degenerates on some names: one built only from
|
|
425
|
+
// underscores derives the empty string, and a leading
|
|
426
|
+
// underscore in front of a digit derives a name that starts
|
|
427
|
+
// with that digit. Applying either trades a naming report for a
|
|
428
|
+
// file that no longer parses — `const = {…}` — and the rename
|
|
429
|
+
// rewrites every reference, so the damage spreads to each use
|
|
430
|
+
// site. Declining leaves the report standing with no fix, which
|
|
431
|
+
// is the honest outcome: the author has to choose a real name,
|
|
432
|
+
// and no mechanical rewrite can choose one for them. The test is
|
|
433
|
+
// the rule's own acceptance predicate, so a derivation that
|
|
434
|
+
// would only relocate the same report (`_$` to `$`) is declined
|
|
435
|
+
// on the same terms.
|
|
436
|
+
if (!isUpperSnakeCase(newName)) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
424
439
|
// An exported binding's name is a cross-file contract: every
|
|
425
440
|
// importer spells it out in a file this single-file fixer
|
|
426
441
|
// cannot reach, so renaming the declaration breaks them all
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.20.126",
|
|
4
|
+
"date": "2026-08-06T22:42:22.372Z",
|
|
5
|
+
"rules": [
|
|
6
|
+
{
|
|
7
|
+
"name": "ensure-pointer-events-none",
|
|
8
|
+
"changeType": "fix",
|
|
9
|
+
"issues": [
|
|
10
|
+
1814
|
|
11
|
+
],
|
|
12
|
+
"summary": "read every selector, name, value and offset through expression assertions (closes #1814)"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "global-const-style",
|
|
16
|
+
"changeType": "fix",
|
|
17
|
+
"issues": [
|
|
18
|
+
1816
|
|
19
|
+
],
|
|
20
|
+
"summary": "decline the rename when the derived name is not an identifier (closes #1816)"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
2
24
|
{
|
|
3
25
|
"version": "1.20.125",
|
|
4
26
|
"date": "2026-08-06T17:33:56.677Z",
|