eslint-cdk-plugin 2.2.0 → 3.0.2

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
@@ -3,7 +3,7 @@ import { ESLintUtils, AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint
3
3
  import * as path from 'path';
4
4
 
5
5
  var name = "eslint-cdk-plugin";
6
- var version = "2.2.0";
6
+ var version = "3.0.1";
7
7
 
8
8
  const isConstructOrStackType = (type, ignoredClasses = ["App", "Stage"]) => {
9
9
  if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
@@ -59,7 +59,7 @@ const validateConstructorProperty = (constructor, context) => {
59
59
  const params = constructor.value.params;
60
60
  if (params.length < 2) {
61
61
  context.report({
62
- node: constructor,
62
+ node: constructor.value,
63
63
  messageId: "invalidConstructorProperty"
64
64
  });
65
65
  return;
@@ -67,7 +67,7 @@ const validateConstructorProperty = (constructor, context) => {
67
67
  const firstParam = params[0];
68
68
  if (firstParam.type === AST_NODE_TYPES.Identifier && firstParam.name !== "scope") {
69
69
  context.report({
70
- node: constructor,
70
+ node: firstParam,
71
71
  messageId: "invalidConstructorProperty"
72
72
  });
73
73
  return;
@@ -75,7 +75,7 @@ const validateConstructorProperty = (constructor, context) => {
75
75
  const secondParam = params[1];
76
76
  if (secondParam.type === AST_NODE_TYPES.Identifier && secondParam.name !== "id") {
77
77
  context.report({
78
- node: constructor,
78
+ node: secondParam,
79
79
  messageId: "invalidConstructorProperty"
80
80
  });
81
81
  return;
@@ -84,7 +84,7 @@ const validateConstructorProperty = (constructor, context) => {
84
84
  const thirdParam = params[2];
85
85
  if (thirdParam.type === AST_NODE_TYPES.Identifier && thirdParam.name !== "props") {
86
86
  context.report({
87
- node: constructor,
87
+ node: thirdParam,
88
88
  messageId: "invalidConstructorProperty"
89
89
  });
90
90
  return;
@@ -99,14 +99,14 @@ const SYNTAX_KIND = {
99
99
  CONSTRUCTOR: 176
100
100
  };
101
101
 
102
- const noClassInInterface = ESLintUtils.RuleCreator.withoutDocs({
102
+ const noConstructInInterface = ESLintUtils.RuleCreator.withoutDocs({
103
103
  meta: {
104
104
  type: "problem",
105
105
  docs: {
106
- description: "Disallow class types in interface properties"
106
+ description: "Disallow CDK Construct types in interface properties"
107
107
  },
108
108
  messages: {
109
- noClassInInterfaceProps: "Interface property '{{ propertyName }}' should not use class type '{{ typeName }}'. Consider using an interface or type alias instead."
109
+ invalidInterfaceProperty: "Interface property '{{ propertyName }}' should not use CDK Construct type '{{ typeName }}'. Consider using an interface or type alias instead."
110
110
  },
111
111
  schema: []
112
112
  },
@@ -120,12 +120,12 @@ const noClassInInterface = ESLintUtils.RuleCreator.withoutDocs({
120
120
  continue;
121
121
  }
122
122
  const type = parserServices.getTypeAtLocation(property);
123
- if (!type.symbol) continue;
123
+ if (!isConstructOrStackType(type)) continue;
124
124
  const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
125
125
  if (!isClass) continue;
126
126
  context.report({
127
127
  node: property,
128
- messageId: "noClassInInterfaceProps",
128
+ messageId: "invalidInterfaceProperty",
129
129
  data: {
130
130
  propertyName: property.key.name,
131
131
  typeName: type.symbol.name
@@ -137,6 +137,87 @@ const noClassInInterface = ESLintUtils.RuleCreator.withoutDocs({
137
137
  }
138
138
  });
139
139
 
140
+ const noConstructInPublicPropertyOfConstruct = ESLintUtils.RuleCreator.withoutDocs({
141
+ meta: {
142
+ type: "problem",
143
+ docs: {
144
+ description: "Disallow Construct types in public property of Construct"
145
+ },
146
+ messages: {
147
+ invalidPublicPropertyOfConstruct: "Public property '{{ propertyName }}' of Construct should not use Construct type '{{ typeName }}'. Consider using an interface or type alias instead."
148
+ },
149
+ schema: []
150
+ },
151
+ defaultOptions: [],
152
+ create(context) {
153
+ const parserServices = ESLintUtils.getParserServices(context);
154
+ return {
155
+ ClassDeclaration(node) {
156
+ const type = parserServices.getTypeAtLocation(node);
157
+ if (!isConstructOrStackType(type)) return;
158
+ validatePublicPropertyOfConstruct(node, context, parserServices);
159
+ const constructor = node.body.body.find(
160
+ (member) => member.type === AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
161
+ );
162
+ if (!constructor || constructor.value.type !== AST_NODE_TYPES.FunctionExpression) {
163
+ return;
164
+ }
165
+ validateConstructorParameterProperty(
166
+ constructor,
167
+ context,
168
+ parserServices
169
+ );
170
+ }
171
+ };
172
+ }
173
+ });
174
+ const validatePublicPropertyOfConstruct = (node, context, parserServices) => {
175
+ for (const property of node.body.body) {
176
+ if (property.type !== AST_NODE_TYPES.PropertyDefinition || property.key.type !== AST_NODE_TYPES.Identifier) {
177
+ continue;
178
+ }
179
+ if (["private", "protected"].includes(property.accessibility ?? "")) {
180
+ continue;
181
+ }
182
+ if (!property.typeAnnotation) continue;
183
+ const type = parserServices.getTypeAtLocation(property);
184
+ if (!isConstructOrStackType(type)) continue;
185
+ const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
186
+ if (!isClass) continue;
187
+ context.report({
188
+ node: property,
189
+ messageId: "invalidPublicPropertyOfConstruct",
190
+ data: {
191
+ propertyName: property.key.name,
192
+ typeName: type.symbol.name
193
+ }
194
+ });
195
+ }
196
+ };
197
+ const validateConstructorParameterProperty = (constructor, context, parserServices) => {
198
+ for (const param of constructor.value.params) {
199
+ if (param.type !== AST_NODE_TYPES.TSParameterProperty || param.parameter.type !== AST_NODE_TYPES.Identifier) {
200
+ continue;
201
+ }
202
+ if (["private", "protected"].includes(param.accessibility ?? "")) {
203
+ continue;
204
+ }
205
+ if (!param.parameter.typeAnnotation) continue;
206
+ const type = parserServices.getTypeAtLocation(param);
207
+ if (!isConstructOrStackType(type)) continue;
208
+ const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
209
+ if (!isClass) continue;
210
+ context.report({
211
+ node: param,
212
+ messageId: "invalidPublicPropertyOfConstruct",
213
+ data: {
214
+ propertyName: param.parameter.name,
215
+ typeName: type.symbol.name
216
+ }
217
+ });
218
+ }
219
+ };
220
+
140
221
  const toPascalCase = (str) => {
141
222
  return str.split(/[-_\s]/).map((word) => {
142
223
  return word.replace(/([A-Z])/g, " $1").split(/\s+/).map(
@@ -174,7 +255,7 @@ const noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
174
255
  description: "Effort to avoid using 'Construct' and 'Stack' suffix in construct id."
175
256
  },
176
257
  messages: {
177
- noConstructStackSuffix: "{{ classType }} ID '{{ id }}' should not include {{ suffix }} suffix."
258
+ invalidConstructId: "{{ classType }} ID '{{ id }}' should not include {{ suffix }} suffix."
178
259
  },
179
260
  schema: [
180
261
  {
@@ -225,8 +306,8 @@ const validateConstructId$3 = (node, context, options) => {
225
306
  const disallowedSuffixes = options.disallowedSuffixes;
226
307
  if (disallowedSuffixes.includes(SUFFIX_TYPE.CONSTRUCT) && formattedConstructId.endsWith(SUFFIX_TYPE.CONSTRUCT)) {
227
308
  context.report({
228
- node,
229
- messageId: "noConstructStackSuffix",
309
+ node: secondArg,
310
+ messageId: "invalidConstructId",
230
311
  data: {
231
312
  classType: "Construct",
232
313
  id: secondArg.value,
@@ -235,8 +316,8 @@ const validateConstructId$3 = (node, context, options) => {
235
316
  });
236
317
  } else if (disallowedSuffixes.includes(SUFFIX_TYPE.STACK) && formattedConstructId.endsWith(SUFFIX_TYPE.STACK)) {
237
318
  context.report({
238
- node,
239
- messageId: "noConstructStackSuffix",
319
+ node: secondArg,
320
+ messageId: "invalidConstructId",
240
321
  data: {
241
322
  classType: "Stack",
242
323
  id: secondArg.value,
@@ -253,7 +334,7 @@ const noImportPrivate = {
253
334
  description: "Cannot import modules from private dir at different levels of the hierarchy."
254
335
  },
255
336
  messages: {
256
- noImportPrivate: "Cannot import modules from private dir at different levels of the hierarchy."
337
+ invalidImportPath: "Cannot import modules from private dir at different levels of the hierarchy."
257
338
  },
258
339
  schema: []
259
340
  },
@@ -272,7 +353,7 @@ const noImportPrivate = {
272
353
  if (currentDirSegments.length !== importDirSegments.length || currentDirSegments.some(
273
354
  (segment, index) => segment !== importDirSegments[index]
274
355
  )) {
275
- context.report({ node, messageId: "noImportPrivate" });
356
+ context.report({ node, messageId: "invalidImportPath" });
276
357
  }
277
358
  }
278
359
  };
@@ -282,15 +363,15 @@ const getDirSegments = (dirPath) => {
282
363
  return dirPath.split(path.sep).filter((segment) => segment !== "");
283
364
  };
284
365
 
285
- const noMutablePropsInterface = ESLintUtils.RuleCreator.withoutDocs({
366
+ const noMutablePropertyOfPropsInterface = ESLintUtils.RuleCreator.withoutDocs({
286
367
  meta: {
287
368
  type: "problem",
288
369
  docs: {
289
- description: "Disallow mutable properties in Props interfaces"
370
+ description: "Disallow mutable properties of Construct Props (interface)"
290
371
  },
291
372
  fixable: "code",
292
373
  messages: {
293
- noMutablePropsInterface: "Property '{{ propertyName }}' in Props interface should be readonly."
374
+ invalidPropertyOfPropsInterface: "Property '{{ propertyName }}' of Construct Props should be readonly."
294
375
  },
295
376
  schema: []
296
377
  },
@@ -307,7 +388,7 @@ const noMutablePropsInterface = ESLintUtils.RuleCreator.withoutDocs({
307
388
  if (property.readonly) continue;
308
389
  context.report({
309
390
  node: property,
310
- messageId: "noMutablePropsInterface",
391
+ messageId: "invalidPropertyOfPropsInterface",
311
392
  data: {
312
393
  propertyName: property.key.name
313
394
  },
@@ -322,15 +403,15 @@ const noMutablePropsInterface = ESLintUtils.RuleCreator.withoutDocs({
322
403
  }
323
404
  });
324
405
 
325
- const noMutablePublicFields = ESLintUtils.RuleCreator.withoutDocs({
406
+ const noMutablePublicPropertyOfConstruct = ESLintUtils.RuleCreator.withoutDocs({
326
407
  meta: {
327
408
  type: "problem",
328
409
  docs: {
329
- description: "Disallow mutable public class fields"
410
+ description: "Disallow mutable public properties of Construct"
330
411
  },
331
412
  fixable: "code",
332
413
  messages: {
333
- noMutablePublicFields: "Public field '{{ propertyName }}' should be readonly. Consider adding the 'readonly' modifier."
414
+ invalidPublicPropertyOfConstruct: "Public property '{{ propertyName }}' should be readonly. Consider adding the 'readonly' modifier."
334
415
  },
335
416
  schema: []
336
417
  },
@@ -352,7 +433,7 @@ const noMutablePublicFields = ESLintUtils.RuleCreator.withoutDocs({
352
433
  if (member.readonly) continue;
353
434
  context.report({
354
435
  node: member,
355
- messageId: "noMutablePublicFields",
436
+ messageId: "invalidPublicPropertyOfConstruct",
356
437
  data: {
357
438
  propertyName: member.key.name
358
439
  },
@@ -381,7 +462,7 @@ const noParentNameConstructIdMatch = ESLintUtils.RuleCreator.withoutDocs(
381
462
  description: "Enforce that construct IDs does not match the parent construct name."
382
463
  },
383
464
  messages: {
384
- noParentNameConstructIdMatch: "Construct ID '{{ constructId }}' should not match parent construct name '{{ parentConstructName }}'. Use a more specific identifier."
465
+ invalidConstructId: "Construct ID '{{ constructId }}' should not match parent construct name '{{ parentConstructName }}'. Use a more specific identifier."
385
466
  },
386
467
  schema: [
387
468
  {
@@ -419,7 +500,6 @@ const noParentNameConstructIdMatch = ESLintUtils.RuleCreator.withoutDocs(
419
500
  continue;
420
501
  }
421
502
  validateConstructorBody({
422
- node,
423
503
  expression: body.value,
424
504
  parentClassName,
425
505
  context,
@@ -433,7 +513,6 @@ const noParentNameConstructIdMatch = ESLintUtils.RuleCreator.withoutDocs(
433
513
  }
434
514
  );
435
515
  const validateConstructorBody = ({
436
- node,
437
516
  expression,
438
517
  parentClassName,
439
518
  context,
@@ -446,7 +525,6 @@ const validateConstructorBody = ({
446
525
  const newExpression = statement.declarations[0].init;
447
526
  if (newExpression?.type !== AST_NODE_TYPES.NewExpression) continue;
448
527
  validateConstructId$2({
449
- node,
450
528
  context,
451
529
  expression: newExpression,
452
530
  parentClassName,
@@ -458,7 +536,6 @@ const validateConstructorBody = ({
458
536
  case AST_NODE_TYPES.ExpressionStatement: {
459
537
  if (statement.expression?.type !== AST_NODE_TYPES.NewExpression) break;
460
538
  validateStatement({
461
- node,
462
539
  statement,
463
540
  parentClassName,
464
541
  context,
@@ -469,7 +546,6 @@ const validateConstructorBody = ({
469
546
  }
470
547
  case AST_NODE_TYPES.IfStatement: {
471
548
  traverseStatements({
472
- node,
473
549
  context,
474
550
  parentClassName,
475
551
  statement: statement.consequent,
@@ -482,7 +558,6 @@ const validateConstructorBody = ({
482
558
  for (const switchCase of statement.cases) {
483
559
  for (const statement2 of switchCase.consequent) {
484
560
  traverseStatements({
485
- node,
486
561
  context,
487
562
  parentClassName,
488
563
  statement: statement2,
@@ -497,7 +572,6 @@ const validateConstructorBody = ({
497
572
  }
498
573
  };
499
574
  const traverseStatements = ({
500
- node,
501
575
  statement,
502
576
  parentClassName,
503
577
  context,
@@ -508,7 +582,6 @@ const traverseStatements = ({
508
582
  case AST_NODE_TYPES.BlockStatement: {
509
583
  for (const body of statement.body) {
510
584
  validateStatement({
511
- node,
512
585
  statement: body,
513
586
  parentClassName,
514
587
  context,
@@ -522,7 +595,6 @@ const traverseStatements = ({
522
595
  const newExpression = statement.expression;
523
596
  if (newExpression?.type !== AST_NODE_TYPES.NewExpression) break;
524
597
  validateStatement({
525
- node,
526
598
  statement,
527
599
  parentClassName,
528
600
  context,
@@ -535,7 +607,6 @@ const traverseStatements = ({
535
607
  const newExpression = statement.declarations[0].init;
536
608
  if (newExpression?.type !== AST_NODE_TYPES.NewExpression) break;
537
609
  validateConstructId$2({
538
- node,
539
610
  context,
540
611
  expression: newExpression,
541
612
  parentClassName,
@@ -547,7 +618,6 @@ const traverseStatements = ({
547
618
  }
548
619
  };
549
620
  const validateStatement = ({
550
- node,
551
621
  statement,
552
622
  parentClassName,
553
623
  context,
@@ -559,7 +629,6 @@ const validateStatement = ({
559
629
  const newExpression = statement.declarations[0].init;
560
630
  if (newExpression?.type !== AST_NODE_TYPES.NewExpression) break;
561
631
  validateConstructId$2({
562
- node,
563
632
  context,
564
633
  expression: newExpression,
565
634
  parentClassName,
@@ -572,7 +641,6 @@ const validateStatement = ({
572
641
  const newExpression = statement.expression;
573
642
  if (newExpression?.type !== AST_NODE_TYPES.NewExpression) break;
574
643
  validateConstructId$2({
575
- node,
576
644
  context,
577
645
  expression: newExpression,
578
646
  parentClassName,
@@ -583,7 +651,6 @@ const validateStatement = ({
583
651
  }
584
652
  case AST_NODE_TYPES.IfStatement: {
585
653
  validateIfStatement({
586
- node,
587
654
  statement,
588
655
  parentClassName,
589
656
  context,
@@ -594,7 +661,6 @@ const validateStatement = ({
594
661
  }
595
662
  case AST_NODE_TYPES.SwitchStatement: {
596
663
  validateSwitchStatement({
597
- node,
598
664
  statement,
599
665
  parentClassName,
600
666
  context,
@@ -606,7 +672,6 @@ const validateStatement = ({
606
672
  }
607
673
  };
608
674
  const validateIfStatement = ({
609
- node,
610
675
  statement,
611
676
  parentClassName,
612
677
  context,
@@ -614,7 +679,6 @@ const validateIfStatement = ({
614
679
  option
615
680
  }) => {
616
681
  traverseStatements({
617
- node,
618
682
  context,
619
683
  parentClassName,
620
684
  statement: statement.consequent,
@@ -623,7 +687,6 @@ const validateIfStatement = ({
623
687
  });
624
688
  };
625
689
  const validateSwitchStatement = ({
626
- node,
627
690
  statement,
628
691
  parentClassName,
629
692
  context,
@@ -633,7 +696,6 @@ const validateSwitchStatement = ({
633
696
  for (const caseStatement of statement.cases) {
634
697
  for (const _consequent of caseStatement.consequent) {
635
698
  traverseStatements({
636
- node,
637
699
  context,
638
700
  parentClassName,
639
701
  statement: _consequent,
@@ -644,7 +706,6 @@ const validateSwitchStatement = ({
644
706
  }
645
707
  };
646
708
  const validateConstructId$2 = ({
647
- node,
648
709
  context,
649
710
  expression,
650
711
  parentClassName,
@@ -662,8 +723,8 @@ const validateConstructId$2 = ({
662
723
  if (!isConstructType(type)) return;
663
724
  if (option.disallowContainingParentName && formattedConstructId.includes(formattedParentClassName)) {
664
725
  context.report({
665
- node,
666
- messageId: "noParentNameConstructIdMatch",
726
+ node: secondArg,
727
+ messageId: "invalidConstructId",
667
728
  data: {
668
729
  constructId: secondArg.value,
669
730
  parentConstructName: parentClassName
@@ -673,8 +734,8 @@ const validateConstructId$2 = ({
673
734
  }
674
735
  if (formattedParentClassName === formattedConstructId) {
675
736
  context.report({
676
- node,
677
- messageId: "noParentNameConstructIdMatch",
737
+ node: secondArg,
738
+ messageId: "invalidConstructId",
678
739
  data: {
679
740
  constructId: secondArg.value,
680
741
  parentConstructName: parentClassName
@@ -683,87 +744,6 @@ const validateConstructId$2 = ({
683
744
  }
684
745
  };
685
746
 
686
- const noPublicClassFields = ESLintUtils.RuleCreator.withoutDocs({
687
- meta: {
688
- type: "problem",
689
- docs: {
690
- description: "Disallow class types in public class fields"
691
- },
692
- messages: {
693
- noPublicClassFields: "Public field '{{ propertyName }}' should not use class type '{{ typeName }}'. Consider using an interface or type alias instead."
694
- },
695
- schema: []
696
- },
697
- defaultOptions: [],
698
- create(context) {
699
- const parserServices = ESLintUtils.getParserServices(context);
700
- return {
701
- ClassDeclaration(node) {
702
- const type = parserServices.getTypeAtLocation(node);
703
- if (!isConstructOrStackType(type)) return;
704
- validateClassMember(node, context, parserServices);
705
- const constructor = node.body.body.find(
706
- (member) => member.type === AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
707
- );
708
- if (!constructor || constructor.value.type !== AST_NODE_TYPES.FunctionExpression) {
709
- return;
710
- }
711
- validateConstructorParameterProperty(
712
- constructor,
713
- context,
714
- parserServices
715
- );
716
- }
717
- };
718
- }
719
- });
720
- const validateClassMember = (node, context, parserServices) => {
721
- for (const member of node.body.body) {
722
- if (member.type !== AST_NODE_TYPES.PropertyDefinition || member.key.type !== AST_NODE_TYPES.Identifier) {
723
- continue;
724
- }
725
- if (["private", "protected"].includes(member.accessibility ?? "")) {
726
- continue;
727
- }
728
- if (!member.typeAnnotation) continue;
729
- const type = parserServices.getTypeAtLocation(member);
730
- if (!type.symbol) continue;
731
- const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
732
- if (!isClass) continue;
733
- context.report({
734
- node: member,
735
- messageId: "noPublicClassFields",
736
- data: {
737
- propertyName: member.key.name,
738
- typeName: type.symbol.name
739
- }
740
- });
741
- }
742
- };
743
- const validateConstructorParameterProperty = (constructor, context, parserServices) => {
744
- for (const param of constructor.value.params) {
745
- if (param.type !== AST_NODE_TYPES.TSParameterProperty || param.parameter.type !== AST_NODE_TYPES.Identifier) {
746
- continue;
747
- }
748
- if (["private", "protected"].includes(param.accessibility ?? "")) {
749
- continue;
750
- }
751
- if (!param.parameter.typeAnnotation) continue;
752
- const type = parserServices.getTypeAtLocation(param);
753
- if (!type.symbol) continue;
754
- const isClass = type.symbol.flags === SYMBOL_FLAGS.CLASS;
755
- if (!isClass) continue;
756
- context.report({
757
- node: param,
758
- messageId: "noPublicClassFields",
759
- data: {
760
- propertyName: param.parameter.name,
761
- typeName: type.symbol.name
762
- }
763
- });
764
- }
765
- };
766
-
767
747
  const noVariableConstructId = ESLintUtils.RuleCreator.withoutDocs({
768
748
  meta: {
769
749
  type: "problem",
@@ -771,7 +751,7 @@ const noVariableConstructId = ESLintUtils.RuleCreator.withoutDocs({
771
751
  description: `Enforce using literal strings for Construct ID.`
772
752
  },
773
753
  messages: {
774
- noVariableConstructId: "Shouldn't use a parameter as a Construct ID."
754
+ invalidConstructId: "Shouldn't use a parameter as a Construct ID."
775
755
  },
776
756
  schema: []
777
757
  },
@@ -799,8 +779,8 @@ const validateConstructId$1 = (node, context) => {
799
779
  return;
800
780
  }
801
781
  context.report({
802
- node,
803
- messageId: "noVariableConstructId"
782
+ node: secondArg,
783
+ messageId: "invalidConstructId"
804
784
  });
805
785
  };
806
786
  const isInsideLoop = (node) => {
@@ -836,7 +816,7 @@ const pascalCaseConstructId = ESLintUtils.RuleCreator.withoutDocs({
836
816
  description: "Enforce PascalCase for Construct ID."
837
817
  },
838
818
  messages: {
839
- pascalCaseConstructId: "Construct ID must be PascalCase."
819
+ invalidConstructId: "Construct ID must be PascalCase."
840
820
  },
841
821
  schema: [],
842
822
  fixable: "code"
@@ -869,8 +849,8 @@ const validateConstructId = (node, context) => {
869
849
  const quote = secondArg.raw?.startsWith('"') ? QUOTE_TYPE.DOUBLE : QUOTE_TYPE.SINGLE;
870
850
  if (isPascalCase(secondArg.value)) return;
871
851
  context.report({
872
- node,
873
- messageId: "pascalCaseConstructId",
852
+ node: secondArg,
853
+ messageId: "invalidConstructId",
874
854
  fix: (fixer) => {
875
855
  const pascalCaseValue = toPascalCase(secondArg.value);
876
856
  return fixer.replaceText(secondArg, `${quote}${pascalCaseValue}${quote}`);
@@ -997,7 +977,7 @@ const requirePassingThis = ESLintUtils.RuleCreator.withoutDocs({
997
977
  description: "Require passing `this` in a constructor."
998
978
  },
999
979
  messages: {
1000
- requirePassingThis: "Require passing `this` in a constructor."
980
+ missingPassingThis: "Require passing `this` in a constructor."
1001
981
  },
1002
982
  schema: [
1003
983
  {
@@ -1033,8 +1013,8 @@ const requirePassingThis = ESLintUtils.RuleCreator.withoutDocs({
1033
1013
  if (constructorPropertyNames[0] !== "scope") return;
1034
1014
  if (!options.allowNonThisAndDisallowScope) {
1035
1015
  context.report({
1036
- node,
1037
- messageId: "requirePassingThis",
1016
+ node: argument,
1017
+ messageId: "missingPassingThis",
1038
1018
  fix: (fixer) => {
1039
1019
  return fixer.replaceText(argument, "this");
1040
1020
  }
@@ -1043,8 +1023,8 @@ const requirePassingThis = ESLintUtils.RuleCreator.withoutDocs({
1043
1023
  }
1044
1024
  if (argument.type === AST_NODE_TYPES.Identifier && argument.name === "scope") {
1045
1025
  context.report({
1046
- node,
1047
- messageId: "requirePassingThis",
1026
+ node: argument,
1027
+ messageId: "missingPassingThis",
1048
1028
  fix: (fixer) => {
1049
1029
  return fixer.replaceText(argument, "this");
1050
1030
  }
@@ -1098,20 +1078,20 @@ const requirePropsDefaultDoc = ESLintUtils.RuleCreator.withoutDocs({
1098
1078
  });
1099
1079
 
1100
1080
  const rules = {
1101
- "no-class-in-interface": noClassInInterface,
1081
+ "construct-constructor-property": constructConstructorProperty,
1082
+ "no-construct-in-interface": noConstructInInterface,
1083
+ "no-construct-in-public-property-of-construct": noConstructInPublicPropertyOfConstruct,
1102
1084
  "no-construct-stack-suffix": noConstructStackSuffix,
1085
+ "no-import-private": noImportPrivate,
1086
+ "no-mutable-property-of-props-interface": noMutablePropertyOfPropsInterface,
1087
+ "no-mutable-public-property-of-construct": noMutablePublicPropertyOfConstruct,
1103
1088
  "no-parent-name-construct-id-match": noParentNameConstructIdMatch,
1104
- "no-public-class-fields": noPublicClassFields,
1105
- "pascal-case-construct-id": pascalCaseConstructId,
1106
- "require-passing-this": requirePassingThis,
1107
1089
  "no-variable-construct-id": noVariableConstructId,
1108
- "no-mutable-public-fields": noMutablePublicFields,
1109
- "no-mutable-props-interface": noMutablePropsInterface,
1110
- "construct-constructor-property": constructConstructorProperty,
1111
- "require-jsdoc": requireJSDoc,
1112
- "require-props-default-doc": requirePropsDefaultDoc,
1090
+ "pascal-case-construct-id": pascalCaseConstructId,
1113
1091
  "props-name-convention": propsNameConvention,
1114
- "no-import-private": noImportPrivate
1092
+ "require-jsdoc": requireJSDoc,
1093
+ "require-passing-this": requirePassingThis,
1094
+ "require-props-default-doc": requirePropsDefaultDoc
1115
1095
  };
1116
1096
  const cdkPlugin = {
1117
1097
  meta: { name, version },
@@ -1132,38 +1112,38 @@ const createFlatConfig = (rules2) => {
1132
1112
  };
1133
1113
  };
1134
1114
  const recommended = createFlatConfig({
1135
- "cdk/no-class-in-interface": "error",
1115
+ "cdk/construct-constructor-property": "error",
1116
+ "cdk/no-construct-in-interface": "error",
1117
+ "cdk/no-construct-in-public-property-of-construct": "error",
1136
1118
  "cdk/no-construct-stack-suffix": "error",
1119
+ "cdk/no-mutable-property-of-props-interface": "warn",
1120
+ "cdk/no-mutable-public-property-of-construct": "warn",
1137
1121
  "cdk/no-parent-name-construct-id-match": [
1138
1122
  "error",
1139
1123
  { disallowContainingParentName: false }
1140
1124
  ],
1141
- "cdk/no-public-class-fields": "error",
1142
- "cdk/pascal-case-construct-id": "error",
1143
- "cdk/require-passing-this": ["error", { allowNonThisAndDisallowScope: true }],
1144
1125
  "cdk/no-variable-construct-id": "error",
1145
- "cdk/no-mutable-public-fields": "warn",
1146
- "cdk/no-mutable-props-interface": "warn",
1147
- "cdk/construct-constructor-property": "error"
1126
+ "cdk/pascal-case-construct-id": "error",
1127
+ "cdk/require-passing-this": ["error", { allowNonThisAndDisallowScope: true }]
1148
1128
  });
1149
1129
  const strict = createFlatConfig({
1150
- "cdk/no-class-in-interface": "error",
1130
+ "cdk/construct-constructor-property": "error",
1131
+ "cdk/no-construct-in-interface": "error",
1132
+ "cdk/no-construct-in-public-property-of-construct": "error",
1151
1133
  "cdk/no-construct-stack-suffix": "error",
1134
+ "cdk/no-import-private": "error",
1135
+ "cdk/no-mutable-property-of-props-interface": "error",
1136
+ "cdk/no-mutable-public-property-of-construct": "error",
1152
1137
  "cdk/no-parent-name-construct-id-match": [
1153
1138
  "error",
1154
1139
  { disallowContainingParentName: true }
1155
1140
  ],
1156
- "cdk/no-public-class-fields": "error",
1157
- "cdk/pascal-case-construct-id": "error",
1158
- "cdk/require-passing-this": "error",
1159
1141
  "cdk/no-variable-construct-id": "error",
1160
- "cdk/no-mutable-public-fields": "error",
1161
- "cdk/no-mutable-props-interface": "error",
1162
- "cdk/construct-constructor-property": "error",
1163
- "cdk/require-jsdoc": "error",
1164
- "cdk/require-props-default-doc": "error",
1142
+ "cdk/pascal-case-construct-id": "error",
1165
1143
  "cdk/props-name-convention": "error",
1166
- "cdk/no-import-private": "error"
1144
+ "cdk/require-jsdoc": "error",
1145
+ "cdk/require-passing-this": "error",
1146
+ "cdk/require-props-default-doc": "error"
1167
1147
  });
1168
1148
  const configs = {
1169
1149
  recommended,