eslint-cdk-plugin 3.4.2 → 3.4.4

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,9 +1,10 @@
1
1
  import tsParser from '@typescript-eslint/parser';
2
2
  import { ESLintUtils, AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils';
3
+ import { SymbolFlags, SyntaxKind, isClassDeclaration, isIdentifier, isPropertyAccessExpression, isConstructorDeclaration } from 'typescript';
3
4
  import * as path from 'path';
4
5
 
5
6
  var name = "eslint-cdk-plugin";
6
- var version = "3.4.2";
7
+ var version = "3.4.4";
7
8
 
8
9
  const createRule = ESLintUtils.RuleCreator(
9
10
  (name) => `https://eslint-cdk-plugin.dev/rules/${name}`
@@ -120,21 +121,11 @@ const validateConstructorProperty = (constructor, context, parserServices) => {
120
121
  }
121
122
  };
122
123
 
123
- const SYMBOL_FLAGS = {
124
- CLASS: 32};
125
- const SYNTAX_KIND = {
126
- CLASS_DECLARATION: 263,
127
- CONSTRUCTOR: 176,
128
- IMPLEMENTS_KEYWORD: 119,
129
- IDENTIFIER: 80,
130
- PROPERTY_ACCESS_EXPRESSION: 211
131
- };
132
-
133
124
  const getSymbol = (type) => {
134
125
  return type.getSymbol?.() ?? type.symbol;
135
126
  };
136
127
  const isClassType = (type) => {
137
- return getSymbol(type)?.flags === SYMBOL_FLAGS.CLASS;
128
+ return getSymbol(type)?.flags === SymbolFlags.Class;
138
129
  };
139
130
  const isArrayType = (type) => {
140
131
  const symbol = getSymbol(type);
@@ -170,20 +161,8 @@ const getGenericTypeArgument = (type) => {
170
161
  return void 0;
171
162
  };
172
163
 
173
- const isClassDeclaration = (node) => {
174
- return node.kind === SYNTAX_KIND.CLASS_DECLARATION;
175
- };
176
- const isIdentifier = (node) => {
177
- return node.kind === SYNTAX_KIND.IDENTIFIER;
178
- };
179
- const isPropertyAccessExpression = (node) => {
180
- return node.kind === SYNTAX_KIND.PROPERTY_ACCESS_EXPRESSION;
181
- };
182
164
  const checkHeritageClauseIsImplements = (node) => {
183
- return node.token === SYNTAX_KIND.IMPLEMENTS_KEYWORD;
184
- };
185
- const isConstructorDeclaration = (node) => {
186
- return node.kind === SYNTAX_KIND.CONSTRUCTOR;
165
+ return node.token === SyntaxKind.ImplementsKeyword;
187
166
  };
188
167
 
189
168
  const isResourceWithReadonlyInterface = (type) => {
@@ -948,76 +927,272 @@ const validateConstructId$2 = ({
948
927
  }
949
928
  };
950
929
 
951
- const propsUsageTrackerFactory = (propsType) => {
952
- const getPropsPropertyNames = (propsType2) => {
953
- const typeProperties = propsType2.getProperties();
954
- if (typeProperties.length) {
955
- return typeProperties.reduce(
956
- (acc, prop) => !isInternalProperty(prop.name) ? [...acc, prop.name] : acc,
957
- []
958
- );
930
+ const getChildNodes = (node) => {
931
+ return Object.entries(node).reduce((acc, [key, value]) => {
932
+ if (["parent", "range", "loc"].includes(key)) return acc;
933
+ if (isESTreeNode(value)) return [...acc, value];
934
+ if (Array.isArray(value)) return [...acc, ...value.filter(isESTreeNode)];
935
+ return acc;
936
+ }, []);
937
+ };
938
+ const isESTreeNode = (value) => {
939
+ return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
940
+ };
941
+
942
+ class PropsUsageAnalyzer {
943
+ propsUsageTracker;
944
+ visitedNodes;
945
+ propsAliases;
946
+ constructor(propsUsageTracker) {
947
+ this.propsUsageTracker = propsUsageTracker;
948
+ this.visitedNodes = /* @__PURE__ */ new Set();
949
+ this.propsAliases = /* @__PURE__ */ new Set();
950
+ }
951
+ analyze(constructor, propsParam) {
952
+ this.initialize();
953
+ const constructorBody = constructor.value.body;
954
+ const classNode = constructor.parent;
955
+ const propsParamName = propsParam.name;
956
+ if (!constructorBody) return;
957
+ this.visitNodes(constructorBody, propsParamName);
958
+ this.analyzeClassBody(classNode, constructor, propsParamName);
959
+ this.analyzePrivateMethodsCalledFromConstructor(
960
+ constructorBody,
961
+ classNode,
962
+ propsParamName
963
+ );
964
+ }
965
+ initialize() {
966
+ this.visitedNodes.clear();
967
+ this.propsAliases.clear();
968
+ }
969
+ analyzeClassBody(classBody, constructor, propsParamName) {
970
+ if (!constructor.value.body) return;
971
+ const instanceVarName = this.findPropsInstanceVariable(
972
+ constructor.value.body,
973
+ propsParamName
974
+ );
975
+ if (!instanceVarName) return;
976
+ for (const member of classBody.body) {
977
+ if (member.type === AST_NODE_TYPES.MethodDefinition && member.value.body) {
978
+ this.visitNodes(member.value.body, instanceVarName);
979
+ }
959
980
  }
960
- const symbol = propsType2.getSymbol();
961
- if (!symbol?.members) return [];
962
- return Array.from(symbol.members.keys()).reduce((acc, key) => {
963
- const name = String(key);
964
- return !isInternalProperty(name) ? [...acc, name] : acc;
965
- }, []);
966
- };
967
- const isInternalProperty = (propertyName) => {
968
- return propertyName.startsWith("_") || propertyName === "constructor" || propertyName === "prototype";
969
- };
970
- const markAsUsed = (propertyName) => {
971
- if (propUsages.has(propertyName)) propUsages.set(propertyName, true);
972
- };
973
- const propUsages = new Map(
974
- getPropsPropertyNames(propsType).map((name) => [name, false])
975
- );
976
- const getUnusedProperties = () => {
977
- return Array.from(propUsages.entries()).reduce(
981
+ }
982
+ analyzePrivateMethodsCalledFromConstructor(constructorBody, classBody, propsParamName) {
983
+ const methodCallsWithProps = this.findMethodCallsWithProps(
984
+ constructorBody,
985
+ propsParamName
986
+ );
987
+ for (const { methodName, propsArgIndices } of methodCallsWithProps) {
988
+ const methodDef = this.findMethodDefinition(classBody, methodName);
989
+ if (!methodDef?.value.body) continue;
990
+ for (const argIndex of propsArgIndices) {
991
+ const param = methodDef.value.params[argIndex];
992
+ if (param && param.type === AST_NODE_TYPES.Identifier) {
993
+ this.visitNodes(methodDef.value.body, param.name);
994
+ }
995
+ }
996
+ }
997
+ }
998
+ visitNodes(node, propsParamName) {
999
+ if (this.visitedNodes.has(node)) return;
1000
+ this.visitedNodes.add(node);
1001
+ switch (node.type) {
1002
+ case AST_NODE_TYPES.MemberExpression:
1003
+ this.propsUsageTracker.markAsUsedForMemberExpression(
1004
+ node,
1005
+ propsParamName
1006
+ );
1007
+ if (node.object.type === AST_NODE_TYPES.Identifier && this.propsAliases.has(node.object.name) && node.property.type === AST_NODE_TYPES.Identifier) {
1008
+ this.propsUsageTracker.markAsUsed(node.property.name);
1009
+ }
1010
+ break;
1011
+ case AST_NODE_TYPES.VariableDeclarator:
1012
+ this.propsUsageTracker.markAsUsedForVariableDeclarator(
1013
+ node,
1014
+ propsParamName
1015
+ );
1016
+ break;
1017
+ case AST_NODE_TYPES.AssignmentExpression:
1018
+ this.propsUsageTracker.markAsUsedForAssignmentExpression(
1019
+ node,
1020
+ propsParamName
1021
+ );
1022
+ break;
1023
+ case AST_NODE_TYPES.Identifier:
1024
+ if (node.name === propsParamName) this.handlePropsIdentifier(node);
1025
+ break;
1026
+ }
1027
+ const children = getChildNodes(node);
1028
+ for (const child of children) {
1029
+ this.visitNodes(child, propsParamName);
1030
+ }
1031
+ }
1032
+ /**
1033
+ * Handles cases where props is used as a whole identifier
1034
+ */
1035
+ handlePropsIdentifier(node) {
1036
+ const parent = node.parent;
1037
+ if (!parent) return;
1038
+ switch (parent.type) {
1039
+ case AST_NODE_TYPES.AssignmentExpression:
1040
+ case AST_NODE_TYPES.MemberExpression: {
1041
+ break;
1042
+ }
1043
+ case AST_NODE_TYPES.VariableDeclarator: {
1044
+ if (parent.init === node && parent.id.type === AST_NODE_TYPES.Identifier) {
1045
+ this.propsAliases.add(parent.id.name);
1046
+ }
1047
+ break;
1048
+ }
1049
+ case AST_NODE_TYPES.CallExpression: {
1050
+ if (!parent.arguments.includes(node)) break;
1051
+ if (parent.callee.type === AST_NODE_TYPES.MemberExpression && parent.callee.object.type === AST_NODE_TYPES.ThisExpression) {
1052
+ break;
1053
+ }
1054
+ this.propsUsageTracker.markAllAsUsed();
1055
+ break;
1056
+ }
1057
+ case AST_NODE_TYPES.ReturnStatement: {
1058
+ if (parent.argument === node) {
1059
+ this.propsUsageTracker.markAllAsUsed();
1060
+ }
1061
+ break;
1062
+ }
1063
+ case AST_NODE_TYPES.ArrayExpression: {
1064
+ if (parent.elements.includes(node)) {
1065
+ this.propsUsageTracker.markAllAsUsed();
1066
+ }
1067
+ break;
1068
+ }
1069
+ case AST_NODE_TYPES.Property: {
1070
+ if (parent.value === node) {
1071
+ this.propsUsageTracker.markAllAsUsed();
1072
+ }
1073
+ break;
1074
+ }
1075
+ }
1076
+ }
1077
+ findPropsInstanceVariable(body, propsParamName) {
1078
+ for (const statement of body.body) {
1079
+ if (statement.type === AST_NODE_TYPES.ExpressionStatement && statement.expression.type === AST_NODE_TYPES.AssignmentExpression && statement.expression.left.type === AST_NODE_TYPES.MemberExpression && statement.expression.left.object.type === AST_NODE_TYPES.ThisExpression && statement.expression.left.property.type === AST_NODE_TYPES.Identifier && statement.expression.right.type === AST_NODE_TYPES.Identifier && statement.expression.right.name === propsParamName) {
1080
+ return statement.expression.left.property.name;
1081
+ }
1082
+ }
1083
+ return null;
1084
+ }
1085
+ /**
1086
+ * Finds method definition in class body
1087
+ */
1088
+ findMethodDefinition(classBody, methodName) {
1089
+ for (const member of classBody.body) {
1090
+ if (member.type === AST_NODE_TYPES.MethodDefinition && member.key.type === AST_NODE_TYPES.Identifier && member.key.name === methodName) {
1091
+ return member;
1092
+ }
1093
+ }
1094
+ return null;
1095
+ }
1096
+ /**
1097
+ * Finds method calls in constructor body that receive props as argument
1098
+ */
1099
+ findMethodCallsWithProps(body, propsParamName) {
1100
+ const result = [];
1101
+ const visited = /* @__PURE__ */ new Set();
1102
+ const visitNode = (node) => {
1103
+ if (visited.has(node)) return;
1104
+ visited.add(node);
1105
+ if (node.type === AST_NODE_TYPES.CallExpression && node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.object.type === AST_NODE_TYPES.ThisExpression && node.callee.property.type === AST_NODE_TYPES.Identifier) {
1106
+ const methodName = node.callee.property.name;
1107
+ const propsArgIndices = node.arguments.reduce(
1108
+ (acc, arg, index) => arg.type === AST_NODE_TYPES.Identifier && arg.name === propsParamName ? (
1109
+ // NOTE: props is passed directly (e.g., this.method(props))
1110
+ [...acc, index]
1111
+ ) : acc,
1112
+ []
1113
+ );
1114
+ if (propsArgIndices.length) {
1115
+ result.push({ methodName, propsArgIndices });
1116
+ }
1117
+ }
1118
+ const children = getChildNodes(node);
1119
+ for (const child of children) {
1120
+ visitNode(child);
1121
+ }
1122
+ };
1123
+ visitNode(body);
1124
+ return result;
1125
+ }
1126
+ }
1127
+
1128
+ class PropsUsageTracker {
1129
+ propUsageMap;
1130
+ constructor(propType) {
1131
+ this.propUsageMap = new Map(
1132
+ this.getPropsPropertyNames(propType).map((name) => [name, false])
1133
+ );
1134
+ }
1135
+ getUnusedProperties() {
1136
+ return Array.from(this.propUsageMap.entries()).reduce(
978
1137
  (acc, [name, used]) => !used ? [...acc, name] : acc,
979
1138
  []
980
1139
  );
981
- };
982
- const markAsUsedForMemberExpression = (node, propsParamName) => {
1140
+ }
1141
+ markAsUsed(propertyName) {
1142
+ if (this.propUsageMap.has(propertyName)) {
1143
+ this.propUsageMap.set(propertyName, true);
1144
+ }
1145
+ }
1146
+ markAllAsUsed() {
1147
+ for (const key of this.propUsageMap.keys()) {
1148
+ this.propUsageMap.set(key, true);
1149
+ }
1150
+ }
1151
+ markAsUsedForMemberExpression(node, propsParamName) {
983
1152
  if (node.object.type === AST_NODE_TYPES.Identifier && node.object.name === propsParamName && node.property.type === AST_NODE_TYPES.Identifier) {
984
- markAsUsed(node.property.name);
1153
+ this.markAsUsed(node.property.name);
985
1154
  return;
986
1155
  }
987
- if (node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.ThisExpression && node.object.property.type === AST_NODE_TYPES.Identifier && node.object.property.name === "props" && node.property.type === AST_NODE_TYPES.Identifier) {
988
- markAsUsed(node.property.name);
1156
+ if (node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.ThisExpression && node.object.property.type === AST_NODE_TYPES.Identifier && node.object.property.name === propsParamName && node.property.type === AST_NODE_TYPES.Identifier) {
1157
+ this.markAsUsed(node.property.name);
989
1158
  return;
990
1159
  }
991
- };
992
- const markAsUsedForVariableDeclarator = (node, propsParamName) => {
1160
+ }
1161
+ markAsUsedForVariableDeclarator(node, propsParamName) {
993
1162
  if (node.id.type !== AST_NODE_TYPES.ObjectPattern || node.init?.type !== AST_NODE_TYPES.Identifier || node.init.name !== propsParamName) {
994
1163
  return;
995
1164
  }
996
1165
  const propertyNames = getPropertyNames(node.id.properties);
997
1166
  for (const name of propertyNames) {
998
- markAsUsed(name);
1167
+ this.markAsUsed(name);
999
1168
  }
1000
- };
1001
- const markAsUsedForAssignmentExpression = (node, propsParamName) => {
1169
+ }
1170
+ markAsUsedForAssignmentExpression(node, propsParamName) {
1002
1171
  if (node.right.type !== AST_NODE_TYPES.MemberExpression || node.right.object.type !== AST_NODE_TYPES.Identifier || node.right.object.name !== propsParamName || node.right.property.type !== AST_NODE_TYPES.Identifier) {
1003
1172
  return;
1004
1173
  }
1005
- markAsUsed(node.right.property.name);
1006
- };
1007
- const markAsUsedForObjectPattern = (node) => {
1008
- for (const propName of getPropertyNames(node.properties)) {
1009
- markAsUsed(propName);
1174
+ this.markAsUsed(node.right.property.name);
1175
+ }
1176
+ /**
1177
+ * Gets the property names from the props type
1178
+ */
1179
+ getPropsPropertyNames(propsType) {
1180
+ const isInternalProperty = (propertyName) => propertyName.startsWith("_") || propertyName === "constructor" || propertyName === "prototype";
1181
+ const typeProperties = propsType.getProperties();
1182
+ if (typeProperties.length) {
1183
+ return typeProperties.reduce(
1184
+ (acc, prop) => !isInternalProperty(prop.name) ? [...acc, prop.name] : acc,
1185
+ []
1186
+ );
1010
1187
  }
1011
- };
1012
- if (!propUsages.size) return null;
1013
- return {
1014
- getUnusedProperties,
1015
- markAsUsedForMemberExpression,
1016
- markAsUsedForVariableDeclarator,
1017
- markAsUsedForAssignmentExpression,
1018
- markAsUsedForObjectPattern
1019
- };
1020
- };
1188
+ const symbol = propsType.getSymbol();
1189
+ if (!symbol?.members) return [];
1190
+ return Array.from(symbol.members.keys()).reduce((acc, key) => {
1191
+ const name = String(key);
1192
+ return !isInternalProperty(name) ? [...acc, name] : acc;
1193
+ }, []);
1194
+ }
1195
+ }
1021
1196
 
1022
1197
  const noUnusedProps = createRule({
1023
1198
  name: "no-unused-props",
@@ -1036,64 +1211,61 @@ const noUnusedProps = createRule({
1036
1211
  const parserServices = ESLintUtils.getParserServices(context);
1037
1212
  return {
1038
1213
  ClassDeclaration(node) {
1214
+ if (node.abstract) return;
1039
1215
  const type = parserServices.getTypeAtLocation(node);
1040
1216
  if (!isConstructType(type)) return;
1041
1217
  const constructor = getConstructor(node);
1042
1218
  if (!constructor) return;
1043
- analyzePropsUsage(constructor, context, parserServices);
1219
+ const propsParam = getPropsParam(constructor, parserServices);
1220
+ if (!propsParam) return;
1221
+ const { node: propsNode, type: propsType } = propsParam;
1222
+ if (isPropsUsedInSuperCall(constructor, propsNode.name)) return;
1223
+ const tracker = new PropsUsageTracker(propsType);
1224
+ const analyzer = new PropsUsageAnalyzer(tracker);
1225
+ analyzer.analyze(constructor, propsNode);
1226
+ reportUnusedProperties(tracker, propsNode, context);
1044
1227
  }
1045
1228
  };
1046
1229
  }
1047
1230
  });
1048
- const analyzePropsUsage = (constructor, context, parserServices) => {
1231
+ const getPropsParam = (constructor, parserServices) => {
1049
1232
  const params = constructor.value.params;
1050
- if (params.length < 3) return;
1233
+ if (params.length < 3) return null;
1051
1234
  const propsParam = params[2];
1052
- switch (propsParam.type) {
1053
- case AST_NODE_TYPES.Identifier: {
1054
- const propsType = parserServices.getTypeAtLocation(propsParam);
1055
- const tracker = propsUsageTrackerFactory(propsType);
1056
- if (!tracker || !constructor.value.body) return;
1057
- analyzeConstructorBody(constructor.value.body, propsParam.name, tracker);
1058
- reportUnusedProperties(tracker, propsParam, context);
1059
- return;
1060
- }
1061
- case AST_NODE_TYPES.ObjectPattern: {
1062
- const typeAnnotation = propsParam.typeAnnotation?.typeAnnotation;
1063
- if (!typeAnnotation) return;
1064
- const propsType = parserServices.getTypeAtLocation(typeAnnotation);
1065
- const tracker = propsUsageTrackerFactory(propsType);
1066
- if (!tracker) return;
1067
- tracker.markAsUsedForObjectPattern(propsParam);
1068
- reportUnusedProperties(tracker, propsParam, context);
1069
- return;
1070
- }
1071
- default:
1072
- return;
1073
- }
1235
+ if (propsParam.type !== AST_NODE_TYPES.Identifier) return null;
1236
+ return {
1237
+ node: propsParam,
1238
+ type: parserServices.getTypeAtLocation(propsParam)
1239
+ };
1074
1240
  };
1075
- const analyzeConstructorBody = (body, propsParamName, tracker) => {
1076
- const visited = /* @__PURE__ */ new Set();
1077
- const visitNode = (node) => {
1078
- if (visited.has(node)) return;
1079
- visited.add(node);
1080
- switch (node.type) {
1081
- case AST_NODE_TYPES.MemberExpression:
1082
- tracker.markAsUsedForMemberExpression(node, propsParamName);
1083
- break;
1084
- case AST_NODE_TYPES.VariableDeclarator:
1085
- tracker.markAsUsedForVariableDeclarator(node, propsParamName);
1086
- break;
1087
- case AST_NODE_TYPES.AssignmentExpression:
1088
- tracker.markAsUsedForAssignmentExpression(node, propsParamName);
1089
- break;
1241
+ const isPropsUsedInSuperCall = (constructor, propsPropertyName) => {
1242
+ if (constructor.kind !== "constructor") return false;
1243
+ const body = constructor.value.body;
1244
+ if (!body) return false;
1245
+ for (const expr of body.body) {
1246
+ if (expr.type !== AST_NODE_TYPES.ExpressionStatement || expr.expression.type !== AST_NODE_TYPES.CallExpression || expr.expression.callee.type !== AST_NODE_TYPES.Super) {
1247
+ continue;
1090
1248
  }
1091
- const children = getChildNodes(node);
1092
- for (const child of children) {
1093
- visitNode(child);
1249
+ const visitNode = (node, propsName) => {
1250
+ const nodeValue = node.type === AST_NODE_TYPES.Property ? node.value : node;
1251
+ switch (nodeValue.type) {
1252
+ case AST_NODE_TYPES.Identifier: {
1253
+ return nodeValue.name === propsName;
1254
+ }
1255
+ case AST_NODE_TYPES.ObjectExpression: {
1256
+ for (const prop of nodeValue.properties) {
1257
+ if (visitNode(prop, propsName)) return true;
1258
+ }
1259
+ break;
1260
+ }
1261
+ }
1262
+ return false;
1263
+ };
1264
+ for (const arg of expr.expression.arguments) {
1265
+ if (visitNode(arg, propsPropertyName)) return true;
1094
1266
  }
1095
- };
1096
- visitNode(body);
1267
+ }
1268
+ return false;
1097
1269
  };
1098
1270
  const reportUnusedProperties = (tracker, propsParam, context) => {
1099
1271
  for (const propName of tracker.getUnusedProperties()) {
@@ -1106,17 +1278,6 @@ const reportUnusedProperties = (tracker, propsParam, context) => {
1106
1278
  });
1107
1279
  }
1108
1280
  };
1109
- const getChildNodes = (node) => {
1110
- return Object.entries(node).reduce((acc, [key, value]) => {
1111
- if (["parent", "range", "loc"].includes(key)) return acc;
1112
- if (isESTreeNode(value)) return [...acc, value];
1113
- if (Array.isArray(value)) return [...acc, ...value.filter(isESTreeNode)];
1114
- return acc;
1115
- }, []);
1116
- };
1117
- const isESTreeNode = (value) => {
1118
- return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
1119
- };
1120
1281
 
1121
1282
  const noVariableConstructId = createRule({
1122
1283
  name: "no-variable-construct-id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-cdk-plugin",
3
- "version": "3.4.2",
3
+ "version": "3.4.4",
4
4
  "description": "eslint plugin for AWS CDK projects",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -30,25 +30,28 @@
30
30
  "prebuild": "rolldown -c"
31
31
  },
32
32
  "devDependencies": {
33
- "@eslint/js": "^9.26.0",
33
+ "@eslint/js": "^9.36.0",
34
34
  "@secretlint/secretlint-rule-preset-recommend": "^11.2.4",
35
- "@types/node": "^22.15.0",
36
- "@typescript-eslint/rule-tester": "^8.32.1",
35
+ "@types/node": "^24.9.2",
36
+ "@typescript-eslint/rule-tester": "^8.46.2",
37
37
  "@vitest/coverage-v8": "3.2.4",
38
38
  "commander": "^14.0.1",
39
39
  "consola": "^3.4.2",
40
- "eslint": "9.36.0",
40
+ "eslint": "^9.38.0",
41
41
  "eslint-plugin-import": "^2.32.0",
42
- "pkgroll": "^2.12.2",
42
+ "pkgroll": "^2.20.1",
43
43
  "rolldown": "1.0.0-beta.45",
44
44
  "secretlint": "^11.2.4",
45
- "typescript": "^5.8.3",
46
- "typescript-eslint": "^8.32.1",
45
+ "typescript": "^5.9.3",
46
+ "typescript-eslint": "^8.46.2",
47
47
  "vitest": "^3.2.4"
48
48
  },
49
49
  "dependencies": {
50
- "@typescript-eslint/parser": "^8.32.1",
51
- "@typescript-eslint/utils": "^8.32.1"
50
+ "@typescript-eslint/parser": "^8.46.2",
51
+ "@typescript-eslint/utils": "^8.46.2"
52
+ },
53
+ "peerDependencies": {
54
+ "typescript": ">=5.0.0"
52
55
  },
53
56
  "engines": {
54
57
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"