@blumintinc/eslint-plugin-blumint 1.18.8 β†’ 1.18.9

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/README.md CHANGED
@@ -114,7 +114,7 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
114
114
  | [enforce-id-capitalization](docs/rules/enforce-id-capitalization.md) | Enforce the use of "ID" instead of "id" in user-facing text | βœ… | | | πŸ”§ | | |
115
115
  | [enforce-identifiable-firestore-type](docs/rules/enforce-identifiable-firestore-type.md) | Enforce that Firestore type definitions extend Identifiable and match their folder name | βœ… | | | | | |
116
116
  | [enforce-is-prefix-validators](docs/rules/enforce-is-prefix-validators.md) | Enforce the `is` (or other allowed predicate) prefix for exported validators in **/validators/**/*.ts files | βœ… | | | | | |
117
- | [enforce-m3-sentence-case](docs/rules/enforce-m3-sentence-case.md) | Enforce Material Design 3 sentence-case capitalisation for user-facing text β€” flag Title Case and ALL CAPS strings in JSX text and configured string props. | | βœ… | | | πŸ’‘ | |
117
+ | [enforce-m3-sentence-case](docs/rules/enforce-m3-sentence-case.md) | Enforce Material Design 3 sentence-case capitalisation for user-facing text β€” flag Title Case and ALL CAPS strings in JSX text and configured string props. | βœ… | | | | πŸ’‘ | |
118
118
  | [enforce-memoize-async](docs/rules/enforce-memoize-async.md) | Enforce @Memoize() decorator on async methods with 0-1 parameters to cache results and prevent redundant API calls or expensive computations. Without memoization, repeated calls trigger redundant requests or expensive computations, increasing latency. @Memoize() caches results by parameter, ensuring subsequent calls with identical inputs return immediately. | βœ… | | | πŸ”§ | | |
119
119
  | [enforce-memoize-getters](docs/rules/enforce-memoize-getters.md) | Enforce @Memoize() decorator on private class getters to avoid re-instantiation and preserve state across accesses. | βœ… | | | πŸ”§ | | |
120
120
  | [enforce-microdiff](docs/rules/enforce-microdiff.md) | Enforce using microdiff for object and array comparison operations | βœ… | | | πŸ”§ | | |
@@ -163,7 +163,7 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
163
163
  | [no-complex-cloud-params](docs/rules/no-complex-cloud-params.md) | Disallow passing complex objects to cloud functions | βœ… | | | | | |
164
164
  | [no-compositing-layer-props](docs/rules/no-compositing-layer-props.md) | Discourage CSS properties that force GPU compositing layers (e.g., transform, filter, will-change). Extra layers consume GPU memory and split rendering work, which slows scrolling and animation when sprinkled across a page. The rule inspects inline style objects and MUI sx props so layer promotion stays intentional rather than incidental. | βœ… | | | | | |
165
165
  | [no-conditional-literals-in-jsx](docs/rules/no-conditional-literals-in-jsx.md) | Disallow conditional string literals beside other JSX text to avoid fragmented text nodes, translation issues, and hydration mismatches. | βœ… | | | | | |
166
- | [no-console-error](docs/rules/no-console-error.md) | Disallow console.error so errors flow through structured handling (HttpsError/useErrorAlert on frontend, structured loggers on backend). | | βœ… | | | | |
166
+ | [no-console-error](docs/rules/no-console-error.md) | Disallow console.error so errors flow through structured handling (HttpsError/useErrorAlert on frontend, structured loggers on backend). | βœ… | | | | | |
167
167
  | [no-curly-brackets-around-commented-properties](docs/rules/no-curly-brackets-around-commented-properties.md) | Disallow curly-brace blocks that only wrap commented-out members inside type declarations | βœ… | | | πŸ”§ | | |
168
168
  | [no-direct-function-state](docs/rules/no-direct-function-state.md) | Prevent passing a function directly to a useState setter β€” React will invoke it as a functional updater instead of storing it. Wrap in a thunk: setState(() => fn). | βœ… | | | πŸ”§ | | |
169
169
  | [no-empty-dependency-use-callbacks](docs/rules/no-empty-dependency-use-callbacks.md) | Discourage useCallback([]) or useLatestCallback around static functions. Static callbacks do not need hook machineryβ€”extract them to module-level utilities for clarity and to avoid unnecessary hook overhead. | βœ… | | | πŸ”§ | | |
@@ -227,8 +227,8 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
227
227
  | [prefer-destructuring-no-class](docs/rules/prefer-destructuring-no-class.md) | Enforce destructuring when accessing object properties, except for class instances | βœ… | | | πŸ”§ | | |
228
228
  | [prefer-docsetter-setall](docs/rules/prefer-docsetter-setall.md) | Enforce batching DocSetter and DocSetterTransaction writes by using setAll instead of set inside loops or array callbacks. | βœ… | | | | | |
229
229
  | [prefer-document-flattening](docs/rules/prefer-document-flattening.md) | Enforce using the shouldFlatten option when setting deeply nested objects in Firestore documents | | | | | πŸ’‘ | |
230
- | [prefer-field-paths-in-transforms](docs/rules/prefer-field-paths-in-transforms.md) | Flatten aggregation updates inside transformEach so diff-based deletes remove only the intended fields instead of wiping sibling data. | | βœ… | | πŸ”§ | | |
231
- | [prefer-flat-transform-each-keys](docs/rules/prefer-flat-transform-each-keys.md) | Warn when transformEach in a propagation strategy returns nested object values instead of flat dot-notation keys. | | βœ… | | | | |
230
+ | [prefer-field-paths-in-transforms](docs/rules/prefer-field-paths-in-transforms.md) | Flatten aggregation updates inside transformEach so diff-based deletes remove only the intended fields instead of wiping sibling data. | βœ… | | | πŸ”§ | | |
231
+ | [prefer-flat-transform-each-keys](docs/rules/prefer-flat-transform-each-keys.md) | Warn when transformEach in a propagation strategy returns nested object values instead of flat dot-notation keys. | βœ… | | | | | |
232
232
  | [prefer-fragment-component](docs/rules/prefer-fragment-component.md) | Require the Fragment named import instead of shorthand fragments or React.Fragment to keep fragments explicit and prop-friendly | | | βœ… | πŸ”§ | | |
233
233
  | [prefer-fragment-shorthand](docs/rules/prefer-fragment-shorthand.md) | Prefer <> shorthand for <React.Fragment> | βœ… | | | πŸ”§ | | |
234
234
  | [prefer-getter-over-parameterless-method](docs/rules/prefer-getter-over-parameterless-method.md) | Enforce getter syntax for synchronous parameterless methods that return values, improving semantic clarity and avoiding accidental method invocation without parentheses. | βœ… | | | πŸ”§ | | |
@@ -248,7 +248,7 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
248
248
  | [prefer-usecallback-over-usememo-for-functions](docs/rules/prefer-usecallback-over-usememo-for-functions.md) | Enforce using useCallback instead of useMemo for memoizing functions | βœ… | | | πŸ”§ | | |
249
249
  | [prefer-usememo-over-useeffect-usestate](docs/rules/prefer-usememo-over-useeffect-usestate.md) | Prefer useMemo over useEffect + useState for pure computations to avoid extra render cycles and stale derived state. | βœ… | | | | | |
250
250
  | [prefer-utility-function-over-private-static](docs/rules/prefer-utility-function-over-private-static.md) | Enforce abstraction of private static methods into utility functions | βœ… | | | | | |
251
- | [prefer-utility-function-own-file](docs/rules/prefer-utility-function-own-file.md) | Enforce that sizable utility functions live in their own file rather than being co-located inside an entry-point or consumer file | | βœ… | | | | |
251
+ | [prefer-utility-function-own-file](docs/rules/prefer-utility-function-own-file.md) | Enforce that sizable utility functions live in their own file rather than being co-located inside an entry-point or consumer file | βœ… | | | | | |
252
252
  | [prevent-children-clobber](docs/rules/prevent-children-clobber.md) | Prevent JSX spreads from silently discarding props.children | βœ… | | | | | |
253
253
  | [react-memoize-literals](docs/rules/react-memoize-literals.md) | Detect object, array, and function literals created in React components or hooks that create new references every render. Prefer memoized values (useMemo/useCallback) or module-level constants to keep referential stability. | βœ… | | | | πŸ’‘ | |
254
254
  | [react-usememo-should-be-component](docs/rules/react-usememo-should-be-component.md) | Enforce that useMemo hooks explicitly returning JSX should be abstracted into separate React components | βœ… | | | | | |
@@ -260,7 +260,7 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
260
260
  | [require-memo](docs/rules/require-memo.md) | React components must be memoized | βœ… | | | πŸ”§ | | |
261
261
  | [require-memoize-jsx-returners](docs/rules/require-memoize-jsx-returners.md) | Require @Memoize() decorator on instance members that return JSX or JSX factories | βœ… | | | πŸ”§ | | |
262
262
  | [require-migration-script-metadata](docs/rules/require-migration-script-metadata.md) | Enforce JSDoc migration metadata in callable scripts | βœ… | | | | | |
263
- | [require-props-composition](docs/rules/require-props-composition.md) | Require React component Props types to compose (via Pick/Omit) with the props types of non-leaf child components rendered in JSX | | βœ… | | | | |
263
+ | [require-props-composition](docs/rules/require-props-composition.md) | Require React component Props types to compose (via Pick/Omit) with the props types of non-leaf child components rendered in JSX | βœ… | | | | | |
264
264
  | [require-server-timestamp-for-firestore-dates](docs/rules/require-server-timestamp-for-firestore-dates.md) | Enforce serverTimestamp() instead of new Date() for Firestore timestamp fields | βœ… | | | | | |
265
265
  | [semantic-function-prefixes](docs/rules/semantic-function-prefixes.md) | Require semantic function prefixes instead of generic verbs so callers know whether a function fetches data, transforms input, or mutates state | βœ… | | | | | |
266
266
  | [sync-onwrite-name-func](docs/rules/sync-onwrite-name-func.md) | Ensure that the name field matches the func field in onWrite handlers | βœ… | | | πŸ”§ | | |
@@ -270,7 +270,7 @@ full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.
270
270
  | [use-custom-router](docs/rules/use-custom-router.md) | Enforce using src/hooks/routing/useRouter instead of next/router | βœ… | | | πŸ”§ | | |
271
271
  | [use-latest-callback](docs/rules/use-latest-callback.md) | Enforce using useLatestCallback from use-latest-callback instead of React useCallback | βœ… | | | πŸ”§ | | |
272
272
  | [vertically-group-related-functions](docs/rules/vertically-group-related-functions.md) | Keep top-level functions grouped vertically so callers, exports, and helpers read top-down. | βœ… | | | πŸ”§ | | |
273
- | [warn-https-error-message-user-friendly](docs/rules/warn-https-error-message-user-friendly.md) | Warn when messageUserFriendly is used in HttpsError or toHttpsError to ensure it is truly a user-caused error. | | βœ… | | | | |
273
+ | [warn-https-error-message-user-friendly](docs/rules/warn-https-error-message-user-friendly.md) | Warn when messageUserFriendly is used in HttpsError or toHttpsError to ensure it is truly a user-caused error. | βœ… | | | | | |
274
274
 
275
275
  <!-- end auto-generated rules list -->
276
276
 
package/lib/index.js CHANGED
@@ -218,7 +218,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
218
218
  module.exports = {
219
219
  meta: {
220
220
  name: '@blumintinc/eslint-plugin-blumint',
221
- version: '1.18.8',
221
+ version: '1.18.9',
222
222
  },
223
223
  parseOptions: {
224
224
  ecmaVersion: 2020,
@@ -262,7 +262,7 @@ module.exports = {
262
262
  '@blumintinc/blumint/no-async-array-filter': 'error',
263
263
  '@blumintinc/blumint/no-async-foreach': 'error',
264
264
  '@blumintinc/blumint/no-console-error': [
265
- 'warn',
265
+ 'error',
266
266
  { allowWithUseAlertDialog: true },
267
267
  ],
268
268
  '@blumintinc/blumint/no-conditional-literals-in-jsx': 'error',
@@ -375,7 +375,7 @@ module.exports = {
375
375
  '@blumintinc/blumint/no-separate-loading-state': 'error',
376
376
  '@blumintinc/blumint/optimize-object-boolean-conditions': 'error',
377
377
  '@blumintinc/blumint/prefer-params-over-parent-id': 'error',
378
- '@blumintinc/blumint/prefer-field-paths-in-transforms': 'warn',
378
+ '@blumintinc/blumint/prefer-field-paths-in-transforms': 'error',
379
379
  '@blumintinc/blumint/no-misleading-boolean-prefixes': 'error',
380
380
  '@blumintinc/blumint/prefer-url-tostring-over-tojson': 'error',
381
381
  '@blumintinc/blumint/prefer-next-dynamic': 'error',
@@ -397,12 +397,12 @@ module.exports = {
397
397
  '@blumintinc/blumint/no-static-constants-in-dynamic-files': 'error',
398
398
  '@blumintinc/blumint/test-file-location-enforcement': 'error',
399
399
  '@blumintinc/blumint/require-migration-script-metadata': 'error',
400
- '@blumintinc/blumint/warn-https-error-message-user-friendly': 'warn',
401
- '@blumintinc/blumint/require-props-composition': 'warn',
400
+ '@blumintinc/blumint/warn-https-error-message-user-friendly': 'error',
401
+ '@blumintinc/blumint/require-props-composition': 'error',
402
402
  '@blumintinc/blumint/require-server-timestamp-for-firestore-dates': 'error',
403
403
  '@blumintinc/blumint/prefer-spread-over-reassembly': 'error',
404
404
  '@blumintinc/blumint/prefer-sx-prop-over-system-props': 'error',
405
- '@blumintinc/blumint/enforce-m3-sentence-case': 'warn',
405
+ '@blumintinc/blumint/enforce-m3-sentence-case': 'error',
406
406
  '@blumintinc/blumint/no-redundant-boolean-callback-props': 'error',
407
407
  '@blumintinc/blumint/enforce-is-prefix-validators': 'error',
408
408
  '@blumintinc/blumint/enforce-types-directory-placement': 'error',
@@ -410,12 +410,12 @@ module.exports = {
410
410
  '@blumintinc/blumint/no-direct-function-state': 'error',
411
411
  '@blumintinc/blumint/no-fill-template-mutation': 'error',
412
412
  '@blumintinc/blumint/enforce-snapshot-state-narrowing': 'error',
413
- '@blumintinc/blumint/prefer-flat-transform-each-keys': 'warn',
413
+ '@blumintinc/blumint/prefer-flat-transform-each-keys': 'error',
414
414
  '@blumintinc/blumint/prefer-use-theme': 'error',
415
415
  '@blumintinc/blumint/no-single-dismiss-dialog-button': 'error',
416
416
  '@blumintinc/blumint/no-portal-inside-tooltip': 'error',
417
417
  '@blumintinc/blumint/no-satisfies-in-frontend-bundle': 'error',
418
- '@blumintinc/blumint/prefer-utility-function-own-file': 'warn',
418
+ '@blumintinc/blumint/prefer-utility-function-own-file': 'error',
419
419
  },
420
420
  /**
421
421
  * Depth-specific overrides block only import strings that traverse to the
@@ -19,7 +19,7 @@ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
19
19
  type: 'suggestion',
20
20
  docs: {
21
21
  description: 'Enforces a top-to-bottom class layout so callers lead into the helpers they rely on.',
22
- recommended: 'warn',
22
+ recommended: 'error',
23
23
  },
24
24
  schema: [],
25
25
  messages: {
@@ -257,7 +257,7 @@ exports.enforceM3SentenceCase = (0, createRule_1.createRule)({
257
257
  type: 'suggestion',
258
258
  docs: {
259
259
  description: 'Enforce Material Design 3 sentence-case capitalisation for user-facing text β€” flag Title Case and ALL CAPS strings in JSX text and configured string props.',
260
- recommended: 'warn',
260
+ recommended: 'error',
261
261
  },
262
262
  hasSuggestions: true,
263
263
  schema: [
@@ -9,7 +9,7 @@ exports.enforcePropsNamingConsistency = (0, createRule_1.createRule)({
9
9
  type: 'suggestion',
10
10
  docs: {
11
11
  description: 'Prefer naming single "Props"-typed parameters as "props"; enforcement defers to enforce-props-argument-name for multi-Props cases',
12
- recommended: 'warn',
12
+ recommended: 'error',
13
13
  },
14
14
  fixable: 'code',
15
15
  schema: [],
@@ -440,7 +440,7 @@ exports.noConsoleError = (0, createRule_1.createRule)({
440
440
  type: 'problem',
441
441
  docs: {
442
442
  description: 'Disallow console.error so errors flow through structured handling (HttpsError/useErrorAlert on frontend, structured loggers on backend).',
443
- recommended: 'warn',
443
+ recommended: 'error',
444
444
  },
445
445
  schema: [
446
446
  {
@@ -156,7 +156,7 @@ exports.noFirestoreObjectArrays = (0, createRule_1.createRule)({
156
156
  type: 'problem',
157
157
  docs: {
158
158
  description: 'Disallow arrays of object types in Firestore models. Prefer Record maps keyed by id with an index field, or subcollections/arrays of IDs.',
159
- recommended: 'warn',
159
+ recommended: 'error',
160
160
  requiresTypeChecking: false,
161
161
  },
162
162
  schema: [],
@@ -40,7 +40,7 @@ exports.noMarginProperties = (0, createRule_1.createRule)({
40
40
  type: 'suggestion',
41
41
  docs: {
42
42
  description: 'Prevent margin properties (margin, marginLeft, marginRight, marginTop, marginBottom, mx, my, etc.) in MUI styling because margins fight container-controlled spacing, double gutters, and misaligned breakpoints; keep spacing centralized with padding, gap, or spacing props instead.',
43
- recommended: 'warn',
43
+ recommended: 'error',
44
44
  },
45
45
  schema: [
46
46
  {
@@ -167,7 +167,7 @@ exports.preferFieldPathsInTransforms = (0, createRule_1.createRule)({
167
167
  type: 'suggestion',
168
168
  docs: {
169
169
  description: 'Flatten aggregation updates inside transformEach so diff-based deletes remove only the intended fields instead of wiping sibling data.',
170
- recommended: 'warn',
170
+ recommended: 'error',
171
171
  },
172
172
  fixable: 'code',
173
173
  schema: [
@@ -174,7 +174,7 @@ exports.preferFlatTransformEachKeys = (0, createRule_1.createRule)({
174
174
  type: 'suggestion',
175
175
  docs: {
176
176
  description: 'Warn when transformEach in a propagation strategy returns nested object values instead of flat dot-notation keys.',
177
- recommended: 'warn',
177
+ recommended: 'error',
178
178
  },
179
179
  fixable: undefined,
180
180
  schema: [],
@@ -225,7 +225,7 @@ exports.preferUtilityFunctionOwnFile = (0, createRule_1.createRule)({
225
225
  type: 'suggestion',
226
226
  docs: {
227
227
  description: 'Enforce that sizable utility functions live in their own file rather than being co-located inside an entry-point or consumer file',
228
- recommended: 'warn',
228
+ recommended: 'error',
229
229
  },
230
230
  schema: [
231
231
  {
@@ -242,7 +242,7 @@ exports.requirePropsComposition = (0, createRule_1.createRule)({
242
242
  type: 'suggestion',
243
243
  docs: {
244
244
  description: 'Require React component Props types to compose (via Pick/Omit) with the props types of non-leaf child components rendered in JSX',
245
- recommended: 'warn',
245
+ recommended: 'error',
246
246
  },
247
247
  fixable: undefined,
248
248
  schema: [
@@ -10,7 +10,7 @@ exports.warnHttpsErrorMessageUserFriendly = (0, createRule_1.createRule)({
10
10
  type: 'suggestion',
11
11
  docs: {
12
12
  description: 'Warn when messageUserFriendly is used in HttpsError or toHttpsError to ensure it is truly a user-caused error.',
13
- recommended: 'warn',
13
+ recommended: 'error',
14
14
  },
15
15
  fixable: undefined,
16
16
  schema: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.18.8",
3
+ "version": "1.18.9",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,98 @@
1
1
  [
2
+ {
3
+ "version": "1.18.9",
4
+ "date": "2026-07-11T01:51:22.294Z",
5
+ "rules": [
6
+ {
7
+ "name": "class-methods-read-top-to-bottom",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1282
11
+ ],
12
+ "summary": "align recommended meta with error config (closes #1282)"
13
+ },
14
+ {
15
+ "name": "enforce-m3-sentence-case",
16
+ "changeType": "fix",
17
+ "issues": [
18
+ 1282
19
+ ],
20
+ "summary": "bump recommended severity to error (closes #1282)"
21
+ },
22
+ {
23
+ "name": "enforce-props-naming-consistency",
24
+ "changeType": "fix",
25
+ "issues": [
26
+ 1282
27
+ ],
28
+ "summary": "align recommended meta with error config (closes #1282)"
29
+ },
30
+ {
31
+ "name": "no-console-error",
32
+ "changeType": "fix",
33
+ "issues": [
34
+ 1282
35
+ ],
36
+ "summary": "bump recommended severity to error (closes #1282)"
37
+ },
38
+ {
39
+ "name": "no-firestore-object-arrays",
40
+ "changeType": "fix",
41
+ "issues": [
42
+ 1282
43
+ ],
44
+ "summary": "align recommended meta with error config (closes #1282)"
45
+ },
46
+ {
47
+ "name": "no-margin-properties",
48
+ "changeType": "fix",
49
+ "issues": [
50
+ 1282
51
+ ],
52
+ "summary": "align recommended meta with error config (closes #1282)"
53
+ },
54
+ {
55
+ "name": "prefer-field-paths-in-transforms",
56
+ "changeType": "fix",
57
+ "issues": [
58
+ 1282
59
+ ],
60
+ "summary": "bump recommended severity to error (closes #1282)"
61
+ },
62
+ {
63
+ "name": "prefer-flat-transform-each-keys",
64
+ "changeType": "fix",
65
+ "issues": [
66
+ 1282
67
+ ],
68
+ "summary": "bump recommended severity to error (closes #1282)"
69
+ },
70
+ {
71
+ "name": "prefer-utility-function-own-file",
72
+ "changeType": "fix",
73
+ "issues": [
74
+ 1282
75
+ ],
76
+ "summary": "bump recommended severity to error (closes #1282)"
77
+ },
78
+ {
79
+ "name": "require-props-composition",
80
+ "changeType": "fix",
81
+ "issues": [
82
+ 1282
83
+ ],
84
+ "summary": "bump recommended severity to error (closes #1282)"
85
+ },
86
+ {
87
+ "name": "warn-https-error-message-user-friendly",
88
+ "changeType": "fix",
89
+ "issues": [
90
+ 1282
91
+ ],
92
+ "summary": "bump recommended severity to error (closes #1282)"
93
+ }
94
+ ]
95
+ },
2
96
  {
3
97
  "version": "1.18.8",
4
98
  "date": "2026-07-10T21:29:12.501Z",