@blumintinc/eslint-plugin-blumint 1.13.0 → 1.15.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 +169 -139
- package/lib/index.js +200 -9
- package/lib/rules/array-methods-this-context.js +1 -1
- package/lib/rules/avoid-utils-directory.js +0 -4
- package/lib/rules/class-methods-read-top-to-bottom.js +24 -5
- package/lib/rules/consistent-callback-naming.js +43 -4
- package/lib/rules/dynamic-https-errors.d.ts +1 -1
- package/lib/rules/dynamic-https-errors.js +134 -44
- package/lib/rules/enforce-assert-safe-object-key.js +11 -11
- package/lib/rules/enforce-boolean-naming-prefixes.js +11 -235
- package/lib/rules/enforce-callback-memo.js +1 -1
- package/lib/rules/enforce-centralized-mock-firestore.js +1 -1
- package/lib/rules/enforce-console-error.js +35 -7
- package/lib/rules/enforce-date-ttime.d.ts +1 -0
- package/lib/rules/enforce-date-ttime.js +156 -0
- 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.d.ts +2 -1
- package/lib/rules/enforce-dynamic-firebase-imports.js +3 -2
- 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 +1 -1
- package/lib/rules/enforce-f-extension-for-entry-points.d.ts +8 -0
- package/lib/rules/enforce-f-extension-for-entry-points.js +283 -0
- package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +100 -50
- package/lib/rules/enforce-firestore-doc-ref-generic.js +15 -3
- package/lib/rules/enforce-firestore-facade.js +4 -2
- package/lib/rules/enforce-firestore-set-merge.js +3 -4
- package/lib/rules/enforce-global-constants.js +4 -4
- package/lib/rules/enforce-id-capitalization.js +1 -1
- package/lib/rules/enforce-identifiable-firestore-type.js +108 -58
- package/lib/rules/enforce-memoize-async.js +71 -21
- package/lib/rules/enforce-memoize-getters.js +39 -15
- package/lib/rules/enforce-microdiff.js +1 -1
- package/lib/rules/enforce-object-literal-as-const.js +4 -4
- package/lib/rules/enforce-positive-naming.js +4 -0
- package/lib/rules/enforce-props-argument-name.js +44 -18
- 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 +1 -1
- 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.js +7 -3
- 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 +3818 -4644
- 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 +40 -13
- package/lib/rules/fast-deep-equal-over-microdiff.js +29 -39
- package/lib/rules/firestore-transaction-reads-before-writes.js +50 -4
- package/lib/rules/flatten-push-calls.d.ts +2 -0
- package/lib/rules/flatten-push-calls.js +428 -0
- package/lib/rules/global-const-style.js +66 -23
- 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 +801 -0
- package/lib/rules/memo-nested-react-components.d.ts +8 -0
- package/lib/rules/memo-nested-react-components.js +415 -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.js +9 -3
- package/lib/rules/no-async-foreach.js +215 -12
- package/lib/rules/no-circular-references.d.ts +2 -1
- package/lib/rules/no-circular-references.js +31 -32
- package/lib/rules/no-class-instance-destructuring.js +55 -12
- package/lib/rules/no-complex-cloud-params.js +7 -3
- package/lib/rules/no-compositing-layer-props.js +2 -2
- 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 +527 -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.js +52 -7
- package/lib/rules/no-excessive-parent-chain.js +4 -1
- 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 +67 -12
- 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 +1 -1
- package/lib/rules/no-inline-component-prop.d.ts +10 -0
- package/lib/rules/no-inline-component-prop.js +465 -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.js +6 -6
- package/lib/rules/no-memoize-on-static.js +9 -1
- package/lib/rules/no-misleading-boolean-prefixes.js +7 -3
- 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.js +29 -17
- package/lib/rules/no-passthrough-getters.d.ts +2 -2
- package/lib/rules/no-passthrough-getters.js +120 -2
- 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 +508 -0
- package/lib/rules/no-redundant-usecallback-wrapper.js +16 -3
- 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.js +11 -10
- package/lib/rules/no-separate-loading-state.js +7 -16
- package/lib/rules/no-stale-state-across-await.js +1 -1
- package/lib/rules/no-type-assertion-returns.js +43 -49
- package/lib/rules/no-undefined-null-passthrough.js +61 -31
- 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 +344 -0
- package/lib/rules/no-unnecessary-destructuring.js +14 -4
- package/lib/rules/no-unnecessary-verb-suffix.js +2 -1
- package/lib/rules/no-unpinned-dependencies.js +36 -5
- package/lib/rules/no-unused-props.d.ts +2 -2
- package/lib/rules/no-unused-props.js +295 -91
- 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.js +6 -4
- package/lib/rules/parallelize-async-operations.js +143 -59
- package/lib/rules/prefer-batch-operations.d.ts +1 -3
- package/lib/rules/prefer-batch-operations.js +32 -5
- package/lib/rules/prefer-block-comments-for-declarations.js +9 -4
- 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-field-paths-in-transforms.js +4 -3
- package/lib/rules/prefer-fragment-component.js +1 -1
- 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.js +88 -13
- 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.js +60 -69
- package/lib/rules/prefer-nullish-coalescing-boolean-props.js +118 -8
- package/lib/rules/prefer-nullish-coalescing-override.d.ts +2 -1
- package/lib/rules/prefer-nullish-coalescing-override.js +11 -5
- package/lib/rules/prefer-params-over-parent-id.js +221 -172
- package/lib/rules/prefer-settings-object.js +27 -10
- package/lib/rules/prefer-type-alias-over-typeof-constant.js +9 -0
- package/lib/rules/prefer-type-over-interface.js +7 -2
- package/lib/rules/prefer-url-tostring-over-tojson.js +6 -3
- package/lib/rules/prefer-use-deep-compare-memo.js +8 -5
- package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +1 -1
- package/lib/rules/prefer-usememo-over-useeffect-usestate.js +1 -1
- 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 +540 -0
- package/lib/rules/react-memoize-literals.d.ts +4 -0
- package/lib/rules/react-memoize-literals.js +614 -0
- package/lib/rules/react-usememo-should-be-component.js +2 -2
- 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 +155 -0
- package/lib/rules/require-https-error.js +43 -21
- package/lib/rules/require-image-optimized.js +1 -1
- package/lib/rules/require-memo.js +18 -10
- 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 +2 -3
- package/lib/rules/test-file-location-enforcement.js +1 -1
- package/lib/rules/use-latest-callback.js +6 -5
- 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 +47 -2
- package/lib/utils/ASTHelpers.js +370 -112
- package/lib/utils/getMethodName.d.ts +27 -0
- package/lib/utils/getMethodName.js +35 -0
- package/lib/utils/tsTypeClassifier.d.ts +30 -0
- package/lib/utils/tsTypeClassifier.js +149 -0
- package/package.json +3 -1
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.preferDocSetterSetAll = void 0;
|
|
4
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
5
|
+
const createRule_1 = require("../utils/createRule");
|
|
6
|
+
const ITERATING_METHODS = new Set(['map', 'forEach']);
|
|
7
|
+
const DOC_SETTER_NAMES = new Set([
|
|
8
|
+
'DocSetter',
|
|
9
|
+
'DocSetterTransaction',
|
|
10
|
+
]);
|
|
11
|
+
function unwrapCallee(callee) {
|
|
12
|
+
return callee.type === utils_1.AST_NODE_TYPES.ChainExpression
|
|
13
|
+
? callee.expression
|
|
14
|
+
: callee;
|
|
15
|
+
}
|
|
16
|
+
function getEntityIdentifier(entity) {
|
|
17
|
+
if (entity.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
18
|
+
return entity.name;
|
|
19
|
+
}
|
|
20
|
+
return getEntityIdentifier(entity.right);
|
|
21
|
+
}
|
|
22
|
+
function getTypeName(typeNode) {
|
|
23
|
+
if (!typeNode || typeNode.type !== utils_1.AST_NODE_TYPES.TSTypeReference) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return getEntityIdentifier(typeNode.typeName);
|
|
27
|
+
}
|
|
28
|
+
function isDocSetterName(name) {
|
|
29
|
+
return Boolean(name && DOC_SETTER_NAMES.has(name));
|
|
30
|
+
}
|
|
31
|
+
function getNewExpressionKind(expression) {
|
|
32
|
+
if (expression?.type !== utils_1.AST_NODE_TYPES.NewExpression) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (expression.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
36
|
+
isDocSetterName(expression.callee.name)) {
|
|
37
|
+
return expression.callee.name;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function getTypeAnnotationKind(identifier) {
|
|
42
|
+
const typeName = getTypeName(identifier.typeAnnotation?.typeAnnotation);
|
|
43
|
+
if (isDocSetterName(typeName)) {
|
|
44
|
+
return typeName;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function extractKindFromDefinition(definition) {
|
|
49
|
+
const nameNode = definition.name;
|
|
50
|
+
if (!nameNode || nameNode.type !== utils_1.AST_NODE_TYPES.Identifier)
|
|
51
|
+
return null;
|
|
52
|
+
const parent = nameNode.parent;
|
|
53
|
+
if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
54
|
+
const ctorKind = getNewExpressionKind(parent.init);
|
|
55
|
+
if (ctorKind)
|
|
56
|
+
return ctorKind;
|
|
57
|
+
}
|
|
58
|
+
const annotationKind = getTypeAnnotationKind(nameNode);
|
|
59
|
+
if (annotationKind)
|
|
60
|
+
return annotationKind;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function resolveDocSetterFromScope(identifier, context) {
|
|
64
|
+
let scope = context.getScope();
|
|
65
|
+
while (scope) {
|
|
66
|
+
const variable = scope.set.get(identifier.name);
|
|
67
|
+
if (variable) {
|
|
68
|
+
for (const def of variable.defs) {
|
|
69
|
+
const kind = extractKindFromDefinition(def);
|
|
70
|
+
if (kind) {
|
|
71
|
+
return { setterName: identifier.name, setterKind: kind };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
scope = scope.upper;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function resolveDocSetterFromClassProperty(propertyName, startNode) {
|
|
80
|
+
let current = startNode;
|
|
81
|
+
while (current) {
|
|
82
|
+
if (current.type === utils_1.AST_NODE_TYPES.ClassBody) {
|
|
83
|
+
for (const element of current.body) {
|
|
84
|
+
if (element.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
|
|
85
|
+
element.key.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
86
|
+
element.key.name === propertyName) {
|
|
87
|
+
const ctorKind = getNewExpressionKind(element.value);
|
|
88
|
+
if (ctorKind)
|
|
89
|
+
return ctorKind;
|
|
90
|
+
const annotationKind = getTypeName(element.typeAnnotation?.typeAnnotation);
|
|
91
|
+
if (isDocSetterName(annotationKind)) {
|
|
92
|
+
return annotationKind;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const classNode = current.parent;
|
|
97
|
+
if (classNode &&
|
|
98
|
+
(classNode.type === utils_1.AST_NODE_TYPES.ClassDeclaration ||
|
|
99
|
+
classNode.type === utils_1.AST_NODE_TYPES.ClassExpression)) {
|
|
100
|
+
const constructor = classNode.body.body.find((member) => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
101
|
+
member.kind === 'constructor');
|
|
102
|
+
if (constructor) {
|
|
103
|
+
for (const param of constructor.value.params) {
|
|
104
|
+
if (param.type === utils_1.AST_NODE_TYPES.TSParameterProperty) {
|
|
105
|
+
const parameter = param.parameter;
|
|
106
|
+
if (parameter.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
107
|
+
parameter.name === propertyName) {
|
|
108
|
+
const annotationKind = getTypeAnnotationKind(parameter);
|
|
109
|
+
if (annotationKind)
|
|
110
|
+
return annotationKind;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
current = current.parent;
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
function isAncestor(ancestor, node) {
|
|
123
|
+
let current = node;
|
|
124
|
+
while (current) {
|
|
125
|
+
if (current === ancestor)
|
|
126
|
+
return true;
|
|
127
|
+
current = current.parent;
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
function findIterationContext(node) {
|
|
132
|
+
let current = node.parent;
|
|
133
|
+
while (current) {
|
|
134
|
+
switch (current.type) {
|
|
135
|
+
case utils_1.AST_NODE_TYPES.ForStatement:
|
|
136
|
+
case utils_1.AST_NODE_TYPES.ForInStatement:
|
|
137
|
+
case utils_1.AST_NODE_TYPES.ForOfStatement:
|
|
138
|
+
case utils_1.AST_NODE_TYPES.WhileStatement:
|
|
139
|
+
case utils_1.AST_NODE_TYPES.DoWhileStatement:
|
|
140
|
+
return { kind: 'loop', loopType: current.type };
|
|
141
|
+
case utils_1.AST_NODE_TYPES.CallExpression: {
|
|
142
|
+
const callee = unwrapCallee(current.callee);
|
|
143
|
+
if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
144
|
+
callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
145
|
+
ITERATING_METHODS.has(callee.property.name)) {
|
|
146
|
+
const callback = current.arguments[0];
|
|
147
|
+
if (callback &&
|
|
148
|
+
(callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
149
|
+
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) &&
|
|
150
|
+
isAncestor(callback, node)) {
|
|
151
|
+
return { kind: 'array-callback', methodName: callee.property.name };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case utils_1.AST_NODE_TYPES.Program:
|
|
157
|
+
return null;
|
|
158
|
+
default:
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
current = current.parent;
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
function formatContext(iteration) {
|
|
166
|
+
if (iteration.kind === 'array-callback') {
|
|
167
|
+
return `${iteration.methodName} callback`;
|
|
168
|
+
}
|
|
169
|
+
switch (iteration.loopType) {
|
|
170
|
+
case utils_1.AST_NODE_TYPES.ForOfStatement:
|
|
171
|
+
return 'for...of loop';
|
|
172
|
+
case utils_1.AST_NODE_TYPES.ForInStatement:
|
|
173
|
+
return 'for...in loop';
|
|
174
|
+
case utils_1.AST_NODE_TYPES.ForStatement:
|
|
175
|
+
return 'for loop';
|
|
176
|
+
case utils_1.AST_NODE_TYPES.WhileStatement:
|
|
177
|
+
return 'while loop';
|
|
178
|
+
case utils_1.AST_NODE_TYPES.DoWhileStatement:
|
|
179
|
+
return 'do...while loop';
|
|
180
|
+
default:
|
|
181
|
+
return 'loop';
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function resolveDocSetterInfo(callee, context) {
|
|
185
|
+
if (callee.property.type !== utils_1.AST_NODE_TYPES.Identifier)
|
|
186
|
+
return null;
|
|
187
|
+
const object = callee.object;
|
|
188
|
+
if (object.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
189
|
+
return resolveDocSetterFromScope(object, context);
|
|
190
|
+
}
|
|
191
|
+
if (object.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
192
|
+
object.object.type === utils_1.AST_NODE_TYPES.ThisExpression &&
|
|
193
|
+
object.property.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
194
|
+
const setterKind = resolveDocSetterFromClassProperty(object.property.name, callee);
|
|
195
|
+
if (setterKind) {
|
|
196
|
+
return { setterName: object.property.name, setterKind };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
exports.preferDocSetterSetAll = (0, createRule_1.createRule)({
|
|
202
|
+
name: 'prefer-docsetter-setall',
|
|
203
|
+
meta: {
|
|
204
|
+
type: 'suggestion',
|
|
205
|
+
docs: {
|
|
206
|
+
description: 'Enforce batching DocSetter and DocSetterTransaction writes by using setAll instead of set inside loops or array callbacks.',
|
|
207
|
+
recommended: 'error',
|
|
208
|
+
},
|
|
209
|
+
schema: [],
|
|
210
|
+
messages: {
|
|
211
|
+
preferSetAll: '{{setterName}}.set() runs inside a {{context}}, which sends one Firestore write per iteration. Collect the document payloads and call setAll() once to batch writes, cut round-trips, and keep payload types narrow (build an updates array and mark entries as const when needed).',
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
defaultOptions: [],
|
|
215
|
+
create(context) {
|
|
216
|
+
return {
|
|
217
|
+
CallExpression(node) {
|
|
218
|
+
const callee = unwrapCallee(node.callee);
|
|
219
|
+
if (callee.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
|
|
220
|
+
callee.property.type !== utils_1.AST_NODE_TYPES.Identifier ||
|
|
221
|
+
callee.property.name !== 'set') {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const setterInfo = resolveDocSetterInfo(callee, context);
|
|
225
|
+
if (!setterInfo)
|
|
226
|
+
return;
|
|
227
|
+
const iterationContext = findIterationContext(node);
|
|
228
|
+
if (!iterationContext)
|
|
229
|
+
return;
|
|
230
|
+
const contextLabel = formatContext(iterationContext);
|
|
231
|
+
context.report({
|
|
232
|
+
node: callee.property,
|
|
233
|
+
messageId: 'preferSetAll',
|
|
234
|
+
data: {
|
|
235
|
+
setterName: setterInfo.setterName,
|
|
236
|
+
context: contextLabel,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=prefer-docsetter-setall.js.map
|
|
@@ -74,8 +74,9 @@ function isBoundToName(fn, name) {
|
|
|
74
74
|
if (parent.type === utils_1.AST_NODE_TYPES.Property ||
|
|
75
75
|
parent.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
|
|
76
76
|
parent.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
|
|
77
|
-
const
|
|
78
|
-
|
|
77
|
+
const narrowedParent = parent;
|
|
78
|
+
const key = narrowedParent.key;
|
|
79
|
+
if (narrowedParent.computed) {
|
|
79
80
|
return key.type === utils_1.AST_NODE_TYPES.Literal && key.value === name;
|
|
80
81
|
}
|
|
81
82
|
if (key.type === utils_1.AST_NODE_TYPES.Identifier)
|
|
@@ -84,7 +85,7 @@ function isBoundToName(fn, name) {
|
|
|
84
85
|
return key.value === name;
|
|
85
86
|
}
|
|
86
87
|
if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
87
|
-
return parent.id.type === utils_1.AST_NODE_TYPES.Identifier && parent.id.name === name;
|
|
88
|
+
return (parent.id.type === utils_1.AST_NODE_TYPES.Identifier && parent.id.name === name);
|
|
88
89
|
}
|
|
89
90
|
if (parent.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
90
91
|
const left = parent.left;
|
|
@@ -20,7 +20,7 @@ exports.preferFragmentComponent = (0, createRule_1.createRule)({
|
|
|
20
20
|
},
|
|
21
21
|
defaultOptions: [],
|
|
22
22
|
create(context) {
|
|
23
|
-
const sourceCode = context.
|
|
23
|
+
const sourceCode = context.sourceCode;
|
|
24
24
|
let hasFragmentImport = false;
|
|
25
25
|
let reactImportNode = null;
|
|
26
26
|
let defaultReactImportNode = null;
|
|
@@ -14,6 +14,7 @@ exports.preferFragmentShorthand = {
|
|
|
14
14
|
context.report({
|
|
15
15
|
node,
|
|
16
16
|
messageId: 'preferShorthand',
|
|
17
|
+
data: { fragmentName: 'React.Fragment' },
|
|
17
18
|
fix: (fixer) => [
|
|
18
19
|
fixer.replaceTextRange(openingElement.range, '<>'),
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -31,7 +32,7 @@ exports.preferFragmentShorthand = {
|
|
|
31
32
|
recommended: 'error',
|
|
32
33
|
},
|
|
33
34
|
messages: {
|
|
34
|
-
preferShorthand: '
|
|
35
|
+
preferShorthand: 'Fragment "{{fragmentName}}" is written with the long <React.Fragment> syntax. That form adds React namespace noise and is only necessary when you need a key or other attributes on the fragment. Prefer the <>...</> shorthand to keep JSX concise, and keep the long form only when fragment attributes are required.',
|
|
35
36
|
},
|
|
36
37
|
schema: [],
|
|
37
38
|
fixable: 'code',
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type OptionShape = {
|
|
2
|
+
stripPrefixes?: string[];
|
|
3
|
+
ignoredMethods?: string[];
|
|
4
|
+
ignoreAsync?: boolean;
|
|
5
|
+
ignoreVoidReturn?: boolean;
|
|
6
|
+
ignoreAbstract?: boolean;
|
|
7
|
+
respectJsDocSideEffects?: boolean;
|
|
8
|
+
minBodyLines?: number;
|
|
9
|
+
};
|
|
10
|
+
type Options = [OptionShape];
|
|
11
|
+
type MessageIds = 'preferGetter' | 'preferGetterSideEffect';
|
|
12
|
+
export declare const preferGetterOverParameterlessMethod: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<MessageIds, Options, import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
|
|
13
|
+
export default preferGetterOverParameterlessMethod;
|