@darraghor/eslint-plugin-nestjs-typed 3.6.0 → 3.8.1

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 CHANGED
@@ -28,6 +28,7 @@ Preventing bugs
28
28
  - param-decorator-name-matches-route-param
29
29
  - validate-nested-of-array-should-set-each
30
30
  - validated-non-primitive-property-needs-type-decorator
31
+ - all-properties-are-whitelisted
31
32
 
32
33
  Security
33
34
 
@@ -114,6 +115,45 @@ Disable a single rule with the full name e.g. in your eslint configuration...
114
115
 
115
116
  ## Rule Details
116
117
 
118
+ ### Rule: all-properties-are-whitelisted
119
+
120
+ You should forbid non-whitelisted properties in your DTOs.
121
+
122
+ If you have a DTO that has one property with a class-validator decorator, it's very unlikely that the same DTO will have any properties without a decorator - i.e. ALL DTO properties should be validated or explicitly whitelisted with `@Allow()`.
123
+
124
+ This rule will flag any properties that are not whitelisted as expected because it's probably a mistake.
125
+
126
+ This PASSES - all properties are decorated
127
+
128
+ ```ts
129
+ export class CreateOrganisationDto {
130
+ @ApiProperty({type: Person, isArray: true})
131
+ @ValidateNested({each: true})
132
+ members!: MyClass[];
133
+
134
+ @ApiProperty()
135
+ @Allow()
136
+ otherProperty!: MyClass;
137
+
138
+ @ApiProperty()
139
+ @IsString()
140
+ someStringProperty!: string;
141
+ }
142
+ ```
143
+
144
+ This FAILS - one property here is missing a validation decorator. This is likely a mistake.
145
+
146
+ ```ts
147
+ export class CreateOrganisationDto {
148
+ @ApiProperty({type: Person, isArray: true})
149
+ @ValidateNested({each: true})
150
+ members!: MyClass[];
151
+
152
+ @ApiProperty()
153
+ otherProperty!: MyClass;
154
+ }
155
+ ```
156
+
117
157
  ### Rule: validate-nested-of-array-should-set-each
118
158
 
119
159
  If you use the `@ValidateNested` decorator you should specify the `{each: true}` option if the property is an array.
@@ -19,6 +19,7 @@ declare const allConfigs: {
19
19
  "@darraghor/nestjs-typed/param-decorator-name-matches-route-param": string;
20
20
  "@darraghor/nestjs-typed/validated-non-primitive-property-needs-type-decorator": string;
21
21
  "@darraghor/nestjs-typed/validate-nested-of-array-should-set-each": string;
22
+ "@darraghor/nestjs-typed/all-properties-are-whitelisted": string;
22
23
  };
23
24
  };
24
25
  "no-swagger": {
@@ -18,6 +18,7 @@ declare const _default: {
18
18
  "@darraghor/nestjs-typed/param-decorator-name-matches-route-param": string;
19
19
  "@darraghor/nestjs-typed/validated-non-primitive-property-needs-type-decorator": string;
20
20
  "@darraghor/nestjs-typed/validate-nested-of-array-should-set-each": string;
21
+ "@darraghor/nestjs-typed/all-properties-are-whitelisted": string;
21
22
  };
22
23
  };
23
24
  export = _default;
@@ -21,6 +21,7 @@ module.exports = {
21
21
  "@darraghor/nestjs-typed/param-decorator-name-matches-route-param": "error",
22
22
  "@darraghor/nestjs-typed/validated-non-primitive-property-needs-type-decorator": "error",
23
23
  "@darraghor/nestjs-typed/validate-nested-of-array-should-set-each": "error",
24
+ "@darraghor/nestjs-typed/all-properties-are-whitelisted": "error",
24
25
  },
25
26
  };
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlncy9yZWNvbW1lbmRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsaUJBQVM7SUFDTCxNQUFNLEVBQUUsMkJBQTJCO0lBQ25DLGFBQWEsRUFBRSxFQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUM7SUFDckMsS0FBSyxFQUFFO1FBQ0gsMkRBQTJEO1FBQzNELDJFQUEyRSxFQUN2RSxPQUFPO1FBQ1gsdURBQXVELEVBQUU7WUFDckQsT0FBTztZQUNQO2dCQUNJLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztnQkFDcEIsZUFBZSxFQUFFLENBQUMsY0FBYyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUM7YUFDeEQ7U0FDSjtRQUNELG1FQUFtRSxFQUMvRCxPQUFPO1FBQ1gsZ0VBQWdFLEVBQzVELE9BQU87UUFDWCw0REFBNEQsRUFBRSxPQUFPO1FBQ3JFLDBEQUEwRCxFQUFFLE9BQU87UUFDbkUsdUVBQXVFLEVBQ25FLE9BQU87UUFDWCw4REFBOEQsRUFBRSxPQUFPO1FBQ3ZFLGtFQUFrRSxFQUM5RCxPQUFPO1FBQ1gsK0VBQStFLEVBQzNFLE9BQU87UUFDWCxrRUFBa0UsRUFDOUQsT0FBTztLQUNkO0NBQ0osQ0FBQyJ9
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlncy9yZWNvbW1lbmRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsaUJBQVM7SUFDTCxNQUFNLEVBQUUsMkJBQTJCO0lBQ25DLGFBQWEsRUFBRSxFQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUM7SUFDckMsS0FBSyxFQUFFO1FBQ0gsMkRBQTJEO1FBQzNELDJFQUEyRSxFQUN2RSxPQUFPO1FBQ1gsdURBQXVELEVBQUU7WUFDckQsT0FBTztZQUNQO2dCQUNJLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztnQkFDcEIsZUFBZSxFQUFFLENBQUMsY0FBYyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUM7YUFDeEQ7U0FDSjtRQUNELG1FQUFtRSxFQUMvRCxPQUFPO1FBQ1gsZ0VBQWdFLEVBQzVELE9BQU87UUFDWCw0REFBNEQsRUFBRSxPQUFPO1FBQ3JFLDBEQUEwRCxFQUFFLE9BQU87UUFDbkUsdUVBQXVFLEVBQ25FLE9BQU87UUFDWCw4REFBOEQsRUFBRSxPQUFPO1FBQ3ZFLGtFQUFrRSxFQUM5RCxPQUFPO1FBQ1gsK0VBQStFLEVBQzNFLE9BQU87UUFDWCxrRUFBa0UsRUFDOUQsT0FBTztRQUNYLHdEQUF3RCxFQUFFLE9BQU87S0FDcEU7Q0FDSixDQUFDIn0=
package/dist/index.d.ts CHANGED
@@ -35,6 +35,9 @@ declare const configuration: {
35
35
  "validate-nested-of-array-should-set-each": import("@typescript-eslint/experimental-utils/dist/ts-eslint/Rule").RuleModule<"shouldSetEachPropertyTrue" | "shouldSetEachPropertyFalse", never[], {
36
36
  PropertyDefinition: (node: import("@typescript-eslint/types/dist/ast-spec").Node) => void;
37
37
  }>;
38
+ "all-properties-are-whitelisted": import("@typescript-eslint/experimental-utils/dist/ts-eslint/Rule").RuleModule<"missing-property-decorator", never[], {
39
+ ClassDeclaration(node: import("@typescript-eslint/types/dist/ast-spec").ClassDeclaration): void;
40
+ }>;
38
41
  };
39
42
  configs: {
40
43
  recommended: {
@@ -57,6 +60,7 @@ declare const configuration: {
57
60
  "@darraghor/nestjs-typed/param-decorator-name-matches-route-param": string;
58
61
  "@darraghor/nestjs-typed/validated-non-primitive-property-needs-type-decorator": string;
59
62
  "@darraghor/nestjs-typed/validate-nested-of-array-should-set-each": string;
63
+ "@darraghor/nestjs-typed/all-properties-are-whitelisted": string;
60
64
  };
61
65
  };
62
66
  "no-swagger": {
@@ -0,0 +1,4 @@
1
+ declare const rule: import("@typescript-eslint/experimental-utils/dist/ts-eslint/Rule").RuleModule<"missing-property-decorator", never[], {
2
+ ClassDeclaration(node: import("@typescript-eslint/types/dist/ast-spec").ClassDeclaration): void;
3
+ }>;
4
+ export default rule;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
23
+ const classValidator = __importStar(require("class-validator"));
24
+ const createRule_1 = require("../../utils/createRule");
25
+ const CLASS_VALIDATOR_DECORATOR_NAMES = new Set(Object.keys(classValidator));
26
+ const rule = (0, createRule_1.createRule)({
27
+ name: "all-properties-are-whitelisted",
28
+ meta: {
29
+ docs: {
30
+ description: "Enforce all properties are whitelisted",
31
+ recommended: "error",
32
+ requiresTypeChecking: false,
33
+ },
34
+ messages: {
35
+ "missing-property-decorator": "Property has no class-validator decorator (use @Allow() if you don't need a validation)",
36
+ },
37
+ type: "problem",
38
+ schema: {},
39
+ },
40
+ defaultOptions: [],
41
+ create: function (context) {
42
+ return {
43
+ // eslint-disable-next-line @typescript-eslint/naming-convention
44
+ ClassDeclaration(node) {
45
+ var _a;
46
+ const withDecorator = [];
47
+ const withoutDecorator = [];
48
+ for (const element of node.body.body) {
49
+ if (element.type !== experimental_utils_1.AST_NODE_TYPES.PropertyDefinition) {
50
+ continue;
51
+ }
52
+ const hasDecorator = (_a = element.decorators) === null || _a === void 0 ? void 0 : _a.some((decorator) => decorator.expression.type ===
53
+ experimental_utils_1.AST_NODE_TYPES.CallExpression &&
54
+ decorator.expression.callee.type ===
55
+ experimental_utils_1.AST_NODE_TYPES.Identifier &&
56
+ CLASS_VALIDATOR_DECORATOR_NAMES.has(decorator.expression.callee.name));
57
+ if (hasDecorator) {
58
+ withDecorator.push(element);
59
+ }
60
+ else {
61
+ withoutDecorator.push(element);
62
+ }
63
+ }
64
+ if (withDecorator.length > 0 && withoutDecorator.length > 0) {
65
+ for (const element of withoutDecorator) {
66
+ context.report({
67
+ node: element,
68
+ messageId: "missing-property-decorator",
69
+ });
70
+ }
71
+ }
72
+ },
73
+ };
74
+ },
75
+ });
76
+ exports.default = rule;
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsUHJvcGVydGllc0FyZVdoaXRlbGlzdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3J1bGVzL2FsbFByb3BlcnRpZXNBcmVXaGl0ZWxpc3RlZC9hbGxQcm9wZXJ0aWVzQXJlV2hpdGVsaXN0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsOEVBQXFFO0FBRXJFLGdFQUFrRDtBQUNsRCx1REFBa0Q7QUFFbEQsTUFBTSwrQkFBK0IsR0FBRyxJQUFJLEdBQUcsQ0FDM0MsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUF3QixDQUFDLENBQ3hDLENBQUM7QUFFRixNQUFNLElBQUksR0FBRyxJQUFBLHVCQUFVLEVBQUM7SUFDcEIsSUFBSSxFQUFFLGdDQUFnQztJQUN0QyxJQUFJLEVBQUU7UUFDRixJQUFJLEVBQUU7WUFDRixXQUFXLEVBQUUsd0NBQXdDO1lBQ3JELFdBQVcsRUFBRSxPQUFPO1lBQ3BCLG9CQUFvQixFQUFFLEtBQUs7U0FDOUI7UUFDRCxRQUFRLEVBQUU7WUFDTiw0QkFBNEIsRUFDeEIseUZBQXlGO1NBQ2hHO1FBQ0QsSUFBSSxFQUFFLFNBQVM7UUFDZixNQUFNLEVBQUUsRUFBRTtLQUNiO0lBQ0QsY0FBYyxFQUFFLEVBQUU7SUFDbEIsTUFBTSxFQUFFLFVBQVUsT0FBTztRQUNyQixPQUFPO1lBQ0gsZ0VBQWdFO1lBQ2hFLGdCQUFnQixDQUFDLElBQUk7O2dCQUNqQixNQUFNLGFBQWEsR0FBeUIsRUFBRSxDQUFDO2dCQUMvQyxNQUFNLGdCQUFnQixHQUF5QixFQUFFLENBQUM7Z0JBQ2xELEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7b0JBQ2xDLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxtQ0FBYyxDQUFDLGtCQUFrQixFQUFFO3dCQUNwRCxTQUFTO3FCQUNaO29CQUNELE1BQU0sWUFBWSxHQUFHLE1BQUEsT0FBTyxDQUFDLFVBQVUsMENBQUUsSUFBSSxDQUN6QyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQ1YsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJO3dCQUNyQixtQ0FBYyxDQUFDLGNBQWM7d0JBQ2pDLFNBQVMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUk7NEJBQzVCLG1DQUFjLENBQUMsVUFBVTt3QkFDN0IsK0JBQStCLENBQUMsR0FBRyxDQUMvQixTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ25DLENBQ1IsQ0FBQztvQkFDRixJQUFJLFlBQVksRUFBRTt3QkFDZCxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUMvQjt5QkFBTTt3QkFDSCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ2xDO2lCQUNKO2dCQUNELElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDekQsS0FBSyxNQUFNLE9BQU8sSUFBSSxnQkFBZ0IsRUFBRTt3QkFDcEMsT0FBTyxDQUFDLE1BQU0sQ0FBQzs0QkFDWCxJQUFJLEVBQUUsT0FBTzs0QkFDYixTQUFTLEVBQUUsNEJBQTRCO3lCQUMxQyxDQUFDLENBQUM7cUJBQ047aUJBQ0o7WUFDTCxDQUFDO1NBQ0osQ0FBQztJQUNOLENBQUM7Q0FDSixDQUFDLENBQUM7QUFFSCxrQkFBZSxJQUFJLENBQUMifQ==
@@ -34,5 +34,8 @@ declare const allRules: {
34
34
  "validate-nested-of-array-should-set-each": import("@typescript-eslint/experimental-utils/dist/ts-eslint/Rule").RuleModule<"shouldSetEachPropertyTrue" | "shouldSetEachPropertyFalse", never[], {
35
35
  PropertyDefinition: (node: import("@typescript-eslint/types/dist/ast-spec").Node) => void;
36
36
  }>;
37
+ "all-properties-are-whitelisted": import("@typescript-eslint/experimental-utils/dist/ts-eslint/Rule").RuleModule<"missing-property-decorator", never[], {
38
+ ClassDeclaration(node: import("@typescript-eslint/types/dist/ast-spec").ClassDeclaration): void;
39
+ }>;
37
40
  };
38
41
  export default allRules;
@@ -14,6 +14,7 @@ const shouldSpecifyForbidUnknownValuesRule_1 = __importDefault(require("./should
14
14
  const paramDecoratorNameMatchesRouteParam_1 = __importDefault(require("./paramDecoratorNameMatchesRouteParam/paramDecoratorNameMatchesRouteParam"));
15
15
  const validateNonPrimitiveNeedsDecorators_1 = __importDefault(require("./validate-non-primitves-needs-type-decorator/validateNonPrimitiveNeedsDecorators"));
16
16
  const validateNestedOfArrayShouldSetEach_1 = __importDefault(require("./validateNestedOfArrayShouldSetEach/validateNestedOfArrayShouldSetEach"));
17
+ const allPropertiesAreWhitelisted_1 = __importDefault(require("./allPropertiesAreWhitelisted/allPropertiesAreWhitelisted"));
17
18
  const allRules = {
18
19
  "api-property-matches-property-optionality": apiPropertyMatchesPropertyOptionality_1.default,
19
20
  "injectable-should-be-provided": injectableShouldBeProvided_1.default,
@@ -26,6 +27,7 @@ const allRules = {
26
27
  "param-decorator-name-matches-route-param": paramDecoratorNameMatchesRouteParam_1.default,
27
28
  "validated-non-primitive-property-needs-type-decorator": validateNonPrimitiveNeedsDecorators_1.default,
28
29
  "validate-nested-of-array-should-set-each": validateNestedOfArrayShouldSetEach_1.default,
30
+ "all-properties-are-whitelisted": allPropertiesAreWhitelisted_1.default,
29
31
  };
30
32
  exports.default = allRules;
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwwSEFBa0c7QUFDbEcsaUpBQW1JO0FBQ25JLDBKQUFrSTtBQUNsSSxrSUFBMEc7QUFDMUcsaUpBQXlIO0FBQ3pILCtIQUF1RztBQUN2RyxnS0FBd0k7QUFDeEksbUpBQXVIO0FBQ3ZILG9KQUFnSTtBQUNoSSw0SkFBb0k7QUFDcEksaUpBQXlIO0FBRXpILE1BQU0sUUFBUSxHQUFHO0lBQ2IsMkNBQTJDLEVBQ3ZDLCtDQUFxQztJQUN6QywrQkFBK0IsRUFBRSxvQ0FBMEI7SUFDM0QsbURBQW1ELEVBQy9DLDRDQUE0QztJQUNoRCxvQ0FBb0MsRUFBRSx1Q0FBNkI7SUFDbkUsd0NBQXdDLEVBQ3BDLDRDQUFrQztJQUN0QyxrQ0FBa0MsRUFBRSxzQ0FBNEI7SUFDaEUsK0NBQStDLEVBQzNDLGlEQUF1QztJQUMzQyxzQ0FBc0MsRUFBRSw4Q0FBZ0M7SUFDeEUsMENBQTBDLEVBQ3RDLDZDQUF1QztJQUMzQyx1REFBdUQsRUFDbkQsNkNBQW1DO0lBQ3ZDLDBDQUEwQyxFQUN0Qyw0Q0FBa0M7Q0FDekMsQ0FBQztBQUVGLGtCQUFlLFFBQVEsQ0FBQyJ9
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwwSEFBa0c7QUFDbEcsaUpBQW1JO0FBQ25JLDBKQUFrSTtBQUNsSSxrSUFBMEc7QUFDMUcsaUpBQXlIO0FBQ3pILCtIQUF1RztBQUN2RyxnS0FBd0k7QUFDeEksbUpBQXVIO0FBQ3ZILG9KQUFnSTtBQUNoSSw0SkFBb0k7QUFDcEksaUpBQXlIO0FBQ3pILDRIQUFvRztBQUVwRyxNQUFNLFFBQVEsR0FBRztJQUNiLDJDQUEyQyxFQUN2QywrQ0FBcUM7SUFDekMsK0JBQStCLEVBQUUsb0NBQTBCO0lBQzNELG1EQUFtRCxFQUMvQyw0Q0FBNEM7SUFDaEQsb0NBQW9DLEVBQUUsdUNBQTZCO0lBQ25FLHdDQUF3QyxFQUNwQyw0Q0FBa0M7SUFDdEMsa0NBQWtDLEVBQUUsc0NBQTRCO0lBQ2hFLCtDQUErQyxFQUMzQyxpREFBdUM7SUFDM0Msc0NBQXNDLEVBQUUsOENBQWdDO0lBQ3hFLDBDQUEwQyxFQUN0Qyw2Q0FBdUM7SUFDM0MsdURBQXVELEVBQ25ELDZDQUFtQztJQUN2QywwQ0FBMEMsRUFDdEMsNENBQWtDO0lBQ3RDLGdDQUFnQyxFQUFFLHFDQUEyQjtDQUNoRSxDQUFDO0FBRUYsa0JBQWUsUUFBUSxDQUFDIn0=
@@ -59,7 +59,9 @@ const isParameterNameIncludedInAPathPart = (paramName, pathPartsToCheck) => {
59
59
  pathPart === `':${paramName}'` ||
60
60
  pathPart.includes(`/:${paramName}/`) ||
61
61
  pathPart.includes(`/:${paramName}"`) ||
62
- pathPart.includes(`":${paramName}/`));
62
+ pathPart.includes(`":${paramName}/`) ||
63
+ pathPart.includes(`/:${paramName}'`) ||
64
+ pathPart.includes(`':${paramName}/`));
63
65
  });
64
66
  };
65
67
  exports.isParameterNameIncludedInAPathPart = isParameterNameIncludedInAPathPart;
@@ -161,4 +163,4 @@ const rule = (0, createRule_1.createRule)({
161
163
  },
162
164
  });
163
165
  exports.default = rule;
164
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvcGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0vcGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsdURBQWtEO0FBT2xELE1BQU0sK0JBQStCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDNUMsS0FBSztJQUNMLE1BQU07SUFDTixLQUFLO0lBQ0wsUUFBUTtJQUNSLE9BQU87SUFDUCxTQUFTO0lBQ1QsTUFBTTtJQUNOLEtBQUs7Q0FDUixDQUFDLENBQUM7QUFFSSxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQTZCLEVBQVksRUFBRTs7SUFDdEUsTUFBTSxpQkFBaUIsR0FBRyxNQUFDLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxVQUFzQywwQ0FDdEUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRW5CLElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssU0FBUyxFQUFFO1FBQ3ZDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUNsQztJQUNELElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssaUJBQWlCLEVBQUU7UUFDL0MsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUNqQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUUsQ0FBc0IsQ0FBQyxHQUFHLENBQ3JDLENBQUM7S0FDTDtJQUNELElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssa0JBQWtCLEVBQUU7UUFDaEQsT0FBTyxpQkFBaUIsQ0FBQyxVQUFV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
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvcGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0vcGFyYW1EZWNvcmF0b3JOYW1lTWF0Y2hlc1JvdXRlUGFyYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsdURBQWtEO0FBT2xELE1BQU0sK0JBQStCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDNUMsS0FBSztJQUNMLE1BQU07SUFDTixLQUFLO0lBQ0wsUUFBUTtJQUNSLE9BQU87SUFDUCxTQUFTO0lBQ1QsTUFBTTtJQUNOLEtBQUs7Q0FDUixDQUFDLENBQUM7QUFFSSxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQTZCLEVBQVksRUFBRTs7SUFDdEUsTUFBTSxpQkFBaUIsR0FBRyxNQUFDLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxVQUFzQywwQ0FDdEUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRW5CLElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssU0FBUyxFQUFFO1FBQ3ZDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUNsQztJQUNELElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssaUJBQWlCLEVBQUU7UUFDL0MsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUNqQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUUsQ0FBc0IsQ0FBQyxHQUFHLENBQ3JDLENBQUM7S0FDTDtJQUNELElBQUksQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxJQUFJLE1BQUssa0JBQWtCLEVBQUU7UUFDaEQsT0FBTyxpQkFBaUIsQ0FBQyxVQUFV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
@@ -39,15 +39,26 @@ const rule = (0, createRule_1.createRule)({
39
39
  return {
40
40
  // eslint-disable-next-line @typescript-eslint/naming-convention
41
41
  PropertyDefinition(node) {
42
- var _a, _b, _c, _d, _e, _f;
42
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
43
43
  // if it's an array get the element type
44
44
  let mainType;
45
45
  const isAnArray = typedTokenHelpers_1.typedTokenHelpers.isTypeArrayTypeOrUnionOfArrayTypes(node, parserServices, typeChecker);
46
+ // this is getting very messy
46
47
  if (isAnArray) {
47
- mainType = (_b = (_a = node.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation) === null || _b === void 0 ? void 0 : _b.elementType.type;
48
+ const mainTypeInShortArray = (_c = (_b = (_a = node.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation) === null || _b === void 0 ? void 0 : _b.elementType) === null || _c === void 0 ? void 0 : _c.type;
49
+ if (!mainTypeInShortArray) {
50
+ // try to get the type of Array<type> syntax
51
+ const foundParams = (_f = (_e = (_d = node.typeAnnotation) === null || _d === void 0 ? void 0 : _d.typeAnnotation) === null || _e === void 0 ? void 0 : _e.typeParameters) === null || _f === void 0 ? void 0 : _f.params;
52
+ if (foundParams && foundParams.length === 1) {
53
+ mainType = foundParams[0].type;
54
+ }
55
+ }
56
+ else {
57
+ mainType = mainTypeInShortArray;
58
+ }
48
59
  }
49
60
  else {
50
- mainType = (_d = (_c = node.typeAnnotation) === null || _c === void 0 ? void 0 : _c.typeAnnotation) === null || _d === void 0 ? void 0 : _d.type;
61
+ mainType = (_h = (_g = node.typeAnnotation) === null || _g === void 0 ? void 0 : _g.typeAnnotation) === null || _h === void 0 ? void 0 : _h.type;
51
62
  }
52
63
  // if this couldn't be found we don't understand the AST
53
64
  if (!mainType) {
@@ -60,7 +71,7 @@ const rule = (0, createRule_1.createRule)({
60
71
  }
61
72
  // property is a union with primitive type - no need to validate
62
73
  const isNodeAUnionWithAPrimitive = mainType === types_1.AST_NODE_TYPES.TSUnionType &&
63
- ((_f = ((_e = node.typeAnnotation) === null || _e === void 0 ? void 0 : _e.typeAnnotation).types) === null || _f === void 0 ? void 0 : _f.some((x) => primitiveTypes.has(x.type)));
74
+ ((_k = ((_j = node.typeAnnotation) === null || _j === void 0 ? void 0 : _j.typeAnnotation).types) === null || _k === void 0 ? void 0 : _k.some((x) => primitiveTypes.has(x.type)));
64
75
  if (isNodeAUnionWithAPrimitive) {
65
76
  return;
66
77
  }
@@ -92,4 +103,4 @@ const rule = (0, createRule_1.createRule)({
92
103
  },
93
104
  });
94
105
  exports.default = rule;
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGVOb25QcmltaXRpdmVOZWVkc0RlY29yYXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvdmFsaWRhdGUtbm9uLXByaW1pdHZlcy1uZWVkcy10eXBlLWRlY29yYXRvci92YWxpZGF0ZU5vblByaW1pdGl2ZU5lZWRzRGVjb3JhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxrREFBa0Q7QUFDbEQsb0RBQWtFO0FBQ2xFLHVEQUFrRDtBQUNsRCxxRUFBZ0U7QUFDaEUsMEZBQTBGO0FBQzFGLG1GQUE4RTtBQUM5RSwwQkFBMEI7QUFFMUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDM0Isc0JBQWMsQ0FBQyxlQUFlO0lBQzlCLHNCQUFjLENBQUMsZ0JBQWdCO0lBQy9CLHNCQUFjLENBQUMsZUFBZTtDQUNqQyxDQUFDLENBQUM7QUFDSSxNQUFNLGFBQWEsR0FBRyxHQUFZLEVBQUU7SUFDdkMsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRlcsUUFBQSxhQUFhLGlCQUV4QjtBQUVGLE1BQU0sSUFBSSxHQUFHLElBQUEsdUJBQVUsRUFBQztJQUNwQixJQUFJLEVBQUUsdURBQXVEO0lBQzdELElBQUksRUFBRTtRQUNGLElBQUksRUFBRTtZQUNGLFdBQVcsRUFDUCwrRUFBK0U7WUFDbkYsV0FBVyxFQUFFLEtBQUs7WUFDbEIsb0JBQW9CLEVBQUUsS0FBSztTQUM5QjtRQUNELFFBQVEsRUFBRTtZQUNOLHNCQUFzQixFQUNsQiwrRUFBK0U7U0FDdEY7UUFDRCxNQUFNLEVBQUUsRUFBRTtRQUNWLGNBQWMsRUFBRSxLQUFLO1FBQ3JCLElBQUksRUFBRSxZQUFZO0tBQ3JCO0lBQ0QsY0FBYyxFQUFFLEVBQUU7SUFFbEIsTUFBTSxDQUFDLE9BQU87UUFDVixNQUFNLGNBQWMsR0FBRyxJQUFBLGdDQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELE1BQU0sV0FB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
106
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGVOb25QcmltaXRpdmVOZWVkc0RlY29yYXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvdmFsaWRhdGUtbm9uLXByaW1pdHZlcy1uZWVkcy10eXBlLWRlY29yYXRvci92YWxpZGF0ZU5vblByaW1pdGl2ZU5lZWRzRGVjb3JhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxrREFBa0Q7QUFDbEQsb0RBQWtFO0FBQ2xFLHVEQUFrRDtBQUNsRCxxRUFBZ0U7QUFDaEUsMEZBQTBGO0FBQzFGLG1GQUE4RTtBQUM5RSwwQkFBMEI7QUFFMUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDM0Isc0JBQWMsQ0FBQyxlQUFlO0lBQzlCLHNCQUFjLENBQUMsZ0JBQWdCO0lBQy9CLHNCQUFjLENBQUMsZUFBZTtDQUNqQyxDQUFDLENBQUM7QUFDSSxNQUFNLGFBQWEsR0FBRyxHQUFZLEVBQUU7SUFDdkMsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRlcsUUFBQSxhQUFhLGlCQUV4QjtBQUVGLE1BQU0sSUFBSSxHQUFHLElBQUEsdUJBQVUsRUFBQztJQUNwQixJQUFJLEVBQUUsdURBQXVEO0lBQzdELElBQUksRUFBRTtRQUNGLElBQUksRUFBRTtZQUNGLFdBQVcsRUFDUCwrRUFBK0U7WUFDbkYsV0FBVyxFQUFFLEtBQUs7WUFDbEIsb0JBQW9CLEVBQUUsS0FBSztTQUM5QjtRQUNELFFBQVEsRUFBRTtZQUNOLHNCQUFzQixFQUNsQiwrRUFBK0U7U0FDdEY7UUFDRCxNQUFNLEVBQUUsRUFBRTtRQUNWLGNBQWMsRUFBRSxLQUFLO1FBQ3JCLElBQUksRUFBRSxZQUFZO0tBQ3JCO0lBQ0QsY0FBYyxFQUFFLEVBQUU7SUFFbEIsTUFBTSxDQUFDLE9BQU87UUFDVixNQUFNLGNBQWMsR0FBRyxJQUFBLGdDQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELE1BQU0sV0FB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darraghor/eslint-plugin-nestjs-typed",
3
- "version": "3.6.0",
3
+ "version": "3.8.1",
4
4
  "description": "Eslint rules for nestjs projects",
5
5
  "scripts": {
6
6
  "clean": "rm -Rf ./dist/",
@@ -55,6 +55,7 @@
55
55
  "@types/node": "16.11.11",
56
56
  "@typescript-eslint/eslint-plugin": "5.5.0",
57
57
  "@typescript-eslint/parser": "5.5.0",
58
+ "class-validator": "^0.13.2",
58
59
  "eslint": "8.3.0",
59
60
  "eslint-config-prettier": "8.3.0",
60
61
  "eslint-plugin-import": "2.25.3",
@@ -73,6 +74,7 @@
73
74
  },
74
75
  "peerDependencies": {
75
76
  "@typescript-eslint/parser": "^5.0.0",
77
+ "class-validator": "*",
76
78
  "eslint": "^8.0.0"
77
79
  },
78
80
  "keywords": [