@blumintinc/eslint-plugin-blumint 1.13.0 → 1.14.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 (186) hide show
  1. package/README.md +170 -139
  2. package/lib/index.js +190 -1
  3. package/lib/rules/array-methods-this-context.js +1 -1
  4. package/lib/rules/class-methods-read-top-to-bottom.js +24 -5
  5. package/lib/rules/consistent-callback-naming.js +1 -1
  6. package/lib/rules/dynamic-https-errors.js +3 -4
  7. package/lib/rules/enforce-assert-safe-object-key.js +11 -11
  8. package/lib/rules/enforce-boolean-naming-prefixes.js +11 -23
  9. package/lib/rules/enforce-callback-memo.js +1 -1
  10. package/lib/rules/enforce-centralized-mock-firestore.js +1 -1
  11. package/lib/rules/enforce-console-error.js +35 -7
  12. package/lib/rules/enforce-dynamic-file-naming.d.ts +2 -0
  13. package/lib/rules/enforce-dynamic-file-naming.js +53 -28
  14. package/lib/rules/enforce-early-destructuring.d.ts +2 -0
  15. package/lib/rules/enforce-early-destructuring.js +980 -0
  16. package/lib/rules/enforce-empty-object-check.d.ts +11 -0
  17. package/lib/rules/enforce-empty-object-check.js +502 -0
  18. package/lib/rules/enforce-exported-function-types.js +1 -1
  19. package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +100 -50
  20. package/lib/rules/enforce-firestore-doc-ref-generic.js +15 -3
  21. package/lib/rules/enforce-firestore-facade.js +4 -2
  22. package/lib/rules/enforce-firestore-set-merge.js +3 -4
  23. package/lib/rules/enforce-global-constants.js +1 -1
  24. package/lib/rules/enforce-identifiable-firestore-type.js +108 -58
  25. package/lib/rules/enforce-memoize-async.js +2 -6
  26. package/lib/rules/enforce-memoize-getters.js +39 -15
  27. package/lib/rules/enforce-microdiff.js +1 -1
  28. package/lib/rules/enforce-object-literal-as-const.js +4 -4
  29. package/lib/rules/enforce-positive-naming.js +4 -0
  30. package/lib/rules/enforce-props-argument-name.js +2 -2
  31. package/lib/rules/enforce-safe-stringify.js +1 -1
  32. package/lib/rules/enforce-serializable-params.js +3 -3
  33. package/lib/rules/enforce-singular-type-names.js +1 -1
  34. package/lib/rules/enforce-stable-hash-spread-props.d.ts +13 -0
  35. package/lib/rules/enforce-stable-hash-spread-props.js +342 -0
  36. package/lib/rules/enforce-storage-context.d.ts +9 -0
  37. package/lib/rules/enforce-storage-context.js +646 -0
  38. package/lib/rules/enforce-timestamp-now.js +23 -7
  39. package/lib/rules/enforce-transform-memoization.d.ts +4 -0
  40. package/lib/rules/enforce-transform-memoization.js +416 -0
  41. package/lib/rules/enforce-typescript-markdown-code-blocks.js +7 -3
  42. package/lib/rules/enforce-unique-cursor-headers.d.ts +16 -0
  43. package/lib/rules/enforce-unique-cursor-headers.js +365 -0
  44. package/lib/rules/enforce-verb-noun-naming.js +5 -4
  45. package/lib/rules/ensure-pointer-events-none.js +28 -2
  46. package/lib/rules/export-if-in-doubt.js +27 -4
  47. package/lib/rules/extract-global-constants.js +40 -13
  48. package/lib/rules/fast-deep-equal-over-microdiff.js +29 -39
  49. package/lib/rules/firestore-transaction-reads-before-writes.js +50 -4
  50. package/lib/rules/flatten-push-calls.d.ts +2 -0
  51. package/lib/rules/flatten-push-calls.js +428 -0
  52. package/lib/rules/global-const-style.js +50 -19
  53. package/lib/rules/jsdoc-above-field.d.ts +11 -0
  54. package/lib/rules/jsdoc-above-field.js +208 -0
  55. package/lib/rules/key-only-outermost-element.js +21 -3
  56. package/lib/rules/logical-top-to-bottom-grouping.d.ts +5 -0
  57. package/lib/rules/logical-top-to-bottom-grouping.js +1258 -0
  58. package/lib/rules/memo-compare-deeply-complex-props.d.ts +3 -0
  59. package/lib/rules/memo-compare-deeply-complex-props.js +788 -0
  60. package/lib/rules/memo-nested-react-components.d.ts +8 -0
  61. package/lib/rules/memo-nested-react-components.js +410 -0
  62. package/lib/rules/no-always-true-false-conditions.d.ts +2 -1
  63. package/lib/rules/no-always-true-false-conditions.js +68 -8
  64. package/lib/rules/no-array-length-in-deps.js +9 -3
  65. package/lib/rules/no-async-foreach.js +210 -12
  66. package/lib/rules/no-circular-references.js +18 -17
  67. package/lib/rules/no-class-instance-destructuring.js +55 -12
  68. package/lib/rules/no-complex-cloud-params.js +7 -3
  69. package/lib/rules/no-compositing-layer-props.js +2 -2
  70. package/lib/rules/no-conditional-literals-in-jsx.js +37 -12
  71. package/lib/rules/no-console-error.d.ts +9 -0
  72. package/lib/rules/no-console-error.js +525 -0
  73. package/lib/rules/no-curly-brackets-around-commented-properties.d.ts +2 -0
  74. package/lib/rules/no-curly-brackets-around-commented-properties.js +258 -0
  75. package/lib/rules/no-empty-dependency-use-callbacks.d.ts +11 -0
  76. package/lib/rules/no-empty-dependency-use-callbacks.js +576 -0
  77. package/lib/rules/no-entire-object-hook-deps.js +4 -6
  78. package/lib/rules/no-excessive-parent-chain.js +1 -1
  79. package/lib/rules/no-explicit-return-type.d.ts +2 -1
  80. package/lib/rules/no-explicit-return-type.js +215 -26
  81. package/lib/rules/no-filter-without-return.js +5 -1
  82. package/lib/rules/no-firestore-jest-mock.d.ts +2 -1
  83. package/lib/rules/no-firestore-jest-mock.js +126 -8
  84. package/lib/rules/no-firestore-object-arrays.js +67 -12
  85. package/lib/rules/no-handler-suffix.d.ts +12 -0
  86. package/lib/rules/no-handler-suffix.js +305 -0
  87. package/lib/rules/no-hungarian.js +1 -1
  88. package/lib/rules/no-inline-component-prop.d.ts +10 -0
  89. package/lib/rules/no-inline-component-prop.js +456 -0
  90. package/lib/rules/no-jsx-in-hooks.js +6 -1
  91. package/lib/rules/no-jsx-whitespace-literal.js +8 -2
  92. package/lib/rules/no-margin-properties.js +6 -6
  93. package/lib/rules/no-memoize-on-static.js +9 -1
  94. package/lib/rules/no-misleading-boolean-prefixes.js +7 -3
  95. package/lib/rules/no-misused-switch-case.js +22 -1
  96. package/lib/rules/no-mixed-firestore-transactions.d.ts +3 -1
  97. package/lib/rules/no-mixed-firestore-transactions.js +296 -34
  98. package/lib/rules/no-mock-firebase-admin.js +5 -2
  99. package/lib/rules/no-object-values-on-strings.js +10 -2
  100. package/lib/rules/no-overridable-method-calls-in-constructor.js +29 -17
  101. package/lib/rules/no-passthrough-getters.js +38 -2
  102. package/lib/rules/no-redundant-annotation-assertion.d.ts +2 -0
  103. package/lib/rules/no-redundant-annotation-assertion.js +402 -0
  104. package/lib/rules/no-redundant-param-types.js +16 -6
  105. package/lib/rules/no-redundant-this-params.d.ts +3 -0
  106. package/lib/rules/no-redundant-this-params.js +459 -0
  107. package/lib/rules/no-redundant-usecallback-wrapper.js +16 -3
  108. package/lib/rules/no-res-error-status-in-onrequest.d.ts +4 -0
  109. package/lib/rules/no-res-error-status-in-onrequest.js +521 -0
  110. package/lib/rules/no-restricted-properties-fix.js +11 -10
  111. package/lib/rules/no-separate-loading-state.js +7 -16
  112. package/lib/rules/no-stale-state-across-await.js +1 -1
  113. package/lib/rules/no-type-assertion-returns.js +43 -49
  114. package/lib/rules/no-undefined-null-passthrough.js +61 -31
  115. package/lib/rules/no-unmemoized-memo-without-props.d.ts +8 -0
  116. package/lib/rules/no-unmemoized-memo-without-props.js +426 -0
  117. package/lib/rules/no-unnecessary-destructuring-rename.d.ts +2 -0
  118. package/lib/rules/no-unnecessary-destructuring-rename.js +347 -0
  119. package/lib/rules/no-unnecessary-destructuring.js +14 -4
  120. package/lib/rules/no-unnecessary-verb-suffix.js +2 -1
  121. package/lib/rules/no-unpinned-dependencies.js +36 -5
  122. package/lib/rules/no-unused-props.d.ts +2 -2
  123. package/lib/rules/no-unused-props.js +295 -91
  124. package/lib/rules/no-unused-usestate.js +6 -2
  125. package/lib/rules/no-useless-fragment.js +28 -2
  126. package/lib/rules/no-useless-usememo-primitives.d.ts +9 -0
  127. package/lib/rules/no-useless-usememo-primitives.js +393 -0
  128. package/lib/rules/no-usememo-for-pass-by-value.d.ts +13 -0
  129. package/lib/rules/no-usememo-for-pass-by-value.js +757 -0
  130. package/lib/rules/no-uuidv4-base62-as-key.js +18 -13
  131. package/lib/rules/omit-index-html.d.ts +2 -1
  132. package/lib/rules/omit-index-html.js +62 -7
  133. package/lib/rules/optimize-object-boolean-conditions.js +6 -4
  134. package/lib/rules/parallelize-async-operations.js +24 -5
  135. package/lib/rules/prefer-batch-operations.d.ts +1 -3
  136. package/lib/rules/prefer-batch-operations.js +32 -5
  137. package/lib/rules/prefer-block-comments-for-declarations.js +9 -4
  138. package/lib/rules/prefer-clone-deep.js +3 -3
  139. package/lib/rules/prefer-destructuring-no-class.d.ts +2 -1
  140. package/lib/rules/prefer-destructuring-no-class.js +244 -59
  141. package/lib/rules/prefer-docsetter-setall.d.ts +2 -0
  142. package/lib/rules/prefer-docsetter-setall.js +243 -0
  143. package/lib/rules/prefer-field-paths-in-transforms.js +4 -3
  144. package/lib/rules/prefer-fragment-component.js +1 -1
  145. package/lib/rules/prefer-fragment-shorthand.js +2 -1
  146. package/lib/rules/prefer-getter-over-parameterless-method.d.ts +13 -0
  147. package/lib/rules/prefer-getter-over-parameterless-method.js +648 -0
  148. package/lib/rules/prefer-global-router-state-key.js +88 -13
  149. package/lib/rules/prefer-memoized-props.d.ts +3 -0
  150. package/lib/rules/prefer-memoized-props.js +445 -0
  151. package/lib/rules/prefer-next-dynamic.js +60 -69
  152. package/lib/rules/prefer-nullish-coalescing-boolean-props.js +9 -4
  153. package/lib/rules/prefer-nullish-coalescing-override.d.ts +2 -1
  154. package/lib/rules/prefer-nullish-coalescing-override.js +11 -5
  155. package/lib/rules/prefer-params-over-parent-id.js +220 -171
  156. package/lib/rules/prefer-settings-object.js +2 -2
  157. package/lib/rules/prefer-type-over-interface.js +7 -2
  158. package/lib/rules/prefer-url-tostring-over-tojson.js +6 -3
  159. package/lib/rules/prefer-use-deep-compare-memo.js +8 -5
  160. package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +1 -1
  161. package/lib/rules/prefer-utility-function-over-private-static.js +34 -2
  162. package/lib/rules/prevent-children-clobber.d.ts +2 -0
  163. package/lib/rules/prevent-children-clobber.js +536 -0
  164. package/lib/rules/react-memoize-literals.d.ts +4 -0
  165. package/lib/rules/react-memoize-literals.js +495 -0
  166. package/lib/rules/react-usememo-should-be-component.js +2 -2
  167. package/lib/rules/require-hooks-default-params.js +17 -16
  168. package/lib/rules/require-https-error-cause.d.ts +4 -0
  169. package/lib/rules/require-https-error-cause.js +136 -0
  170. package/lib/rules/require-https-error.js +43 -21
  171. package/lib/rules/require-image-optimized.js +1 -1
  172. package/lib/rules/require-memo.js +1 -1
  173. package/lib/rules/require-memoize-jsx-returners.d.ts +3 -0
  174. package/lib/rules/require-memoize-jsx-returners.js +485 -0
  175. package/lib/rules/require-usememo-object-literals.js +2 -3
  176. package/lib/rules/test-file-location-enforcement.js +1 -1
  177. package/lib/rules/use-latest-callback.js +6 -5
  178. package/lib/rules/vertically-group-related-functions.d.ts +16 -0
  179. package/lib/rules/vertically-group-related-functions.js +480 -0
  180. package/lib/utils/ASTHelpers.d.ts +13 -1
  181. package/lib/utils/ASTHelpers.js +24 -0
  182. package/lib/utils/getMethodName.d.ts +27 -0
  183. package/lib/utils/getMethodName.js +35 -0
  184. package/lib/utils/tsTypeClassifier.d.ts +30 -0
  185. package/lib/utils/tsTypeClassifier.js +149 -0
  186. package/package.json +3 -1
package/lib/index.js CHANGED
@@ -6,10 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const array_methods_this_context_1 = require("./rules/array-methods-this-context");
7
7
  const class_methods_read_top_to_bottom_1 = require("./rules/class-methods-read-top-to-bottom");
8
8
  const consistent_callback_naming_1 = __importDefault(require("./rules/consistent-callback-naming"));
9
+ const no_handler_suffix_1 = require("./rules/no-handler-suffix");
9
10
  const parallelize_async_operations_1 = require("./rules/parallelize-async-operations");
10
11
  const dynamic_https_errors_1 = require("./rules/dynamic-https-errors");
12
+ const enforce_empty_object_check_1 = require("./rules/enforce-empty-object-check");
11
13
  const enforce_identifiable_firestore_type_1 = require("./rules/enforce-identifiable-firestore-type");
12
14
  const enforce_callback_memo_1 = __importDefault(require("./rules/enforce-callback-memo"));
15
+ const react_memoize_literals_1 = require("./rules/react-memoize-literals");
13
16
  const enforce_callable_types_1 = require("./rules/enforce-callable-types");
14
17
  const enforce_console_error_1 = require("./rules/enforce-console-error");
15
18
  const enforce_dynamic_firebase_imports_1 = require("./rules/enforce-dynamic-firebase-imports");
@@ -24,6 +27,7 @@ const generic_starts_with_t_1 = require("./rules/generic-starts-with-t");
24
27
  const global_const_style_1 = __importDefault(require("./rules/global-const-style"));
25
28
  const no_async_array_filter_1 = require("./rules/no-async-array-filter");
26
29
  const no_async_foreach_1 = require("./rules/no-async-foreach");
30
+ const no_console_error_1 = require("./rules/no-console-error");
27
31
  const no_conditional_literals_in_jsx_1 = require("./rules/no-conditional-literals-in-jsx");
28
32
  const no_filter_without_return_1 = require("./rules/no-filter-without-return");
29
33
  const no_hungarian_1 = require("./rules/no-hungarian");
@@ -32,16 +36,21 @@ const no_unpinned_dependencies_1 = require("./rules/no-unpinned-dependencies");
32
36
  const no_unused_props_1 = require("./rules/no-unused-props");
33
37
  const no_useless_fragment_1 = require("./rules/no-useless-fragment");
34
38
  const prefer_fragment_shorthand_1 = require("./rules/prefer-fragment-shorthand");
39
+ const prefer_getter_over_parameterless_method_1 = require("./rules/prefer-getter-over-parameterless-method");
35
40
  const prefer_type_over_interface_1 = require("./rules/prefer-type-over-interface");
36
41
  const prefer_type_alias_over_typeof_constant_1 = require("./rules/prefer-type-alias-over-typeof-constant");
42
+ const prefer_memoized_props_1 = require("./rules/prefer-memoized-props");
37
43
  const require_memo_1 = require("./rules/require-memo");
44
+ const require_memoize_jsx_returners_1 = require("./rules/require-memoize-jsx-returners");
38
45
  const no_jsx_whitespace_literal_1 = require("./rules/no-jsx-whitespace-literal");
39
46
  const require_dynamic_firebase_imports_1 = __importDefault(require("./rules/require-dynamic-firebase-imports"));
40
47
  const require_https_error_1 = __importDefault(require("./rules/require-https-error"));
48
+ const require_https_error_cause_1 = require("./rules/require-https-error-cause");
41
49
  const use_custom_router_1 = require("./rules/use-custom-router");
42
50
  const require_image_optimized_1 = __importDefault(require("./rules/require-image-optimized"));
43
51
  const require_usememo_object_literals_1 = require("./rules/require-usememo-object-literals");
44
52
  const enforce_safe_stringify_1 = require("./rules/enforce-safe-stringify");
53
+ const enforce_storage_context_1 = require("./rules/enforce-storage-context");
45
54
  const avoid_utils_directory_1 = require("./rules/avoid-utils-directory");
46
55
  const no_entire_object_hook_deps_1 = require("./rules/no-entire-object-hook-deps");
47
56
  const enforce_firestore_path_utils_1 = require("./rules/enforce-firestore-path-utils");
@@ -51,6 +60,7 @@ const semantic_function_prefixes_1 = require("./rules/semantic-function-prefixes
51
60
  const enforce_mock_firestore_1 = require("./rules/enforce-mock-firestore");
52
61
  const prefer_settings_object_1 = require("./rules/prefer-settings-object");
53
62
  const enforce_firestore_set_merge_1 = require("./rules/enforce-firestore-set-merge");
63
+ const enforce_early_destructuring_1 = require("./rules/enforce-early-destructuring");
54
64
  const enforce_verb_noun_naming_1 = require("./rules/enforce-verb-noun-naming");
55
65
  const no_explicit_return_type_1 = require("./rules/no-explicit-return-type");
56
66
  const use_custom_memo_1 = require("./rules/use-custom-memo");
@@ -60,15 +70,19 @@ const enforce_serializable_params_1 = __importDefault(require("./rules/enforce-s
60
70
  const enforce_realtimedb_path_utils_1 = require("./rules/enforce-realtimedb-path-utils");
61
71
  const enforce_memoize_async_1 = require("./rules/enforce-memoize-async");
62
72
  const enforce_exported_function_types_1 = require("./rules/enforce-exported-function-types");
73
+ const no_redundant_annotation_assertion_1 = require("./rules/no-redundant-annotation-assertion");
63
74
  const enforce_memoize_getters_1 = require("./rules/enforce-memoize-getters");
64
75
  const no_redundant_param_types_1 = require("./rules/no-redundant-param-types");
76
+ const no_redundant_this_params_1 = require("./rules/no-redundant-this-params");
65
77
  const no_class_instance_destructuring_1 = require("./rules/no-class-instance-destructuring");
66
78
  const no_firestore_object_arrays_1 = require("./rules/no-firestore-object-arrays");
67
79
  const no_memoize_on_static_1 = require("./rules/no-memoize-on-static");
68
80
  const no_unsafe_firestore_spread_1 = require("./rules/no-unsafe-firestore-spread");
69
81
  const no_jsx_in_hooks_1 = require("./rules/no-jsx-in-hooks");
82
+ const no_unmemoized_memo_without_props_1 = require("./rules/no-unmemoized-memo-without-props");
70
83
  const enforce_assert_throws_1 = require("./rules/enforce-assert-throws");
71
84
  const prefer_batch_operations_1 = require("./rules/prefer-batch-operations");
85
+ const prefer_docsetter_setall_1 = require("./rules/prefer-docsetter-setall");
72
86
  const no_complex_cloud_params_1 = require("./rules/no-complex-cloud-params");
73
87
  const no_mixed_firestore_transactions_1 = require("./rules/no-mixed-firestore-transactions");
74
88
  const enforce_firestore_facade_1 = require("./rules/enforce-firestore-facade");
@@ -85,12 +99,15 @@ const react_usememo_should_be_component_1 = require("./rules/react-usememo-shoul
85
99
  const no_unnecessary_verb_suffix_1 = require("./rules/no-unnecessary-verb-suffix");
86
100
  const enforce_assert_safe_object_key_1 = require("./rules/enforce-assert-safe-object-key");
87
101
  const enforce_object_literal_as_const_1 = require("./rules/enforce-object-literal-as-const");
102
+ const enforce_stable_hash_spread_props_1 = require("./rules/enforce-stable-hash-spread-props");
88
103
  const enforce_positive_naming_1 = require("./rules/enforce-positive-naming");
89
104
  const no_type_assertion_returns_1 = require("./rules/no-type-assertion-returns");
90
105
  const prefer_utility_function_over_private_static_1 = require("./rules/prefer-utility-function-over-private-static");
91
106
  const enforce_microdiff_1 = require("./rules/enforce-microdiff");
92
107
  const fast_deep_equal_over_microdiff_1 = require("./rules/fast-deep-equal-over-microdiff");
108
+ const flatten_push_calls_1 = require("./rules/flatten-push-calls");
93
109
  const enforce_timestamp_now_1 = require("./rules/enforce-timestamp-now");
110
+ const enforce_unique_cursor_headers_1 = require("./rules/enforce-unique-cursor-headers");
94
111
  const no_always_true_false_conditions_1 = require("./rules/no-always-true-false-conditions");
95
112
  const enforce_props_argument_name_1 = require("./rules/enforce-props-argument-name");
96
113
  const enforce_props_naming_consistency_1 = require("./rules/enforce-props-naming-consistency");
@@ -101,14 +118,17 @@ const ensure_pointer_events_none_1 = require("./rules/ensure-pointer-events-none
101
118
  const no_object_values_on_strings_1 = require("./rules/no-object-values-on-strings");
102
119
  const key_only_outermost_element_1 = require("./rules/key-only-outermost-element");
103
120
  const no_unnecessary_destructuring_1 = require("./rules/no-unnecessary-destructuring");
121
+ const no_unnecessary_destructuring_rename_1 = require("./rules/no-unnecessary-destructuring-rename");
104
122
  const enforce_singular_type_names_1 = require("./rules/enforce-singular-type-names");
105
123
  const enforce_css_media_queries_1 = require("./rules/enforce-css-media-queries");
106
124
  const omit_index_html_1 = require("./rules/omit-index-html");
107
125
  const enforce_id_capitalization_1 = require("./rules/enforce-id-capitalization");
108
126
  const no_unused_usestate_1 = require("./rules/no-unused-usestate");
109
127
  const no_uuidv4_base62_as_key_1 = require("./rules/no-uuidv4-base62-as-key");
128
+ const logical_top_to_bottom_grouping_1 = require("./rules/logical-top-to-bottom-grouping");
110
129
  const enforce_dynamic_file_naming_1 = __importDefault(require("./rules/enforce-dynamic-file-naming"));
111
130
  const prefer_usecallback_over_usememo_for_functions_1 = __importDefault(require("./rules/prefer-usecallback-over-usememo-for-functions"));
131
+ const no_usememo_for_pass_by_value_1 = require("./rules/no-usememo-for-pass-by-value");
112
132
  const no_margin_properties_1 = require("./rules/no-margin-properties");
113
133
  const enforce_boolean_naming_prefixes_1 = require("./rules/enforce-boolean-naming-prefixes");
114
134
  const enforce_fieldpath_syntax_in_docsetter_1 = require("./rules/enforce-fieldpath-syntax-in-docsetter");
@@ -123,6 +143,7 @@ const no_excessive_parent_chain_1 = require("./rules/no-excessive-parent-chain")
123
143
  const prefer_document_flattening_1 = require("./rules/prefer-document-flattening");
124
144
  const no_overridable_method_calls_in_constructor_1 = require("./rules/no-overridable-method-calls-in-constructor");
125
145
  const use_latest_callback_1 = require("./rules/use-latest-callback");
146
+ const no_empty_dependency_use_callbacks_1 = require("./rules/no-empty-dependency-use-callbacks");
126
147
  const no_stale_state_across_await_1 = require("./rules/no-stale-state-across-await");
127
148
  const no_separate_loading_state_1 = require("./rules/no-separate-loading-state");
128
149
  const optimize_object_boolean_conditions_1 = require("./rules/optimize-object-boolean-conditions");
@@ -134,15 +155,47 @@ const prefer_next_dynamic_1 = require("./rules/prefer-next-dynamic");
134
155
  const no_redundant_usecallback_wrapper_1 = __importDefault(require("./rules/no-redundant-usecallback-wrapper"));
135
156
  const no_array_length_in_deps_1 = require("./rules/no-array-length-in-deps");
136
157
  const prefer_use_deep_compare_memo_1 = require("./rules/prefer-use-deep-compare-memo");
158
+ const memo_compare_deeply_complex_props_1 = require("./rules/memo-compare-deeply-complex-props");
137
159
  const no_circular_references_1 = require("./rules/no-circular-references");
138
160
  const no_passthrough_getters_1 = require("./rules/no-passthrough-getters");
161
+ const no_curly_brackets_around_commented_properties_1 = require("./rules/no-curly-brackets-around-commented-properties");
162
+ const no_res_error_status_in_onrequest_1 = require("./rules/no-res-error-status-in-onrequest");
139
163
  const no_try_catch_already_exists_in_transaction_1 = require("./rules/no-try-catch-already-exists-in-transaction");
164
+ const memo_nested_react_components_1 = require("./rules/memo-nested-react-components");
165
+ const no_useless_usememo_primitives_1 = require("./rules/no-useless-usememo-primitives");
166
+ const jsdoc_above_field_1 = require("./rules/jsdoc-above-field");
167
+ const enforce_transform_memoization_1 = require("./rules/enforce-transform-memoization");
168
+ const vertically_group_related_functions_1 = require("./rules/vertically-group-related-functions");
140
169
  const no_static_constants_in_dynamic_files_1 = __importDefault(require("./rules/no-static-constants-in-dynamic-files"));
141
170
  const test_file_location_enforcement_1 = require("./rules/test-file-location-enforcement");
171
+ const prevent_children_clobber_1 = require("./rules/prevent-children-clobber");
172
+ const NO_FRONTEND_IMPORTS_FROM_FUNCTIONS_MESSAGE = 'Backend Cloud Functions (.f.ts under functions/) must not import frontend modules from the repo root src/**. Frontend code can depend on browser-only APIs and bundling it into Cloud Functions breaks server execution; move shared logic into functions/src or a shared package.';
173
+ function noFrontendImportsFromFunctionsPatterns(pattern) {
174
+ return [
175
+ {
176
+ /**
177
+ * no-restricted-imports matches import strings literally (it does not
178
+ * resolve them to the filesystem). This monorepo layout contains both a
179
+ * frontend `src/` and a backend `functions/src/`, so broad `../src/**`
180
+ * patterns applied indiscriminately can also block legitimate
181
+ * backend-to-backend imports within `functions/src/**`.
182
+ *
183
+ * Each override targets one `functions/**` + `/*.f.ts` nesting depth and
184
+ * restricts only the exact traversal depth that reaches the repo root
185
+ * `src/`, so relative imports that stay inside `functions/src/**` do not
186
+ * match.
187
+ * Projects using path aliases should add matching restrictions in their
188
+ * own configs.
189
+ */
190
+ group: [pattern],
191
+ message: NO_FRONTEND_IMPORTS_FROM_FUNCTIONS_MESSAGE,
192
+ },
193
+ ];
194
+ }
142
195
  module.exports = {
143
196
  meta: {
144
197
  name: '@blumintinc/eslint-plugin-blumint',
145
- version: '1.13.0',
198
+ version: '1.14.0',
146
199
  },
147
200
  parseOptions: {
148
201
  ecmaVersion: 2020,
@@ -157,6 +210,7 @@ module.exports = {
157
210
  '@blumintinc/blumint/prefer-nullish-coalescing-override': 'error',
158
211
  '@blumintinc/blumint/prefer-block-comments-for-declarations': 'error',
159
212
  '@blumintinc/blumint/key-only-outermost-element': 'error',
213
+ '@blumintinc/blumint/logical-top-to-bottom-grouping': 'error',
160
214
  '@blumintinc/blumint/parallelize-async-operations': 'error',
161
215
  '@blumintinc/blumint/avoid-utils-directory': 'error',
162
216
  '@blumintinc/blumint/enforce-firestore-path-utils': 'error',
@@ -166,9 +220,11 @@ module.exports = {
166
220
  '@blumintinc/blumint/class-methods-read-top-to-bottom': 'error',
167
221
  '@blumintinc/blumint/consistent-callback-naming': 'error',
168
222
  '@blumintinc/blumint/dynamic-https-errors': 'error',
223
+ '@blumintinc/blumint/enforce-empty-object-check': 'error',
169
224
  '@blumintinc/blumint/enforce-mui-rounded-icons': 'error',
170
225
  '@blumintinc/blumint/enforce-identifiable-firestore-type': 'error',
171
226
  '@blumintinc/blumint/enforce-callback-memo': 'error',
227
+ '@blumintinc/blumint/react-memoize-literals': 'error',
172
228
  '@blumintinc/blumint/enforce-callable-types': 'error',
173
229
  '@blumintinc/blumint/enforce-console-error': 'error',
174
230
  '@blumintinc/blumint/enforce-dynamic-firebase-imports': 'error',
@@ -180,25 +236,37 @@ module.exports = {
180
236
  '@blumintinc/blumint/global-const-style': 'error',
181
237
  '@blumintinc/blumint/no-async-array-filter': 'error',
182
238
  '@blumintinc/blumint/no-async-foreach': 'error',
239
+ '@blumintinc/blumint/no-console-error': [
240
+ 'warn',
241
+ { allowWithUseAlertDialog: true },
242
+ ],
183
243
  '@blumintinc/blumint/no-conditional-literals-in-jsx': 'error',
184
244
  '@blumintinc/blumint/no-filter-without-return': 'error',
185
245
  '@blumintinc/blumint/no-hungarian': 'error',
246
+ '@blumintinc/blumint/no-handler-suffix': 'error',
186
247
  '@blumintinc/blumint/no-misused-switch-case': 'error',
187
248
  '@blumintinc/blumint/no-unpinned-dependencies': 'error',
188
249
  '@blumintinc/blumint/no-unused-props': 'error',
189
250
  '@blumintinc/blumint/no-uuidv4-base62-as-key': 'error',
190
251
  '@blumintinc/blumint/no-useless-fragment': 'error',
252
+ '@blumintinc/blumint/no-useless-usememo-primitives': 'error',
191
253
  '@blumintinc/blumint/prefer-fragment-shorthand': 'error',
254
+ '@blumintinc/blumint/prefer-getter-over-parameterless-method': 'error',
192
255
  '@blumintinc/blumint/prefer-type-over-interface': 'error',
193
256
  '@blumintinc/blumint/prefer-type-alias-over-typeof-constant': 'error',
194
257
  '@blumintinc/blumint/require-memo': 'error',
258
+ '@blumintinc/blumint/require-memoize-jsx-returners': 'error',
259
+ '@blumintinc/blumint/no-unmemoized-memo-without-props': 'error',
195
260
  '@blumintinc/blumint/require-dynamic-firebase-imports': 'error',
196
261
  '@blumintinc/blumint/require-https-error': 'error',
262
+ '@blumintinc/blumint/require-https-error-cause': 'error',
197
263
  '@blumintinc/blumint/use-custom-router': 'error',
198
264
  '@blumintinc/blumint/require-image-optimized': 'error',
199
265
  '@blumintinc/blumint/require-usememo-object-literals': 'error',
200
266
  '@blumintinc/blumint/memoize-root-level-hocs': 'error',
201
267
  '@blumintinc/blumint/enforce-safe-stringify': 'error',
268
+ '@blumintinc/blumint/enforce-early-destructuring': 'error',
269
+ '@blumintinc/blumint/enforce-storage-context': 'error',
202
270
  '@blumintinc/blumint/no-entire-object-hook-deps': 'error',
203
271
  '@blumintinc/blumint/no-compositing-layer-props': 'error',
204
272
  '@blumintinc/blumint/enforce-firestore-doc-ref-generic': 'error',
@@ -214,6 +282,7 @@ module.exports = {
214
282
  '@blumintinc/blumint/enforce-realtimedb-path-utils': 'error',
215
283
  '@blumintinc/blumint/enforce-memoize-async': 'error',
216
284
  '@blumintinc/blumint/enforce-exported-function-types': 'error',
285
+ '@blumintinc/blumint/no-redundant-annotation-assertion': 'error',
217
286
  '@blumintinc/blumint/no-redundant-param-types': 'error',
218
287
  '@blumintinc/blumint/enforce-memoize-getters': 'error',
219
288
  '@blumintinc/blumint/no-class-instance-destructuring': 'error',
@@ -223,6 +292,7 @@ module.exports = {
223
292
  '@blumintinc/blumint/no-jsx-in-hooks': 'error',
224
293
  '@blumintinc/blumint/enforce-assert-throws': 'error',
225
294
  '@blumintinc/blumint/prefer-batch-operations': 'error',
295
+ '@blumintinc/blumint/prefer-docsetter-setall': 'error',
226
296
  '@blumintinc/blumint/no-complex-cloud-params': 'error',
227
297
  '@blumintinc/blumint/no-mixed-firestore-transactions': 'error',
228
298
  '@blumintinc/blumint/enforce-firestore-facade': 'error',
@@ -234,6 +304,7 @@ module.exports = {
234
304
  '@blumintinc/blumint/require-hooks-default-params': 'error',
235
305
  '@blumintinc/blumint/prefer-destructuring-no-class': 'error',
236
306
  '@blumintinc/blumint/enforce-render-hits-memoization': 'error',
307
+ '@blumintinc/blumint/enforce-transform-memoization': 'error',
237
308
  '@blumintinc/blumint/prefer-fragment-component': 'off',
238
309
  '@blumintinc/blumint/react-usememo-should-be-component': 'error',
239
310
  '@blumintinc/blumint/no-unnecessary-verb-suffix': 'error',
@@ -244,23 +315,29 @@ module.exports = {
244
315
  '@blumintinc/blumint/prefer-utility-function-over-private-static': 'error',
245
316
  '@blumintinc/blumint/enforce-microdiff': 'error',
246
317
  '@blumintinc/blumint/fast-deep-equal-over-microdiff': 'error',
318
+ '@blumintinc/blumint/flatten-push-calls': 'error',
247
319
  '@blumintinc/blumint/enforce-timestamp-now': 'error',
320
+ '@blumintinc/blumint/enforce-unique-cursor-headers': 'error',
248
321
  '@blumintinc/blumint/enforce-typescript-markdown-code-blocks': 'error',
249
322
  '@blumintinc/blumint/no-always-true-false-conditions': 'error',
250
323
  '@blumintinc/blumint/enforce-props-argument-name': 'error',
251
324
  '@blumintinc/blumint/enforce-props-naming-consistency': 'error',
252
325
  '@blumintinc/blumint/prefer-global-router-state-key': 'error',
253
326
  '@blumintinc/blumint/prefer-usememo-over-useeffect-usestate': 'error',
327
+ '@blumintinc/blumint/prefer-memoized-props': 'error',
254
328
  '@blumintinc/blumint/enforce-dynamic-imports': 'error',
255
329
  '@blumintinc/blumint/ensure-pointer-events-none': 'error',
256
330
  '@blumintinc/blumint/no-object-values-on-strings': 'error',
257
331
  '@blumintinc/blumint/no-unnecessary-destructuring': 'error',
332
+ '@blumintinc/blumint/no-unnecessary-destructuring-rename': 'error',
258
333
  '@blumintinc/blumint/enforce-singular-type-names': 'error',
334
+ '@blumintinc/blumint/prevent-children-clobber': 'error',
259
335
  '@blumintinc/blumint/enforce-css-media-queries': 'error',
260
336
  '@blumintinc/blumint/omit-index-html': 'error',
261
337
  '@blumintinc/blumint/enforce-id-capitalization': 'error',
262
338
  '@blumintinc/blumint/no-unused-usestate': 'error',
263
339
  '@blumintinc/blumint/prefer-usecallback-over-usememo-for-functions': 'error',
340
+ '@blumintinc/blumint/no-usememo-for-pass-by-value': 'error',
264
341
  '@blumintinc/blumint/no-margin-properties': 'error',
265
342
  '@blumintinc/blumint/enforce-boolean-naming-prefixes': 'error',
266
343
  '@blumintinc/blumint/enforce-fieldpath-syntax-in-docsetter': 'error',
@@ -268,6 +345,7 @@ module.exports = {
268
345
  '@blumintinc/blumint/prefer-nullish-coalescing-boolean-props': 'error',
269
346
  '@blumintinc/blumint/no-overridable-method-calls-in-constructor': 'error',
270
347
  '@blumintinc/blumint/use-latest-callback': 'error',
348
+ '@blumintinc/blumint/no-empty-dependency-use-callbacks': 'error',
271
349
  '@blumintinc/blumint/enforce-querykey-ts': 'error',
272
350
  '@blumintinc/blumint/no-stale-state-across-await': 'error',
273
351
  '@blumintinc/blumint/no-separate-loading-state': 'error',
@@ -277,15 +355,96 @@ module.exports = {
277
355
  '@blumintinc/blumint/no-misleading-boolean-prefixes': 'error',
278
356
  '@blumintinc/blumint/prefer-url-tostring-over-tojson': 'error',
279
357
  '@blumintinc/blumint/prefer-next-dynamic': 'error',
358
+ '@blumintinc/blumint/jsdoc-above-field': 'error',
280
359
  '@blumintinc/blumint/no-redundant-usecallback-wrapper': 'error',
360
+ '@blumintinc/blumint/no-redundant-this-params': 'error',
361
+ '@blumintinc/blumint/no-res-error-status-in-onrequest': 'error',
281
362
  '@blumintinc/blumint/no-array-length-in-deps': 'error',
363
+ '@blumintinc/blumint/enforce-stable-hash-spread-props': 'error',
282
364
  '@blumintinc/blumint/prefer-use-deep-compare-memo': 'error',
365
+ '@blumintinc/blumint/memo-nested-react-components': 'error',
366
+ '@blumintinc/blumint/memo-compare-deeply-complex-props': 'error',
283
367
  '@blumintinc/blumint/no-circular-references': 'error',
284
368
  '@blumintinc/blumint/no-try-catch-already-exists-in-transaction': 'error',
369
+ '@blumintinc/blumint/no-curly-brackets-around-commented-properties': 'error',
285
370
  '@blumintinc/blumint/no-passthrough-getters': 'error',
371
+ '@blumintinc/blumint/vertically-group-related-functions': 'error',
286
372
  '@blumintinc/blumint/no-static-constants-in-dynamic-files': 'error',
287
373
  '@blumintinc/blumint/test-file-location-enforcement': 'error',
288
374
  },
375
+ /**
376
+ * Depth-specific overrides block only import strings that traverse to the
377
+ * repo root `src/`. The list covers nesting depths 1–6; deeper nesting
378
+ * requires an additional override.
379
+ */
380
+ overrides: [
381
+ {
382
+ files: ['functions/*.f.ts'],
383
+ rules: {
384
+ 'no-restricted-imports': [
385
+ 'error',
386
+ {
387
+ patterns: noFrontendImportsFromFunctionsPatterns('../src/**'),
388
+ },
389
+ ],
390
+ },
391
+ },
392
+ {
393
+ files: ['functions/*/*.f.ts'],
394
+ rules: {
395
+ 'no-restricted-imports': [
396
+ 'error',
397
+ {
398
+ patterns: noFrontendImportsFromFunctionsPatterns('../../src/**'),
399
+ },
400
+ ],
401
+ },
402
+ },
403
+ {
404
+ files: ['functions/*/*/*.f.ts'],
405
+ rules: {
406
+ 'no-restricted-imports': [
407
+ 'error',
408
+ {
409
+ patterns: noFrontendImportsFromFunctionsPatterns('../../../src/**'),
410
+ },
411
+ ],
412
+ },
413
+ },
414
+ {
415
+ files: ['functions/*/*/*/*.f.ts'],
416
+ rules: {
417
+ 'no-restricted-imports': [
418
+ 'error',
419
+ {
420
+ patterns: noFrontendImportsFromFunctionsPatterns('../../../../src/**'),
421
+ },
422
+ ],
423
+ },
424
+ },
425
+ {
426
+ files: ['functions/*/*/*/*/*.f.ts'],
427
+ rules: {
428
+ 'no-restricted-imports': [
429
+ 'error',
430
+ {
431
+ patterns: noFrontendImportsFromFunctionsPatterns('../../../../../src/**'),
432
+ },
433
+ ],
434
+ },
435
+ },
436
+ {
437
+ files: ['functions/*/*/*/*/*/*.f.ts'],
438
+ rules: {
439
+ 'no-restricted-imports': [
440
+ 'error',
441
+ {
442
+ patterns: noFrontendImportsFromFunctionsPatterns('../../../../../../src/**'),
443
+ },
444
+ ],
445
+ },
446
+ },
447
+ ],
289
448
  },
290
449
  },
291
450
  rules: {
@@ -296,13 +455,16 @@ module.exports = {
296
455
  'prefer-document-flattening': prefer_document_flattening_1.preferDocumentFlattening,
297
456
  'prefer-block-comments-for-declarations': prefer_block_comments_for_declarations_1.preferBlockCommentsForDeclarations,
298
457
  'key-only-outermost-element': key_only_outermost_element_1.keyOnlyOutermostElement,
458
+ 'logical-top-to-bottom-grouping': logical_top_to_bottom_grouping_1.logicalTopToBottomGrouping,
299
459
  'array-methods-this-context': array_methods_this_context_1.arrayMethodsThisContext,
300
460
  'class-methods-read-top-to-bottom': class_methods_read_top_to_bottom_1.classMethodsReadTopToBottom,
301
461
  'consistent-callback-naming': consistent_callback_naming_1.default,
302
462
  'parallelize-async-operations': parallelize_async_operations_1.parallelizeAsyncOperations,
303
463
  'dynamic-https-errors': dynamic_https_errors_1.dynamicHttpsErrors,
464
+ 'enforce-empty-object-check': enforce_empty_object_check_1.enforceEmptyObjectCheck,
304
465
  'enforce-identifiable-firestore-type': enforce_identifiable_firestore_type_1.enforceIdentifiableFirestoreType,
305
466
  'enforce-callback-memo': enforce_callback_memo_1.default,
467
+ 'react-memoize-literals': react_memoize_literals_1.reactMemoizeLiterals,
306
468
  'enforce-react-type-naming': enforce_react_type_naming_1.enforceReactTypeNaming,
307
469
  'enforce-firestore-rules-get-access': enforce_firestore_rules_get_access_1.enforceFirestoreRulesGetAccess,
308
470
  'enforce-callable-types': enforce_callable_types_1.enforceCallableTypes,
@@ -319,6 +481,7 @@ module.exports = {
319
481
  'no-conditional-literals-in-jsx': no_conditional_literals_in_jsx_1.noConditionalLiteralsInJsx,
320
482
  'no-filter-without-return': no_filter_without_return_1.noFilterWithoutReturn,
321
483
  'no-hungarian': no_hungarian_1.noHungarian,
484
+ 'no-handler-suffix': no_handler_suffix_1.noHandlerSuffix,
322
485
  'no-misused-switch-case': no_misused_switch_case_1.noMisusedSwitchCase,
323
486
  'no-unpinned-dependencies': no_unpinned_dependencies_1.noUnpinnedDependencies,
324
487
  'no-unused-props': no_unused_props_1.noUnusedProps,
@@ -326,17 +489,23 @@ module.exports = {
326
489
  'no-uuidv4-base62-as-key': no_uuidv4_base62_as_key_1.noUuidv4Base62AsKey,
327
490
  'enforce-dynamic-file-naming': enforce_dynamic_file_naming_1.default,
328
491
  'prefer-fragment-shorthand': prefer_fragment_shorthand_1.preferFragmentShorthand,
492
+ 'prefer-getter-over-parameterless-method': prefer_getter_over_parameterless_method_1.preferGetterOverParameterlessMethod,
329
493
  'prefer-type-over-interface': prefer_type_over_interface_1.preferTypeOverInterface,
330
494
  'prefer-type-alias-over-typeof-constant': prefer_type_alias_over_typeof_constant_1.preferTypeAliasOverTypeofConstant,
331
495
  'require-memo': require_memo_1.requireMemo,
496
+ 'require-memoize-jsx-returners': require_memoize_jsx_returners_1.requireMemoizeJsxReturners,
497
+ 'no-unmemoized-memo-without-props': no_unmemoized_memo_without_props_1.noUnmemoizedMemoWithoutProps,
332
498
  'no-jsx-whitespace-literal': no_jsx_whitespace_literal_1.noJsxWhitespaceLiteral,
333
499
  'require-dynamic-firebase-imports': require_dynamic_firebase_imports_1.default,
334
500
  'require-https-error': require_https_error_1.default,
501
+ 'require-https-error-cause': require_https_error_cause_1.requireHttpsErrorCause,
335
502
  'use-custom-router': use_custom_router_1.useCustomRouter,
336
503
  'require-image-optimized': require_image_optimized_1.default,
337
504
  'require-usememo-object-literals': require_usememo_object_literals_1.requireUseMemoObjectLiterals,
338
505
  'memoize-root-level-hocs': memoize_root_level_hocs_1.memoizeRootLevelHocs,
339
506
  'enforce-safe-stringify': enforce_safe_stringify_1.enforceStableStringify,
507
+ 'enforce-early-destructuring': enforce_early_destructuring_1.enforceEarlyDestructuring,
508
+ 'enforce-storage-context': enforce_storage_context_1.enforceStorageContext,
340
509
  'avoid-utils-directory': avoid_utils_directory_1.avoidUtilsDirectory,
341
510
  'no-entire-object-hook-deps': no_entire_object_hook_deps_1.noEntireObjectHookDeps,
342
511
  'enforce-firestore-path-utils': enforce_firestore_path_utils_1.enforceFirestorePathUtils,
@@ -354,7 +523,9 @@ module.exports = {
354
523
  'enforce-realtimedb-path-utils': enforce_realtimedb_path_utils_1.enforceRealtimedbPathUtils,
355
524
  'enforce-memoize-async': enforce_memoize_async_1.enforceMemoizeAsync,
356
525
  'enforce-exported-function-types': enforce_exported_function_types_1.enforceExportedFunctionTypes,
526
+ 'no-redundant-annotation-assertion': no_redundant_annotation_assertion_1.noRedundantAnnotationAssertion,
357
527
  'no-redundant-param-types': no_redundant_param_types_1.noRedundantParamTypes,
528
+ 'no-redundant-this-params': no_redundant_this_params_1.noRedundantThisParams,
358
529
  'enforce-memoize-getters': enforce_memoize_getters_1.enforceMemoizeGetters,
359
530
  'no-class-instance-destructuring': no_class_instance_destructuring_1.noClassInstanceDestructuring,
360
531
  'no-firestore-object-arrays': no_firestore_object_arrays_1.noFirestoreObjectArrays,
@@ -363,6 +534,7 @@ module.exports = {
363
534
  'no-jsx-in-hooks': no_jsx_in_hooks_1.noJsxInHooks,
364
535
  'enforce-assert-throws': enforce_assert_throws_1.enforceAssertThrows,
365
536
  'prefer-batch-operations': prefer_batch_operations_1.preferBatchOperations,
537
+ 'prefer-docsetter-setall': prefer_docsetter_setall_1.preferDocSetterSetAll,
366
538
  'no-complex-cloud-params': no_complex_cloud_params_1.noComplexCloudParams,
367
539
  'no-mixed-firestore-transactions': no_mixed_firestore_transactions_1.noMixedFirestoreTransactions,
368
540
  'enforce-firestore-facade': enforce_firestore_facade_1.enforceFirestoreFacade,
@@ -374,17 +546,21 @@ module.exports = {
374
546
  'require-hooks-default-params': require_hooks_default_params_1.requireHooksDefaultParams,
375
547
  'prefer-destructuring-no-class': prefer_destructuring_no_class_1.preferDestructuringNoClass,
376
548
  'enforce-render-hits-memoization': enforce_render_hits_memoization_1.enforceRenderHitsMemoization,
549
+ 'enforce-transform-memoization': enforce_transform_memoization_1.enforceTransformMemoization,
377
550
  'prefer-fragment-component': prefer_fragment_component_1.preferFragmentComponent,
378
551
  'react-usememo-should-be-component': react_usememo_should_be_component_1.reactUseMemoShouldBeComponent,
379
552
  'no-unnecessary-verb-suffix': no_unnecessary_verb_suffix_1.noUnnecessaryVerbSuffix,
380
553
  'enforce-assert-safe-object-key': enforce_assert_safe_object_key_1.enforceAssertSafeObjectKey,
381
554
  'enforce-object-literal-as-const': enforce_object_literal_as_const_1.enforceObjectLiteralAsConst,
555
+ 'enforce-stable-hash-spread-props': enforce_stable_hash_spread_props_1.enforceStableHashSpreadProps,
382
556
  'enforce-positive-naming': enforce_positive_naming_1.enforcePositiveNaming,
383
557
  'no-type-assertion-returns': no_type_assertion_returns_1.noTypeAssertionReturns,
384
558
  'prefer-utility-function-over-private-static': prefer_utility_function_over_private_static_1.preferUtilityFunctionOverPrivateStatic,
385
559
  'enforce-microdiff': enforce_microdiff_1.enforceMicrodiff,
386
560
  'fast-deep-equal-over-microdiff': fast_deep_equal_over_microdiff_1.fastDeepEqualOverMicrodiff,
561
+ 'flatten-push-calls': flatten_push_calls_1.flattenPushCalls,
387
562
  'enforce-timestamp-now': enforce_timestamp_now_1.enforceTimestampNow,
563
+ 'enforce-unique-cursor-headers': enforce_unique_cursor_headers_1.enforceUniqueCursorHeaders,
388
564
  'enforce-typescript-markdown-code-blocks': enforce_typescript_markdown_code_blocks_1.enforceTypescriptMarkdownCodeBlocks,
389
565
  'no-always-true-false-conditions': no_always_true_false_conditions_1.noAlwaysTrueFalseConditions,
390
566
  'enforce-props-argument-name': enforce_props_argument_name_1.enforcePropsArgumentName,
@@ -395,12 +571,16 @@ module.exports = {
395
571
  'ensure-pointer-events-none': ensure_pointer_events_none_1.ensurePointerEventsNone,
396
572
  'no-object-values-on-strings': no_object_values_on_strings_1.noObjectValuesOnStrings,
397
573
  'no-unnecessary-destructuring': no_unnecessary_destructuring_1.noUnnecessaryDestructuring,
574
+ 'no-unnecessary-destructuring-rename': no_unnecessary_destructuring_rename_1.noUnnecessaryDestructuringRename,
398
575
  'enforce-singular-type-names': enforce_singular_type_names_1.enforceSingularTypeNames,
576
+ 'prevent-children-clobber': prevent_children_clobber_1.preventChildrenClobber,
399
577
  'enforce-css-media-queries': enforce_css_media_queries_1.enforceCssMediaQueries,
400
578
  'omit-index-html': omit_index_html_1.omitIndexHtml,
401
579
  'enforce-id-capitalization': enforce_id_capitalization_1.enforceIdCapitalization,
402
580
  'no-unused-usestate': no_unused_usestate_1.noUnusedUseState,
581
+ 'no-useless-usememo-primitives': no_useless_usememo_primitives_1.noUselessUsememoPrimitives,
403
582
  'prefer-usecallback-over-usememo-for-functions': prefer_usecallback_over_usememo_for_functions_1.default,
583
+ 'no-usememo-for-pass-by-value': no_usememo_for_pass_by_value_1.noUsememoForPassByValue,
404
584
  'no-margin-properties': no_margin_properties_1.noMarginProperties,
405
585
  'enforce-boolean-naming-prefixes': enforce_boolean_naming_prefixes_1.enforceBooleanNamingPrefixes,
406
586
  'enforce-fieldpath-syntax-in-docsetter': enforce_fieldpath_syntax_in_docsetter_1.enforceFieldPathSyntaxInDocSetter,
@@ -408,6 +588,7 @@ module.exports = {
408
588
  'prefer-nullish-coalescing-boolean-props': prefer_nullish_coalescing_boolean_props_1.preferNullishCoalescingBooleanProps,
409
589
  'no-overridable-method-calls-in-constructor': no_overridable_method_calls_in_constructor_1.noOverridableMethodCallsInConstructor,
410
590
  'use-latest-callback': use_latest_callback_1.useLatestCallback,
591
+ 'no-empty-dependency-use-callbacks': no_empty_dependency_use_callbacks_1.noEmptyDependencyUseCallbacks,
411
592
  'enforce-querykey-ts': enforce_querykey_ts_1.enforceQueryKeyTs,
412
593
  'no-stale-state-across-await': no_stale_state_across_await_1.noStaleStateAcrossAwait,
413
594
  'no-separate-loading-state': no_separate_loading_state_1.noSeparateLoadingState,
@@ -417,12 +598,20 @@ module.exports = {
417
598
  'no-misleading-boolean-prefixes': no_misleading_boolean_prefixes_1.noMisleadingBooleanPrefixes,
418
599
  'prefer-url-tostring-over-tojson': prefer_url_tostring_over_tojson_1.preferUrlToStringOverToJson,
419
600
  'prefer-next-dynamic': prefer_next_dynamic_1.preferNextDynamic,
601
+ 'jsdoc-above-field': jsdoc_above_field_1.jsdocAboveField,
420
602
  'no-redundant-usecallback-wrapper': no_redundant_usecallback_wrapper_1.default,
603
+ 'no-res-error-status-in-onrequest': no_res_error_status_in_onrequest_1.requireHttpsErrorInOnRequestHandlers,
421
604
  'no-array-length-in-deps': no_array_length_in_deps_1.noArrayLengthInDeps,
605
+ 'prefer-memoized-props': prefer_memoized_props_1.preferMemoizedProps,
422
606
  'prefer-use-deep-compare-memo': prefer_use_deep_compare_memo_1.preferUseDeepCompareMemo,
607
+ 'memo-nested-react-components': memo_nested_react_components_1.memoNestedReactComponents,
608
+ 'memo-compare-deeply-complex-props': memo_compare_deeply_complex_props_1.memoCompareDeeplyComplexProps,
423
609
  'no-circular-references': no_circular_references_1.noCircularReferences,
610
+ 'no-console-error': no_console_error_1.noConsoleError,
424
611
  'no-try-catch-already-exists-in-transaction': no_try_catch_already_exists_in_transaction_1.noTryCatchAlreadyExistsInTransaction,
612
+ 'no-curly-brackets-around-commented-properties': no_curly_brackets_around_commented_properties_1.noCurlyBracketsAroundCommentedProperties,
425
613
  'no-passthrough-getters': no_passthrough_getters_1.noPassthroughGetters,
614
+ 'vertically-group-related-functions': vertically_group_related_functions_1.verticallyGroupRelatedFunctions,
426
615
  'no-static-constants-in-dynamic-files': no_static_constants_in_dynamic_files_1.default,
427
616
  'test-file-location-enforcement': test_file_location_enforcement_1.testFileLocationEnforcement,
428
617
  },
@@ -12,7 +12,7 @@ exports.ARRAY_METHODS = [
12
12
  ];
13
13
  exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
14
14
  create(context) {
15
- const sourceCode = context.getSourceCode();
15
+ const sourceCode = context.sourceCode;
16
16
  return {
17
17
  CallExpression(node) {
18
18
  // Array method called with a class method reference
@@ -15,23 +15,31 @@ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
15
15
  meta: {
16
16
  type: 'suggestion',
17
17
  docs: {
18
- description: 'Ensures classes read linearly from top to bottom.',
18
+ description: 'Enforces a top-to-bottom class layout so callers lead into the helpers they rely on.',
19
19
  recommended: 'warn',
20
20
  },
21
21
  schema: [],
22
22
  messages: {
23
- classMethodsReadTopToBottom: 'Methods should be ordered for top-down readability.',
23
+ classMethodsReadTopToBottom: [
24
+ "What's wrong: In {{className}}, {{actualMember}} appears before {{expectedMember}}.",
25
+ 'Why it matters: Top-down flow enables local reasoning: you can verify each caller without scrolling back. Upward jumps make code reviews harder (must verify call chains in reverse), obscure which fields a helper assumes are initialized, and increase the risk of calling helpers before state is ready (leading to null reference errors or accessing uninitialized fields).',
26
+ 'How to fix: Move {{expectedMember}} above {{actualMember}} so the class reads top-to-bottom (fields to constructor to callers to helpers).',
27
+ ].join('\n'),
24
28
  },
25
29
  fixable: 'code', // To allow ESLint to autofix issues.
26
30
  },
27
31
  defaultOptions: [],
28
32
  create(context) {
29
- let className;
33
+ const classNames = new WeakMap();
30
34
  return {
31
35
  ClassDeclaration(node) {
32
- className = node.id?.name || '';
36
+ classNames.set(node.body, node.id?.name || '');
37
+ },
38
+ ClassExpression(node) {
39
+ classNames.set(node.body, node.id?.name || '');
33
40
  },
34
41
  'ClassBody:exit'(node) {
42
+ const className = classNames.get(node) || '';
35
43
  const graphBuilder = new ClassGraphBuilder_1.ClassGraphBuilder(className, node);
36
44
  const sortedOrder = graphBuilder.memberNamesSorted;
37
45
  const actualOrder = node.body
@@ -51,7 +59,13 @@ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
51
59
  return; // Skip if there are actual duplicates
52
60
  }
53
61
  for (let i = 0; i < actualOrder.length; i++) {
54
- if (actualOrder[i] !== sortedOrder[i]) {
62
+ const actualMember = actualOrder[i];
63
+ const expectedMember = sortedOrder[i];
64
+ if (!actualMember || !expectedMember) {
65
+ throw new Error(`class-methods-read-top-to-bottom invariant violated while comparing members in ${className || 'an unnamed class'} at position ${i}: actualMember=${String(actualMember)}, expectedMember=${String(expectedMember)}, actualOrder.length=${actualOrder.length}, sortedOrder.length=${sortedOrder.length}`);
66
+ }
67
+ if (actualMember !== expectedMember) {
68
+ const classNameReport = className || 'this class';
55
69
  const sourceCode = context.getSourceCode();
56
70
  const newClassBody = sortedOrder
57
71
  .map((n) => {
@@ -75,6 +89,11 @@ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
75
89
  return context.report({
76
90
  node,
77
91
  messageId: 'classMethodsReadTopToBottom',
92
+ data: {
93
+ className: classNameReport,
94
+ actualMember,
95
+ expectedMember,
96
+ },
78
97
  fix(fixer) {
79
98
  return fixer.replaceTextRange([node.range[0] + 1, node.range[1] - 1], // Exclude the curly braces
80
99
  newClassBody);
@@ -210,7 +210,7 @@ module.exports = (0, createRule_1.createRule)({
210
210
  }
211
211
  }
212
212
  // Get references from global scope
213
- const sourceCode = context.getSourceCode();
213
+ const sourceCode = context.sourceCode;
214
214
  if (sourceCode.scopeManager?.globalScope) {
215
215
  const globalVar = sourceCode.scopeManager.globalScope.variables.find((v) => v.name === functionName);
216
216
  if (globalVar) {
@@ -20,13 +20,13 @@ exports.dynamicHttpsErrors = (0, createRule_1.createRule)({
20
20
  meta: {
21
21
  type: 'suggestion',
22
22
  docs: {
23
- description: 'Dynamic error details should only be in the third argument of the HttpsError constructor. The second argument is hashed to produce a unique id. All HttpsError constructor calls must include a third argument for contextual details.',
23
+ description: 'Keep HttpsError messages static and move request-specific details to the third argument so error identifiers remain stable and debugging context is preserved.',
24
24
  recommended: 'error',
25
25
  },
26
26
  schema: [],
27
27
  messages: {
28
- dynamicHttpsErrors: 'Found dynamic error details in the second argument of the HttpsError constructor - the "message" field. This field is hashed to produce a unique id for error monitoring. Move any dynamic details to the third argument - the "details" field - to preserve the unique id and to monitor the error correctly.',
29
- missingThirdArgument: "HttpsError constructor calls must include a third argument for contextual details. The third argument should contain relevant context that aids in debugging without affecting the error's unique identifier.",
28
+ dynamicHttpsErrors: 'The HttpsError message (second argument) must stay static. Template expressions here change the hashed message and explode the number of error ids for the same failure. Keep this argument constant and move interpolated values into the third "details" argument so monitoring groups the error while still capturing request context.',
29
+ missingThirdArgument: 'HttpsError calls must include a third "details" argument. The message (second argument) is hashed into a stable identifier, so omitting details leaves errors hard to debug and encourages packing variables into the hashed message. Provide a third argument with the request-specific context (object or string) to keep identifiers stable and diagnostics useful.',
30
30
  },
31
31
  },
32
32
  defaultOptions: [],
@@ -40,7 +40,6 @@ exports.dynamicHttpsErrors = (0, createRule_1.createRule)({
40
40
  node,
41
41
  messageId: 'missingThirdArgument',
42
42
  });
43
- return;
44
43
  }
45
44
  // Check for dynamic content in second argument (existing functionality)
46
45
  const secondArg = node.arguments[1];