eslint-cdk-plugin 1.1.1 → 2.0.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/dist/index.mjs CHANGED
@@ -1,15 +1,103 @@
1
+ import tsParser from '@typescript-eslint/parser';
1
2
  import { ESLintUtils, AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils';
2
3
  import * as path from 'path';
3
4
 
4
- var SymbolFlags = /* @__PURE__ */ ((SymbolFlags2) => {
5
- SymbolFlags2[SymbolFlags2["Class"] = 32] = "Class";
6
- return SymbolFlags2;
7
- })(SymbolFlags || {});
8
- var SyntaxKind = /* @__PURE__ */ ((SyntaxKind2) => {
9
- SyntaxKind2[SyntaxKind2["ClassDeclaration"] = 263] = "ClassDeclaration";
10
- SyntaxKind2[SyntaxKind2["Constructor"] = 176] = "Constructor";
11
- return SyntaxKind2;
12
- })(SyntaxKind || {});
5
+ var name = "eslint-cdk-plugin";
6
+ var version = "2.0.0";
7
+
8
+ const isConstructOrStackType = (type, ignoredClasses = ["App", "Stage"]) => {
9
+ if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
10
+ return isTargetSuperClassType(
11
+ type,
12
+ ["Construct", "Stack"],
13
+ isConstructOrStackType
14
+ );
15
+ };
16
+ const isConstructType = (type, ignoredClasses = ["App", "Stage", "Stack"]) => {
17
+ if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
18
+ return isTargetSuperClassType(type, ["Construct"], isConstructType);
19
+ };
20
+ const isTargetSuperClassType = (type, targetSuperClasses, typeCheckFunction) => {
21
+ if (!type.symbol) return false;
22
+ if (targetSuperClasses.some((suffix) => type.symbol.name.endsWith(suffix))) {
23
+ return true;
24
+ }
25
+ const baseTypes = type.getBaseTypes() ?? [];
26
+ return baseTypes.some((baseType) => typeCheckFunction(baseType));
27
+ };
28
+
29
+ const constructConstructorProperty = ESLintUtils.RuleCreator.withoutDocs(
30
+ {
31
+ meta: {
32
+ type: "problem",
33
+ docs: {
34
+ description: "Enforces that constructors of classes extending Construct have the property names 'scope, id' or 'scope, id, props'"
35
+ },
36
+ messages: {
37
+ invalidConstructorProperty: "Constructor of a class extending Construct must have the property names 'scope, id' or 'scope, id, props'"
38
+ },
39
+ schema: []
40
+ },
41
+ defaultOptions: [],
42
+ create(context) {
43
+ const parserServices = ESLintUtils.getParserServices(context);
44
+ return {
45
+ ClassDeclaration(node) {
46
+ const type = parserServices.getTypeAtLocation(node);
47
+ if (!isConstructType(type)) return;
48
+ const constructor = node.body.body.find(
49
+ (member) => member.type === AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
50
+ );
51
+ if (!constructor) return;
52
+ validateConstructorProperty(constructor, context);
53
+ }
54
+ };
55
+ }
56
+ }
57
+ );
58
+ const validateConstructorProperty = (constructor, context) => {
59
+ const params = constructor.value.params;
60
+ if (params.length < 2) {
61
+ context.report({
62
+ node: constructor,
63
+ messageId: "invalidConstructorProperty"
64
+ });
65
+ return;
66
+ }
67
+ const firstParam = params[0];
68
+ if (firstParam.type === AST_NODE_TYPES.Identifier && firstParam.name !== "scope") {
69
+ context.report({
70
+ node: constructor,
71
+ messageId: "invalidConstructorProperty"
72
+ });
73
+ return;
74
+ }
75
+ const secondParam = params[1];
76
+ if (secondParam.type === AST_NODE_TYPES.Identifier && secondParam.name !== "id") {
77
+ context.report({
78
+ node: constructor,
79
+ messageId: "invalidConstructorProperty"
80
+ });
81
+ return;
82
+ }
83
+ if (params.length < 3) return;
84
+ const thirdParam = params[2];
85
+ if (thirdParam.type === AST_NODE_TYPES.Identifier && thirdParam.name !== "props") {
86
+ context.report({
87
+ node: constructor,
88
+ messageId: "invalidConstructorProperty"
89
+ });
90
+ return;
91
+ }
92
+ };
93
+
94
+ const SYMBOL_FLAGS = {
95
+ CLASS: 32
96
+ };
97
+ const SYNTAX_KIND = {
98
+ CLASS_DECLARATION: 263,
99
+ CONSTRUCTOR: 176
100
+ };
13
101
 
14
102
  const noClassInInterface = ESLintUtils.RuleCreator.withoutDocs({
15
103
  meta: {
@@ -33,7 +121,7 @@ const noClassInInterface = ESLintUtils.RuleCreator.withoutDocs({
33
121
  }
34
122
  const type = parserServices.getTypeAtLocation(property);
35
123
  if (!type.symbol) continue;
36
- const isClass = type.symbol.flags === SymbolFlags.Class;
124
+ const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
37
125
  if (!isClass) continue;
38
126
  context.report({
39
127
  node: property,
@@ -69,33 +157,16 @@ const getConstructorPropertyNames = (type) => {
69
157
  return constructor.parameters.map((param) => param.name.getText());
70
158
  };
71
159
  const isClassDeclaration = (declaration) => {
72
- return declaration.kind === SyntaxKind.ClassDeclaration;
160
+ return declaration.kind === SYNTAX_KIND.CLASS_DECLARATION;
73
161
  };
74
162
  const isConstructorDeclaration = (node) => {
75
- return node.kind === SyntaxKind.Constructor;
163
+ return node.kind === SYNTAX_KIND.CONSTRUCTOR;
76
164
  };
77
165
 
78
- const isConstructOrStackType = (type, ignoredClasses = ["App", "Stage"]) => {
79
- if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
80
- return isTargetSuperClassType(
81
- type,
82
- ["Construct", "Stack"],
83
- isConstructOrStackType
84
- );
85
- };
86
- const isConstructType = (type, ignoredClasses = ["App", "Stage", "Stack"]) => {
87
- if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
88
- return isTargetSuperClassType(type, ["Construct"], isConstructType);
89
- };
90
- const isTargetSuperClassType = (type, targetSuperClasses, typeCheckFunction) => {
91
- if (!type.symbol) return false;
92
- if (targetSuperClasses.some((suffix) => type.symbol.name.endsWith(suffix))) {
93
- return true;
94
- }
95
- const baseTypes = type.getBaseTypes() || [];
96
- return baseTypes.some((baseType) => typeCheckFunction(baseType));
166
+ const SUFFIX_TYPE = {
167
+ CONSTRUCT: "Construct",
168
+ STACK: "Stack"
97
169
  };
98
-
99
170
  const noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
100
171
  meta: {
101
172
  type: "problem",
@@ -105,11 +176,33 @@ const noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
105
176
  messages: {
106
177
  noConstructStackSuffix: "{{ classType }} ID '{{ id }}' should not include {{ suffix }} suffix."
107
178
  },
108
- schema: []
179
+ schema: [
180
+ {
181
+ type: "object",
182
+ properties: {
183
+ disallowedSuffixes: {
184
+ type: "array",
185
+ items: {
186
+ type: "string",
187
+ enum: [SUFFIX_TYPE.CONSTRUCT, SUFFIX_TYPE.STACK]
188
+ },
189
+ uniqueItems: true
190
+ }
191
+ },
192
+ additionalProperties: false
193
+ }
194
+ ]
109
195
  },
110
- defaultOptions: [],
196
+ defaultOptions: [
197
+ {
198
+ disallowedSuffixes: [SUFFIX_TYPE.CONSTRUCT, SUFFIX_TYPE.STACK]
199
+ }
200
+ ],
111
201
  create(context) {
112
202
  const parserServices = ESLintUtils.getParserServices(context);
203
+ const options = context.options[0] ?? {
204
+ disallowedSuffixes: [SUFFIX_TYPE.CONSTRUCT, SUFFIX_TYPE.STACK]
205
+ };
113
206
  return {
114
207
  NewExpression(node) {
115
208
  const type = parserServices.getTypeAtLocation(node);
@@ -118,35 +211,36 @@ const noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
118
211
  }
119
212
  const constructorPropertyNames = getConstructorPropertyNames(type);
120
213
  if (constructorPropertyNames[1] !== "id") return;
121
- validateConstructId$3(node, context);
214
+ validateConstructId$3(node, context, options);
122
215
  }
123
216
  };
124
217
  }
125
218
  });
126
- const validateConstructId$3 = (node, context) => {
219
+ const validateConstructId$3 = (node, context, options) => {
127
220
  const secondArg = node.arguments[1];
128
221
  if (secondArg.type !== AST_NODE_TYPES.Literal || typeof secondArg.value !== "string") {
129
222
  return;
130
223
  }
131
224
  const formattedConstructId = toPascalCase(secondArg.value);
132
- if (formattedConstructId.endsWith("Construct")) {
225
+ const disallowedSuffixes = options.disallowedSuffixes;
226
+ if (disallowedSuffixes.includes(SUFFIX_TYPE.CONSTRUCT) && formattedConstructId.endsWith(SUFFIX_TYPE.CONSTRUCT)) {
133
227
  context.report({
134
228
  node,
135
229
  messageId: "noConstructStackSuffix",
136
230
  data: {
137
231
  classType: "Construct",
138
232
  id: secondArg.value,
139
- suffix: "Construct"
233
+ suffix: SUFFIX_TYPE.CONSTRUCT
140
234
  }
141
235
  });
142
- } else if (formattedConstructId.endsWith("Stack")) {
236
+ } else if (disallowedSuffixes.includes(SUFFIX_TYPE.STACK) && formattedConstructId.endsWith(SUFFIX_TYPE.STACK)) {
143
237
  context.report({
144
238
  node,
145
239
  messageId: "noConstructStackSuffix",
146
240
  data: {
147
241
  classType: "Stack",
148
242
  id: secondArg.value,
149
- suffix: "Stack"
243
+ suffix: SUFFIX_TYPE.STACK
150
244
  }
151
245
  });
152
246
  }
@@ -559,7 +653,7 @@ const validateClassMember = (node, context, parserServices) => {
559
653
  if (!member.typeAnnotation) continue;
560
654
  const type = parserServices.getTypeAtLocation(member);
561
655
  if (!type.symbol) continue;
562
- const isClass = type.symbol.flags === SymbolFlags.Class;
656
+ const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
563
657
  if (!isClass) continue;
564
658
  context.report({
565
659
  node: member,
@@ -582,7 +676,7 @@ const validateConstructorParameterProperty = (constructor, context, parserServic
582
676
  if (!param.parameter.typeAnnotation) continue;
583
677
  const type = parserServices.getTypeAtLocation(param);
584
678
  if (!type.symbol) continue;
585
- const isClass = type.symbol.flags === SymbolFlags.Class;
679
+ const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
586
680
  if (!isClass) continue;
587
681
  context.report({
588
682
  node: param,
@@ -640,6 +734,17 @@ const isInsideLoop = (node) => {
640
734
  if (current.type === AST_NODE_TYPES.ForStatement || current.type === AST_NODE_TYPES.ForInStatement || current.type === AST_NODE_TYPES.ForOfStatement || current.type === AST_NODE_TYPES.WhileStatement || current.type === AST_NODE_TYPES.DoWhileStatement) {
641
735
  return true;
642
736
  }
737
+ if (current.type === AST_NODE_TYPES.CallExpression && current.callee.type === AST_NODE_TYPES.MemberExpression && current.callee.property.type === AST_NODE_TYPES.Identifier && [
738
+ "forEach",
739
+ "map",
740
+ "filter",
741
+ "reduce",
742
+ "flatMap",
743
+ "some",
744
+ "every"
745
+ ].includes(current.callee.property.name)) {
746
+ return true;
747
+ }
643
748
  current = current.parent;
644
749
  }
645
750
  return false;
@@ -819,11 +924,29 @@ const requirePassingThis = ESLintUtils.RuleCreator.withoutDocs({
819
924
  messages: {
820
925
  requirePassingThis: "Require passing `this` in a constructor."
821
926
  },
822
- schema: [],
927
+ schema: [
928
+ {
929
+ type: "object",
930
+ properties: {
931
+ allowNonThisAndDisallowScope: {
932
+ type: "boolean",
933
+ default: false
934
+ }
935
+ },
936
+ additionalProperties: false
937
+ }
938
+ ],
823
939
  fixable: "code"
824
940
  },
825
- defaultOptions: [],
941
+ defaultOptions: [
942
+ {
943
+ allowNonThisAndDisallowScope: false
944
+ }
945
+ ],
826
946
  create(context) {
947
+ const options = context.options[0] || {
948
+ allowNonThisAndDisallowScope: false
949
+ };
827
950
  const parserServices = ESLintUtils.getParserServices(context);
828
951
  return {
829
952
  NewExpression(node) {
@@ -833,13 +956,25 @@ const requirePassingThis = ESLintUtils.RuleCreator.withoutDocs({
833
956
  if (argument.type === AST_NODE_TYPES.ThisExpression) return;
834
957
  const constructorPropertyNames = getConstructorPropertyNames(type);
835
958
  if (constructorPropertyNames[0] !== "scope") return;
836
- context.report({
837
- node,
838
- messageId: "requirePassingThis",
839
- fix: (fixer) => {
840
- return fixer.replaceText(argument, "this");
841
- }
842
- });
959
+ if (!options.allowNonThisAndDisallowScope) {
960
+ context.report({
961
+ node,
962
+ messageId: "requirePassingThis",
963
+ fix: (fixer) => {
964
+ return fixer.replaceText(argument, "this");
965
+ }
966
+ });
967
+ return;
968
+ }
969
+ if (argument.type === AST_NODE_TYPES.Identifier && argument.name === "scope") {
970
+ context.report({
971
+ node,
972
+ messageId: "requirePassingThis",
973
+ fix: (fixer) => {
974
+ return fixer.replaceText(argument, "this");
975
+ }
976
+ });
977
+ }
843
978
  }
844
979
  };
845
980
  }
@@ -893,49 +1028,65 @@ const rules = {
893
1028
  "no-parent-name-construct-id-match": noParentNameConstructIdMatch,
894
1029
  "no-public-class-fields": noPublicClassFields,
895
1030
  "pascal-case-construct-id": pascalCaseConstructId,
896
- "no-mutable-public-fields": noMutablePublicFields,
897
- "no-mutable-props-interface": noMutablePropsInterface,
898
1031
  "require-passing-this": requirePassingThis,
899
1032
  "no-variable-construct-id": noVariableConstructId,
1033
+ "no-mutable-public-fields": noMutablePublicFields,
1034
+ "no-mutable-props-interface": noMutablePropsInterface,
1035
+ "construct-constructor-property": constructConstructorProperty,
900
1036
  "require-jsdoc": requireJSDoc,
901
1037
  "require-props-default-doc": requirePropsDefaultDoc,
902
1038
  "props-name-convention": propsNameConvention,
903
1039
  "no-import-private": noImportPrivate
904
1040
  };
1041
+ const cdkPlugin = {
1042
+ meta: { name, version },
1043
+ rules
1044
+ };
1045
+ const createFlatConfig = (rules2) => {
1046
+ return {
1047
+ languageOptions: {
1048
+ parser: tsParser,
1049
+ parserOptions: {
1050
+ projectService: true
1051
+ }
1052
+ },
1053
+ plugins: {
1054
+ cdk: cdkPlugin
1055
+ },
1056
+ rules: rules2
1057
+ };
1058
+ };
1059
+ const recommended = createFlatConfig({
1060
+ "cdk/no-class-in-interface": "error",
1061
+ "cdk/no-construct-stack-suffix": "error",
1062
+ "cdk/no-parent-name-construct-id-match": "error",
1063
+ "cdk/no-public-class-fields": "error",
1064
+ "cdk/pascal-case-construct-id": "error",
1065
+ "cdk/require-passing-this": ["error", { allowNonThisAndDisallowScope: true }],
1066
+ "cdk/no-variable-construct-id": "error",
1067
+ "cdk/no-mutable-public-fields": "warn",
1068
+ "cdk/no-mutable-props-interface": "warn",
1069
+ "cdk/construct-constructor-property": "error"
1070
+ });
1071
+ const strict = createFlatConfig({
1072
+ "cdk/no-class-in-interface": "error",
1073
+ "cdk/no-construct-stack-suffix": "error",
1074
+ "cdk/no-parent-name-construct-id-match": "error",
1075
+ "cdk/no-public-class-fields": "error",
1076
+ "cdk/pascal-case-construct-id": "error",
1077
+ "cdk/require-passing-this": "error",
1078
+ "cdk/no-variable-construct-id": "error",
1079
+ "cdk/no-mutable-public-fields": "error",
1080
+ "cdk/no-mutable-props-interface": "error",
1081
+ "cdk/construct-constructor-property": "error",
1082
+ "cdk/require-jsdoc": "error",
1083
+ "cdk/require-props-default-doc": "error",
1084
+ "cdk/props-name-convention": "error",
1085
+ "cdk/no-import-private": "error"
1086
+ });
905
1087
  const configs = {
906
- recommended: {
907
- plugins: ["cdk"],
908
- rules: {
909
- "cdk/no-class-in-interface": "error",
910
- "cdk/no-construct-stack-suffix": "error",
911
- "cdk/no-parent-name-construct-id-match": "error",
912
- "cdk/no-public-class-fields": "error",
913
- "cdk/pascal-case-construct-id": "error",
914
- "cdk/require-passing-this": "error",
915
- "cdk/no-variable-construct-id": "error",
916
- "cdk/no-mutable-public-fields": "warn",
917
- "cdk/no-mutable-props-interface": "warn",
918
- "cdk/props-name-convention": "warn"
919
- }
920
- },
921
- strict: {
922
- plugins: ["cdk"],
923
- rules: {
924
- "cdk/no-class-in-interface": "error",
925
- "cdk/no-construct-stack-suffix": "error",
926
- "cdk/no-parent-name-construct-id-match": "error",
927
- "cdk/no-public-class-fields": "error",
928
- "cdk/pascal-case-construct-id": "error",
929
- "cdk/require-passing-this": "error",
930
- "cdk/no-variable-construct-id": "error",
931
- "cdk/no-mutable-public-fields": "error",
932
- "cdk/no-mutable-props-interface": "error",
933
- "cdk/no-import-private": "error",
934
- "cdk/require-props-default-doc": "error",
935
- "cdk/props-name-convention": "error",
936
- "cdk/require-jsdoc": "error"
937
- }
938
- }
1088
+ recommended,
1089
+ strict
939
1090
  };
940
1091
  const eslintCdkPlugin = {
941
1092
  rules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-cdk-plugin",
3
- "version": "1.1.1",
3
+ "version": "2.0.1",
4
4
  "description": "eslint plugin for AWS CDK projects",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -20,7 +20,8 @@
20
20
  "build": "sh scripts/build.sh",
21
21
  "test": "vitest --run",
22
22
  "lint": "eslint --fix --config eslint.config.js",
23
- "type-check": "tsc --noEmit",
23
+ "check": "tsc --noEmit",
24
+ "pack": "pnpm run build && npm pack",
24
25
  "release:minor": "standard-version --release-as minor",
25
26
  "release:major": "standard-version --release-as major",
26
27
  "release:patch": "standard-version --release-as patch",
@@ -29,23 +30,23 @@
29
30
  "docs:preview": "cd ./docs && pnpm install && pnpm run preview"
30
31
  },
31
32
  "devDependencies": {
32
- "@eslint/js": "^9.15.0",
33
- "@types/estree": "^1.0.6",
34
- "@types/node": "^22.9.0",
35
- "@typescript-eslint/rule-tester": "^8.14.0",
36
- "eslint": "9.10.0",
33
+ "@eslint/js": "^9.22.0",
34
+ "@types/node": "^22.13.10",
35
+ "@typescript-eslint/rule-tester": "^8.26.0",
36
+ "eslint": "9.22.0",
37
37
  "eslint-plugin-import": "^2.31.0",
38
- "pkgroll": "^2.6.0",
38
+ "pkgroll": "^2.11.2",
39
39
  "standard-version": "^9.5.0",
40
- "typescript": "^5.6.3",
41
- "typescript-eslint": "^8.14.0",
42
- "vitest": "^2.1.5"
40
+ "typescript": "^5.8.2",
41
+ "typescript-eslint": "^8.26.0",
42
+ "vitest": "^3.0.8"
43
43
  },
44
44
  "dependencies": {
45
- "@typescript-eslint/utils": "^8.14.0"
45
+ "@typescript-eslint/parser": "^8.26.0",
46
+ "@typescript-eslint/utils": "^8.26.0"
46
47
  },
47
48
  "volta": {
48
- "node": "22.11.0"
49
+ "node": "22.14.0"
49
50
  },
50
51
  "files": [
51
52
  "dist",
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * Implementing `SymbolFlags` defined in typescript on your own, in order not to include TypeScript in dependencies
3
3
  */
4
- export enum SymbolFlags {
5
- Class = 32,
6
- }
4
+ export const SYMBOL_FLAGS = {
5
+ CLASS: 32,
6
+ } as const;
7
7
 
8
8
  /**
9
9
  * Implementing `SyntaxKind` defined in typescript on your own, in order not to include TypeScript in dependencies
10
10
  */
11
- export enum SyntaxKind {
12
- ClassDeclaration = 263,
13
- Constructor = 176,
14
- }
11
+ export const SYNTAX_KIND = {
12
+ CLASS_DECLARATION: 263,
13
+ CONSTRUCTOR: 176,
14
+ } as const;
package/src/index.ts CHANGED
@@ -1,3 +1,8 @@
1
+ import tsParser from "@typescript-eslint/parser";
2
+
3
+ import { name, version } from "../package.json";
4
+
5
+ import { constructConstructorProperty } from "./rules/construct-constructor-property";
1
6
  import { noClassInInterface } from "./rules/no-class-in-interface";
2
7
  import { noConstructStackSuffix } from "./rules/no-construct-stack-suffix";
3
8
  import { noImportPrivate } from "./rules/no-import-private";
@@ -18,50 +23,70 @@ const rules = {
18
23
  "no-parent-name-construct-id-match": noParentNameConstructIdMatch,
19
24
  "no-public-class-fields": noPublicClassFields,
20
25
  "pascal-case-construct-id": pascalCaseConstructId,
21
- "no-mutable-public-fields": noMutablePublicFields,
22
- "no-mutable-props-interface": noMutablePropsInterface,
23
26
  "require-passing-this": requirePassingThis,
24
27
  "no-variable-construct-id": noVariableConstructId,
28
+ "no-mutable-public-fields": noMutablePublicFields,
29
+ "no-mutable-props-interface": noMutablePropsInterface,
30
+ "construct-constructor-property": constructConstructorProperty,
25
31
  "require-jsdoc": requireJSDoc,
26
32
  "require-props-default-doc": requirePropsDefaultDoc,
27
33
  "props-name-convention": propsNameConvention,
28
34
  "no-import-private": noImportPrivate,
29
35
  };
30
36
 
31
- const configs = {
32
- recommended: {
33
- plugins: ["cdk"],
34
- rules: {
35
- "cdk/no-class-in-interface": "error",
36
- "cdk/no-construct-stack-suffix": "error",
37
- "cdk/no-parent-name-construct-id-match": "error",
38
- "cdk/no-public-class-fields": "error",
39
- "cdk/pascal-case-construct-id": "error",
40
- "cdk/require-passing-this": "error",
41
- "cdk/no-variable-construct-id": "error",
42
- "cdk/no-mutable-public-fields": "warn",
43
- "cdk/no-mutable-props-interface": "warn",
44
- "cdk/props-name-convention": "warn",
37
+ const cdkPlugin = {
38
+ meta: { name, version },
39
+ rules,
40
+ };
41
+
42
+ const createFlatConfig = (rules: Record<string, unknown>) => {
43
+ return {
44
+ languageOptions: {
45
+ parser: tsParser,
46
+ parserOptions: {
47
+ projectService: true,
48
+ },
45
49
  },
46
- },
47
- strict: {
48
- plugins: ["cdk"],
49
- rules: {
50
- "cdk/no-class-in-interface": "error",
51
- "cdk/no-construct-stack-suffix": "error",
52
- "cdk/no-parent-name-construct-id-match": "error",
53
- "cdk/no-public-class-fields": "error",
54
- "cdk/pascal-case-construct-id": "error",
55
- "cdk/require-passing-this": "error",
56
- "cdk/no-variable-construct-id": "error",
57
- "cdk/no-mutable-public-fields": "error",
58
- "cdk/no-mutable-props-interface": "error",
59
- "cdk/no-import-private": "error",
60
- "cdk/require-props-default-doc": "error",
61
- "cdk/props-name-convention": "error",
62
- "cdk/require-jsdoc": "error",
50
+ plugins: {
51
+ cdk: cdkPlugin,
63
52
  },
64
- },
53
+ rules,
54
+ };
55
+ };
56
+
57
+ const recommended = createFlatConfig({
58
+ "cdk/no-class-in-interface": "error",
59
+ "cdk/no-construct-stack-suffix": "error",
60
+ "cdk/no-parent-name-construct-id-match": "error",
61
+ "cdk/no-public-class-fields": "error",
62
+ "cdk/pascal-case-construct-id": "error",
63
+ "cdk/require-passing-this": ["error", { allowNonThisAndDisallowScope: true }],
64
+ "cdk/no-variable-construct-id": "error",
65
+ "cdk/no-mutable-public-fields": "warn",
66
+ "cdk/no-mutable-props-interface": "warn",
67
+ "cdk/construct-constructor-property": "error",
68
+ });
69
+
70
+ const strict = createFlatConfig({
71
+ "cdk/no-class-in-interface": "error",
72
+ "cdk/no-construct-stack-suffix": "error",
73
+ "cdk/no-parent-name-construct-id-match": "error",
74
+ "cdk/no-public-class-fields": "error",
75
+ "cdk/pascal-case-construct-id": "error",
76
+ "cdk/require-passing-this": "error",
77
+ "cdk/no-variable-construct-id": "error",
78
+ "cdk/no-mutable-public-fields": "error",
79
+ "cdk/no-mutable-props-interface": "error",
80
+ "cdk/construct-constructor-property": "error",
81
+ "cdk/require-jsdoc": "error",
82
+ "cdk/require-props-default-doc": "error",
83
+ "cdk/props-name-convention": "error",
84
+ "cdk/no-import-private": "error",
85
+ });
86
+
87
+ const configs = {
88
+ recommended,
89
+ strict,
65
90
  };
66
91
 
67
92
  export { configs, rules };