@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
@@ -223,7 +223,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
223
223
  module.exports = {
224
224
  meta: {
225
225
  name: '@blumintinc/eslint-plugin-blumint',
226
- version: '1.20.125',
226
+ version: '1.20.126',
227
227
  },
228
228
  parseOptions: {
229
229
  ecmaVersion: 2020,
@@ -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
- if (node.type === utils_1.AST_NODE_TYPES.Literal) {
28
- return String(node.value);
56
+ const target = unwrapAssertions(node);
57
+ if (target.type === utils_1.AST_NODE_TYPES.Literal) {
58
+ return String(target.value);
29
59
  }
30
- if (node.type === utils_1.AST_NODE_TYPES.Identifier) {
31
- return node.name;
60
+ if (target.type === utils_1.AST_NODE_TYPES.Identifier) {
61
+ return target.name;
32
62
  }
33
- if (node.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
34
- node.expressions.length === 0 &&
35
- node.quasis.length === 1) {
36
- return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
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(value) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.20.125",
3
+ "version": "1.20.126",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -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",