eslint-cdk-plugin 3.0.3 → 3.2.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 +16 -11
- package/dist/index.cjs +223 -31
- package/dist/index.d.ts +13 -77
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +223 -31
- package/package.json +2 -4
- package/src/index.ts +17 -2
- package/src/rules/construct-constructor-property.ts +36 -17
- package/src/rules/no-construct-in-public-property-of-construct.ts +2 -5
- package/src/rules/no-construct-stack-suffix.ts +1 -1
- package/src/rules/no-unused-props.ts +176 -0
- package/src/rules/no-variable-construct-id.ts +1 -1
- package/src/rules/pascal-case-construct-id.ts +1 -1
- package/src/rules/props-name-convention.ts +5 -11
- package/src/rules/require-jsdoc.ts +9 -6
- package/src/rules/require-passing-this.ts +1 -1
- package/src/rules/require-props-default-doc.ts +6 -14
- package/src/utils/getConstructor.ts +16 -0
- package/src/utils/{parseType.ts → getPropertyNames.ts} +20 -0
- package/src/utils/propsUsageTracker.ts +188 -0
- package/src/utils/typeCheck.ts +1 -1
package/README.md
CHANGED
|
@@ -35,29 +35,34 @@ Note: This plugin uses typescript type information and must be used in conjuncti
|
|
|
35
35
|
|
|
36
36
|
```js
|
|
37
37
|
// eslint.config.mjs
|
|
38
|
+
import eslint from "@eslint/js";
|
|
39
|
+
import { defineConfig } from "eslint/config";
|
|
40
|
+
import tseslint from "typescript-eslint";
|
|
38
41
|
import cdkPlugin from "eslint-cdk-plugin";
|
|
39
|
-
import tsEslint from "typescript-eslint";
|
|
40
42
|
|
|
41
|
-
export default [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
cdkPlugin.configs.recommended,
|
|
43
|
+
export default defineConfig([
|
|
44
|
+
eslint.configs.recommended,
|
|
45
|
+
...tseslint.configs.recommended,
|
|
45
46
|
{
|
|
46
47
|
files: ["lib/**/*.ts", "bin/*.ts"],
|
|
47
|
-
//
|
|
48
|
+
// ✅ Add plugins
|
|
49
|
+
extends: [cdkPlugin.configs.recommended],
|
|
48
50
|
},
|
|
49
|
-
];
|
|
51
|
+
]);
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
### When using custom config
|
|
53
55
|
|
|
54
56
|
```js
|
|
55
57
|
// eslint.config.mjs
|
|
56
|
-
import
|
|
58
|
+
import eslint from "@eslint/js";
|
|
59
|
+
import { defineConfig } from "eslint/config";
|
|
60
|
+
import tseslint from "typescript-eslint";
|
|
57
61
|
import cdkPlugin from "eslint-cdk-plugin";
|
|
58
62
|
|
|
59
|
-
export default [
|
|
60
|
-
|
|
63
|
+
export default defineConfig([
|
|
64
|
+
eslint.configs.recommended,
|
|
65
|
+
...tseslint.configs.recommended,
|
|
61
66
|
{
|
|
62
67
|
files: ["lib/**/*.ts", "bin/*.ts"],
|
|
63
68
|
languageOptions: {
|
|
@@ -77,7 +82,7 @@ export default [
|
|
|
77
82
|
"cdk/no-parent-name-construct-id-match": "error",
|
|
78
83
|
},
|
|
79
84
|
},
|
|
80
|
-
];
|
|
85
|
+
]);
|
|
81
86
|
```
|
|
82
87
|
|
|
83
88
|
## ❗ Issue
|
package/dist/index.cjs
CHANGED
|
@@ -26,12 +26,18 @@ function _interopNamespaceDefault(e) {
|
|
|
26
26
|
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
27
27
|
|
|
28
28
|
var name = "eslint-cdk-plugin";
|
|
29
|
-
var version = "3.0
|
|
29
|
+
var version = "3.2.0";
|
|
30
30
|
|
|
31
31
|
const createRule = utils.ESLintUtils.RuleCreator(
|
|
32
32
|
(name) => `https://eslint-cdk-plugin.dev/rules/${name}`
|
|
33
33
|
);
|
|
34
34
|
|
|
35
|
+
const getConstructor = (node) => {
|
|
36
|
+
return node.body.body.find(
|
|
37
|
+
(member) => member.type === utils.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
35
41
|
const isConstructOrStackType = (type, ignoredClasses = ["App", "Stage"]) => {
|
|
36
42
|
if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
|
|
37
43
|
return isTargetSuperClassType(
|
|
@@ -46,7 +52,7 @@ const isConstructType = (type, ignoredClasses = ["App", "Stage", "Stack"]) => {
|
|
|
46
52
|
};
|
|
47
53
|
const isTargetSuperClassType = (type, targetSuperClasses, typeCheckFunction) => {
|
|
48
54
|
if (!type.symbol) return false;
|
|
49
|
-
if (targetSuperClasses.some((suffix) => type.symbol.name
|
|
55
|
+
if (targetSuperClasses.some((suffix) => type.symbol.name === suffix)) {
|
|
50
56
|
return true;
|
|
51
57
|
}
|
|
52
58
|
const baseTypes = type.getBaseTypes() ?? [];
|
|
@@ -61,7 +67,9 @@ const constructConstructorProperty = createRule({
|
|
|
61
67
|
description: "Enforces that constructors of classes extending Construct have the property names 'scope, id' or 'scope, id, props'"
|
|
62
68
|
},
|
|
63
69
|
messages: {
|
|
64
|
-
invalidConstructorProperty: "Constructor of a class extending Construct must have the property names 'scope, id' or 'scope, id, props'"
|
|
70
|
+
invalidConstructorProperty: "Constructor of a class extending Construct must have the property names 'scope, id' or 'scope, id, props'",
|
|
71
|
+
invalidConstructorType: "Constructor of a class extending Construct must have the type 'Construct' for the first parameter",
|
|
72
|
+
invalidConstructorIdType: "Constructor of a class extending Construct must have the type 'string' for the second parameter"
|
|
65
73
|
},
|
|
66
74
|
schema: []
|
|
67
75
|
},
|
|
@@ -72,16 +80,14 @@ const constructConstructorProperty = createRule({
|
|
|
72
80
|
ClassDeclaration(node) {
|
|
73
81
|
const type = parserServices.getTypeAtLocation(node);
|
|
74
82
|
if (!isConstructType(type)) return;
|
|
75
|
-
const constructor = node
|
|
76
|
-
(member) => member.type === utils.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
|
|
77
|
-
);
|
|
83
|
+
const constructor = getConstructor(node);
|
|
78
84
|
if (!constructor) return;
|
|
79
|
-
validateConstructorProperty(constructor, context);
|
|
85
|
+
validateConstructorProperty(constructor, context, parserServices);
|
|
80
86
|
}
|
|
81
87
|
};
|
|
82
88
|
}
|
|
83
89
|
});
|
|
84
|
-
const validateConstructorProperty = (constructor, context) => {
|
|
90
|
+
const validateConstructorProperty = (constructor, context, parserServices) => {
|
|
85
91
|
const params = constructor.value.params;
|
|
86
92
|
if (params.length < 2) {
|
|
87
93
|
context.report({
|
|
@@ -91,24 +97,35 @@ const validateConstructorProperty = (constructor, context) => {
|
|
|
91
97
|
return;
|
|
92
98
|
}
|
|
93
99
|
const firstParam = params[0];
|
|
94
|
-
if (firstParam.type
|
|
100
|
+
if (firstParam.type !== utils.AST_NODE_TYPES.Identifier || firstParam.name !== "scope") {
|
|
95
101
|
context.report({
|
|
96
102
|
node: firstParam,
|
|
97
103
|
messageId: "invalidConstructorProperty"
|
|
98
104
|
});
|
|
99
|
-
|
|
105
|
+
} else if (!isConstructType(parserServices.getTypeAtLocation(firstParam))) {
|
|
106
|
+
context.report({
|
|
107
|
+
node: firstParam,
|
|
108
|
+
messageId: "invalidConstructorType"
|
|
109
|
+
});
|
|
100
110
|
}
|
|
101
111
|
const secondParam = params[1];
|
|
102
|
-
if (secondParam.type
|
|
112
|
+
if (secondParam.type !== utils.AST_NODE_TYPES.Identifier || secondParam.name !== "id") {
|
|
103
113
|
context.report({
|
|
104
114
|
node: secondParam,
|
|
105
115
|
messageId: "invalidConstructorProperty"
|
|
106
116
|
});
|
|
107
117
|
return;
|
|
118
|
+
} else if (secondParam.typeAnnotation?.typeAnnotation.type !== utils.AST_NODE_TYPES.TSStringKeyword) {
|
|
119
|
+
context.report({
|
|
120
|
+
node: secondParam,
|
|
121
|
+
messageId: "invalidConstructorIdType"
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
108
124
|
}
|
|
109
|
-
if (params.length < 3)
|
|
125
|
+
if (params.length < 3)
|
|
126
|
+
return;
|
|
110
127
|
const thirdParam = params[2];
|
|
111
|
-
if (thirdParam.type
|
|
128
|
+
if (thirdParam.type !== utils.AST_NODE_TYPES.Identifier || thirdParam.name !== "props") {
|
|
112
129
|
context.report({
|
|
113
130
|
node: thirdParam,
|
|
114
131
|
messageId: "invalidConstructorProperty"
|
|
@@ -184,9 +201,7 @@ const noConstructInPublicPropertyOfConstruct = createRule({
|
|
|
184
201
|
const type = parserServices.getTypeAtLocation(node);
|
|
185
202
|
if (!isConstructOrStackType(type)) return;
|
|
186
203
|
validatePublicPropertyOfConstruct(node, context, parserServices);
|
|
187
|
-
const constructor = node
|
|
188
|
-
(member) => member.type === utils.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
|
|
189
|
-
);
|
|
204
|
+
const constructor = getConstructor(node);
|
|
190
205
|
if (!constructor || constructor.value.type !== utils.AST_NODE_TYPES.FunctionExpression) {
|
|
191
206
|
return;
|
|
192
207
|
}
|
|
@@ -254,6 +269,12 @@ const toPascalCase = (str) => {
|
|
|
254
269
|
}).join("");
|
|
255
270
|
};
|
|
256
271
|
|
|
272
|
+
const getPropertyNames = (properties) => {
|
|
273
|
+
return properties.reduce(
|
|
274
|
+
(acc, prop) => prop.type === utils.AST_NODE_TYPES.Property && prop.key.type === utils.AST_NODE_TYPES.Identifier ? [...acc, prop.key.name] : acc,
|
|
275
|
+
[]
|
|
276
|
+
);
|
|
277
|
+
};
|
|
257
278
|
const getConstructorPropertyNames = (type) => {
|
|
258
279
|
const declarations = type.symbol?.declarations;
|
|
259
280
|
if (!declarations?.length) return [];
|
|
@@ -775,6 +796,176 @@ const validateConstructId$2 = ({
|
|
|
775
796
|
}
|
|
776
797
|
};
|
|
777
798
|
|
|
799
|
+
const propsUsageTrackerFactory = (propsType) => {
|
|
800
|
+
const getPropsPropertyNames = (propsType2) => {
|
|
801
|
+
const typeProperties = propsType2.getProperties();
|
|
802
|
+
if (typeProperties.length) {
|
|
803
|
+
return typeProperties.reduce(
|
|
804
|
+
(acc, prop) => !isInternalProperty(prop.name) ? [...acc, prop.name] : acc,
|
|
805
|
+
[]
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
const symbol = propsType2.getSymbol();
|
|
809
|
+
if (!symbol?.members) return [];
|
|
810
|
+
return Array.from(symbol.members.keys()).reduce((acc, key) => {
|
|
811
|
+
const name = String(key);
|
|
812
|
+
return !isInternalProperty(name) ? [...acc, name] : acc;
|
|
813
|
+
}, []);
|
|
814
|
+
};
|
|
815
|
+
const isInternalProperty = (propertyName) => {
|
|
816
|
+
return propertyName.startsWith("_") || propertyName === "constructor" || propertyName === "prototype";
|
|
817
|
+
};
|
|
818
|
+
const markAsUsed = (propertyName) => {
|
|
819
|
+
if (propUsages.has(propertyName)) propUsages.set(propertyName, true);
|
|
820
|
+
};
|
|
821
|
+
const propUsages = new Map(
|
|
822
|
+
getPropsPropertyNames(propsType).map((name) => [name, false])
|
|
823
|
+
);
|
|
824
|
+
const getUnusedProperties = () => {
|
|
825
|
+
return Array.from(propUsages.entries()).reduce(
|
|
826
|
+
(acc, [name, used]) => !used ? [...acc, name] : acc,
|
|
827
|
+
[]
|
|
828
|
+
);
|
|
829
|
+
};
|
|
830
|
+
const markAsUsedForMemberExpression = (node, propsParamName) => {
|
|
831
|
+
if (node.object.type === utils.AST_NODE_TYPES.Identifier && node.object.name === propsParamName && node.property.type === utils.AST_NODE_TYPES.Identifier) {
|
|
832
|
+
markAsUsed(node.property.name);
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
if (node.object.type === utils.AST_NODE_TYPES.MemberExpression && node.object.object.type === utils.AST_NODE_TYPES.ThisExpression && node.object.property.type === utils.AST_NODE_TYPES.Identifier && node.object.property.name === "props" && node.property.type === utils.AST_NODE_TYPES.Identifier) {
|
|
836
|
+
markAsUsed(node.property.name);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
const markAsUsedForVariableDeclarator = (node, propsParamName) => {
|
|
841
|
+
if (node.id.type !== utils.AST_NODE_TYPES.ObjectPattern || node.init?.type !== utils.AST_NODE_TYPES.Identifier || node.init.name !== propsParamName) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
const propertyNames = getPropertyNames(node.id.properties);
|
|
845
|
+
for (const name of propertyNames) {
|
|
846
|
+
markAsUsed(name);
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
const markAsUsedForAssignmentExpression = (node, propsParamName) => {
|
|
850
|
+
if (node.right.type !== utils.AST_NODE_TYPES.MemberExpression || node.right.object.type !== utils.AST_NODE_TYPES.Identifier || node.right.object.name !== propsParamName || node.right.property.type !== utils.AST_NODE_TYPES.Identifier) {
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
markAsUsed(node.right.property.name);
|
|
854
|
+
};
|
|
855
|
+
const markAsUsedForObjectPattern = (node) => {
|
|
856
|
+
for (const propName of getPropertyNames(node.properties)) {
|
|
857
|
+
markAsUsed(propName);
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
if (!propUsages.size) return null;
|
|
861
|
+
return {
|
|
862
|
+
getUnusedProperties,
|
|
863
|
+
markAsUsedForMemberExpression,
|
|
864
|
+
markAsUsedForVariableDeclarator,
|
|
865
|
+
markAsUsedForAssignmentExpression,
|
|
866
|
+
markAsUsedForObjectPattern
|
|
867
|
+
};
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
const noUnusedProps = createRule({
|
|
871
|
+
name: "no-unused-props",
|
|
872
|
+
meta: {
|
|
873
|
+
type: "suggestion",
|
|
874
|
+
docs: {
|
|
875
|
+
description: "Enforces that all properties defined in props type are used within the constructor"
|
|
876
|
+
},
|
|
877
|
+
messages: {
|
|
878
|
+
unusedProp: "Property '{{propName}}' is defined in props but never used"
|
|
879
|
+
},
|
|
880
|
+
schema: []
|
|
881
|
+
},
|
|
882
|
+
defaultOptions: [],
|
|
883
|
+
create(context) {
|
|
884
|
+
const parserServices = utils.ESLintUtils.getParserServices(context);
|
|
885
|
+
return {
|
|
886
|
+
ClassDeclaration(node) {
|
|
887
|
+
const type = parserServices.getTypeAtLocation(node);
|
|
888
|
+
if (!isConstructType(type)) return;
|
|
889
|
+
const constructor = getConstructor(node);
|
|
890
|
+
if (!constructor) return;
|
|
891
|
+
analyzePropsUsage(constructor, context, parserServices);
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
const analyzePropsUsage = (constructor, context, parserServices) => {
|
|
897
|
+
const params = constructor.value.params;
|
|
898
|
+
if (params.length < 3) return;
|
|
899
|
+
const propsParam = params[2];
|
|
900
|
+
switch (propsParam.type) {
|
|
901
|
+
case utils.AST_NODE_TYPES.Identifier: {
|
|
902
|
+
const propsType = parserServices.getTypeAtLocation(propsParam);
|
|
903
|
+
const tracker = propsUsageTrackerFactory(propsType);
|
|
904
|
+
if (!tracker || !constructor.value.body) return;
|
|
905
|
+
analyzeConstructorBody(constructor.value.body, propsParam.name, tracker);
|
|
906
|
+
reportUnusedProperties(tracker, propsParam, context);
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
case utils.AST_NODE_TYPES.ObjectPattern: {
|
|
910
|
+
const typeAnnotation = propsParam.typeAnnotation?.typeAnnotation;
|
|
911
|
+
if (!typeAnnotation) return;
|
|
912
|
+
const propsType = parserServices.getTypeAtLocation(typeAnnotation);
|
|
913
|
+
const tracker = propsUsageTrackerFactory(propsType);
|
|
914
|
+
if (!tracker) return;
|
|
915
|
+
tracker.markAsUsedForObjectPattern(propsParam);
|
|
916
|
+
reportUnusedProperties(tracker, propsParam, context);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
default:
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
const analyzeConstructorBody = (body, propsParamName, tracker) => {
|
|
924
|
+
const visited = /* @__PURE__ */ new Set();
|
|
925
|
+
const visitNode = (node) => {
|
|
926
|
+
if (visited.has(node)) return;
|
|
927
|
+
visited.add(node);
|
|
928
|
+
switch (node.type) {
|
|
929
|
+
case utils.AST_NODE_TYPES.MemberExpression:
|
|
930
|
+
tracker.markAsUsedForMemberExpression(node, propsParamName);
|
|
931
|
+
break;
|
|
932
|
+
case utils.AST_NODE_TYPES.VariableDeclarator:
|
|
933
|
+
tracker.markAsUsedForVariableDeclarator(node, propsParamName);
|
|
934
|
+
break;
|
|
935
|
+
case utils.AST_NODE_TYPES.AssignmentExpression:
|
|
936
|
+
tracker.markAsUsedForAssignmentExpression(node, propsParamName);
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
939
|
+
const children = getChildNodes(node);
|
|
940
|
+
for (const child of children) {
|
|
941
|
+
visitNode(child);
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
visitNode(body);
|
|
945
|
+
};
|
|
946
|
+
const reportUnusedProperties = (tracker, propsParam, context) => {
|
|
947
|
+
for (const propName of tracker.getUnusedProperties()) {
|
|
948
|
+
context.report({
|
|
949
|
+
node: propsParam,
|
|
950
|
+
messageId: "unusedProp",
|
|
951
|
+
data: {
|
|
952
|
+
propName
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
const getChildNodes = (node) => {
|
|
958
|
+
return Object.entries(node).reduce((acc, [key, value]) => {
|
|
959
|
+
if (["parent", "range", "loc"].includes(key)) return acc;
|
|
960
|
+
if (isESTreeNode(value)) return [...acc, value];
|
|
961
|
+
if (Array.isArray(value)) return [...acc, ...value.filter(isESTreeNode)];
|
|
962
|
+
return acc;
|
|
963
|
+
}, []);
|
|
964
|
+
};
|
|
965
|
+
const isESTreeNode = (value) => {
|
|
966
|
+
return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
|
|
967
|
+
};
|
|
968
|
+
|
|
778
969
|
const noVariableConstructId = createRule({
|
|
779
970
|
name: "no-variable-construct-id",
|
|
780
971
|
meta: {
|
|
@@ -911,10 +1102,9 @@ const propsNameConvention = createRule({
|
|
|
911
1102
|
if (!node.id || !node.superClass) return;
|
|
912
1103
|
const type = parserServices.getTypeAtLocation(node.superClass);
|
|
913
1104
|
if (!isConstructType(type)) return;
|
|
914
|
-
const constructor = node
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
const propsParam = constructor?.value.params?.[2];
|
|
1105
|
+
const constructor = getConstructor(node);
|
|
1106
|
+
if (!constructor) return;
|
|
1107
|
+
const propsParam = constructor.value.params?.[2];
|
|
918
1108
|
if (propsParam?.type !== utils.AST_NODE_TYPES.Identifier) return;
|
|
919
1109
|
const typeAnnotation = propsParam.typeAnnotation;
|
|
920
1110
|
if (typeAnnotation?.type !== utils.AST_NODE_TYPES.TSTypeAnnotation) return;
|
|
@@ -956,9 +1146,10 @@ const requireJSDoc = createRule({
|
|
|
956
1146
|
const parserServices = utils.ESLintUtils.getParserServices(context);
|
|
957
1147
|
return {
|
|
958
1148
|
TSPropertySignature(node) {
|
|
959
|
-
if (node.key.type !== utils.AST_NODE_TYPES.Identifier
|
|
960
|
-
|
|
961
|
-
|
|
1149
|
+
if (node.key.type !== utils.AST_NODE_TYPES.Identifier) return;
|
|
1150
|
+
const parent = node.parent.parent;
|
|
1151
|
+
if (parent.type !== utils.AST_NODE_TYPES.TSInterfaceDeclaration) return;
|
|
1152
|
+
if (!parent.id.name.endsWith("Props")) return;
|
|
962
1153
|
const sourceCode = context.sourceCode;
|
|
963
1154
|
const comments = sourceCode.getCommentsBefore(node);
|
|
964
1155
|
const hasJSDoc = comments.some(
|
|
@@ -1087,14 +1278,11 @@ const requirePropsDefaultDoc = createRule({
|
|
|
1087
1278
|
create(context) {
|
|
1088
1279
|
return {
|
|
1089
1280
|
TSPropertySignature(node) {
|
|
1281
|
+
if (node.key.type !== utils.AST_NODE_TYPES.Identifier) return;
|
|
1090
1282
|
if (!node.optional) return;
|
|
1091
|
-
const parent = node.parent
|
|
1092
|
-
if (parent
|
|
1093
|
-
|
|
1094
|
-
}
|
|
1095
|
-
if (parent.id.type !== utils.AST_NODE_TYPES.Identifier || !parent.id.name.endsWith("Props")) {
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1283
|
+
const parent = node.parent.parent;
|
|
1284
|
+
if (parent.type !== utils.AST_NODE_TYPES.TSInterfaceDeclaration) return;
|
|
1285
|
+
if (!parent.id.name.endsWith("Props")) return;
|
|
1098
1286
|
const sourceCode = context.sourceCode;
|
|
1099
1287
|
const comments = sourceCode.getCommentsBefore(node);
|
|
1100
1288
|
const hasDefaultDoc = comments.some(
|
|
@@ -1105,7 +1293,7 @@ const requirePropsDefaultDoc = createRule({
|
|
|
1105
1293
|
node,
|
|
1106
1294
|
messageId: "missingDefaultDoc",
|
|
1107
1295
|
data: {
|
|
1108
|
-
propertyName: node.key.
|
|
1296
|
+
propertyName: node.key.name
|
|
1109
1297
|
}
|
|
1110
1298
|
});
|
|
1111
1299
|
}
|
|
@@ -1123,6 +1311,7 @@ const rules = {
|
|
|
1123
1311
|
"no-mutable-property-of-props-interface": noMutablePropertyOfPropsInterface,
|
|
1124
1312
|
"no-mutable-public-property-of-construct": noMutablePublicPropertyOfConstruct,
|
|
1125
1313
|
"no-parent-name-construct-id-match": noParentNameConstructIdMatch,
|
|
1314
|
+
"no-unused-props": noUnusedProps,
|
|
1126
1315
|
"no-variable-construct-id": noVariableConstructId,
|
|
1127
1316
|
"pascal-case-construct-id": pascalCaseConstructId,
|
|
1128
1317
|
"props-name-convention": propsNameConvention,
|
|
@@ -1159,6 +1348,8 @@ const recommended = createFlatConfig({
|
|
|
1159
1348
|
"error",
|
|
1160
1349
|
{ disallowContainingParentName: false }
|
|
1161
1350
|
],
|
|
1351
|
+
// TODO: Enable this rule at v4.0.0
|
|
1352
|
+
// "cdk/no-unused-props": "error",
|
|
1162
1353
|
"cdk/no-variable-construct-id": "error",
|
|
1163
1354
|
"cdk/pascal-case-construct-id": "error",
|
|
1164
1355
|
"cdk/require-passing-this": ["error", { allowNonThisAndDisallowScope: true }]
|
|
@@ -1175,6 +1366,7 @@ const strict = createFlatConfig({
|
|
|
1175
1366
|
"error",
|
|
1176
1367
|
{ disallowContainingParentName: true }
|
|
1177
1368
|
],
|
|
1369
|
+
"cdk/no-unused-props": "error",
|
|
1178
1370
|
"cdk/no-variable-construct-id": "error",
|
|
1179
1371
|
"cdk/pascal-case-construct-id": "error",
|
|
1180
1372
|
"cdk/props-name-convention": "error",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FlatConfig } from "@typescript-eslint/utils/ts-eslint";
|
|
2
2
|
declare const rules: {
|
|
3
|
-
"construct-constructor-property": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructorProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
3
|
+
"construct-constructor-property": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructorProperty" | "invalidConstructorType" | "invalidConstructorIdType", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
4
|
"no-construct-in-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidInterfaceProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
5
|
"no-construct-in-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
6
6
|
"no-construct-stack-suffix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
@@ -12,6 +12,7 @@ declare const rules: {
|
|
|
12
12
|
"no-parent-name-construct-id-match": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
13
13
|
disallowContainingParentName?: boolean;
|
|
14
14
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
15
|
+
"no-unused-props": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unusedProp", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
15
16
|
"no-variable-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
16
17
|
"pascal-case-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
17
18
|
"props-name-convention": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropsName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
@@ -23,88 +24,23 @@ declare const rules: {
|
|
|
23
24
|
};
|
|
24
25
|
declare const configs: {
|
|
25
26
|
recommended: {
|
|
26
|
-
languageOptions:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
projectService: boolean;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
plugins: {
|
|
33
|
-
cdk: {
|
|
34
|
-
meta: {
|
|
35
|
-
name: string;
|
|
36
|
-
version: string;
|
|
37
|
-
};
|
|
38
|
-
rules: {
|
|
39
|
-
"construct-constructor-property": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructorProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
40
|
-
"no-construct-in-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidInterfaceProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
41
|
-
"no-construct-in-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
42
|
-
"no-construct-stack-suffix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
43
|
-
disallowedSuffixes: ("Construct" | "Stack")[];
|
|
44
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
45
|
-
"no-import-private": import("eslint").Rule.RuleModule;
|
|
46
|
-
"no-mutable-property-of-props-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropertyOfPropsInterface", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
47
|
-
"no-mutable-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
48
|
-
"no-parent-name-construct-id-match": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
49
|
-
disallowContainingParentName?: boolean;
|
|
50
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
51
|
-
"no-variable-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
52
|
-
"pascal-case-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
53
|
-
"props-name-convention": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropsName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
54
|
-
"require-jsdoc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingJSDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
55
|
-
"require-passing-this": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingPassingThis", [{
|
|
56
|
-
allowNonThisAndDisallowScope?: boolean;
|
|
57
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
58
|
-
"require-props-default-doc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingDefaultDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
rules: Record<string, unknown>;
|
|
27
|
+
languageOptions: FlatConfig.LanguageOptions;
|
|
28
|
+
plugins: FlatConfig.Plugins;
|
|
29
|
+
rules: FlatConfig.Rules;
|
|
63
30
|
};
|
|
64
31
|
strict: {
|
|
65
|
-
languageOptions:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
projectService: boolean;
|
|
69
|
-
};
|
|
70
|
-
};
|
|
71
|
-
plugins: {
|
|
72
|
-
cdk: {
|
|
73
|
-
meta: {
|
|
74
|
-
name: string;
|
|
75
|
-
version: string;
|
|
76
|
-
};
|
|
77
|
-
rules: {
|
|
78
|
-
"construct-constructor-property": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructorProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
79
|
-
"no-construct-in-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidInterfaceProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
80
|
-
"no-construct-in-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
81
|
-
"no-construct-stack-suffix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
82
|
-
disallowedSuffixes: ("Construct" | "Stack")[];
|
|
83
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
84
|
-
"no-import-private": import("eslint").Rule.RuleModule;
|
|
85
|
-
"no-mutable-property-of-props-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropertyOfPropsInterface", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
86
|
-
"no-mutable-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
87
|
-
"no-parent-name-construct-id-match": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
|
|
88
|
-
disallowContainingParentName?: boolean;
|
|
89
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
90
|
-
"no-variable-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
91
|
-
"pascal-case-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
92
|
-
"props-name-convention": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropsName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
93
|
-
"require-jsdoc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingJSDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
94
|
-
"require-passing-this": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingPassingThis", [{
|
|
95
|
-
allowNonThisAndDisallowScope?: boolean;
|
|
96
|
-
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
97
|
-
"require-props-default-doc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingDefaultDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
rules: Record<string, unknown>;
|
|
32
|
+
languageOptions: FlatConfig.LanguageOptions;
|
|
33
|
+
plugins: FlatConfig.Plugins;
|
|
34
|
+
rules: FlatConfig.Rules;
|
|
102
35
|
};
|
|
103
36
|
};
|
|
104
37
|
export { configs, rules };
|
|
105
38
|
export interface EslintCdkPlugin {
|
|
106
39
|
rules: typeof rules;
|
|
107
|
-
configs:
|
|
40
|
+
configs: Readonly<{
|
|
41
|
+
recommended: FlatConfig.Config;
|
|
42
|
+
strict: FlatConfig.Config;
|
|
43
|
+
}>;
|
|
108
44
|
}
|
|
109
45
|
declare const eslintCdkPlugin: EslintCdkPlugin;
|
|
110
46
|
export default eslintCdkPlugin;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAoBhE,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;CAiBV,CAAC;AAmEF,QAAA,MAAM,OAAO;;yBAzDM,UAAU,CAAC,eAAe;iBAClC,UAAU,CAAC,OAAO;eACpB,UAAU,CAAC,KAAK;;;yBAFN,UAAU,CAAC,eAAe;iBAClC,UAAU,CAAC,OAAO;eACpB,UAAU,CAAC,KAAK;;CA0DxB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,OAAO,EAAE,QAAQ,CAAC;QAChB,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC;QAC/B,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;KAC3B,CAAC,CAAC;CACJ;AAED,QAAA,MAAM,eAAe,EAAE,eAGtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|