@blumintinc/eslint-plugin-blumint 1.12.6 → 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.
- package/README.md +140 -99
- package/lib/index.js +111 -17
- package/lib/rules/array-methods-this-context.js +20 -2
- package/lib/rules/avoid-utils-directory.js +11 -2
- package/lib/rules/dynamic-https-errors.d.ts +3 -1
- package/lib/rules/dynamic-https-errors.js +48 -10
- package/lib/rules/enforce-assert-safe-object-key.d.ts +8 -0
- package/lib/rules/{enforce-assertSafe-object-key.js → enforce-assert-safe-object-key.js} +51 -95
- package/lib/rules/enforce-assert-throws.d.ts +3 -1
- package/lib/rules/enforce-assert-throws.js +493 -51
- package/lib/rules/enforce-boolean-naming-prefixes.d.ts +3 -1
- package/lib/rules/enforce-boolean-naming-prefixes.js +832 -39
- package/lib/rules/enforce-callable-types.js +4 -4
- package/lib/rules/enforce-callback-memo.js +143 -18
- package/lib/rules/enforce-centralized-mock-firestore.js +4 -1
- package/lib/rules/enforce-console-error.d.ts +3 -0
- package/lib/rules/enforce-console-error.js +250 -0
- package/lib/rules/enforce-css-media-queries.js +24 -46
- package/lib/rules/enforce-dynamic-firebase-imports.js +100 -19
- package/lib/rules/enforce-dynamic-imports.js +1 -1
- package/lib/rules/enforce-exported-function-types.js +3 -3
- package/lib/rules/enforce-fieldpath-syntax-in-docsetter.d.ts +2 -0
- package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +212 -0
- package/lib/rules/enforce-firestore-doc-ref-generic.js +335 -0
- package/lib/rules/enforce-firestore-facade.js +347 -157
- package/lib/rules/enforce-firestore-rules-get-access.d.ts +3 -0
- package/lib/rules/enforce-firestore-rules-get-access.js +109 -0
- package/lib/rules/enforce-global-constants.d.ts +4 -1
- package/lib/rules/enforce-global-constants.js +240 -12
- package/lib/rules/enforce-memoize-async.d.ts +2 -1
- package/lib/rules/enforce-memoize-async.js +96 -27
- package/lib/rules/enforce-memoize-getters.d.ts +3 -0
- package/lib/rules/enforce-memoize-getters.js +123 -0
- package/lib/rules/enforce-microdiff.js +2 -1
- package/lib/rules/enforce-positive-naming.js +5 -7
- package/lib/rules/enforce-props-argument-name.d.ts +2 -7
- package/lib/rules/enforce-props-argument-name.js +165 -151
- package/lib/rules/enforce-props-naming-consistency.d.ts +2 -0
- package/lib/rules/enforce-props-naming-consistency.js +145 -0
- package/lib/rules/enforce-querykey-ts.d.ts +9 -0
- package/lib/rules/enforce-querykey-ts.js +274 -0
- package/lib/rules/enforce-singular-type-names.js +9 -5
- package/lib/rules/enforce-typescript-markdown-code-blocks.d.ts +1 -0
- package/lib/rules/enforce-typescript-markdown-code-blocks.js +96 -0
- package/lib/rules/enforce-verb-noun-naming.js +85 -10
- package/lib/rules/extract-global-constants.js +57 -45
- package/lib/rules/fast-deep-equal-over-microdiff.d.ts +2 -1
- package/lib/rules/fast-deep-equal-over-microdiff.js +356 -78
- package/lib/rules/firestore-transaction-reads-before-writes.d.ts +1 -0
- package/lib/rules/firestore-transaction-reads-before-writes.js +231 -0
- package/lib/rules/generic-starts-with-t.js +8 -2
- package/lib/rules/memoize-root-level-hocs.d.ts +7 -0
- package/lib/rules/memoize-root-level-hocs.js +242 -0
- package/lib/rules/no-array-length-in-deps.d.ts +12 -0
- package/lib/rules/no-array-length-in-deps.js +308 -0
- package/lib/rules/no-async-array-filter.js +5 -2
- package/lib/rules/no-complex-cloud-params.js +15 -2
- package/lib/rules/no-compositing-layer-props.js +4 -2
- package/lib/rules/no-entire-object-hook-deps.d.ts +3 -1
- package/lib/rules/no-entire-object-hook-deps.js +317 -63
- package/lib/rules/no-excessive-parent-chain.d.ts +5 -0
- package/lib/rules/no-excessive-parent-chain.js +273 -0
- package/lib/rules/no-firestore-object-arrays.js +345 -30
- package/lib/rules/no-hungarian.js +13 -13
- package/lib/rules/no-margin-properties.d.ts +7 -1
- package/lib/rules/no-margin-properties.js +16 -3
- package/lib/rules/no-misleading-boolean-prefixes.d.ts +7 -0
- package/lib/rules/no-misleading-boolean-prefixes.js +327 -0
- package/lib/rules/no-overridable-method-calls-in-constructor.d.ts +1 -0
- package/lib/rules/no-overridable-method-calls-in-constructor.js +260 -0
- package/lib/rules/no-passthrough-getters.d.ts +4 -0
- package/lib/rules/no-passthrough-getters.js +170 -0
- package/lib/rules/no-redundant-usecallback-wrapper.d.ts +8 -0
- package/lib/rules/no-redundant-usecallback-wrapper.js +315 -0
- package/lib/rules/no-restricted-properties-fix.d.ts +12 -0
- package/lib/rules/no-restricted-properties-fix.js +172 -0
- package/lib/rules/no-separate-loading-state.d.ts +8 -0
- package/lib/rules/no-separate-loading-state.js +142 -0
- package/lib/rules/no-stale-state-across-await.d.ts +1 -0
- package/lib/rules/no-stale-state-across-await.js +185 -0
- package/lib/rules/no-static-constants-in-dynamic-files.d.ts +3 -0
- package/lib/rules/no-static-constants-in-dynamic-files.js +149 -0
- package/lib/rules/no-try-catch-already-exists-in-transaction.d.ts +1 -0
- package/lib/rules/no-try-catch-already-exists-in-transaction.js +342 -0
- package/lib/rules/no-type-assertion-returns.js +6 -0
- package/lib/rules/no-undefined-null-passthrough.js +166 -19
- package/lib/rules/no-unnecessary-verb-suffix.js +0 -2
- package/lib/rules/no-unsafe-firestore-spread.js +8 -5
- package/lib/rules/no-unused-props.d.ts +3 -0
- package/lib/rules/no-unused-props.js +213 -78
- package/lib/rules/optimize-object-boolean-conditions.d.ts +1 -0
- package/lib/rules/optimize-object-boolean-conditions.js +234 -0
- package/lib/rules/parallelize-async-operations.d.ts +8 -0
- package/lib/rules/parallelize-async-operations.js +375 -0
- package/lib/rules/prefer-batch-operations.js +199 -33
- package/lib/rules/prefer-block-comments-for-declarations.js +13 -3
- package/lib/rules/prefer-document-flattening.d.ts +4 -0
- package/lib/rules/prefer-document-flattening.js +239 -0
- package/lib/rules/prefer-field-paths-in-transforms.d.ts +7 -0
- package/lib/rules/prefer-field-paths-in-transforms.js +250 -0
- package/lib/rules/prefer-fragment-component.js +3 -3
- package/lib/rules/prefer-global-router-state-key.d.ts +7 -3
- package/lib/rules/prefer-global-router-state-key.js +230 -31
- package/lib/rules/prefer-next-dynamic.d.ts +9 -0
- package/lib/rules/prefer-next-dynamic.js +366 -0
- package/lib/rules/prefer-nullish-coalescing-boolean-props.d.ts +1 -0
- package/lib/rules/prefer-nullish-coalescing-boolean-props.js +430 -0
- package/lib/rules/prefer-nullish-coalescing-override.d.ts +6 -0
- package/lib/rules/prefer-nullish-coalescing-override.js +182 -0
- package/lib/rules/prefer-params-over-parent-id.d.ts +5 -0
- package/lib/rules/prefer-params-over-parent-id.js +228 -0
- package/lib/rules/prefer-settings-object.js +23 -15
- package/lib/rules/prefer-type-alias-over-typeof-constant.d.ts +3 -0
- package/lib/rules/prefer-type-alias-over-typeof-constant.js +259 -0
- package/lib/rules/prefer-url-tostring-over-tojson.d.ts +2 -0
- package/lib/rules/prefer-url-tostring-over-tojson.js +166 -0
- package/lib/rules/prefer-use-deep-compare-memo.d.ts +4 -0
- package/lib/rules/prefer-use-deep-compare-memo.js +428 -0
- package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +24 -1
- package/lib/rules/prefer-usememo-over-useeffect-usestate.js +24 -5
- package/lib/rules/react-usememo-should-be-component.d.ts +2 -1
- package/lib/rules/react-usememo-should-be-component.js +144 -78
- package/lib/rules/require-dynamic-firebase-imports.js +2 -1
- package/lib/rules/require-image-optimized.js +1 -1
- package/lib/rules/require-memo.js +11 -1
- package/lib/rules/require-usememo-object-literals.js +7 -1
- package/lib/rules/semantic-function-prefixes.js +38 -18
- package/lib/rules/sync-onwrite-name-func.js +5 -1
- package/lib/rules/test-file-location-enforcement.d.ts +1 -0
- package/lib/rules/test-file-location-enforcement.js +57 -0
- package/lib/rules/use-custom-link.js +6 -1
- package/lib/rules/use-custom-router.js +6 -1
- package/lib/rules/use-latest-callback.d.ts +3 -0
- package/lib/rules/use-latest-callback.js +270 -0
- package/lib/utils/ASTHelpers.js +10 -0
- package/lib/utils/createRule.js +1 -1
- package/lib/utils/graph/ClassGraphSorterReadability.js +1 -1
- package/lib/utils/ruleTester.d.ts +1 -0
- package/lib/utils/ruleTester.js +4 -1
- package/package.json +21 -14
- package/lib/rules/enforce-assertSafe-object-key.d.ts +0 -2
package/lib/index.js
CHANGED
|
@@ -6,13 +6,17 @@ 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 parallelize_async_operations_1 = require("./rules/parallelize-async-operations");
|
|
9
10
|
const dynamic_https_errors_1 = require("./rules/dynamic-https-errors");
|
|
10
11
|
const enforce_identifiable_firestore_type_1 = require("./rules/enforce-identifiable-firestore-type");
|
|
11
12
|
const enforce_callback_memo_1 = __importDefault(require("./rules/enforce-callback-memo"));
|
|
12
13
|
const enforce_callable_types_1 = require("./rules/enforce-callable-types");
|
|
14
|
+
const enforce_console_error_1 = require("./rules/enforce-console-error");
|
|
13
15
|
const enforce_dynamic_firebase_imports_1 = require("./rules/enforce-dynamic-firebase-imports");
|
|
14
16
|
const enforce_mui_rounded_icons_1 = require("./rules/enforce-mui-rounded-icons");
|
|
17
|
+
const enforce_querykey_ts_1 = require("./rules/enforce-querykey-ts");
|
|
15
18
|
const enforce_react_type_naming_1 = require("./rules/enforce-react-type-naming");
|
|
19
|
+
const enforce_firestore_rules_get_access_1 = require("./rules/enforce-firestore-rules-get-access");
|
|
16
20
|
const export_if_in_doubt_1 = require("./rules/export-if-in-doubt");
|
|
17
21
|
const extract_global_constants_1 = require("./rules/extract-global-constants");
|
|
18
22
|
const enforce_global_constants_1 = require("./rules/enforce-global-constants");
|
|
@@ -29,6 +33,7 @@ const no_unused_props_1 = require("./rules/no-unused-props");
|
|
|
29
33
|
const no_useless_fragment_1 = require("./rules/no-useless-fragment");
|
|
30
34
|
const prefer_fragment_shorthand_1 = require("./rules/prefer-fragment-shorthand");
|
|
31
35
|
const prefer_type_over_interface_1 = require("./rules/prefer-type-over-interface");
|
|
36
|
+
const prefer_type_alias_over_typeof_constant_1 = require("./rules/prefer-type-alias-over-typeof-constant");
|
|
32
37
|
const require_memo_1 = require("./rules/require-memo");
|
|
33
38
|
const no_jsx_whitespace_literal_1 = require("./rules/no-jsx-whitespace-literal");
|
|
34
39
|
const require_dynamic_firebase_imports_1 = __importDefault(require("./rules/require-dynamic-firebase-imports"));
|
|
@@ -49,11 +54,13 @@ const enforce_firestore_set_merge_1 = require("./rules/enforce-firestore-set-mer
|
|
|
49
54
|
const enforce_verb_noun_naming_1 = require("./rules/enforce-verb-noun-naming");
|
|
50
55
|
const no_explicit_return_type_1 = require("./rules/no-explicit-return-type");
|
|
51
56
|
const use_custom_memo_1 = require("./rules/use-custom-memo");
|
|
57
|
+
const memoize_root_level_hocs_1 = require("./rules/memoize-root-level-hocs");
|
|
52
58
|
const use_custom_link_1 = require("./rules/use-custom-link");
|
|
53
59
|
const enforce_serializable_params_1 = __importDefault(require("./rules/enforce-serializable-params"));
|
|
54
60
|
const enforce_realtimedb_path_utils_1 = require("./rules/enforce-realtimedb-path-utils");
|
|
55
61
|
const enforce_memoize_async_1 = require("./rules/enforce-memoize-async");
|
|
56
62
|
const enforce_exported_function_types_1 = require("./rules/enforce-exported-function-types");
|
|
63
|
+
const enforce_memoize_getters_1 = require("./rules/enforce-memoize-getters");
|
|
57
64
|
const no_redundant_param_types_1 = require("./rules/no-redundant-param-types");
|
|
58
65
|
const no_class_instance_destructuring_1 = require("./rules/no-class-instance-destructuring");
|
|
59
66
|
const no_firestore_object_arrays_1 = require("./rules/no-firestore-object-arrays");
|
|
@@ -76,7 +83,7 @@ const enforce_render_hits_memoization_1 = require("./rules/enforce-render-hits-m
|
|
|
76
83
|
const prefer_fragment_component_1 = require("./rules/prefer-fragment-component");
|
|
77
84
|
const react_usememo_should_be_component_1 = require("./rules/react-usememo-should-be-component");
|
|
78
85
|
const no_unnecessary_verb_suffix_1 = require("./rules/no-unnecessary-verb-suffix");
|
|
79
|
-
const
|
|
86
|
+
const enforce_assert_safe_object_key_1 = require("./rules/enforce-assert-safe-object-key");
|
|
80
87
|
const enforce_object_literal_as_const_1 = require("./rules/enforce-object-literal-as-const");
|
|
81
88
|
const enforce_positive_naming_1 = require("./rules/enforce-positive-naming");
|
|
82
89
|
const no_type_assertion_returns_1 = require("./rules/no-type-assertion-returns");
|
|
@@ -86,6 +93,7 @@ const fast_deep_equal_over_microdiff_1 = require("./rules/fast-deep-equal-over-m
|
|
|
86
93
|
const enforce_timestamp_now_1 = require("./rules/enforce-timestamp-now");
|
|
87
94
|
const no_always_true_false_conditions_1 = require("./rules/no-always-true-false-conditions");
|
|
88
95
|
const enforce_props_argument_name_1 = require("./rules/enforce-props-argument-name");
|
|
96
|
+
const enforce_props_naming_consistency_1 = require("./rules/enforce-props-naming-consistency");
|
|
89
97
|
const prefer_global_router_state_key_1 = require("./rules/prefer-global-router-state-key");
|
|
90
98
|
const prefer_usememo_over_useeffect_usestate_1 = require("./rules/prefer-usememo-over-useeffect-usestate");
|
|
91
99
|
const enforce_dynamic_imports_1 = __importDefault(require("./rules/enforce-dynamic-imports"));
|
|
@@ -103,12 +111,38 @@ const enforce_dynamic_file_naming_1 = __importDefault(require("./rules/enforce-d
|
|
|
103
111
|
const prefer_usecallback_over_usememo_for_functions_1 = __importDefault(require("./rules/prefer-usecallback-over-usememo-for-functions"));
|
|
104
112
|
const no_margin_properties_1 = require("./rules/no-margin-properties");
|
|
105
113
|
const enforce_boolean_naming_prefixes_1 = require("./rules/enforce-boolean-naming-prefixes");
|
|
114
|
+
const enforce_fieldpath_syntax_in_docsetter_1 = require("./rules/enforce-fieldpath-syntax-in-docsetter");
|
|
106
115
|
const prefer_block_comments_for_declarations_1 = require("./rules/prefer-block-comments-for-declarations");
|
|
107
116
|
const no_undefined_null_passthrough_1 = require("./rules/no-undefined-null-passthrough");
|
|
117
|
+
const firestore_transaction_reads_before_writes_1 = require("./rules/firestore-transaction-reads-before-writes");
|
|
118
|
+
const enforce_typescript_markdown_code_blocks_1 = require("./rules/enforce-typescript-markdown-code-blocks");
|
|
119
|
+
const prefer_nullish_coalescing_override_1 = require("./rules/prefer-nullish-coalescing-override");
|
|
120
|
+
const prefer_nullish_coalescing_boolean_props_1 = require("./rules/prefer-nullish-coalescing-boolean-props");
|
|
121
|
+
const no_restricted_properties_fix_1 = require("./rules/no-restricted-properties-fix");
|
|
122
|
+
const no_excessive_parent_chain_1 = require("./rules/no-excessive-parent-chain");
|
|
123
|
+
const prefer_document_flattening_1 = require("./rules/prefer-document-flattening");
|
|
124
|
+
const no_overridable_method_calls_in_constructor_1 = require("./rules/no-overridable-method-calls-in-constructor");
|
|
125
|
+
const use_latest_callback_1 = require("./rules/use-latest-callback");
|
|
126
|
+
const no_stale_state_across_await_1 = require("./rules/no-stale-state-across-await");
|
|
127
|
+
const no_separate_loading_state_1 = require("./rules/no-separate-loading-state");
|
|
128
|
+
const optimize_object_boolean_conditions_1 = require("./rules/optimize-object-boolean-conditions");
|
|
129
|
+
const prefer_params_over_parent_id_1 = require("./rules/prefer-params-over-parent-id");
|
|
130
|
+
const prefer_field_paths_in_transforms_1 = require("./rules/prefer-field-paths-in-transforms");
|
|
131
|
+
const no_misleading_boolean_prefixes_1 = require("./rules/no-misleading-boolean-prefixes");
|
|
132
|
+
const prefer_url_tostring_over_tojson_1 = require("./rules/prefer-url-tostring-over-tojson");
|
|
133
|
+
const prefer_next_dynamic_1 = require("./rules/prefer-next-dynamic");
|
|
134
|
+
const no_redundant_usecallback_wrapper_1 = __importDefault(require("./rules/no-redundant-usecallback-wrapper"));
|
|
135
|
+
const no_array_length_in_deps_1 = require("./rules/no-array-length-in-deps");
|
|
136
|
+
const prefer_use_deep_compare_memo_1 = require("./rules/prefer-use-deep-compare-memo");
|
|
137
|
+
const no_circular_references_1 = require("./rules/no-circular-references");
|
|
138
|
+
const no_passthrough_getters_1 = require("./rules/no-passthrough-getters");
|
|
139
|
+
const no_try_catch_already_exists_in_transaction_1 = require("./rules/no-try-catch-already-exists-in-transaction");
|
|
140
|
+
const no_static_constants_in_dynamic_files_1 = __importDefault(require("./rules/no-static-constants-in-dynamic-files"));
|
|
141
|
+
const test_file_location_enforcement_1 = require("./rules/test-file-location-enforcement");
|
|
108
142
|
module.exports = {
|
|
109
143
|
meta: {
|
|
110
144
|
name: '@blumintinc/eslint-plugin-blumint',
|
|
111
|
-
version: '1.
|
|
145
|
+
version: '1.13.0',
|
|
112
146
|
},
|
|
113
147
|
parseOptions: {
|
|
114
148
|
ecmaVersion: 2020,
|
|
@@ -117,10 +151,16 @@ module.exports = {
|
|
|
117
151
|
recommended: {
|
|
118
152
|
plugins: ['@blumintinc/blumint'],
|
|
119
153
|
rules: {
|
|
154
|
+
'@blumintinc/blumint/firestore-transaction-reads-before-writes': 'error',
|
|
155
|
+
// Override the @typescript-eslint/prefer-nullish-coalescing rule
|
|
156
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
157
|
+
'@blumintinc/blumint/prefer-nullish-coalescing-override': 'error',
|
|
120
158
|
'@blumintinc/blumint/prefer-block-comments-for-declarations': 'error',
|
|
121
159
|
'@blumintinc/blumint/key-only-outermost-element': 'error',
|
|
160
|
+
'@blumintinc/blumint/parallelize-async-operations': 'error',
|
|
122
161
|
'@blumintinc/blumint/avoid-utils-directory': 'error',
|
|
123
162
|
'@blumintinc/blumint/enforce-firestore-path-utils': 'error',
|
|
163
|
+
'@blumintinc/blumint/enforce-firestore-rules-get-access': 'error',
|
|
124
164
|
'@blumintinc/blumint/no-jsx-whitespace-literal': 'error',
|
|
125
165
|
'@blumintinc/blumint/array-methods-this-context': 'error',
|
|
126
166
|
'@blumintinc/blumint/class-methods-read-top-to-bottom': 'error',
|
|
@@ -130,9 +170,10 @@ module.exports = {
|
|
|
130
170
|
'@blumintinc/blumint/enforce-identifiable-firestore-type': 'error',
|
|
131
171
|
'@blumintinc/blumint/enforce-callback-memo': 'error',
|
|
132
172
|
'@blumintinc/blumint/enforce-callable-types': 'error',
|
|
173
|
+
'@blumintinc/blumint/enforce-console-error': 'error',
|
|
133
174
|
'@blumintinc/blumint/enforce-dynamic-firebase-imports': 'error',
|
|
134
175
|
'@blumintinc/blumint/enforce-react-type-naming': 'error',
|
|
135
|
-
|
|
176
|
+
'@blumintinc/blumint/export-if-in-doubt': 'error',
|
|
136
177
|
'@blumintinc/blumint/extract-global-constants': 'error',
|
|
137
178
|
'@blumintinc/blumint/enforce-global-constants': 'error',
|
|
138
179
|
'@blumintinc/blumint/generic-starts-with-t': 'error',
|
|
@@ -146,15 +187,17 @@ module.exports = {
|
|
|
146
187
|
'@blumintinc/blumint/no-unpinned-dependencies': 'error',
|
|
147
188
|
'@blumintinc/blumint/no-unused-props': 'error',
|
|
148
189
|
'@blumintinc/blumint/no-uuidv4-base62-as-key': 'error',
|
|
149
|
-
|
|
150
|
-
|
|
190
|
+
'@blumintinc/blumint/no-useless-fragment': 'error',
|
|
191
|
+
'@blumintinc/blumint/prefer-fragment-shorthand': 'error',
|
|
151
192
|
'@blumintinc/blumint/prefer-type-over-interface': 'error',
|
|
193
|
+
'@blumintinc/blumint/prefer-type-alias-over-typeof-constant': 'error',
|
|
152
194
|
'@blumintinc/blumint/require-memo': 'error',
|
|
153
195
|
'@blumintinc/blumint/require-dynamic-firebase-imports': 'error',
|
|
154
196
|
'@blumintinc/blumint/require-https-error': 'error',
|
|
155
197
|
'@blumintinc/blumint/use-custom-router': 'error',
|
|
156
198
|
'@blumintinc/blumint/require-image-optimized': 'error',
|
|
157
199
|
'@blumintinc/blumint/require-usememo-object-literals': 'error',
|
|
200
|
+
'@blumintinc/blumint/memoize-root-level-hocs': 'error',
|
|
158
201
|
'@blumintinc/blumint/enforce-safe-stringify': 'error',
|
|
159
202
|
'@blumintinc/blumint/no-entire-object-hook-deps': 'error',
|
|
160
203
|
'@blumintinc/blumint/no-compositing-layer-props': 'error',
|
|
@@ -172,8 +215,9 @@ module.exports = {
|
|
|
172
215
|
'@blumintinc/blumint/enforce-memoize-async': 'error',
|
|
173
216
|
'@blumintinc/blumint/enforce-exported-function-types': 'error',
|
|
174
217
|
'@blumintinc/blumint/no-redundant-param-types': 'error',
|
|
218
|
+
'@blumintinc/blumint/enforce-memoize-getters': 'error',
|
|
175
219
|
'@blumintinc/blumint/no-class-instance-destructuring': 'error',
|
|
176
|
-
'@blumintinc/blumint/no-firestore-object-arrays': '
|
|
220
|
+
'@blumintinc/blumint/no-firestore-object-arrays': 'error',
|
|
177
221
|
'@blumintinc/blumint/no-memoize-on-static': 'error',
|
|
178
222
|
'@blumintinc/blumint/no-unsafe-firestore-spread': 'error',
|
|
179
223
|
'@blumintinc/blumint/no-jsx-in-hooks': 'error',
|
|
@@ -190,10 +234,10 @@ module.exports = {
|
|
|
190
234
|
'@blumintinc/blumint/require-hooks-default-params': 'error',
|
|
191
235
|
'@blumintinc/blumint/prefer-destructuring-no-class': 'error',
|
|
192
236
|
'@blumintinc/blumint/enforce-render-hits-memoization': 'error',
|
|
193
|
-
'@blumintinc/blumint/prefer-fragment-component': '
|
|
237
|
+
'@blumintinc/blumint/prefer-fragment-component': 'off',
|
|
194
238
|
'@blumintinc/blumint/react-usememo-should-be-component': 'error',
|
|
195
239
|
'@blumintinc/blumint/no-unnecessary-verb-suffix': 'error',
|
|
196
|
-
'@blumintinc/blumint/enforce-
|
|
240
|
+
'@blumintinc/blumint/enforce-assert-safe-object-key': 'error',
|
|
197
241
|
'@blumintinc/blumint/enforce-object-literal-as-const': 'error',
|
|
198
242
|
'@blumintinc/blumint/enforce-positive-naming': 'error',
|
|
199
243
|
'@blumintinc/blumint/no-type-assertion-returns': 'error',
|
|
@@ -201,17 +245,13 @@ module.exports = {
|
|
|
201
245
|
'@blumintinc/blumint/enforce-microdiff': 'error',
|
|
202
246
|
'@blumintinc/blumint/fast-deep-equal-over-microdiff': 'error',
|
|
203
247
|
'@blumintinc/blumint/enforce-timestamp-now': 'error',
|
|
248
|
+
'@blumintinc/blumint/enforce-typescript-markdown-code-blocks': 'error',
|
|
204
249
|
'@blumintinc/blumint/no-always-true-false-conditions': 'error',
|
|
205
250
|
'@blumintinc/blumint/enforce-props-argument-name': 'error',
|
|
251
|
+
'@blumintinc/blumint/enforce-props-naming-consistency': 'error',
|
|
206
252
|
'@blumintinc/blumint/prefer-global-router-state-key': 'error',
|
|
207
253
|
'@blumintinc/blumint/prefer-usememo-over-useeffect-usestate': 'error',
|
|
208
|
-
'@blumintinc/blumint/enforce-dynamic-imports':
|
|
209
|
-
'error',
|
|
210
|
-
{
|
|
211
|
-
libraries: ['@stream-io/video-react-sdk', 'some-heavy-lib*'],
|
|
212
|
-
allowImportType: true,
|
|
213
|
-
},
|
|
214
|
-
],
|
|
254
|
+
'@blumintinc/blumint/enforce-dynamic-imports': 'error',
|
|
215
255
|
'@blumintinc/blumint/ensure-pointer-events-none': 'error',
|
|
216
256
|
'@blumintinc/blumint/no-object-values-on-strings': 'error',
|
|
217
257
|
'@blumintinc/blumint/no-unnecessary-destructuring': 'error',
|
|
@@ -220,25 +260,53 @@ module.exports = {
|
|
|
220
260
|
'@blumintinc/blumint/omit-index-html': 'error',
|
|
221
261
|
'@blumintinc/blumint/enforce-id-capitalization': 'error',
|
|
222
262
|
'@blumintinc/blumint/no-unused-usestate': 'error',
|
|
223
|
-
'@blumintinc/blumint/enforce-dynamic-file-naming': 'error',
|
|
224
263
|
'@blumintinc/blumint/prefer-usecallback-over-usememo-for-functions': 'error',
|
|
225
264
|
'@blumintinc/blumint/no-margin-properties': 'error',
|
|
226
265
|
'@blumintinc/blumint/enforce-boolean-naming-prefixes': 'error',
|
|
266
|
+
'@blumintinc/blumint/enforce-fieldpath-syntax-in-docsetter': 'error',
|
|
227
267
|
'@blumintinc/blumint/no-undefined-null-passthrough': 'error',
|
|
268
|
+
'@blumintinc/blumint/prefer-nullish-coalescing-boolean-props': 'error',
|
|
269
|
+
'@blumintinc/blumint/no-overridable-method-calls-in-constructor': 'error',
|
|
270
|
+
'@blumintinc/blumint/use-latest-callback': 'error',
|
|
271
|
+
'@blumintinc/blumint/enforce-querykey-ts': 'error',
|
|
272
|
+
'@blumintinc/blumint/no-stale-state-across-await': 'error',
|
|
273
|
+
'@blumintinc/blumint/no-separate-loading-state': 'error',
|
|
274
|
+
'@blumintinc/blumint/optimize-object-boolean-conditions': 'error',
|
|
275
|
+
'@blumintinc/blumint/prefer-params-over-parent-id': 'error',
|
|
276
|
+
'@blumintinc/blumint/prefer-field-paths-in-transforms': 'warn',
|
|
277
|
+
'@blumintinc/blumint/no-misleading-boolean-prefixes': 'error',
|
|
278
|
+
'@blumintinc/blumint/prefer-url-tostring-over-tojson': 'error',
|
|
279
|
+
'@blumintinc/blumint/prefer-next-dynamic': 'error',
|
|
280
|
+
'@blumintinc/blumint/no-redundant-usecallback-wrapper': 'error',
|
|
281
|
+
'@blumintinc/blumint/no-array-length-in-deps': 'error',
|
|
282
|
+
'@blumintinc/blumint/prefer-use-deep-compare-memo': 'error',
|
|
283
|
+
'@blumintinc/blumint/no-circular-references': 'error',
|
|
284
|
+
'@blumintinc/blumint/no-try-catch-already-exists-in-transaction': 'error',
|
|
285
|
+
'@blumintinc/blumint/no-passthrough-getters': 'error',
|
|
286
|
+
'@blumintinc/blumint/no-static-constants-in-dynamic-files': 'error',
|
|
287
|
+
'@blumintinc/blumint/test-file-location-enforcement': 'error',
|
|
228
288
|
},
|
|
229
289
|
},
|
|
230
290
|
},
|
|
231
291
|
rules: {
|
|
292
|
+
'firestore-transaction-reads-before-writes': firestore_transaction_reads_before_writes_1.firestoreTransactionReadsBeforeWrites,
|
|
293
|
+
'prefer-nullish-coalescing-override': prefer_nullish_coalescing_override_1.preferNullishCoalescingOverride,
|
|
294
|
+
'no-restricted-properties-fix': no_restricted_properties_fix_1.noRestrictedPropertiesFix,
|
|
295
|
+
'no-excessive-parent-chain': no_excessive_parent_chain_1.noExcessiveParentChain,
|
|
296
|
+
'prefer-document-flattening': prefer_document_flattening_1.preferDocumentFlattening,
|
|
232
297
|
'prefer-block-comments-for-declarations': prefer_block_comments_for_declarations_1.preferBlockCommentsForDeclarations,
|
|
233
298
|
'key-only-outermost-element': key_only_outermost_element_1.keyOnlyOutermostElement,
|
|
234
299
|
'array-methods-this-context': array_methods_this_context_1.arrayMethodsThisContext,
|
|
235
300
|
'class-methods-read-top-to-bottom': class_methods_read_top_to_bottom_1.classMethodsReadTopToBottom,
|
|
236
301
|
'consistent-callback-naming': consistent_callback_naming_1.default,
|
|
302
|
+
'parallelize-async-operations': parallelize_async_operations_1.parallelizeAsyncOperations,
|
|
237
303
|
'dynamic-https-errors': dynamic_https_errors_1.dynamicHttpsErrors,
|
|
238
304
|
'enforce-identifiable-firestore-type': enforce_identifiable_firestore_type_1.enforceIdentifiableFirestoreType,
|
|
239
305
|
'enforce-callback-memo': enforce_callback_memo_1.default,
|
|
240
306
|
'enforce-react-type-naming': enforce_react_type_naming_1.enforceReactTypeNaming,
|
|
307
|
+
'enforce-firestore-rules-get-access': enforce_firestore_rules_get_access_1.enforceFirestoreRulesGetAccess,
|
|
241
308
|
'enforce-callable-types': enforce_callable_types_1.enforceCallableTypes,
|
|
309
|
+
'enforce-console-error': enforce_console_error_1.enforceConsoleError,
|
|
242
310
|
'enforce-dynamic-firebase-imports': enforce_dynamic_firebase_imports_1.enforceFirebaseImports,
|
|
243
311
|
'enforce-mui-rounded-icons': enforce_mui_rounded_icons_1.enforceMuiRoundedIcons,
|
|
244
312
|
'export-if-in-doubt': export_if_in_doubt_1.exportIfInDoubt,
|
|
@@ -259,6 +327,7 @@ module.exports = {
|
|
|
259
327
|
'enforce-dynamic-file-naming': enforce_dynamic_file_naming_1.default,
|
|
260
328
|
'prefer-fragment-shorthand': prefer_fragment_shorthand_1.preferFragmentShorthand,
|
|
261
329
|
'prefer-type-over-interface': prefer_type_over_interface_1.preferTypeOverInterface,
|
|
330
|
+
'prefer-type-alias-over-typeof-constant': prefer_type_alias_over_typeof_constant_1.preferTypeAliasOverTypeofConstant,
|
|
262
331
|
'require-memo': require_memo_1.requireMemo,
|
|
263
332
|
'no-jsx-whitespace-literal': no_jsx_whitespace_literal_1.noJsxWhitespaceLiteral,
|
|
264
333
|
'require-dynamic-firebase-imports': require_dynamic_firebase_imports_1.default,
|
|
@@ -266,6 +335,7 @@ module.exports = {
|
|
|
266
335
|
'use-custom-router': use_custom_router_1.useCustomRouter,
|
|
267
336
|
'require-image-optimized': require_image_optimized_1.default,
|
|
268
337
|
'require-usememo-object-literals': require_usememo_object_literals_1.requireUseMemoObjectLiterals,
|
|
338
|
+
'memoize-root-level-hocs': memoize_root_level_hocs_1.memoizeRootLevelHocs,
|
|
269
339
|
'enforce-safe-stringify': enforce_safe_stringify_1.enforceStableStringify,
|
|
270
340
|
'avoid-utils-directory': avoid_utils_directory_1.avoidUtilsDirectory,
|
|
271
341
|
'no-entire-object-hook-deps': no_entire_object_hook_deps_1.noEntireObjectHookDeps,
|
|
@@ -285,6 +355,7 @@ module.exports = {
|
|
|
285
355
|
'enforce-memoize-async': enforce_memoize_async_1.enforceMemoizeAsync,
|
|
286
356
|
'enforce-exported-function-types': enforce_exported_function_types_1.enforceExportedFunctionTypes,
|
|
287
357
|
'no-redundant-param-types': no_redundant_param_types_1.noRedundantParamTypes,
|
|
358
|
+
'enforce-memoize-getters': enforce_memoize_getters_1.enforceMemoizeGetters,
|
|
288
359
|
'no-class-instance-destructuring': no_class_instance_destructuring_1.noClassInstanceDestructuring,
|
|
289
360
|
'no-firestore-object-arrays': no_firestore_object_arrays_1.noFirestoreObjectArrays,
|
|
290
361
|
'no-memoize-on-static': no_memoize_on_static_1.noMemoizeOnStatic,
|
|
@@ -306,7 +377,7 @@ module.exports = {
|
|
|
306
377
|
'prefer-fragment-component': prefer_fragment_component_1.preferFragmentComponent,
|
|
307
378
|
'react-usememo-should-be-component': react_usememo_should_be_component_1.reactUseMemoShouldBeComponent,
|
|
308
379
|
'no-unnecessary-verb-suffix': no_unnecessary_verb_suffix_1.noUnnecessaryVerbSuffix,
|
|
309
|
-
'enforce-
|
|
380
|
+
'enforce-assert-safe-object-key': enforce_assert_safe_object_key_1.enforceAssertSafeObjectKey,
|
|
310
381
|
'enforce-object-literal-as-const': enforce_object_literal_as_const_1.enforceObjectLiteralAsConst,
|
|
311
382
|
'enforce-positive-naming': enforce_positive_naming_1.enforcePositiveNaming,
|
|
312
383
|
'no-type-assertion-returns': no_type_assertion_returns_1.noTypeAssertionReturns,
|
|
@@ -314,8 +385,10 @@ module.exports = {
|
|
|
314
385
|
'enforce-microdiff': enforce_microdiff_1.enforceMicrodiff,
|
|
315
386
|
'fast-deep-equal-over-microdiff': fast_deep_equal_over_microdiff_1.fastDeepEqualOverMicrodiff,
|
|
316
387
|
'enforce-timestamp-now': enforce_timestamp_now_1.enforceTimestampNow,
|
|
388
|
+
'enforce-typescript-markdown-code-blocks': enforce_typescript_markdown_code_blocks_1.enforceTypescriptMarkdownCodeBlocks,
|
|
317
389
|
'no-always-true-false-conditions': no_always_true_false_conditions_1.noAlwaysTrueFalseConditions,
|
|
318
390
|
'enforce-props-argument-name': enforce_props_argument_name_1.enforcePropsArgumentName,
|
|
391
|
+
'enforce-props-naming-consistency': enforce_props_naming_consistency_1.enforcePropsNamingConsistency,
|
|
319
392
|
'prefer-global-router-state-key': prefer_global_router_state_key_1.preferGlobalRouterStateKey,
|
|
320
393
|
'prefer-usememo-over-useeffect-usestate': prefer_usememo_over_useeffect_usestate_1.preferUseMemoOverUseEffectUseState,
|
|
321
394
|
'enforce-dynamic-imports': enforce_dynamic_imports_1.default,
|
|
@@ -330,7 +403,28 @@ module.exports = {
|
|
|
330
403
|
'prefer-usecallback-over-usememo-for-functions': prefer_usecallback_over_usememo_for_functions_1.default,
|
|
331
404
|
'no-margin-properties': no_margin_properties_1.noMarginProperties,
|
|
332
405
|
'enforce-boolean-naming-prefixes': enforce_boolean_naming_prefixes_1.enforceBooleanNamingPrefixes,
|
|
406
|
+
'enforce-fieldpath-syntax-in-docsetter': enforce_fieldpath_syntax_in_docsetter_1.enforceFieldPathSyntaxInDocSetter,
|
|
333
407
|
'no-undefined-null-passthrough': no_undefined_null_passthrough_1.noUndefinedNullPassthrough,
|
|
408
|
+
'prefer-nullish-coalescing-boolean-props': prefer_nullish_coalescing_boolean_props_1.preferNullishCoalescingBooleanProps,
|
|
409
|
+
'no-overridable-method-calls-in-constructor': no_overridable_method_calls_in_constructor_1.noOverridableMethodCallsInConstructor,
|
|
410
|
+
'use-latest-callback': use_latest_callback_1.useLatestCallback,
|
|
411
|
+
'enforce-querykey-ts': enforce_querykey_ts_1.enforceQueryKeyTs,
|
|
412
|
+
'no-stale-state-across-await': no_stale_state_across_await_1.noStaleStateAcrossAwait,
|
|
413
|
+
'no-separate-loading-state': no_separate_loading_state_1.noSeparateLoadingState,
|
|
414
|
+
'optimize-object-boolean-conditions': optimize_object_boolean_conditions_1.optimizeObjectBooleanConditions,
|
|
415
|
+
'prefer-params-over-parent-id': prefer_params_over_parent_id_1.preferParamsOverParentId,
|
|
416
|
+
'prefer-field-paths-in-transforms': prefer_field_paths_in_transforms_1.preferFieldPathsInTransforms,
|
|
417
|
+
'no-misleading-boolean-prefixes': no_misleading_boolean_prefixes_1.noMisleadingBooleanPrefixes,
|
|
418
|
+
'prefer-url-tostring-over-tojson': prefer_url_tostring_over_tojson_1.preferUrlToStringOverToJson,
|
|
419
|
+
'prefer-next-dynamic': prefer_next_dynamic_1.preferNextDynamic,
|
|
420
|
+
'no-redundant-usecallback-wrapper': no_redundant_usecallback_wrapper_1.default,
|
|
421
|
+
'no-array-length-in-deps': no_array_length_in_deps_1.noArrayLengthInDeps,
|
|
422
|
+
'prefer-use-deep-compare-memo': prefer_use_deep_compare_memo_1.preferUseDeepCompareMemo,
|
|
423
|
+
'no-circular-references': no_circular_references_1.noCircularReferences,
|
|
424
|
+
'no-try-catch-already-exists-in-transaction': no_try_catch_already_exists_in_transaction_1.noTryCatchAlreadyExistsInTransaction,
|
|
425
|
+
'no-passthrough-getters': no_passthrough_getters_1.noPassthroughGetters,
|
|
426
|
+
'no-static-constants-in-dynamic-files': no_static_constants_in_dynamic_files_1.default,
|
|
427
|
+
'test-file-location-enforcement': test_file_location_enforcement_1.testFileLocationEnforcement,
|
|
334
428
|
},
|
|
335
429
|
};
|
|
336
430
|
//# sourceMappingURL=index.js.map
|
|
@@ -12,6 +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
16
|
return {
|
|
16
17
|
CallExpression(node) {
|
|
17
18
|
// Array method called with a class method reference
|
|
@@ -21,9 +22,23 @@ exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
|
21
22
|
node.arguments.length > 0 &&
|
|
22
23
|
node.arguments[0].type === 'MemberExpression' &&
|
|
23
24
|
node.arguments[0].object.type === 'ThisExpression') {
|
|
25
|
+
const methodProperty = node.arguments[0].property;
|
|
26
|
+
const methodAccessor = node.arguments[0].computed
|
|
27
|
+
? `[${sourceCode.getText(methodProperty)}]`
|
|
28
|
+
: methodProperty.type === 'Identifier'
|
|
29
|
+
? `.${methodProperty.name}`
|
|
30
|
+
: methodProperty.type === 'PrivateIdentifier'
|
|
31
|
+
? `.#${methodProperty.name}`
|
|
32
|
+
: `.${sourceCode.getText(methodProperty)}`;
|
|
33
|
+
const methodReference = `this${methodAccessor}`;
|
|
24
34
|
context.report({
|
|
25
35
|
node: node.arguments[0],
|
|
26
36
|
messageId: 'unexpected',
|
|
37
|
+
data: {
|
|
38
|
+
arrayMethod: node.callee.property.name,
|
|
39
|
+
methodAccessor,
|
|
40
|
+
methodReference,
|
|
41
|
+
},
|
|
27
42
|
});
|
|
28
43
|
}
|
|
29
44
|
// Function expression bound to `this` in array method
|
|
@@ -41,6 +56,9 @@ exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
|
41
56
|
context.report({
|
|
42
57
|
node: node.arguments[0],
|
|
43
58
|
messageId: 'preferArrow',
|
|
59
|
+
data: {
|
|
60
|
+
arrayMethod: node.callee.property.name,
|
|
61
|
+
},
|
|
44
62
|
});
|
|
45
63
|
}
|
|
46
64
|
},
|
|
@@ -55,8 +73,8 @@ exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
|
|
|
55
73
|
},
|
|
56
74
|
schema: [],
|
|
57
75
|
messages: {
|
|
58
|
-
unexpected: '
|
|
59
|
-
preferArrow: '
|
|
76
|
+
unexpected: 'Array method "{{arrayMethod}}" receives the class method reference {{methodReference}}, which strips its "this" binding when the callback runs. Use an arrow callback so the class instance remains available, e.g. {{arrayMethod}}((item) => this{{methodAccessor}}(item)).',
|
|
77
|
+
preferArrow: 'Array method "{{arrayMethod}}" binds a callback with ".bind(this)", which allocates a new function and hides that the code depends on the class instance. Prefer an arrow callback that captures "this" without rebinding, e.g. {{arrayMethod}}((item) => this.handleItem(item)).',
|
|
60
78
|
},
|
|
61
79
|
},
|
|
62
80
|
defaultOptions: [],
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.avoidUtilsDirectory = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
4
8
|
const createRule_1 = require("../utils/createRule");
|
|
5
9
|
exports.avoidUtilsDirectory = (0, createRule_1.createRule)({
|
|
6
10
|
name: 'avoid-utils-directory',
|
|
@@ -10,10 +14,9 @@ exports.avoidUtilsDirectory = (0, createRule_1.createRule)({
|
|
|
10
14
|
description: 'Enforce using util/ instead of utils/ directory',
|
|
11
15
|
recommended: 'error',
|
|
12
16
|
},
|
|
13
|
-
fixable: 'code',
|
|
14
17
|
schema: [],
|
|
15
18
|
messages: {
|
|
16
|
-
avoidUtils: '
|
|
19
|
+
avoidUtils: 'Path "{{path}}" lives under a "utils/" directory. Generic "utils" folders become grab bags where unrelated helpers accumulate, which makes imports unpredictable and hides ownership. Move this file into a focused "util/" folder (e.g., "util/date" or "util/string") so callers know where to find it and understand its responsibility.',
|
|
17
20
|
},
|
|
18
21
|
},
|
|
19
22
|
defaultOptions: [],
|
|
@@ -21,6 +24,9 @@ exports.avoidUtilsDirectory = (0, createRule_1.createRule)({
|
|
|
21
24
|
return {
|
|
22
25
|
Program(node) {
|
|
23
26
|
const filename = context.getFilename();
|
|
27
|
+
const relativePath = path_1.default.isAbsolute(filename)
|
|
28
|
+
? path_1.default.relative(process.cwd(), filename) || filename
|
|
29
|
+
: filename;
|
|
24
30
|
// Skip files in node_modules
|
|
25
31
|
if (filename.includes('node_modules')) {
|
|
26
32
|
return;
|
|
@@ -31,6 +37,9 @@ exports.avoidUtilsDirectory = (0, createRule_1.createRule)({
|
|
|
31
37
|
context.report({
|
|
32
38
|
node,
|
|
33
39
|
messageId: 'avoidUtils',
|
|
40
|
+
data: {
|
|
41
|
+
path: relativePath,
|
|
42
|
+
},
|
|
34
43
|
fix() {
|
|
35
44
|
// We can't provide an auto-fix since directory renaming is beyond ESLint's scope
|
|
36
45
|
return null;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
-
|
|
2
|
+
type MessageIds = 'dynamicHttpsErrors' | 'missingThirdArgument';
|
|
3
|
+
export declare const dynamicHttpsErrors: TSESLint.RuleModule<MessageIds, never[]>;
|
|
4
|
+
export {};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dynamicHttpsErrors = void 0;
|
|
4
4
|
const createRule_1 = require("../utils/createRule");
|
|
5
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
5
6
|
const isHttpsErrorCall = (callee) => {
|
|
6
7
|
if (callee.type === 'MemberExpression') {
|
|
7
8
|
return (callee.object.type === 'Identifier' &&
|
|
@@ -19,12 +20,13 @@ exports.dynamicHttpsErrors = (0, createRule_1.createRule)({
|
|
|
19
20
|
meta: {
|
|
20
21
|
type: 'suggestion',
|
|
21
22
|
docs: {
|
|
22
|
-
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.',
|
|
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
24
|
recommended: 'error',
|
|
24
25
|
},
|
|
25
26
|
schema: [],
|
|
26
27
|
messages: {
|
|
27
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
30
|
},
|
|
29
31
|
},
|
|
30
32
|
defaultOptions: [],
|
|
@@ -32,23 +34,59 @@ exports.dynamicHttpsErrors = (0, createRule_1.createRule)({
|
|
|
32
34
|
const checkForHttpsError = (node) => {
|
|
33
35
|
const callee = node.callee;
|
|
34
36
|
if (isHttpsErrorCall(callee)) {
|
|
37
|
+
// Check for missing third argument
|
|
38
|
+
if (node.arguments.length < 3) {
|
|
39
|
+
context.report({
|
|
40
|
+
node,
|
|
41
|
+
messageId: 'missingThirdArgument',
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Check for dynamic content in second argument (existing functionality)
|
|
35
46
|
const secondArg = node.arguments[1];
|
|
36
|
-
if (secondArg
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
if (!secondArg)
|
|
48
|
+
return;
|
|
49
|
+
if (secondArg.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
|
|
50
|
+
secondArg.expressions.length > 0) {
|
|
51
|
+
context.report({
|
|
52
|
+
node: secondArg,
|
|
53
|
+
messageId: 'dynamicHttpsErrors',
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Only string concatenation with "+" can be static; all other operators
|
|
58
|
+
// are treated as dynamic to avoid hashing non-literal message content.
|
|
59
|
+
const isDynamicBinaryExpression = (expression) => {
|
|
60
|
+
if (expression.operator !== '+')
|
|
61
|
+
return true;
|
|
62
|
+
const isStaticLiteral = (expr) => expr.type === utils_1.AST_NODE_TYPES.Literal &&
|
|
63
|
+
typeof expr.value === 'string';
|
|
64
|
+
const isSafe = (expr) => {
|
|
65
|
+
if (expr.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (expr.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
|
|
69
|
+
return !isDynamicBinaryExpression(expr);
|
|
70
|
+
}
|
|
71
|
+
return isStaticLiteral(expr);
|
|
72
|
+
};
|
|
73
|
+
return !(isSafe(expression.left) && isSafe(expression.right));
|
|
74
|
+
};
|
|
75
|
+
if (secondArg.type === utils_1.AST_NODE_TYPES.BinaryExpression &&
|
|
76
|
+
isDynamicBinaryExpression(secondArg)) {
|
|
77
|
+
context.report({
|
|
78
|
+
node: secondArg,
|
|
79
|
+
messageId: 'dynamicHttpsErrors',
|
|
80
|
+
});
|
|
43
81
|
}
|
|
44
82
|
}
|
|
45
83
|
};
|
|
46
84
|
return {
|
|
47
85
|
NewExpression(node) {
|
|
48
|
-
|
|
86
|
+
checkForHttpsError(node);
|
|
49
87
|
},
|
|
50
88
|
CallExpression(node) {
|
|
51
|
-
|
|
89
|
+
checkForHttpsError(node);
|
|
52
90
|
},
|
|
53
91
|
};
|
|
54
92
|
},
|