@blumintinc/eslint-plugin-blumint 1.12.5 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -99
- package/lib/index.js +111 -20
- 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-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/rules/no-restricted-imports-dynamic.d.ts +0 -25
- package/lib/rules/no-restricted-imports-dynamic.js +0 -213
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,13 +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");
|
|
108
|
-
const
|
|
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");
|
|
109
142
|
module.exports = {
|
|
110
143
|
meta: {
|
|
111
144
|
name: '@blumintinc/eslint-plugin-blumint',
|
|
112
|
-
version: '1.
|
|
145
|
+
version: '1.13.0',
|
|
113
146
|
},
|
|
114
147
|
parseOptions: {
|
|
115
148
|
ecmaVersion: 2020,
|
|
@@ -118,10 +151,16 @@ module.exports = {
|
|
|
118
151
|
recommended: {
|
|
119
152
|
plugins: ['@blumintinc/blumint'],
|
|
120
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',
|
|
121
158
|
'@blumintinc/blumint/prefer-block-comments-for-declarations': 'error',
|
|
122
159
|
'@blumintinc/blumint/key-only-outermost-element': 'error',
|
|
160
|
+
'@blumintinc/blumint/parallelize-async-operations': 'error',
|
|
123
161
|
'@blumintinc/blumint/avoid-utils-directory': 'error',
|
|
124
162
|
'@blumintinc/blumint/enforce-firestore-path-utils': 'error',
|
|
163
|
+
'@blumintinc/blumint/enforce-firestore-rules-get-access': 'error',
|
|
125
164
|
'@blumintinc/blumint/no-jsx-whitespace-literal': 'error',
|
|
126
165
|
'@blumintinc/blumint/array-methods-this-context': 'error',
|
|
127
166
|
'@blumintinc/blumint/class-methods-read-top-to-bottom': 'error',
|
|
@@ -131,9 +170,10 @@ module.exports = {
|
|
|
131
170
|
'@blumintinc/blumint/enforce-identifiable-firestore-type': 'error',
|
|
132
171
|
'@blumintinc/blumint/enforce-callback-memo': 'error',
|
|
133
172
|
'@blumintinc/blumint/enforce-callable-types': 'error',
|
|
173
|
+
'@blumintinc/blumint/enforce-console-error': 'error',
|
|
134
174
|
'@blumintinc/blumint/enforce-dynamic-firebase-imports': 'error',
|
|
135
175
|
'@blumintinc/blumint/enforce-react-type-naming': 'error',
|
|
136
|
-
|
|
176
|
+
'@blumintinc/blumint/export-if-in-doubt': 'error',
|
|
137
177
|
'@blumintinc/blumint/extract-global-constants': 'error',
|
|
138
178
|
'@blumintinc/blumint/enforce-global-constants': 'error',
|
|
139
179
|
'@blumintinc/blumint/generic-starts-with-t': 'error',
|
|
@@ -147,15 +187,17 @@ module.exports = {
|
|
|
147
187
|
'@blumintinc/blumint/no-unpinned-dependencies': 'error',
|
|
148
188
|
'@blumintinc/blumint/no-unused-props': 'error',
|
|
149
189
|
'@blumintinc/blumint/no-uuidv4-base62-as-key': 'error',
|
|
150
|
-
|
|
151
|
-
|
|
190
|
+
'@blumintinc/blumint/no-useless-fragment': 'error',
|
|
191
|
+
'@blumintinc/blumint/prefer-fragment-shorthand': 'error',
|
|
152
192
|
'@blumintinc/blumint/prefer-type-over-interface': 'error',
|
|
193
|
+
'@blumintinc/blumint/prefer-type-alias-over-typeof-constant': 'error',
|
|
153
194
|
'@blumintinc/blumint/require-memo': 'error',
|
|
154
195
|
'@blumintinc/blumint/require-dynamic-firebase-imports': 'error',
|
|
155
196
|
'@blumintinc/blumint/require-https-error': 'error',
|
|
156
197
|
'@blumintinc/blumint/use-custom-router': 'error',
|
|
157
198
|
'@blumintinc/blumint/require-image-optimized': 'error',
|
|
158
199
|
'@blumintinc/blumint/require-usememo-object-literals': 'error',
|
|
200
|
+
'@blumintinc/blumint/memoize-root-level-hocs': 'error',
|
|
159
201
|
'@blumintinc/blumint/enforce-safe-stringify': 'error',
|
|
160
202
|
'@blumintinc/blumint/no-entire-object-hook-deps': 'error',
|
|
161
203
|
'@blumintinc/blumint/no-compositing-layer-props': 'error',
|
|
@@ -173,8 +215,9 @@ module.exports = {
|
|
|
173
215
|
'@blumintinc/blumint/enforce-memoize-async': 'error',
|
|
174
216
|
'@blumintinc/blumint/enforce-exported-function-types': 'error',
|
|
175
217
|
'@blumintinc/blumint/no-redundant-param-types': 'error',
|
|
218
|
+
'@blumintinc/blumint/enforce-memoize-getters': 'error',
|
|
176
219
|
'@blumintinc/blumint/no-class-instance-destructuring': 'error',
|
|
177
|
-
'@blumintinc/blumint/no-firestore-object-arrays': '
|
|
220
|
+
'@blumintinc/blumint/no-firestore-object-arrays': 'error',
|
|
178
221
|
'@blumintinc/blumint/no-memoize-on-static': 'error',
|
|
179
222
|
'@blumintinc/blumint/no-unsafe-firestore-spread': 'error',
|
|
180
223
|
'@blumintinc/blumint/no-jsx-in-hooks': 'error',
|
|
@@ -191,10 +234,10 @@ module.exports = {
|
|
|
191
234
|
'@blumintinc/blumint/require-hooks-default-params': 'error',
|
|
192
235
|
'@blumintinc/blumint/prefer-destructuring-no-class': 'error',
|
|
193
236
|
'@blumintinc/blumint/enforce-render-hits-memoization': 'error',
|
|
194
|
-
'@blumintinc/blumint/prefer-fragment-component': '
|
|
237
|
+
'@blumintinc/blumint/prefer-fragment-component': 'off',
|
|
195
238
|
'@blumintinc/blumint/react-usememo-should-be-component': 'error',
|
|
196
239
|
'@blumintinc/blumint/no-unnecessary-verb-suffix': 'error',
|
|
197
|
-
'@blumintinc/blumint/enforce-
|
|
240
|
+
'@blumintinc/blumint/enforce-assert-safe-object-key': 'error',
|
|
198
241
|
'@blumintinc/blumint/enforce-object-literal-as-const': 'error',
|
|
199
242
|
'@blumintinc/blumint/enforce-positive-naming': 'error',
|
|
200
243
|
'@blumintinc/blumint/no-type-assertion-returns': 'error',
|
|
@@ -202,17 +245,13 @@ module.exports = {
|
|
|
202
245
|
'@blumintinc/blumint/enforce-microdiff': 'error',
|
|
203
246
|
'@blumintinc/blumint/fast-deep-equal-over-microdiff': 'error',
|
|
204
247
|
'@blumintinc/blumint/enforce-timestamp-now': 'error',
|
|
248
|
+
'@blumintinc/blumint/enforce-typescript-markdown-code-blocks': 'error',
|
|
205
249
|
'@blumintinc/blumint/no-always-true-false-conditions': 'error',
|
|
206
250
|
'@blumintinc/blumint/enforce-props-argument-name': 'error',
|
|
251
|
+
'@blumintinc/blumint/enforce-props-naming-consistency': 'error',
|
|
207
252
|
'@blumintinc/blumint/prefer-global-router-state-key': 'error',
|
|
208
253
|
'@blumintinc/blumint/prefer-usememo-over-useeffect-usestate': 'error',
|
|
209
|
-
'@blumintinc/blumint/enforce-dynamic-imports':
|
|
210
|
-
'error',
|
|
211
|
-
{
|
|
212
|
-
libraries: ['@stream-io/video-react-sdk', 'some-heavy-lib*'],
|
|
213
|
-
allowImportType: true,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
254
|
+
'@blumintinc/blumint/enforce-dynamic-imports': 'error',
|
|
216
255
|
'@blumintinc/blumint/ensure-pointer-events-none': 'error',
|
|
217
256
|
'@blumintinc/blumint/no-object-values-on-strings': 'error',
|
|
218
257
|
'@blumintinc/blumint/no-unnecessary-destructuring': 'error',
|
|
@@ -221,26 +260,53 @@ module.exports = {
|
|
|
221
260
|
'@blumintinc/blumint/omit-index-html': 'error',
|
|
222
261
|
'@blumintinc/blumint/enforce-id-capitalization': 'error',
|
|
223
262
|
'@blumintinc/blumint/no-unused-usestate': 'error',
|
|
224
|
-
'@blumintinc/blumint/enforce-dynamic-file-naming': 'error',
|
|
225
263
|
'@blumintinc/blumint/prefer-usecallback-over-usememo-for-functions': 'error',
|
|
226
264
|
'@blumintinc/blumint/no-margin-properties': 'error',
|
|
227
265
|
'@blumintinc/blumint/enforce-boolean-naming-prefixes': 'error',
|
|
266
|
+
'@blumintinc/blumint/enforce-fieldpath-syntax-in-docsetter': 'error',
|
|
228
267
|
'@blumintinc/blumint/no-undefined-null-passthrough': 'error',
|
|
229
|
-
'@blumintinc/blumint/
|
|
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',
|
|
230
288
|
},
|
|
231
289
|
},
|
|
232
290
|
},
|
|
233
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,
|
|
234
297
|
'prefer-block-comments-for-declarations': prefer_block_comments_for_declarations_1.preferBlockCommentsForDeclarations,
|
|
235
298
|
'key-only-outermost-element': key_only_outermost_element_1.keyOnlyOutermostElement,
|
|
236
299
|
'array-methods-this-context': array_methods_this_context_1.arrayMethodsThisContext,
|
|
237
300
|
'class-methods-read-top-to-bottom': class_methods_read_top_to_bottom_1.classMethodsReadTopToBottom,
|
|
238
301
|
'consistent-callback-naming': consistent_callback_naming_1.default,
|
|
302
|
+
'parallelize-async-operations': parallelize_async_operations_1.parallelizeAsyncOperations,
|
|
239
303
|
'dynamic-https-errors': dynamic_https_errors_1.dynamicHttpsErrors,
|
|
240
304
|
'enforce-identifiable-firestore-type': enforce_identifiable_firestore_type_1.enforceIdentifiableFirestoreType,
|
|
241
305
|
'enforce-callback-memo': enforce_callback_memo_1.default,
|
|
242
306
|
'enforce-react-type-naming': enforce_react_type_naming_1.enforceReactTypeNaming,
|
|
307
|
+
'enforce-firestore-rules-get-access': enforce_firestore_rules_get_access_1.enforceFirestoreRulesGetAccess,
|
|
243
308
|
'enforce-callable-types': enforce_callable_types_1.enforceCallableTypes,
|
|
309
|
+
'enforce-console-error': enforce_console_error_1.enforceConsoleError,
|
|
244
310
|
'enforce-dynamic-firebase-imports': enforce_dynamic_firebase_imports_1.enforceFirebaseImports,
|
|
245
311
|
'enforce-mui-rounded-icons': enforce_mui_rounded_icons_1.enforceMuiRoundedIcons,
|
|
246
312
|
'export-if-in-doubt': export_if_in_doubt_1.exportIfInDoubt,
|
|
@@ -261,6 +327,7 @@ module.exports = {
|
|
|
261
327
|
'enforce-dynamic-file-naming': enforce_dynamic_file_naming_1.default,
|
|
262
328
|
'prefer-fragment-shorthand': prefer_fragment_shorthand_1.preferFragmentShorthand,
|
|
263
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,
|
|
264
331
|
'require-memo': require_memo_1.requireMemo,
|
|
265
332
|
'no-jsx-whitespace-literal': no_jsx_whitespace_literal_1.noJsxWhitespaceLiteral,
|
|
266
333
|
'require-dynamic-firebase-imports': require_dynamic_firebase_imports_1.default,
|
|
@@ -268,6 +335,7 @@ module.exports = {
|
|
|
268
335
|
'use-custom-router': use_custom_router_1.useCustomRouter,
|
|
269
336
|
'require-image-optimized': require_image_optimized_1.default,
|
|
270
337
|
'require-usememo-object-literals': require_usememo_object_literals_1.requireUseMemoObjectLiterals,
|
|
338
|
+
'memoize-root-level-hocs': memoize_root_level_hocs_1.memoizeRootLevelHocs,
|
|
271
339
|
'enforce-safe-stringify': enforce_safe_stringify_1.enforceStableStringify,
|
|
272
340
|
'avoid-utils-directory': avoid_utils_directory_1.avoidUtilsDirectory,
|
|
273
341
|
'no-entire-object-hook-deps': no_entire_object_hook_deps_1.noEntireObjectHookDeps,
|
|
@@ -287,6 +355,7 @@ module.exports = {
|
|
|
287
355
|
'enforce-memoize-async': enforce_memoize_async_1.enforceMemoizeAsync,
|
|
288
356
|
'enforce-exported-function-types': enforce_exported_function_types_1.enforceExportedFunctionTypes,
|
|
289
357
|
'no-redundant-param-types': no_redundant_param_types_1.noRedundantParamTypes,
|
|
358
|
+
'enforce-memoize-getters': enforce_memoize_getters_1.enforceMemoizeGetters,
|
|
290
359
|
'no-class-instance-destructuring': no_class_instance_destructuring_1.noClassInstanceDestructuring,
|
|
291
360
|
'no-firestore-object-arrays': no_firestore_object_arrays_1.noFirestoreObjectArrays,
|
|
292
361
|
'no-memoize-on-static': no_memoize_on_static_1.noMemoizeOnStatic,
|
|
@@ -308,7 +377,7 @@ module.exports = {
|
|
|
308
377
|
'prefer-fragment-component': prefer_fragment_component_1.preferFragmentComponent,
|
|
309
378
|
'react-usememo-should-be-component': react_usememo_should_be_component_1.reactUseMemoShouldBeComponent,
|
|
310
379
|
'no-unnecessary-verb-suffix': no_unnecessary_verb_suffix_1.noUnnecessaryVerbSuffix,
|
|
311
|
-
'enforce-
|
|
380
|
+
'enforce-assert-safe-object-key': enforce_assert_safe_object_key_1.enforceAssertSafeObjectKey,
|
|
312
381
|
'enforce-object-literal-as-const': enforce_object_literal_as_const_1.enforceObjectLiteralAsConst,
|
|
313
382
|
'enforce-positive-naming': enforce_positive_naming_1.enforcePositiveNaming,
|
|
314
383
|
'no-type-assertion-returns': no_type_assertion_returns_1.noTypeAssertionReturns,
|
|
@@ -316,8 +385,10 @@ module.exports = {
|
|
|
316
385
|
'enforce-microdiff': enforce_microdiff_1.enforceMicrodiff,
|
|
317
386
|
'fast-deep-equal-over-microdiff': fast_deep_equal_over_microdiff_1.fastDeepEqualOverMicrodiff,
|
|
318
387
|
'enforce-timestamp-now': enforce_timestamp_now_1.enforceTimestampNow,
|
|
388
|
+
'enforce-typescript-markdown-code-blocks': enforce_typescript_markdown_code_blocks_1.enforceTypescriptMarkdownCodeBlocks,
|
|
319
389
|
'no-always-true-false-conditions': no_always_true_false_conditions_1.noAlwaysTrueFalseConditions,
|
|
320
390
|
'enforce-props-argument-name': enforce_props_argument_name_1.enforcePropsArgumentName,
|
|
391
|
+
'enforce-props-naming-consistency': enforce_props_naming_consistency_1.enforcePropsNamingConsistency,
|
|
321
392
|
'prefer-global-router-state-key': prefer_global_router_state_key_1.preferGlobalRouterStateKey,
|
|
322
393
|
'prefer-usememo-over-useeffect-usestate': prefer_usememo_over_useeffect_usestate_1.preferUseMemoOverUseEffectUseState,
|
|
323
394
|
'enforce-dynamic-imports': enforce_dynamic_imports_1.default,
|
|
@@ -332,8 +403,28 @@ module.exports = {
|
|
|
332
403
|
'prefer-usecallback-over-usememo-for-functions': prefer_usecallback_over_usememo_for_functions_1.default,
|
|
333
404
|
'no-margin-properties': no_margin_properties_1.noMarginProperties,
|
|
334
405
|
'enforce-boolean-naming-prefixes': enforce_boolean_naming_prefixes_1.enforceBooleanNamingPrefixes,
|
|
406
|
+
'enforce-fieldpath-syntax-in-docsetter': enforce_fieldpath_syntax_in_docsetter_1.enforceFieldPathSyntaxInDocSetter,
|
|
335
407
|
'no-undefined-null-passthrough': no_undefined_null_passthrough_1.noUndefinedNullPassthrough,
|
|
336
|
-
'
|
|
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,
|
|
337
428
|
},
|
|
338
429
|
};
|
|
339
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
|
},
|