@darraghor/eslint-plugin-nestjs-typed 6.13.0 → 6.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/dist/rules/allPropertiesAreWhitelisted/allPropertiesAreWhitelisted.d.ts +6 -1
- package/dist/rules/allPropertiesAreWhitelisted/allPropertiesAreWhitelisted.js +24 -9
- package/dist/rules/allPropertiesHaveExplicitDefined/allPropertiesHaveExplicitDefined.d.ts +6 -1
- package/dist/rules/allPropertiesHaveExplicitDefined/allPropertiesHaveExplicitDefined.js +46 -32
- package/dist/rules/apiPropertyMatchesPropertyOptionality/apiPropertyMatchesPropertyOptionality.d.ts +7 -1
- package/dist/rules/apiPropertyMatchesPropertyOptionality/apiPropertyMatchesPropertyOptionality.js +47 -3
- package/dist/rules/index.d.ts +9 -3
- package/package.json +1 -1
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
type Options = [
|
|
2
|
+
{
|
|
3
|
+
additionalDecorators?: string[];
|
|
4
|
+
}
|
|
5
|
+
];
|
|
6
|
+
declare const rule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-property-decorator", Options, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
2
7
|
export default rule;
|
|
@@ -11,24 +11,39 @@ const rule = createRule({
|
|
|
11
11
|
"missing-property-decorator": "Property has no class-validator decorator (use @Allow() if you don't need a validation)",
|
|
12
12
|
},
|
|
13
13
|
type: "problem",
|
|
14
|
-
schema: [
|
|
14
|
+
schema: [
|
|
15
|
+
{
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
additionalDecorators: {
|
|
19
|
+
type: "array",
|
|
20
|
+
items: {
|
|
21
|
+
type: "string",
|
|
22
|
+
},
|
|
23
|
+
description: "List of custom decorator names that should be treated as class-validator decorators",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
15
29
|
},
|
|
16
|
-
defaultOptions: [
|
|
30
|
+
defaultOptions: [
|
|
31
|
+
{
|
|
32
|
+
additionalDecorators: [],
|
|
33
|
+
},
|
|
34
|
+
],
|
|
17
35
|
create: function (context) {
|
|
36
|
+
const { additionalDecorators = [] } = context.options[0] || {};
|
|
18
37
|
return {
|
|
19
38
|
ClassDeclaration(node) {
|
|
20
|
-
const program = typedTokenHelpers.getRootProgram(node);
|
|
21
39
|
const withDecorator = [];
|
|
22
40
|
const withoutDecorator = [];
|
|
23
41
|
for (const element of node.body.body) {
|
|
24
42
|
if (element.type !== AST_NODE_TYPES.PropertyDefinition) {
|
|
25
43
|
continue;
|
|
26
44
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
decorator.expression.callee.type ===
|
|
30
|
-
AST_NODE_TYPES.Identifier &&
|
|
31
|
-
typedTokenHelpers.decoratorIsClassValidatorDecorator(program, decorator));
|
|
45
|
+
const validationDecorators = typedTokenHelpers.getValidationDecorators(element, additionalDecorators);
|
|
46
|
+
const hasDecorator = validationDecorators.length > 0;
|
|
32
47
|
if (hasDecorator) {
|
|
33
48
|
withDecorator.push(element);
|
|
34
49
|
}
|
|
@@ -49,4 +64,4 @@ const rule = createRule({
|
|
|
49
64
|
},
|
|
50
65
|
});
|
|
51
66
|
export default rule;
|
|
52
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsUHJvcGVydGllc0FyZVdoaXRlbGlzdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3J1bGVzL2FsbFByb3BlcnRpZXNBcmVXaGl0ZWxpc3RlZC9hbGxQcm9wZXJ0aWVzQXJlV2hpdGVsaXN0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLGNBQWMsRUFBVyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xFLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQztBQVFuRSxNQUFNLElBQUksR0FBRyxVQUFVLENBQXdDO0lBQzNELElBQUksRUFBRSxnQ0FBZ0M7SUFDdEMsSUFBSSxFQUFFO1FBQ0YsSUFBSSxFQUFFO1lBQ0YsV0FBVyxFQUFFLHdDQUF3QztTQUN4RDtRQUNELFFBQVEsRUFBRTtZQUNOLDRCQUE0QixFQUN4Qix5RkFBeUY7U0FDaEc7UUFDRCxJQUFJLEVBQUUsU0FBUztRQUNmLE1BQU0sRUFBRTtZQUNKO2dCQUNJLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDUixvQkFBb0IsRUFBRTt3QkFDbEIsSUFBSSxFQUFFLE9BQU87d0JBQ2IsS0FBSyxFQUFFOzRCQUNILElBQUksRUFBRSxRQUFRO3lCQUNqQjt3QkFDRCxXQUFXLEVBQ1AscUZBQXFGO3FCQUM1RjtpQkFDSjtnQkFDRCxvQkFBb0IsRUFBRSxLQUFLO2FBQzlCO1NBQ0o7S0FDSjtJQUNELGNBQWMsRUFBRTtRQUNaO1lBQ0ksb0JBQW9CLEVBQUUsRUFBRTtTQUMzQjtLQUNKO0lBQ0QsTUFBTSxFQUFFLFVBQVUsT0FBTztRQUNyQixNQUFNLEVBQUMsb0JBQW9CLEdBQUcsRUFBRSxFQUFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFN0QsT0FBTztZQUNILGdCQUFnQixDQUFDLElBQStCO2dCQUM1QyxNQUFNLGFBQWEsR0FBa0MsRUFBRSxDQUFDO2dCQUN4RCxNQUFNLGdCQUFnQixHQUFrQyxFQUFFLENBQUM7Z0JBQzNELEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDbkMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO3dCQUNyRCxTQUFTO29CQUNiLENBQUM7b0JBQ0QsTUFBTSxvQkFBb0IsR0FDdEIsaUJBQWlCLENBQUMsdUJBQXVCLENBQ3JDLE9BQU8sRUFDUCxvQkFBb0IsQ0FDdkIsQ0FBQztvQkFDTixNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUVyRCxJQUFJLFlBQVksRUFBRSxDQUFDO3dCQUNmLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ2hDLENBQUM7eUJBQU0sQ0FBQzt3QkFDSixnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ25DLENBQUM7Z0JBQ0wsQ0FBQztnQkFDRCxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDMUQsS0FBSyxNQUFNLE9BQU8sSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO3dCQUNyQyxPQUFPLENBQUMsTUFBTSxDQUFDOzRCQUNYLElBQUksRUFBRSxPQUFPOzRCQUNiLFNBQVMsRUFBRSw0QkFBNEI7eUJBQzFDLENBQUMsQ0FBQztvQkFDUCxDQUFDO2dCQUNMLENBQUM7WUFDTCxDQUFDO1NBQ0osQ0FBQztJQUNOLENBQUM7Q0FDSixDQUFDLENBQUM7QUFFSCxlQUFlLElBQUksQ0FBQyJ9
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
-
|
|
2
|
+
type Options = [
|
|
3
|
+
{
|
|
4
|
+
additionalDecorators?: string[];
|
|
5
|
+
}
|
|
6
|
+
];
|
|
7
|
+
declare const rule: ESLintUtils.RuleModule<"missing-is-defined-decorator" | "missing-is-optional-decorator" | "conflicting-defined-decorators-defined-optional" | "conflicting-defined-decorators-optional-validate-if" | "conflicting-defined-decorators-all", Options, unknown, ESLintUtils.RuleListener>;
|
|
3
8
|
export default rule;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ESLintUtils, } from "@typescript-eslint/utils";
|
|
2
2
|
import { isNullableType } from "@typescript-eslint/type-utils";
|
|
3
3
|
import { getPropertiesDefinitions } from "../../utils/ast.js";
|
|
4
4
|
import { createRule } from "../../utils/createRule.js";
|
|
@@ -17,11 +17,30 @@ const rule = createRule({
|
|
|
17
17
|
"conflicting-defined-decorators-all": "Properties can have one of @IsDefined() or @IsOptional() or @ValidateIf()",
|
|
18
18
|
},
|
|
19
19
|
type: "problem",
|
|
20
|
-
schema: [
|
|
20
|
+
schema: [
|
|
21
|
+
{
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
additionalDecorators: {
|
|
25
|
+
type: "array",
|
|
26
|
+
items: {
|
|
27
|
+
type: "string",
|
|
28
|
+
},
|
|
29
|
+
description: "List of custom decorator names that should be treated as class-validator decorators",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
21
35
|
},
|
|
22
|
-
defaultOptions: [
|
|
36
|
+
defaultOptions: [
|
|
37
|
+
{
|
|
38
|
+
additionalDecorators: [],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
23
41
|
create: function (context) {
|
|
24
42
|
const service = ESLintUtils.getParserServices(context);
|
|
43
|
+
const { additionalDecorators = [] } = context.options[0] || {};
|
|
25
44
|
const checker = service.program.getTypeChecker();
|
|
26
45
|
return {
|
|
27
46
|
ClassDeclaration(node) {
|
|
@@ -31,7 +50,7 @@ const rule = createRule({
|
|
|
31
50
|
// for each property in the class
|
|
32
51
|
for (const propertyDefinition of propertyDefinitions) {
|
|
33
52
|
// check for the optional or defined decorators, or any class-validator decorator
|
|
34
|
-
const decoratorsStatus = getDecoratorsStatus(propertyDefinition);
|
|
53
|
+
const decoratorsStatus = getDecoratorsStatus(propertyDefinition, additionalDecorators);
|
|
35
54
|
propertyDefinitionsWithDecoratorsStatus.push([
|
|
36
55
|
propertyDefinition,
|
|
37
56
|
decoratorsStatus,
|
|
@@ -106,37 +125,32 @@ function getType(typeNode, service, checker) {
|
|
|
106
125
|
const type = checker.getTypeAtLocation(tsNode);
|
|
107
126
|
return type;
|
|
108
127
|
}
|
|
109
|
-
function getDecoratorsStatus(propertyDefinition) {
|
|
128
|
+
function getDecoratorsStatus(propertyDefinition, additionalDecorators = []) {
|
|
110
129
|
let hasIsDefinedDecorator = false;
|
|
111
130
|
let hasTypeCheckingDecorator = false;
|
|
112
131
|
let hasIsOptionalDecorator = false;
|
|
113
132
|
let hasValidateIfDecorator = false;
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
if (decorator.expression.callee.name === "ValidateIf") {
|
|
137
|
-
hasValidateIfDecorator = true;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
133
|
+
const validationDecorators = typedTokenHelpers.getValidationDecorators(propertyDefinition, additionalDecorators);
|
|
134
|
+
for (const decorator of validationDecorators) {
|
|
135
|
+
const decoratorName = typedTokenHelpers.getDecoratorName(decorator);
|
|
136
|
+
if (!decoratorName) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// We care if the decorator is a validation decorator like IsString etc for checks later
|
|
140
|
+
if (decoratorName !== "IsDefined" &&
|
|
141
|
+
decoratorName !== "IsOptional" &&
|
|
142
|
+
decoratorName !== "ValidateIf") {
|
|
143
|
+
hasTypeCheckingDecorator = true;
|
|
144
|
+
}
|
|
145
|
+
// otherwise check if it is isDefined or isOptional, we will use this later
|
|
146
|
+
if (decoratorName === "IsDefined") {
|
|
147
|
+
hasIsDefinedDecorator = true;
|
|
148
|
+
}
|
|
149
|
+
if (decoratorName === "IsOptional") {
|
|
150
|
+
hasIsOptionalDecorator = true;
|
|
151
|
+
}
|
|
152
|
+
if (decoratorName === "ValidateIf") {
|
|
153
|
+
hasValidateIfDecorator = true;
|
|
140
154
|
}
|
|
141
155
|
}
|
|
142
156
|
return {
|
|
@@ -146,4 +160,4 @@ function getDecoratorsStatus(propertyDefinition) {
|
|
|
146
160
|
hasValidateIfDecorator,
|
|
147
161
|
};
|
|
148
162
|
}
|
|
149
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsUHJvcGVydGllc0hhdmVFeHBsaWNpdERlZmluZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvYWxsUHJvcGVydGllc0hhdmVFeHBsaWNpdERlZmluZWQvYWxsUHJvcGVydGllc0hhdmVFeHBsaWNpdERlZmluZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVILFdBQVcsR0FFZCxNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUM1RCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFFckQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFRbkUsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQU9yQjtJQUNFLElBQUksRUFBRSxzQ0FBc0M7SUFDNUMsSUFBSSxFQUFFO1FBQ0YsSUFBSSxFQUFFO1lBQ0YsV0FBVyxFQUNQLGtFQUFrRTtTQUN6RTtRQUNELFFBQVEsRUFBRTtZQUNOLDhCQUE4QixFQUMxQiw0R0FBNEc7WUFDaEgsK0JBQStCLEVBQzNCLHdFQUF3RTtZQUM1RSxpREFBaUQsRUFDN0MsZ0VBQWdFO1lBQ3BFLHFEQUFxRCxFQUNqRCxpRUFBaUU7WUFDckUsb0NBQW9DLEVBQ2hDLDJFQUEyRTtTQUNsRjtRQUNELElBQUksRUFBRSxTQUFTO1FBQ2YsTUFBTSxFQUFFO1lBQ0o7Z0JBQ0ksSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsVUFBVSxFQUFFO29CQUNSLG9CQUFvQixFQUFFO3dCQUNsQixJQUFJLEVBQUUsT0FBTzt3QkFDYixLQUFLLEVBQUU7NEJBQ0gsSUFBSSxFQUFFLFFBQVE7eUJBQ2pCO3dCQUNELFdBQVcsRUFDUCxxRkFBcUY7cUJBQzVGO2lCQUNKO2dCQUNELG9CQUFvQixFQUFFLEtBQUs7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
|
package/dist/rules/apiPropertyMatchesPropertyOptionality/apiPropertyMatchesPropertyOptionality.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
2
|
export declare const shouldUseRequiredDecorator: (node: TSESTree.PropertyDefinition) => boolean;
|
|
3
3
|
export declare const shouldUseOptionalDecorator: (node: TSESTree.PropertyDefinition) => boolean;
|
|
4
|
-
declare const
|
|
4
|
+
export declare const hasRedundantRequired: (node: TSESTree.PropertyDefinition) => boolean;
|
|
5
|
+
type Options = [
|
|
6
|
+
{
|
|
7
|
+
checkRedundantRequired?: boolean;
|
|
8
|
+
}
|
|
9
|
+
];
|
|
10
|
+
declare const rule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldUseOptionalDecorator" | "shouldUseRequiredDecorator" | "redundantRequired", Options, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
11
|
export default rule;
|
package/dist/rules/apiPropertyMatchesPropertyOptionality/apiPropertyMatchesPropertyOptionality.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
1
2
|
import { createRule } from "../../utils/createRule.js";
|
|
2
3
|
import { typedTokenHelpers } from "../../utils/typedTokenHelpers.js";
|
|
3
4
|
export const shouldUseRequiredDecorator = (node) => {
|
|
@@ -10,6 +11,24 @@ export const shouldUseOptionalDecorator = (node) => {
|
|
|
10
11
|
const isOptionalPropertyValue = typedTokenHelpers.isOptionalPropertyValue(node);
|
|
11
12
|
return hasRequiredDecorator && isOptionalPropertyValue;
|
|
12
13
|
};
|
|
14
|
+
export const hasRedundantRequired = (node) => {
|
|
15
|
+
const apiPropertyDecorators = typedTokenHelpers.getDecoratorsNamed(node, [
|
|
16
|
+
"ApiProperty",
|
|
17
|
+
]);
|
|
18
|
+
for (const decorator of apiPropertyDecorators) {
|
|
19
|
+
if (decorator.expression.type === TSESTree.AST_NODE_TYPES.CallExpression) {
|
|
20
|
+
const firstArgument = decorator.expression.arguments[0];
|
|
21
|
+
if (firstArgument &&
|
|
22
|
+
firstArgument.type === TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
23
|
+
const hasRequiredTrue = typedTokenHelpers.getPropertyValueEqualsExpected(firstArgument, "required", true);
|
|
24
|
+
if (hasRequiredTrue) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
13
32
|
const rule = createRule({
|
|
14
33
|
name: "api-property-matches-property-optionality",
|
|
15
34
|
meta: {
|
|
@@ -19,13 +38,31 @@ const rule = createRule({
|
|
|
19
38
|
messages: {
|
|
20
39
|
shouldUseOptionalDecorator: `Property marked as optional should use @ApiPropertyOptional decorator`,
|
|
21
40
|
shouldUseRequiredDecorator: `Property marked as required should use @ApiProperty decorator`,
|
|
41
|
+
redundantRequired: `Redundant 'required: true' in @ApiProperty. Properties are required by default.`,
|
|
22
42
|
},
|
|
23
|
-
schema: [
|
|
43
|
+
schema: [
|
|
44
|
+
{
|
|
45
|
+
type: "object",
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
properties: {
|
|
48
|
+
checkRedundantRequired: {
|
|
49
|
+
description: "Check for redundant 'required: true' in @ApiProperty (default: true)",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
24
55
|
hasSuggestions: false,
|
|
25
56
|
type: "suggestion",
|
|
26
57
|
},
|
|
27
|
-
defaultOptions: [
|
|
58
|
+
defaultOptions: [
|
|
59
|
+
{
|
|
60
|
+
checkRedundantRequired: true,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
28
63
|
create(context) {
|
|
64
|
+
const options = context.options[0] || {};
|
|
65
|
+
const shouldCheckRedundantRequired = options.checkRedundantRequired ?? true;
|
|
29
66
|
return {
|
|
30
67
|
PropertyDefinition(node) {
|
|
31
68
|
if (shouldUseOptionalDecorator(node)) {
|
|
@@ -40,9 +77,16 @@ const rule = createRule({
|
|
|
40
77
|
messageId: "shouldUseRequiredDecorator",
|
|
41
78
|
});
|
|
42
79
|
}
|
|
80
|
+
if (shouldCheckRedundantRequired &&
|
|
81
|
+
hasRedundantRequired(node)) {
|
|
82
|
+
context.report({
|
|
83
|
+
node: node,
|
|
84
|
+
messageId: "redundantRequired",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
43
87
|
},
|
|
44
88
|
};
|
|
45
89
|
},
|
|
46
90
|
});
|
|
47
91
|
export default rule;
|
|
48
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
92
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpUHJvcGVydHlNYXRjaGVzUHJvcGVydHlPcHRpb25hbGl0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ydWxlcy9hcGlQcm9wZXJ0eU1hdGNoZXNQcm9wZXJ0eU9wdGlvbmFsaXR5L2FwaVByb3BlcnR5TWF0Y2hlc1Byb3BlcnR5T3B0aW9uYWxpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQztBQUVuRSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxDQUN0QyxJQUFpQyxFQUMxQixFQUFFO0lBQ1QsTUFBTSxvQkFBb0IsR0FBRyxpQkFBaUIsQ0FBQyxzQkFBc0IsQ0FDakUsSUFBSSxFQUNKLENBQUMscUJBQXFCLENBQUMsQ0FDMUIsQ0FBQztJQUVGLE1BQU0sdUJBQXVCLEdBQ3pCLGlCQUFpQixDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXBELE9BQU8sb0JBQW9CLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztBQUM1RCxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxDQUN0QyxJQUFpQyxFQUMxQixFQUFFO0lBQ1QsTUFBTSxvQkFBb0IsR0FBRyxpQkFBaUIsQ0FBQyxzQkFBc0IsQ0FDakUsSUFBSSxFQUNKLENBQUMsYUFBYSxDQUFDLENBQ2xCLENBQUM7SUFFRixNQUFNLHVCQUF1QixHQUN6QixpQkFBaUIsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVwRCxPQUFPLG9CQUFvQixJQUFJLHVCQUF1QixDQUFDO0FBQzNELENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQ2hDLElBQWlDLEVB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
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
declare const allRules: {
|
|
2
|
-
"all-properties-have-explicit-defined": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-is-defined-decorator" | "missing-is-optional-decorator" | "conflicting-defined-decorators-defined-optional" | "conflicting-defined-decorators-optional-validate-if" | "conflicting-defined-decorators-all", [
|
|
3
|
-
|
|
2
|
+
"all-properties-have-explicit-defined": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-is-defined-decorator" | "missing-is-optional-decorator" | "conflicting-defined-decorators-defined-optional" | "conflicting-defined-decorators-optional-validate-if" | "conflicting-defined-decorators-all", [{
|
|
3
|
+
additionalDecorators?: string[];
|
|
4
|
+
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
|
+
"api-property-matches-property-optionality": import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldUseOptionalDecorator" | "shouldUseRequiredDecorator" | "redundantRequired", [{
|
|
6
|
+
checkRedundantRequired?: boolean;
|
|
7
|
+
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
8
|
"injectable-should-be-provided": import("@typescript-eslint/utils/ts-eslint").RuleModule<"injectableInModule" | "controllersInModule", [{
|
|
5
9
|
src: string[];
|
|
6
10
|
filterFromPaths: string[];
|
|
@@ -18,7 +22,9 @@ declare const allRules: {
|
|
|
18
22
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
19
23
|
"validated-non-primitive-property-needs-type-decorator": import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldUseTypeDecorator" | "autofixWithTypeDecorator", import("./validateNonPrimitiveNeedsTypeDecorator/validateNonPrimitiveNeedsDecorators.js").ValidateNonPrimitivePropertyTypeDecoratorOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
20
24
|
"validate-nested-of-array-should-set-each": import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldSetEachPropertyTrue" | "shouldSetEachPropertyFalse", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
21
|
-
"all-properties-are-whitelisted": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-property-decorator", [
|
|
25
|
+
"all-properties-are-whitelisted": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-property-decorator", [{
|
|
26
|
+
additionalDecorators?: string[];
|
|
27
|
+
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
22
28
|
"api-methods-should-be-guarded": import("@typescript-eslint/utils/ts-eslint").RuleModule<"apiMethodsShouldBeGuarded", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
23
29
|
"sort-module-metadata-arrays": import("@typescript-eslint/utils/ts-eslint").RuleModule<"moduleMetadataArraysAreSorted", import("./sortModuleMetadataArrays/sortModuleMetadataArrays.js").RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
24
30
|
"use-correct-endpoint-naming-convention": import("@typescript-eslint/utils/ts-eslint").RuleModule<"controllerPathShouldBePlural" | "controllerPathShouldBeKebabCase" | "routePathShouldBeKebabCase", [{
|