@blumintinc/eslint-plugin-blumint 1.12.6 → 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.
- package/README.md +171 -99
- package/lib/index.js +300 -17
- package/lib/rules/array-methods-this-context.js +20 -2
- package/lib/rules/avoid-utils-directory.js +11 -2
- package/lib/rules/class-methods-read-top-to-bottom.js +24 -5
- package/lib/rules/consistent-callback-naming.js +1 -1
- package/lib/rules/dynamic-https-errors.d.ts +3 -1
- package/lib/rules/dynamic-https-errors.js +48 -11
- 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} +52 -96
- 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 +820 -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 +5 -2
- package/lib/rules/enforce-console-error.d.ts +3 -0
- package/lib/rules/enforce-console-error.js +278 -0
- package/lib/rules/enforce-css-media-queries.js +24 -46
- package/lib/rules/enforce-dynamic-file-naming.d.ts +2 -0
- package/lib/rules/enforce-dynamic-file-naming.js +53 -28
- package/lib/rules/enforce-dynamic-firebase-imports.js +100 -19
- package/lib/rules/enforce-dynamic-imports.js +1 -1
- package/lib/rules/enforce-early-destructuring.d.ts +2 -0
- package/lib/rules/enforce-early-destructuring.js +980 -0
- package/lib/rules/enforce-empty-object-check.d.ts +11 -0
- package/lib/rules/enforce-empty-object-check.js +502 -0
- package/lib/rules/enforce-exported-function-types.js +4 -4
- package/lib/rules/enforce-fieldpath-syntax-in-docsetter.d.ts +2 -0
- package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +262 -0
- package/lib/rules/enforce-firestore-doc-ref-generic.js +350 -3
- package/lib/rules/enforce-firestore-facade.js +349 -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-firestore-set-merge.js +3 -4
- package/lib/rules/enforce-global-constants.d.ts +4 -1
- package/lib/rules/enforce-global-constants.js +240 -12
- package/lib/rules/enforce-identifiable-firestore-type.js +108 -58
- package/lib/rules/enforce-memoize-async.d.ts +2 -1
- package/lib/rules/enforce-memoize-async.js +92 -27
- package/lib/rules/enforce-memoize-getters.d.ts +3 -0
- package/lib/rules/enforce-memoize-getters.js +147 -0
- package/lib/rules/enforce-microdiff.js +3 -2
- package/lib/rules/enforce-object-literal-as-const.js +4 -4
- package/lib/rules/enforce-positive-naming.js +9 -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-safe-stringify.js +1 -1
- package/lib/rules/enforce-serializable-params.js +3 -3
- package/lib/rules/enforce-singular-type-names.js +10 -6
- package/lib/rules/enforce-stable-hash-spread-props.d.ts +13 -0
- package/lib/rules/enforce-stable-hash-spread-props.js +342 -0
- package/lib/rules/enforce-storage-context.d.ts +9 -0
- package/lib/rules/enforce-storage-context.js +646 -0
- package/lib/rules/enforce-timestamp-now.js +23 -7
- package/lib/rules/enforce-transform-memoization.d.ts +4 -0
- package/lib/rules/enforce-transform-memoization.js +416 -0
- package/lib/rules/enforce-typescript-markdown-code-blocks.d.ts +1 -0
- package/lib/rules/enforce-typescript-markdown-code-blocks.js +100 -0
- package/lib/rules/enforce-unique-cursor-headers.d.ts +16 -0
- package/lib/rules/enforce-unique-cursor-headers.js +365 -0
- package/lib/rules/enforce-verb-noun-naming.js +90 -14
- package/lib/rules/ensure-pointer-events-none.js +28 -2
- package/lib/rules/export-if-in-doubt.js +27 -4
- package/lib/rules/extract-global-constants.js +92 -53
- package/lib/rules/fast-deep-equal-over-microdiff.d.ts +2 -1
- package/lib/rules/fast-deep-equal-over-microdiff.js +351 -83
- package/lib/rules/firestore-transaction-reads-before-writes.d.ts +1 -0
- package/lib/rules/firestore-transaction-reads-before-writes.js +277 -0
- package/lib/rules/flatten-push-calls.d.ts +2 -0
- package/lib/rules/flatten-push-calls.js +428 -0
- package/lib/rules/generic-starts-with-t.js +8 -2
- package/lib/rules/global-const-style.js +50 -19
- package/lib/rules/jsdoc-above-field.d.ts +11 -0
- package/lib/rules/jsdoc-above-field.js +208 -0
- package/lib/rules/key-only-outermost-element.js +21 -3
- package/lib/rules/logical-top-to-bottom-grouping.d.ts +5 -0
- package/lib/rules/logical-top-to-bottom-grouping.js +1258 -0
- package/lib/rules/memo-compare-deeply-complex-props.d.ts +3 -0
- package/lib/rules/memo-compare-deeply-complex-props.js +788 -0
- package/lib/rules/memo-nested-react-components.d.ts +8 -0
- package/lib/rules/memo-nested-react-components.js +410 -0
- 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-always-true-false-conditions.d.ts +2 -1
- package/lib/rules/no-always-true-false-conditions.js +68 -8
- package/lib/rules/no-array-length-in-deps.d.ts +12 -0
- package/lib/rules/no-array-length-in-deps.js +314 -0
- package/lib/rules/no-async-array-filter.js +5 -2
- package/lib/rules/no-async-foreach.js +210 -12
- package/lib/rules/no-circular-references.js +18 -17
- package/lib/rules/no-class-instance-destructuring.js +55 -12
- package/lib/rules/no-complex-cloud-params.js +22 -5
- package/lib/rules/no-compositing-layer-props.js +6 -4
- package/lib/rules/no-conditional-literals-in-jsx.js +37 -12
- package/lib/rules/no-console-error.d.ts +9 -0
- package/lib/rules/no-console-error.js +525 -0
- package/lib/rules/no-curly-brackets-around-commented-properties.d.ts +2 -0
- package/lib/rules/no-curly-brackets-around-commented-properties.js +258 -0
- package/lib/rules/no-empty-dependency-use-callbacks.d.ts +11 -0
- package/lib/rules/no-empty-dependency-use-callbacks.js +576 -0
- package/lib/rules/no-entire-object-hook-deps.d.ts +3 -1
- package/lib/rules/no-entire-object-hook-deps.js +320 -68
- 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-explicit-return-type.d.ts +2 -1
- package/lib/rules/no-explicit-return-type.js +215 -26
- package/lib/rules/no-filter-without-return.js +5 -1
- package/lib/rules/no-firestore-jest-mock.d.ts +2 -1
- package/lib/rules/no-firestore-jest-mock.js +126 -8
- package/lib/rules/no-firestore-object-arrays.js +398 -28
- package/lib/rules/no-handler-suffix.d.ts +12 -0
- package/lib/rules/no-handler-suffix.js +305 -0
- package/lib/rules/no-hungarian.js +14 -14
- package/lib/rules/no-inline-component-prop.d.ts +10 -0
- package/lib/rules/no-inline-component-prop.js +456 -0
- package/lib/rules/no-jsx-in-hooks.js +6 -1
- package/lib/rules/no-jsx-whitespace-literal.js +8 -2
- package/lib/rules/no-margin-properties.d.ts +7 -1
- package/lib/rules/no-margin-properties.js +22 -9
- package/lib/rules/no-memoize-on-static.js +9 -1
- package/lib/rules/no-misleading-boolean-prefixes.d.ts +7 -0
- package/lib/rules/no-misleading-boolean-prefixes.js +331 -0
- package/lib/rules/no-misused-switch-case.js +22 -1
- package/lib/rules/no-mixed-firestore-transactions.d.ts +3 -1
- package/lib/rules/no-mixed-firestore-transactions.js +296 -34
- package/lib/rules/no-mock-firebase-admin.js +5 -2
- package/lib/rules/no-object-values-on-strings.js +10 -2
- package/lib/rules/no-overridable-method-calls-in-constructor.d.ts +1 -0
- package/lib/rules/no-overridable-method-calls-in-constructor.js +272 -0
- package/lib/rules/no-passthrough-getters.d.ts +4 -0
- package/lib/rules/no-passthrough-getters.js +206 -0
- package/lib/rules/no-redundant-annotation-assertion.d.ts +2 -0
- package/lib/rules/no-redundant-annotation-assertion.js +402 -0
- package/lib/rules/no-redundant-param-types.js +16 -6
- package/lib/rules/no-redundant-this-params.d.ts +3 -0
- package/lib/rules/no-redundant-this-params.js +459 -0
- package/lib/rules/no-redundant-usecallback-wrapper.d.ts +8 -0
- package/lib/rules/no-redundant-usecallback-wrapper.js +328 -0
- package/lib/rules/no-res-error-status-in-onrequest.d.ts +4 -0
- package/lib/rules/no-res-error-status-in-onrequest.js +521 -0
- package/lib/rules/no-restricted-properties-fix.d.ts +12 -0
- package/lib/rules/no-restricted-properties-fix.js +173 -0
- package/lib/rules/no-separate-loading-state.d.ts +8 -0
- package/lib/rules/no-separate-loading-state.js +133 -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 +49 -49
- package/lib/rules/no-undefined-null-passthrough.js +217 -40
- package/lib/rules/no-unmemoized-memo-without-props.d.ts +8 -0
- package/lib/rules/no-unmemoized-memo-without-props.js +426 -0
- package/lib/rules/no-unnecessary-destructuring-rename.d.ts +2 -0
- package/lib/rules/no-unnecessary-destructuring-rename.js +347 -0
- package/lib/rules/no-unnecessary-destructuring.js +14 -4
- package/lib/rules/no-unnecessary-verb-suffix.js +2 -3
- package/lib/rules/no-unpinned-dependencies.js +36 -5
- package/lib/rules/no-unsafe-firestore-spread.js +8 -5
- package/lib/rules/no-unused-props.d.ts +5 -2
- package/lib/rules/no-unused-props.js +451 -112
- package/lib/rules/no-unused-usestate.js +6 -2
- package/lib/rules/no-useless-fragment.js +28 -2
- package/lib/rules/no-useless-usememo-primitives.d.ts +9 -0
- package/lib/rules/no-useless-usememo-primitives.js +393 -0
- package/lib/rules/no-usememo-for-pass-by-value.d.ts +13 -0
- package/lib/rules/no-usememo-for-pass-by-value.js +757 -0
- package/lib/rules/no-uuidv4-base62-as-key.js +18 -13
- package/lib/rules/omit-index-html.d.ts +2 -1
- package/lib/rules/omit-index-html.js +62 -7
- package/lib/rules/optimize-object-boolean-conditions.d.ts +1 -0
- package/lib/rules/optimize-object-boolean-conditions.js +236 -0
- package/lib/rules/parallelize-async-operations.d.ts +8 -0
- package/lib/rules/parallelize-async-operations.js +394 -0
- package/lib/rules/prefer-batch-operations.d.ts +1 -3
- package/lib/rules/prefer-batch-operations.js +228 -35
- package/lib/rules/prefer-block-comments-for-declarations.js +22 -7
- package/lib/rules/prefer-clone-deep.js +3 -3
- package/lib/rules/prefer-destructuring-no-class.d.ts +2 -1
- package/lib/rules/prefer-destructuring-no-class.js +244 -59
- package/lib/rules/prefer-docsetter-setall.d.ts +2 -0
- package/lib/rules/prefer-docsetter-setall.js +243 -0
- 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 +251 -0
- package/lib/rules/prefer-fragment-component.js +4 -4
- package/lib/rules/prefer-fragment-shorthand.js +2 -1
- package/lib/rules/prefer-getter-over-parameterless-method.d.ts +13 -0
- package/lib/rules/prefer-getter-over-parameterless-method.js +648 -0
- package/lib/rules/prefer-global-router-state-key.d.ts +7 -3
- package/lib/rules/prefer-global-router-state-key.js +305 -31
- package/lib/rules/prefer-memoized-props.d.ts +3 -0
- package/lib/rules/prefer-memoized-props.js +445 -0
- package/lib/rules/prefer-next-dynamic.d.ts +9 -0
- package/lib/rules/prefer-next-dynamic.js +357 -0
- package/lib/rules/prefer-nullish-coalescing-boolean-props.d.ts +1 -0
- package/lib/rules/prefer-nullish-coalescing-boolean-props.js +435 -0
- package/lib/rules/prefer-nullish-coalescing-override.d.ts +7 -0
- package/lib/rules/prefer-nullish-coalescing-override.js +188 -0
- package/lib/rules/prefer-params-over-parent-id.d.ts +5 -0
- package/lib/rules/prefer-params-over-parent-id.js +277 -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-type-over-interface.js +7 -2
- package/lib/rules/prefer-url-tostring-over-tojson.d.ts +2 -0
- package/lib/rules/prefer-url-tostring-over-tojson.js +169 -0
- package/lib/rules/prefer-use-deep-compare-memo.d.ts +4 -0
- package/lib/rules/prefer-use-deep-compare-memo.js +431 -0
- package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +25 -2
- package/lib/rules/prefer-usememo-over-useeffect-usestate.js +24 -5
- package/lib/rules/prefer-utility-function-over-private-static.js +34 -2
- package/lib/rules/prevent-children-clobber.d.ts +2 -0
- package/lib/rules/prevent-children-clobber.js +536 -0
- package/lib/rules/react-memoize-literals.d.ts +4 -0
- package/lib/rules/react-memoize-literals.js +495 -0
- 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-hooks-default-params.js +17 -16
- package/lib/rules/require-https-error-cause.d.ts +4 -0
- package/lib/rules/require-https-error-cause.js +136 -0
- package/lib/rules/require-https-error.js +43 -21
- package/lib/rules/require-image-optimized.js +2 -2
- package/lib/rules/require-memo.js +12 -2
- package/lib/rules/require-memoize-jsx-returners.d.ts +3 -0
- package/lib/rules/require-memoize-jsx-returners.js +485 -0
- package/lib/rules/require-usememo-object-literals.js +9 -4
- 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 +271 -0
- package/lib/rules/vertically-group-related-functions.d.ts +16 -0
- package/lib/rules/vertically-group-related-functions.js +480 -0
- package/lib/utils/ASTHelpers.d.ts +13 -1
- package/lib/utils/ASTHelpers.js +34 -0
- package/lib/utils/createRule.js +1 -1
- package/lib/utils/getMethodName.d.ts +27 -0
- package/lib/utils/getMethodName.js +35 -0
- package/lib/utils/graph/ClassGraphSorterReadability.js +1 -1
- package/lib/utils/ruleTester.d.ts +1 -0
- package/lib/utils/ruleTester.js +4 -1
- package/lib/utils/tsTypeClassifier.d.ts +30 -0
- package/lib/utils/tsTypeClassifier.js +149 -0
- package/package.json +23 -14
- package/lib/rules/enforce-assertSafe-object-key.d.ts +0 -2
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noCurlyBracketsAroundCommentedProperties = void 0;
|
|
4
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
5
|
+
const ASTHelpers_1 = require("../utils/ASTHelpers");
|
|
6
|
+
const createRule_1 = require("../utils/createRule");
|
|
7
|
+
const MEMBER_SIGNATURE_PATTERN = /\b[A-Za-z_$][\w$]*\s*\??\s*:\s*[^;]+;?/;
|
|
8
|
+
const METHOD_SIGNATURE_PATTERN = /\b[A-Za-z_$][\w$]*\s*\([^)]*\)\s*:?[^;]*;?/;
|
|
9
|
+
const JSDOC_MEMBER_TAGS = [
|
|
10
|
+
'@remarks',
|
|
11
|
+
'@deprecated',
|
|
12
|
+
'@see',
|
|
13
|
+
'@example',
|
|
14
|
+
'@param',
|
|
15
|
+
'@returns',
|
|
16
|
+
'@type',
|
|
17
|
+
'@property',
|
|
18
|
+
'@method',
|
|
19
|
+
'@default',
|
|
20
|
+
'@readonly',
|
|
21
|
+
'@private',
|
|
22
|
+
'@public',
|
|
23
|
+
'@protected',
|
|
24
|
+
'@internal',
|
|
25
|
+
'@beta',
|
|
26
|
+
'@alpha',
|
|
27
|
+
'@experimental',
|
|
28
|
+
'@override',
|
|
29
|
+
'@throws',
|
|
30
|
+
'@todo',
|
|
31
|
+
'@future',
|
|
32
|
+
];
|
|
33
|
+
function isTypeMemberComment(rawComment) {
|
|
34
|
+
const normalized = rawComment.replace(/^\s*\*/gm, '').trim();
|
|
35
|
+
if (!normalized) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (JSDOC_MEMBER_TAGS.some((tag) => normalized.startsWith(tag))) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return (MEMBER_SIGNATURE_PATTERN.test(normalized) ||
|
|
42
|
+
METHOD_SIGNATURE_PATTERN.test(normalized));
|
|
43
|
+
}
|
|
44
|
+
function getBlockComments(sourceCode, node) {
|
|
45
|
+
return sourceCode
|
|
46
|
+
.getAllComments()
|
|
47
|
+
.filter((comment) => comment.range[0] >= node.range[0] && comment.range[1] <= node.range[1]);
|
|
48
|
+
}
|
|
49
|
+
function isEmptyTopLevelBlock(node, parent) {
|
|
50
|
+
return (node.body.length === 0 &&
|
|
51
|
+
!!parent &&
|
|
52
|
+
(parent.type === utils_1.AST_NODE_TYPES.Program ||
|
|
53
|
+
parent.type === utils_1.AST_NODE_TYPES.TSModuleBlock));
|
|
54
|
+
}
|
|
55
|
+
function hasTypeMemberComments(comments) {
|
|
56
|
+
return comments.some((comment) => isTypeMemberComment(comment.value));
|
|
57
|
+
}
|
|
58
|
+
function describeContext(ancestors, parent) {
|
|
59
|
+
for (let index = ancestors.length - 1; index >= 0; index -= 1) {
|
|
60
|
+
const ancestor = ancestors[index];
|
|
61
|
+
if (ancestor.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration) {
|
|
62
|
+
return ancestor.id.type === utils_1.AST_NODE_TYPES.Identifier
|
|
63
|
+
? `namespace "${ancestor.id.name}"`
|
|
64
|
+
: 'this module';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (parent?.type === utils_1.AST_NODE_TYPES.TSModuleBlock) {
|
|
68
|
+
/* istanbul ignore next -- TSModuleBlock always has TSModuleDeclaration ancestor in valid parsing */
|
|
69
|
+
return 'this namespace or module block';
|
|
70
|
+
}
|
|
71
|
+
return 'this file';
|
|
72
|
+
}
|
|
73
|
+
function getSiblingIndent(sourceCode, parent, current) {
|
|
74
|
+
const container = parent &&
|
|
75
|
+
'body' in parent &&
|
|
76
|
+
Array.isArray(parent.body)
|
|
77
|
+
? parent.body
|
|
78
|
+
: null;
|
|
79
|
+
/* istanbul ignore next -- defensive, parent is guaranteed to be Program or TSModuleBlock */
|
|
80
|
+
if (!container) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
let indent = null;
|
|
84
|
+
for (const statement of container) {
|
|
85
|
+
if (statement === current || !statement.loc) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const lineText = sourceCode.lines[statement.loc.start.line - 1];
|
|
89
|
+
/* istanbul ignore next -- sourceCode always returns string lines */
|
|
90
|
+
if (typeof lineText !== 'string') {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const leading = lineText.match(/^\s*/)?.[0] ?? '';
|
|
94
|
+
if (indent === null || leading.length < indent.length) {
|
|
95
|
+
indent = leading;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return indent;
|
|
99
|
+
}
|
|
100
|
+
function extractContentBetweenBraces(sourceCode, node) {
|
|
101
|
+
const openingBrace = sourceCode.getFirstToken(node);
|
|
102
|
+
const closingBrace = sourceCode.getLastToken(node);
|
|
103
|
+
/* istanbul ignore next -- block nodes always have brace tokens */
|
|
104
|
+
if (!openingBrace || !closingBrace) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return sourceCode.text.slice(openingBrace.range[1], closingBrace.range[0]);
|
|
108
|
+
}
|
|
109
|
+
function trimEmptyLines(lines) {
|
|
110
|
+
const result = [...lines];
|
|
111
|
+
while (result.length > 0 && result[0].trim() === '') {
|
|
112
|
+
result.shift();
|
|
113
|
+
}
|
|
114
|
+
while (result.length > 0 && result[result.length - 1].trim() === '') {
|
|
115
|
+
result.pop();
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
function calculateMinAdditionalIndent(lines) {
|
|
120
|
+
const indents = lines
|
|
121
|
+
.filter((line) => line.trim() !== '')
|
|
122
|
+
.map((line) => line.match(/^\s*/)?.[0].length ?? 0);
|
|
123
|
+
return indents.length ? Math.min(...indents) : 0;
|
|
124
|
+
}
|
|
125
|
+
function normalizeLineIndentation(lines, targetIndent, indentDelta, minAdditionalIndent) {
|
|
126
|
+
const firstLinePrefix = indentDelta > 0 ? ' '.repeat(indentDelta) : '';
|
|
127
|
+
return lines.map((line, index) => {
|
|
128
|
+
const currentIndent = line.match(/^\s*/)?.[0].length ?? 0;
|
|
129
|
+
const removeLength = Math.min(currentIndent, minAdditionalIndent);
|
|
130
|
+
const withoutIndent = removeLength > 0 ? line.slice(Math.min(removeLength, line.length)) : line;
|
|
131
|
+
const baseIndent = index === 0 ? firstLinePrefix : targetIndent;
|
|
132
|
+
return `${baseIndent}${withoutIndent.trimEnd()}`;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function determineBaseIndent(indentFromLine, baseIndentOverride) {
|
|
136
|
+
if (baseIndentOverride === null || baseIndentOverride === undefined) {
|
|
137
|
+
return indentFromLine;
|
|
138
|
+
}
|
|
139
|
+
return baseIndentOverride.length <= indentFromLine.length
|
|
140
|
+
? baseIndentOverride
|
|
141
|
+
: indentFromLine;
|
|
142
|
+
}
|
|
143
|
+
function computeReplacement(sourceCode, node, baseIndentOverride) {
|
|
144
|
+
const content = extractContentBetweenBraces(sourceCode, node);
|
|
145
|
+
/* istanbul ignore next -- extractContentBetweenBraces only null when tokens are missing */
|
|
146
|
+
if (content === null) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const trimmedLines = trimEmptyLines(content.split('\n'));
|
|
150
|
+
/* istanbul ignore next -- empty blocks are filtered earlier */
|
|
151
|
+
if (!trimmedLines.length) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const indentFromLine = sourceCode.lines[node.loc.start.line - 1]?.match(/^\s*/)?.[0] ?? '';
|
|
155
|
+
const targetIndent = determineBaseIndent(indentFromLine, baseIndentOverride);
|
|
156
|
+
const indentDelta = Math.max(targetIndent.length - indentFromLine.length, 0);
|
|
157
|
+
const minAdditionalIndent = calculateMinAdditionalIndent(trimmedLines);
|
|
158
|
+
const normalizedLines = normalizeLineIndentation(trimmedLines, targetIndent, indentDelta, minAdditionalIndent);
|
|
159
|
+
return normalizedLines.join('\n');
|
|
160
|
+
}
|
|
161
|
+
function getReportableBlockContext(context, sourceCode, node) {
|
|
162
|
+
const parent = node.parent;
|
|
163
|
+
if (!isEmptyTopLevelBlock(node, parent)) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const comments = getBlockComments(sourceCode, node);
|
|
167
|
+
if (!hasTypeMemberComments(comments)) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
parent,
|
|
172
|
+
ancestors: ASTHelpers_1.ASTHelpers.getAncestors(context, node),
|
|
173
|
+
siblingIndent: getSiblingIndent(sourceCode, parent, node),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Creates a fixer function that removes unnecessary curly brackets around
|
|
178
|
+
* commented properties by computing the appropriate replacement text and
|
|
179
|
+
* handling indentation and edge cases with trailing code.
|
|
180
|
+
*/
|
|
181
|
+
function createBlockRemovalFix(sourceCode, node, reportableContext) {
|
|
182
|
+
return (fixer) => {
|
|
183
|
+
const startLine = node.loc.start.line;
|
|
184
|
+
const lineText = sourceCode.lines[startLine - 1];
|
|
185
|
+
const leadingWhitespace = lineText.match(/^\s*/)?.[0] ?? '';
|
|
186
|
+
const targetIndent = reportableContext.siblingIndent ?? leadingWhitespace;
|
|
187
|
+
const replacement = computeReplacement(sourceCode, node, reportableContext.siblingIndent);
|
|
188
|
+
/* istanbul ignore next -- replacement only null when tokens are missing */
|
|
189
|
+
if (replacement === null) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
let fixRange = [node.range[0], node.range[1]];
|
|
193
|
+
let finalText = replacement;
|
|
194
|
+
/**
|
|
195
|
+
* If the node is at the start of the line (only whitespace before it),
|
|
196
|
+
* we replace from the very beginning of the line to handle both
|
|
197
|
+
* de-indentation and increasing indentation correctly.
|
|
198
|
+
*/
|
|
199
|
+
if (node.loc.start.column === leadingWhitespace.length) {
|
|
200
|
+
const lineStart = sourceCode.getIndexFromLoc({
|
|
201
|
+
line: startLine,
|
|
202
|
+
column: 0,
|
|
203
|
+
});
|
|
204
|
+
fixRange[0] = lineStart;
|
|
205
|
+
finalText = targetIndent + replacement;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* If the replacement ends with a line comment and there's code on the
|
|
209
|
+
* same line after the block, we must add a newline and proper
|
|
210
|
+
* indentation to prevent commenting out the subsequent code.
|
|
211
|
+
*/
|
|
212
|
+
const nextToken = sourceCode.getTokenAfter(node);
|
|
213
|
+
if (nextToken?.loc.start.line === node.loc.end.line) {
|
|
214
|
+
const lastLine = replacement.split('\n').pop() ?? '';
|
|
215
|
+
if (lastLine.trim().startsWith('//')) {
|
|
216
|
+
fixRange[1] = nextToken.range[0];
|
|
217
|
+
finalText += '\n' + targetIndent;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return fixer.replaceTextRange(fixRange, finalText);
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
exports.noCurlyBracketsAroundCommentedProperties = (0, createRule_1.createRule)({
|
|
224
|
+
name: 'no-curly-brackets-around-commented-properties',
|
|
225
|
+
meta: {
|
|
226
|
+
type: 'problem',
|
|
227
|
+
docs: {
|
|
228
|
+
description: 'Disallow curly-brace blocks that only wrap commented-out members inside type declarations',
|
|
229
|
+
recommended: 'error',
|
|
230
|
+
},
|
|
231
|
+
fixable: 'code',
|
|
232
|
+
schema: [],
|
|
233
|
+
messages: {
|
|
234
|
+
removeCommentWrappedBlock: 'Curly braces in {{context}} wrap only comments (often commented-out members). They leave the declaration invalid or misleading. Remove the braces and keep the comments inline so the type stays readable and syntactically correct.',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
defaultOptions: [],
|
|
238
|
+
create(context) {
|
|
239
|
+
const sourceCode = context.sourceCode;
|
|
240
|
+
return {
|
|
241
|
+
BlockStatement(node) {
|
|
242
|
+
const reportableContext = getReportableBlockContext(context, sourceCode, node);
|
|
243
|
+
if (!reportableContext) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
context.report({
|
|
247
|
+
node,
|
|
248
|
+
messageId: 'removeCommentWrappedBlock',
|
|
249
|
+
data: {
|
|
250
|
+
context: describeContext(reportableContext.ancestors, reportableContext.parent),
|
|
251
|
+
},
|
|
252
|
+
fix: createBlockRemovalFix(sourceCode, node, reportableContext),
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
//# sourceMappingURL=no-curly-brackets-around-commented-properties.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
type Options = [
|
|
3
|
+
{
|
|
4
|
+
ignoreTestFiles?: boolean;
|
|
5
|
+
testFilePatterns?: string[];
|
|
6
|
+
ignoreUseLatestCallback?: boolean;
|
|
7
|
+
}
|
|
8
|
+
];
|
|
9
|
+
type MessageIds = 'preferUtilityFunction' | 'preferUtilityLatest';
|
|
10
|
+
export declare const noEmptyDependencyUseCallbacks: TSESLint.RuleModule<MessageIds, Options, TSESLint.RuleListener>;
|
|
11
|
+
export default noEmptyDependencyUseCallbacks;
|