@blumintinc/eslint-plugin-blumint 1.21.2 → 1.21.3

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.
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCustomMemo = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const createRule_1 = require("../utils/createRule");
6
- const MEMO_MODULE = `'src/util/memo'`;
7
- /** `MEMO_MODULE` carries the quotes the fixer emits; a path never does. */
8
- const MEMO_MODULE_PATH = MEMO_MODULE.slice(1, -1);
6
+ const memoModule_1 = require("../utils/memoModule");
9
7
  const SOURCE_EXTENSION = /\.(?:ts|tsx|js|jsx)$/;
10
8
  /**
11
9
  * The module the fixer points every `memo` import at is the one module that must
@@ -20,10 +18,10 @@ const SOURCE_EXTENSION = /\.(?:ts|tsx|js|jsx)$/;
20
18
  */
21
19
  const isMemoModule = (filename) => {
22
20
  const normalized = filename.replace(/\\/g, '/').replace(SOURCE_EXTENSION, '');
23
- if (!normalized.endsWith(MEMO_MODULE_PATH)) {
21
+ if (!normalized.endsWith(memoModule_1.CUSTOM_MEMO_MODULE_PATH)) {
24
22
  return false;
25
23
  }
26
- const suffixStart = normalized.length - MEMO_MODULE_PATH.length;
24
+ const suffixStart = normalized.length - memoModule_1.CUSTOM_MEMO_MODULE_PATH.length;
27
25
  return suffixStart === 0 || normalized[suffixStart - 1] === '/';
28
26
  };
29
27
  const isComment = (token) => token.type === utils_1.AST_TOKEN_TYPES.Line || token.type === utils_1.AST_TOKEN_TYPES.Block;
@@ -206,7 +204,7 @@ exports.useCustomMemo = (0, createRule_1.createRule)({
206
204
  messageId: 'useCustomMemo',
207
205
  fix(fixer) {
208
206
  const sourceCode = context.getSourceCode();
209
- const memoImport = buildImport(memoSpecifiers, MEMO_MODULE, node.importKind, sourceCode);
207
+ const memoImport = buildImport(memoSpecifiers, memoModule_1.CUSTOM_MEMO_MODULE_SOURCE, node.importKind, sourceCode);
210
208
  const survivingSpecifiers = node.specifiers.filter((specifier) => !isMemoSpecifier(specifier));
211
209
  const comments = sourceCode
212
210
  .getCommentsInside(node)
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The project's memo wrapper: the module `use-custom-memo`'s fixer points every
3
+ * `import { memo } from 'react'` at. It re-exports React's `memo`, so a rule
4
+ * that recognises a `memo(...)` call has to accept this module's binding as
5
+ * React's — keying recognition on the `'react'` spelling alone lets that fixer
6
+ * switch the recogniser off on the very convention this plugin enforces.
7
+ *
8
+ * The quotes live inside the value because the fixer splices the specifier into
9
+ * emitted import text verbatim, beside `sourceCode.getText(node.source)`, which
10
+ * carries its own quotes.
11
+ */
12
+ export declare const CUSTOM_MEMO_MODULE_SOURCE = "'src/util/memo'";
13
+ /** `CUSTOM_MEMO_MODULE_SOURCE` carries the quotes the fixer emits; a path never does. */
14
+ export declare const CUSTOM_MEMO_MODULE_PATH: string;
15
+ /** Whether an import specifier, read alone, names the memo wrapper module. */
16
+ export declare const isCustomMemoModuleSource: (source: string) => boolean;
17
+ /**
18
+ * Whether `source`, imported from `filename`, names the memo wrapper module.
19
+ *
20
+ * A relative specifier is resolved against the importing file before matching,
21
+ * because a file that sits inside the wrapper's own directory spells the same
22
+ * module `../memo` — a specifier naming no `util` segment of its own. Only
23
+ * relative specifiers resolve: a bare specifier is a package or an alias whose
24
+ * target the linter cannot know without a resolver.
25
+ */
26
+ export declare const isCustomMemoModuleImport: (source: string, filename?: string) => boolean;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isCustomMemoModuleImport = exports.isCustomMemoModuleSource = exports.CUSTOM_MEMO_MODULE_PATH = exports.CUSTOM_MEMO_MODULE_SOURCE = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ /**
9
+ * The project's memo wrapper: the module `use-custom-memo`'s fixer points every
10
+ * `import { memo } from 'react'` at. It re-exports React's `memo`, so a rule
11
+ * that recognises a `memo(...)` call has to accept this module's binding as
12
+ * React's — keying recognition on the `'react'` spelling alone lets that fixer
13
+ * switch the recogniser off on the very convention this plugin enforces.
14
+ *
15
+ * The quotes live inside the value because the fixer splices the specifier into
16
+ * emitted import text verbatim, beside `sourceCode.getText(node.source)`, which
17
+ * carries its own quotes.
18
+ */
19
+ exports.CUSTOM_MEMO_MODULE_SOURCE = `'src/util/memo'`;
20
+ /** `CUSTOM_MEMO_MODULE_SOURCE` carries the quotes the fixer emits; a path never does. */
21
+ exports.CUSTOM_MEMO_MODULE_PATH = exports.CUSTOM_MEMO_MODULE_SOURCE.slice(1, -1);
22
+ /**
23
+ * The trailing segments that identify the wrapper module however it is spelled.
24
+ * Only the leading segments vary between spellings of the same module — the
25
+ * `src/` alias the fixer emits, a `@/` alias, or any depth of `../` — so the
26
+ * tail is what a specifier has to carry. It has to land on a segment boundary,
27
+ * so `./memo`, `lodash-memo` and `react-memo` name other modules and stay out.
28
+ */
29
+ const MODULE_TAIL = exports.CUSTOM_MEMO_MODULE_PATH.split('/').slice(-2).join('/');
30
+ const MODULE_TAIL_PATTERN = new RegExp(`(?:^|/)${MODULE_TAIL}$`);
31
+ /** Whether an import specifier, read alone, names the memo wrapper module. */
32
+ const isCustomMemoModuleSource = (source) => MODULE_TAIL_PATTERN.test(source);
33
+ exports.isCustomMemoModuleSource = isCustomMemoModuleSource;
34
+ /**
35
+ * Whether `source`, imported from `filename`, names the memo wrapper module.
36
+ *
37
+ * A relative specifier is resolved against the importing file before matching,
38
+ * because a file that sits inside the wrapper's own directory spells the same
39
+ * module `../memo` — a specifier naming no `util` segment of its own. Only
40
+ * relative specifiers resolve: a bare specifier is a package or an alias whose
41
+ * target the linter cannot know without a resolver.
42
+ */
43
+ const isCustomMemoModuleImport = (source, filename) => {
44
+ if ((0, exports.isCustomMemoModuleSource)(source)) {
45
+ return true;
46
+ }
47
+ if (!filename || !source.startsWith('.')) {
48
+ return false;
49
+ }
50
+ const importerDirectory = path_1.default.posix.dirname(filename.replace(/\\/g, '/'));
51
+ return (0, exports.isCustomMemoModuleSource)(path_1.default.posix.normalize(path_1.default.posix.join(importerDirectory, source)));
52
+ };
53
+ exports.isCustomMemoModuleImport = isCustomMemoModuleImport;
54
+ //# sourceMappingURL=memoModule.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.21.2",
3
+ "version": "1.21.3",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,138 @@
1
1
  [
2
+ {
3
+ "version": "1.21.3",
4
+ "date": "2026-09-03T23:34:34.310Z",
5
+ "rules": [
6
+ {
7
+ "name": "enforce-boolean-naming-prefixes",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 2308
11
+ ],
12
+ "summary": "accept `??` as a boolean fallback operator (closes #2308)"
13
+ },
14
+ {
15
+ "name": "enforce-centralized-mock-firestore",
16
+ "changeType": "fix",
17
+ "issues": [
18
+ 2307
19
+ ],
20
+ "summary": "match the local mock by normalized name so a MOCK_FIRESTORE constant is flagged (closes #2307)"
21
+ },
22
+ {
23
+ "name": "enforce-fieldpath-syntax-in-docsetter",
24
+ "changeType": "fix",
25
+ "issues": [
26
+ 2303
27
+ ],
28
+ "summary": "decline the fix when a flattened key collides (closes #2303)"
29
+ },
30
+ {
31
+ "name": "enforce-firestore-set-merge",
32
+ "changeType": "fix",
33
+ "issues": [
34
+ 2311
35
+ ],
36
+ "summary": "decline the merge rewrite on update's varargs and precondition forms (closes #2311)"
37
+ },
38
+ {
39
+ "name": "enforce-object-literal-as-const",
40
+ "changeType": "fix",
41
+ "issues": [
42
+ 2319
43
+ ],
44
+ "summary": "fall back to the sole return's own assertion for the declared type (closes #2319)"
45
+ },
46
+ {
47
+ "name": "enforce-positive-naming",
48
+ "changeType": "fix",
49
+ "issues": [
50
+ 2306
51
+ ],
52
+ "summary": "make the boolean-like gate spelling-independent (closes #2306)"
53
+ },
54
+ {
55
+ "name": "enforce-snapshot-state-narrowing",
56
+ "changeType": "fix",
57
+ "issues": [
58
+ 2315
59
+ ],
60
+ "summary": "accept ?? alongside || in the logical guard (closes #2315)"
61
+ },
62
+ {
63
+ "name": "memo-nested-react-components",
64
+ "changeType": "fix",
65
+ "issues": [
66
+ 2313
67
+ ],
68
+ "summary": "admit useLatestCallback as a callback hook (closes #2313)"
69
+ },
70
+ {
71
+ "name": "no-entire-object-hook-deps",
72
+ "changeType": "fix",
73
+ "issues": [
74
+ 2309
75
+ ],
76
+ "summary": "govern the deep-compare hooks, which the useMemo rename walked out of view (closes #2309)"
77
+ },
78
+ {
79
+ "name": "no-hungarian",
80
+ "changeType": "fix",
81
+ "issues": [
82
+ 2317
83
+ ],
84
+ "summary": "read a leading single-letter segment as a prefix in SCREAMING_SNAKE_CASE (closes #2317)"
85
+ },
86
+ {
87
+ "name": "no-inline-component-prop",
88
+ "changeType": "fix",
89
+ "issues": [
90
+ 2314
91
+ ],
92
+ "summary": "resolve a memo(namedReference) argument to its declaration (closes #2314)"
93
+ },
94
+ {
95
+ "name": "no-restricted-properties-fix",
96
+ "changeType": "fix",
97
+ "issues": [
98
+ 2318
99
+ ],
100
+ "summary": "match a configured object through global-const-style's rename (closes #2318)"
101
+ },
102
+ {
103
+ "name": "no-useless-usememo-primitives",
104
+ "changeType": "fix",
105
+ "issues": [
106
+ 2312
107
+ ],
108
+ "summary": "recognise the deep-compare memo spelling so a renamed callee still reports (closes #2312)"
109
+ },
110
+ {
111
+ "name": "prefer-destructuring-no-class",
112
+ "changeType": "fix",
113
+ "issues": [
114
+ 2316
115
+ ],
116
+ "summary": "match a binding to its property ignoring case and underscores (closes #2316)"
117
+ },
118
+ {
119
+ "name": "prefer-document-flattening",
120
+ "changeType": "fix",
121
+ "issues": [
122
+ 2304
123
+ ],
124
+ "summary": "rewrite an existing shouldFlatten in place rather than appending a duplicate key (closes #2304)"
125
+ },
126
+ {
127
+ "name": "require-memoize-jsx-returners",
128
+ "changeType": "fix",
129
+ "issues": [
130
+ 2305
131
+ ],
132
+ "summary": "re-cut the degenerate-identifier duplicate ceiling for the wrapper-memo fixtures (closes #2305); recognise memo imported from the project memo wrapper (closes #2305)"
133
+ }
134
+ ]
135
+ },
2
136
  {
3
137
  "version": "1.21.2",
4
138
  "date": "2026-09-03T01:55:23.074Z",