@blumintinc/eslint-plugin-blumint 1.12.5 → 1.13.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.
Files changed (142) hide show
  1. package/README.md +140 -99
  2. package/lib/index.js +111 -20
  3. package/lib/rules/array-methods-this-context.js +20 -2
  4. package/lib/rules/avoid-utils-directory.js +11 -2
  5. package/lib/rules/dynamic-https-errors.d.ts +3 -1
  6. package/lib/rules/dynamic-https-errors.js +48 -10
  7. package/lib/rules/enforce-assert-safe-object-key.d.ts +8 -0
  8. package/lib/rules/{enforce-assertSafe-object-key.js → enforce-assert-safe-object-key.js} +51 -95
  9. package/lib/rules/enforce-assert-throws.d.ts +3 -1
  10. package/lib/rules/enforce-assert-throws.js +493 -51
  11. package/lib/rules/enforce-boolean-naming-prefixes.d.ts +3 -1
  12. package/lib/rules/enforce-boolean-naming-prefixes.js +832 -39
  13. package/lib/rules/enforce-callable-types.js +4 -4
  14. package/lib/rules/enforce-callback-memo.js +143 -18
  15. package/lib/rules/enforce-centralized-mock-firestore.js +4 -1
  16. package/lib/rules/enforce-console-error.d.ts +3 -0
  17. package/lib/rules/enforce-console-error.js +250 -0
  18. package/lib/rules/enforce-css-media-queries.js +24 -46
  19. package/lib/rules/enforce-dynamic-firebase-imports.js +100 -19
  20. package/lib/rules/enforce-dynamic-imports.js +1 -1
  21. package/lib/rules/enforce-exported-function-types.js +3 -3
  22. package/lib/rules/enforce-fieldpath-syntax-in-docsetter.d.ts +2 -0
  23. package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +212 -0
  24. package/lib/rules/enforce-firestore-doc-ref-generic.js +335 -0
  25. package/lib/rules/enforce-firestore-facade.js +347 -157
  26. package/lib/rules/enforce-firestore-rules-get-access.d.ts +3 -0
  27. package/lib/rules/enforce-firestore-rules-get-access.js +109 -0
  28. package/lib/rules/enforce-global-constants.d.ts +4 -1
  29. package/lib/rules/enforce-global-constants.js +240 -12
  30. package/lib/rules/enforce-memoize-async.d.ts +2 -1
  31. package/lib/rules/enforce-memoize-async.js +96 -27
  32. package/lib/rules/enforce-memoize-getters.d.ts +3 -0
  33. package/lib/rules/enforce-memoize-getters.js +123 -0
  34. package/lib/rules/enforce-microdiff.js +2 -1
  35. package/lib/rules/enforce-positive-naming.js +5 -7
  36. package/lib/rules/enforce-props-argument-name.d.ts +2 -7
  37. package/lib/rules/enforce-props-argument-name.js +165 -151
  38. package/lib/rules/enforce-props-naming-consistency.d.ts +2 -0
  39. package/lib/rules/enforce-props-naming-consistency.js +145 -0
  40. package/lib/rules/enforce-querykey-ts.d.ts +9 -0
  41. package/lib/rules/enforce-querykey-ts.js +274 -0
  42. package/lib/rules/enforce-singular-type-names.js +9 -5
  43. package/lib/rules/enforce-typescript-markdown-code-blocks.d.ts +1 -0
  44. package/lib/rules/enforce-typescript-markdown-code-blocks.js +96 -0
  45. package/lib/rules/enforce-verb-noun-naming.js +85 -10
  46. package/lib/rules/extract-global-constants.js +57 -45
  47. package/lib/rules/fast-deep-equal-over-microdiff.d.ts +2 -1
  48. package/lib/rules/fast-deep-equal-over-microdiff.js +356 -78
  49. package/lib/rules/firestore-transaction-reads-before-writes.d.ts +1 -0
  50. package/lib/rules/firestore-transaction-reads-before-writes.js +231 -0
  51. package/lib/rules/generic-starts-with-t.js +8 -2
  52. package/lib/rules/memoize-root-level-hocs.d.ts +7 -0
  53. package/lib/rules/memoize-root-level-hocs.js +242 -0
  54. package/lib/rules/no-array-length-in-deps.d.ts +12 -0
  55. package/lib/rules/no-array-length-in-deps.js +308 -0
  56. package/lib/rules/no-async-array-filter.js +5 -2
  57. package/lib/rules/no-complex-cloud-params.js +15 -2
  58. package/lib/rules/no-compositing-layer-props.js +4 -2
  59. package/lib/rules/no-entire-object-hook-deps.d.ts +3 -1
  60. package/lib/rules/no-entire-object-hook-deps.js +317 -63
  61. package/lib/rules/no-excessive-parent-chain.d.ts +5 -0
  62. package/lib/rules/no-excessive-parent-chain.js +273 -0
  63. package/lib/rules/no-firestore-object-arrays.js +345 -30
  64. package/lib/rules/no-hungarian.js +13 -13
  65. package/lib/rules/no-margin-properties.d.ts +7 -1
  66. package/lib/rules/no-margin-properties.js +16 -3
  67. package/lib/rules/no-misleading-boolean-prefixes.d.ts +7 -0
  68. package/lib/rules/no-misleading-boolean-prefixes.js +327 -0
  69. package/lib/rules/no-overridable-method-calls-in-constructor.d.ts +1 -0
  70. package/lib/rules/no-overridable-method-calls-in-constructor.js +260 -0
  71. package/lib/rules/no-passthrough-getters.d.ts +4 -0
  72. package/lib/rules/no-passthrough-getters.js +170 -0
  73. package/lib/rules/no-redundant-usecallback-wrapper.d.ts +8 -0
  74. package/lib/rules/no-redundant-usecallback-wrapper.js +315 -0
  75. package/lib/rules/no-restricted-properties-fix.d.ts +12 -0
  76. package/lib/rules/no-restricted-properties-fix.js +172 -0
  77. package/lib/rules/no-separate-loading-state.d.ts +8 -0
  78. package/lib/rules/no-separate-loading-state.js +142 -0
  79. package/lib/rules/no-stale-state-across-await.d.ts +1 -0
  80. package/lib/rules/no-stale-state-across-await.js +185 -0
  81. package/lib/rules/no-static-constants-in-dynamic-files.d.ts +3 -0
  82. package/lib/rules/no-static-constants-in-dynamic-files.js +149 -0
  83. package/lib/rules/no-try-catch-already-exists-in-transaction.d.ts +1 -0
  84. package/lib/rules/no-try-catch-already-exists-in-transaction.js +342 -0
  85. package/lib/rules/no-undefined-null-passthrough.js +166 -19
  86. package/lib/rules/no-unnecessary-verb-suffix.js +0 -2
  87. package/lib/rules/no-unsafe-firestore-spread.js +8 -5
  88. package/lib/rules/no-unused-props.d.ts +3 -0
  89. package/lib/rules/no-unused-props.js +213 -78
  90. package/lib/rules/optimize-object-boolean-conditions.d.ts +1 -0
  91. package/lib/rules/optimize-object-boolean-conditions.js +234 -0
  92. package/lib/rules/parallelize-async-operations.d.ts +8 -0
  93. package/lib/rules/parallelize-async-operations.js +375 -0
  94. package/lib/rules/prefer-batch-operations.js +199 -33
  95. package/lib/rules/prefer-block-comments-for-declarations.js +13 -3
  96. package/lib/rules/prefer-document-flattening.d.ts +4 -0
  97. package/lib/rules/prefer-document-flattening.js +239 -0
  98. package/lib/rules/prefer-field-paths-in-transforms.d.ts +7 -0
  99. package/lib/rules/prefer-field-paths-in-transforms.js +250 -0
  100. package/lib/rules/prefer-fragment-component.js +3 -3
  101. package/lib/rules/prefer-global-router-state-key.d.ts +7 -3
  102. package/lib/rules/prefer-global-router-state-key.js +230 -31
  103. package/lib/rules/prefer-next-dynamic.d.ts +9 -0
  104. package/lib/rules/prefer-next-dynamic.js +366 -0
  105. package/lib/rules/prefer-nullish-coalescing-boolean-props.d.ts +1 -0
  106. package/lib/rules/prefer-nullish-coalescing-boolean-props.js +430 -0
  107. package/lib/rules/prefer-nullish-coalescing-override.d.ts +6 -0
  108. package/lib/rules/prefer-nullish-coalescing-override.js +182 -0
  109. package/lib/rules/prefer-params-over-parent-id.d.ts +5 -0
  110. package/lib/rules/prefer-params-over-parent-id.js +228 -0
  111. package/lib/rules/prefer-settings-object.js +23 -15
  112. package/lib/rules/prefer-type-alias-over-typeof-constant.d.ts +3 -0
  113. package/lib/rules/prefer-type-alias-over-typeof-constant.js +259 -0
  114. package/lib/rules/prefer-url-tostring-over-tojson.d.ts +2 -0
  115. package/lib/rules/prefer-url-tostring-over-tojson.js +166 -0
  116. package/lib/rules/prefer-use-deep-compare-memo.d.ts +4 -0
  117. package/lib/rules/prefer-use-deep-compare-memo.js +428 -0
  118. package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +24 -1
  119. package/lib/rules/prefer-usememo-over-useeffect-usestate.js +24 -5
  120. package/lib/rules/react-usememo-should-be-component.d.ts +2 -1
  121. package/lib/rules/react-usememo-should-be-component.js +144 -78
  122. package/lib/rules/require-dynamic-firebase-imports.js +2 -1
  123. package/lib/rules/require-image-optimized.js +1 -1
  124. package/lib/rules/require-memo.js +11 -1
  125. package/lib/rules/require-usememo-object-literals.js +7 -1
  126. package/lib/rules/semantic-function-prefixes.js +38 -18
  127. package/lib/rules/sync-onwrite-name-func.js +5 -1
  128. package/lib/rules/test-file-location-enforcement.d.ts +1 -0
  129. package/lib/rules/test-file-location-enforcement.js +57 -0
  130. package/lib/rules/use-custom-link.js +6 -1
  131. package/lib/rules/use-custom-router.js +6 -1
  132. package/lib/rules/use-latest-callback.d.ts +3 -0
  133. package/lib/rules/use-latest-callback.js +270 -0
  134. package/lib/utils/ASTHelpers.js +10 -0
  135. package/lib/utils/createRule.js +1 -1
  136. package/lib/utils/graph/ClassGraphSorterReadability.js +1 -1
  137. package/lib/utils/ruleTester.d.ts +1 -0
  138. package/lib/utils/ruleTester.js +4 -1
  139. package/package.json +21 -14
  140. package/lib/rules/enforce-assertSafe-object-key.d.ts +0 -2
  141. package/lib/rules/no-restricted-imports-dynamic.d.ts +0 -25
  142. package/lib/rules/no-restricted-imports-dynamic.js +0 -213
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enforceAssertSafeObjectKey = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const createRule_1 = require("../utils/createRule");
6
+ const DEFAULT_IMPORT_PATH = 'functions/src/util/assertSafe';
6
7
  exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
7
- name: 'enforce-assertSafe-object-key',
8
+ name: 'enforce-assert-safe-object-key',
8
9
  meta: {
9
10
  type: 'problem',
10
11
  docs: {
@@ -12,13 +13,22 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
12
13
  recommended: 'error',
13
14
  },
14
15
  fixable: 'code',
15
- schema: [],
16
+ schema: [
17
+ {
18
+ type: 'object',
19
+ properties: {
20
+ assertSafeImportPath: { type: 'string' },
21
+ },
22
+ additionalProperties: false,
23
+ },
24
+ ],
16
25
  messages: {
17
- useAssertSafe: 'Use assertSafe() for object key access to ensure safe property access. Replace `obj[String(id)]` or `obj[`${id}`]` with `obj[assertSafe(id)]`.',
26
+ useAssertSafe: 'Dynamic object key "{{key}}" is used without assertSafe() validation. Unvalidated keys can resolve to unexpected properties (including prototype fields) and make lookups fragile or unsafe. Wrap the key with assertSafe({{key}}) before accessing the object.',
18
27
  },
19
28
  },
20
- defaultOptions: [],
21
- create(context) {
29
+ defaultOptions: [{}],
30
+ create(context, [options]) {
31
+ const importPath = options?.assertSafeImportPath || DEFAULT_IMPORT_PATH;
22
32
  let hasAssertSafeImport = false;
23
33
  /**
24
34
  * Helper function to add assertSafe import if needed
@@ -26,7 +36,7 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
26
36
  const addAssertSafeImport = (fixer) => {
27
37
  const program = context.getSourceCode().ast;
28
38
  const firstImport = program.body.find((node) => node.type === utils_1.AST_NODE_TYPES.ImportDeclaration);
29
- const importStatement = "import { assertSafe } from 'functions/src/util/assertSafe';\n";
39
+ const importStatement = `import { assertSafe } from '${importPath}';\n`;
30
40
  if (firstImport) {
31
41
  return fixer.insertTextBefore(firstImport, importStatement);
32
42
  }
@@ -48,6 +58,14 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
48
58
  fixes.push(fixer.replaceText(node, `assertSafe(${argText})`));
49
59
  return fixes;
50
60
  };
61
+ const reportUseAssertSafe = (node, expressionText) => context.report({
62
+ node,
63
+ messageId: 'useAssertSafe',
64
+ data: { key: expressionText },
65
+ fix(fixer) {
66
+ return createFixes(fixer, node, expressionText);
67
+ },
68
+ });
51
69
  return {
52
70
  ImportDeclaration(node) {
53
71
  // Check if assertSafe is already imported
@@ -64,15 +82,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
64
82
  if (key.type === utils_1.AST_NODE_TYPES.CallExpression &&
65
83
  key.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
66
84
  key.callee.name === 'String') {
67
- context.report({
68
- node: key,
69
- messageId: 'useAssertSafe',
70
- fix(fixer) {
71
- const arg = key.arguments[0];
72
- const argText = context.getSourceCode().getText(arg);
73
- return createFixes(fixer, key, argText);
74
- },
75
- });
85
+ const arg = key.arguments[0];
86
+ const argText = context.getSourceCode().getText(arg);
87
+ reportUseAssertSafe(key, argText);
76
88
  }
77
89
  // Check for template literals like `${id}`
78
90
  if (key.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
@@ -80,15 +92,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
80
92
  key.quasis.length === 2 &&
81
93
  key.quasis[0].value.raw === '' &&
82
94
  key.quasis[1].value.raw === '') {
83
- context.report({
84
- node: key,
85
- messageId: 'useAssertSafe',
86
- fix(fixer) {
87
- const expr = key.expressions[0];
88
- const exprText = context.getSourceCode().getText(expr);
89
- return createFixes(fixer, key, exprText);
90
- },
91
- });
95
+ const expr = key.expressions[0];
96
+ const exprText = context.getSourceCode().getText(expr);
97
+ reportUseAssertSafe(key, exprText);
92
98
  }
93
99
  }
94
100
  },
@@ -100,15 +106,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
100
106
  if (left.type === utils_1.AST_NODE_TYPES.CallExpression &&
101
107
  left.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
102
108
  left.callee.name === 'String') {
103
- context.report({
104
- node: left,
105
- messageId: 'useAssertSafe',
106
- fix(fixer) {
107
- const arg = left.arguments[0];
108
- const argText = context.getSourceCode().getText(arg);
109
- return createFixes(fixer, left, argText);
110
- },
111
- });
109
+ const arg = left.arguments[0];
110
+ const argText = context.getSourceCode().getText(arg);
111
+ reportUseAssertSafe(left, argText);
112
112
  }
113
113
  // Check for template literals like `${id}`
114
114
  if (left.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
@@ -116,15 +116,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
116
116
  left.quasis.length === 2 &&
117
117
  left.quasis[0].value.raw === '' &&
118
118
  left.quasis[1].value.raw === '') {
119
- context.report({
120
- node: left,
121
- messageId: 'useAssertSafe',
122
- fix(fixer) {
123
- const expr = left.expressions[0];
124
- const exprText = context.getSourceCode().getText(expr);
125
- return createFixes(fixer, left, exprText);
126
- },
127
- });
119
+ const expr = left.expressions[0];
120
+ const exprText = context.getSourceCode().getText(expr);
121
+ reportUseAssertSafe(left, exprText);
128
122
  }
129
123
  }
130
124
  },
@@ -163,15 +157,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
163
157
  if (property.type === utils_1.AST_NODE_TYPES.CallExpression &&
164
158
  property.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
165
159
  property.callee.name === 'String') {
166
- context.report({
167
- node: property,
168
- messageId: 'useAssertSafe',
169
- fix(fixer) {
170
- const arg = property.arguments[0];
171
- const argText = context.getSourceCode().getText(arg);
172
- return createFixes(fixer, property, argText);
173
- },
174
- });
160
+ const arg = property.arguments[0];
161
+ const argText = context.getSourceCode().getText(arg);
162
+ reportUseAssertSafe(property, argText);
175
163
  return;
176
164
  }
177
165
  // Check for template literals
@@ -190,16 +178,9 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
190
178
  // Complex template literals with additional text are fine
191
179
  return;
192
180
  }
193
- context.report({
194
- node: property,
195
- messageId: 'useAssertSafe',
196
- fix(fixer) {
197
- // Extract the expression from the template literal
198
- const expr = property.expressions[0];
199
- const exprText = context.getSourceCode().getText(expr);
200
- return createFixes(fixer, property, exprText);
201
- },
202
- });
181
+ const expr = property.expressions[0];
182
+ const exprText = context.getSourceCode().getText(expr);
183
+ reportUseAssertSafe(property, exprText);
203
184
  return;
204
185
  }
205
186
  // Check for direct variable usage (identifiers)
@@ -212,15 +193,8 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
212
193
  if (isLikelyArray) {
213
194
  return;
214
195
  }
215
- context.report({
216
- node: property,
217
- messageId: 'useAssertSafe',
218
- fix(fixer) {
219
- // For direct variable use, just use the variable name
220
- const propText = context.getSourceCode().getText(property);
221
- return createFixes(fixer, property, propText);
222
- },
223
- });
196
+ const propText = context.getSourceCode().getText(property);
197
+ reportUseAssertSafe(property, propText);
224
198
  return;
225
199
  }
226
200
  // Check for binary expressions (like index + 1)
@@ -229,14 +203,8 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
229
203
  if (isLikelyArray) {
230
204
  return;
231
205
  }
232
- context.report({
233
- node: property,
234
- messageId: 'useAssertSafe',
235
- fix(fixer) {
236
- const propText = context.getSourceCode().getText(property);
237
- return createFixes(fixer, property, propText);
238
- },
239
- });
206
+ const propText = context.getSourceCode().getText(property);
207
+ reportUseAssertSafe(property, propText);
240
208
  return;
241
209
  }
242
210
  // Check for boolean expressions and other literals
@@ -247,14 +215,8 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
247
215
  if (isLikelyArray) {
248
216
  return;
249
217
  }
250
- context.report({
251
- node: property,
252
- messageId: 'useAssertSafe',
253
- fix(fixer) {
254
- const propText = context.getSourceCode().getText(property);
255
- return createFixes(fixer, property, propText);
256
- },
257
- });
218
+ const propText = context.getSourceCode().getText(property);
219
+ reportUseAssertSafe(property, propText);
258
220
  return;
259
221
  }
260
222
  // Check for function calls (anything that isn't handled above)
@@ -266,14 +228,8 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
266
228
  if (isLikelyArray) {
267
229
  return;
268
230
  }
269
- context.report({
270
- node: property,
271
- messageId: 'useAssertSafe',
272
- fix(fixer) {
273
- const propText = context.getSourceCode().getText(property);
274
- return createFixes(fixer, property, propText);
275
- },
276
- });
231
+ const propText = context.getSourceCode().getText(property);
232
+ reportUseAssertSafe(property, propText);
277
233
  return;
278
234
  }
279
235
  }
@@ -281,4 +237,4 @@ exports.enforceAssertSafeObjectKey = (0, createRule_1.createRule)({
281
237
  };
282
238
  },
283
239
  });
284
- //# sourceMappingURL=enforce-assertSafe-object-key.js.map
240
+ //# sourceMappingURL=enforce-assert-safe-object-key.js.map
@@ -1 +1,3 @@
1
- export declare const enforceAssertThrows: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"assertShouldThrow", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
1
+ type MessageIds = 'assertShouldThrow' | 'shouldBeAssertPrefixed';
2
+ export declare const enforceAssertThrows: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<MessageIds, [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
3
+ export {};