@checkdigit/eslint-plugin 7.15.0 → 7.16.0-PR.136-c0c4

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.
@@ -1,4 +1,4 @@
1
- // src/is-aws-sdk-v3-used.ts
1
+ // src/aws/is-aws-sdk-v3-used.ts
2
2
  import { promises as fs } from "node:fs";
3
3
  var cachedIsAwsSdkV3Used;
4
4
  async function isAwsSdkV3Used() {
@@ -13,4 +13,4 @@ async function isAwsSdkV3Used() {
13
13
  export {
14
14
  isAwsSdkV3Used as default
15
15
  };
16
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2lzLWF3cy1zZGstdjMtdXNlZC50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFFQSxTQUFTLFlBQVksVUFBVTtBQVMvQixJQUFJO0FBRUosZUFBTyxpQkFBMEQ7QUFDL0QsTUFBSSx5QkFBeUIsUUFBVztBQUN0QyxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sY0FBYyxLQUFLLE1BQU0sTUFBTSxHQUFHLFNBQVMsZ0JBQWdCLE1BQU0sQ0FBQztBQUN4RSxRQUFNLGVBQWUsWUFBWSxnQkFBZ0IsQ0FBQztBQUVsRCx5QkFBdUIsT0FBTyxLQUFLLFlBQVksRUFBRSxLQUFLLENBQUMsZUFBZSxXQUFXLFdBQVcsV0FBVyxDQUFDO0FBQ3hHLFNBQU87QUFDVDsiLAogICJuYW1lcyI6IFtdCn0K
16
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2F3cy9pcy1hd3Mtc2RrLXYzLXVzZWQudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsU0FBUyxZQUFZLFVBQVU7QUFTL0IsSUFBSTtBQUVKLGVBQU8saUJBQTBEO0FBQy9ELE1BQUkseUJBQXlCLFFBQVc7QUFDdEMsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLGNBQWMsS0FBSyxNQUFNLE1BQU0sR0FBRyxTQUFTLGdCQUFnQixNQUFNLENBQUM7QUFDeEUsUUFBTSxlQUFlLFlBQVksZ0JBQWdCLENBQUM7QUFFbEQseUJBQXVCLE9BQU8sS0FBSyxZQUFZLEVBQUUsS0FBSyxDQUFDLGVBQWUsV0FBVyxXQUFXLFdBQVcsQ0FBQztBQUN4RyxTQUFPO0FBQ1Q7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -1,6 +1,6 @@
1
- // src/require-aws-config.ts
1
+ // src/aws/require-aws-config.ts
2
2
  import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
3
- import getDocumentationUrl from "./get-documentation-url.mjs";
3
+ import getDocumentationUrl from "../get-documentation-url.mjs";
4
4
  var ruleId = "require-aws-config";
5
5
  var MESSAGE_ID_REQUIRE_AWS_CONFIG = "requireAwsConfig";
6
6
  var MESSAGE_ID_NO_CHECKDIGIT_AWS = "noCheckdigitAws";
@@ -82,4 +82,4 @@ export {
82
82
  require_aws_config_default as default,
83
83
  ruleId
84
84
  };
85
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlcXVpcmUtYXdzLWNvbmZpZy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLGdCQUFnQixtQkFBNkI7QUFDdEQsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBQ2YsSUFBTSxnQ0FBZ0M7QUFDdEMsSUFBTSwrQkFBK0I7QUFDNUMsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxTQUFTLHFCQUFxQixtQkFBd0Q7QUFDcEYsU0FBTyxrQkFBa0IsT0FBTyxNQUFNLFdBQVcsa0JBQWtCO0FBQ3JFO0FBRUEsU0FBUyxzQkFBc0IsbUJBQXdEO0FBQ3JGLFNBQU8sa0JBQWtCLE9BQU8sVUFBVTtBQUM1QztBQUVBLFNBQVMsWUFBWSxlQUF1QixvQkFBMkM7QUFHckYsU0FDRSxjQUFjLFNBQVMsUUFBUSxNQUFNLHVCQUF1QixVQUFhLG1CQUFtQixJQUFJLGFBQWE7QUFFakg7QUFFQSxJQUFNLE9BQ0osV0FBVztBQUFBLEVBQ1QsTUFBTTtBQUFBLEVBQ04sTUFBTTtBQUFBLElBQ0osTUFBTTtBQUFBLElBQ04sTUFBTTtBQUFBLE1BQ0osYUFDRTtBQUFBLElBQ0o7QUFBQSxJQUNBLFVBQVU7QUFBQSxNQUNSLENBQUMsNkJBQTZCLEdBQzVCO0FBQUEsTUFDRixDQUFDLDRCQUE0QixHQUMzQjtBQUFBLElBQ0o7QUFBQSxJQUNBLFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxFQUFFLGVBQWUsSUFBSSxRQUFRO0FBQ25DLFVBQU0scUJBQXFCLG9CQUFJLElBQVk7QUFFM0MsV0FBTztBQUFBLE1BQ0wsa0JBQWtCLE1BQU07QUFDdEIsWUFBSSxtQkFBbUIsTUFBTTtBQUMzQjtBQUFBLFFBQ0Y7QUFFQSxZQUFJLHNCQUFzQixJQUFJLEdBQUc7QUFDL0Isa0JBQVEsT0FBTztBQUFBLFlBQ2I7QUFBQSxZQUNBLFdBQVc7QUFBQSxVQUNiLENBQUM7QUFDRDtBQUFBLFFBQ0Y7QUFFQSxZQUFJLHFCQUFxQixJQUFJLEdBQUc7QUFDOUIscUJBQVcsYUFBYSxLQUFLLFlBQVk7QUFDdkMsZ0JBQUksVUFBVSxTQUFTLGVBQWUsbUJBQW1CLFlBQVksVUFBVSxNQUFNLElBQUksR0FBRztBQUMxRixpQ0FBbUIsSUFBSSxVQUFVLE1BQU0sSUFBSTtBQUFBLFlBQzdDO0FBQUEsVUFDRjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsTUFFQSxjQUFjLE1BQU07QUFDbEIsWUFBSSxtQkFBbUIsTUFBTTtBQUMzQjtBQUFBLFFBQ0Y7QUFFQSxZQUFJLEtBQUssT0FBTyxTQUFTLGVBQWUsY0FBYyxZQUFZLEtBQUssT0FBTyxNQUFNLGtCQUFrQixHQUFHO0FBQ3ZHLGtCQUFRLE9BQU87QUFBQSxZQUNiO0FBQUEsWUFDQSxXQUFXO0FBQUEsWUFDWCxNQUFNLEVBQUUsZUFBZSxLQUFLLE9BQU8sS0FBSztBQUFBLFVBQzFDLENBQUM7QUFBQSxRQUNILFdBQVcsS0FBSyxPQUFPLFNBQVMsZUFBZSxrQkFBa0I7QUFFL0QsZ0JBQU0sV0FBVyxLQUFLLE9BQU87QUFDN0IsY0FBSSxTQUFTLFNBQVMsZUFBZSxjQUFjLFlBQVksU0FBUyxNQUFNLGtCQUFrQixHQUFHO0FBQ2pHLG9CQUFRLE9BQU87QUFBQSxjQUNiO0FBQUEsY0FDQSxXQUFXO0FBQUEsY0FDWCxNQUFNLEVBQUUsZUFBZSxTQUFTLEtBQUs7QUFBQSxZQUN2QyxDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRixDQUFDO0FBRUgsSUFBTyw2QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K
85
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2F3cy9yZXF1aXJlLWF3cy1jb25maWcudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBUUEsU0FBUyxnQkFBZ0IsbUJBQTZCO0FBQ3RELE9BQU8seUJBQXlCO0FBRXpCLElBQU0sU0FBUztBQUNmLElBQU0sZ0NBQWdDO0FBQ3RDLElBQU0sK0JBQStCO0FBQzVDLElBQU0sYUFBYSxZQUFZLFlBQVksQ0FBQyxTQUFTLG9CQUFvQixJQUFJLENBQUM7QUFFOUUsU0FBUyxxQkFBcUIsbUJBQXdEO0FBQ3BGLFNBQU8sa0JBQWtCLE9BQU8sTUFBTSxXQUFXLGtCQUFrQjtBQUNyRTtBQUVBLFNBQVMsc0JBQXNCLG1CQUF3RDtBQUNyRixTQUFPLGtCQUFrQixPQUFPLFVBQVU7QUFDNUM7QUFFQSxTQUFTLFlBQVksZUFBdUIsb0JBQTJDO0FBR3JGLFNBQ0UsY0FBYyxTQUFTLFFBQVEsTUFBTSx1QkFBdUIsVUFBYSxtQkFBbUIsSUFBSSxhQUFhO0FBRWpIO0FBRUEsSUFBTSxPQUNKLFdBQVc7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQ0U7QUFBQSxJQUNKO0FBQUEsSUFDQSxVQUFVO0FBQUEsTUFDUixDQUFDLDZCQUE2QixHQUM1QjtBQUFBLE1BQ0YsQ0FBQyw0QkFBNEIsR0FDM0I7QUFBQSxJQUNKO0FBQUEsSUFDQSxRQUFRLENBQUM7QUFBQSxFQUNYO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQztBQUFBLEVBQ2pCLE9BQU8sU0FBUztBQUNkLFVBQU0sRUFBRSxlQUFlLElBQUksUUFBUTtBQUNuQyxVQUFNLHFCQUFxQixvQkFBSSxJQUFZO0FBRTNDLFdBQU87QUFBQSxNQUNMLGtCQUFrQixNQUFNO0FBQ3RCLFlBQUksbUJBQW1CLE1BQU07QUFDM0I7QUFBQSxRQUNGO0FBRUEsWUFBSSxzQkFBc0IsSUFBSSxHQUFHO0FBQy9CLGtCQUFRLE9BQU87QUFBQSxZQUNiO0FBQUEsWUFDQSxXQUFXO0FBQUEsVUFDYixDQUFDO0FBQ0Q7QUFBQSxRQUNGO0FBRUEsWUFBSSxxQkFBcUIsSUFBSSxHQUFHO0FBQzlCLHFCQUFXLGFBQWEsS0FBSyxZQUFZO0FBQ3ZDLGdCQUFJLFVBQVUsU0FBUyxlQUFlLG1CQUFtQixZQUFZLFVBQVUsTUFBTSxJQUFJLEdBQUc7QUFDMUYsaUNBQW1CLElBQUksVUFBVSxNQUFNLElBQUk7QUFBQSxZQUM3QztBQUFBLFVBQ0Y7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLE1BRUEsY0FBYyxNQUFNO0FBQ2xCLFlBQUksbUJBQW1CLE1BQU07QUFDM0I7QUFBQSxRQUNGO0FBRUEsWUFBSSxLQUFLLE9BQU8sU0FBUyxlQUFlLGNBQWMsWUFBWSxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsR0FBRztBQUN2RyxrQkFBUSxPQUFPO0FBQUEsWUFDYjtBQUFBLFlBQ0EsV0FBVztBQUFBLFlBQ1gsTUFBTSxFQUFFLGVBQWUsS0FBSyxPQUFPLEtBQUs7QUFBQSxVQUMxQyxDQUFDO0FBQUEsUUFDSCxXQUFXLEtBQUssT0FBTyxTQUFTLGVBQWUsa0JBQWtCO0FBRS9ELGdCQUFNLFdBQVcsS0FBSyxPQUFPO0FBQzdCLGNBQUksU0FBUyxTQUFTLGVBQWUsY0FBYyxZQUFZLFNBQVMsTUFBTSxrQkFBa0IsR0FBRztBQUNqRyxvQkFBUSxPQUFPO0FBQUEsY0FDYjtBQUFBLGNBQ0EsV0FBVztBQUFBLGNBQ1gsTUFBTSxFQUFFLGVBQWUsU0FBUyxLQUFLO0FBQUEsWUFDdkMsQ0FBQztBQUFBLFVBQ0g7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVILElBQU8sNkJBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,128 @@
1
+ // src/aws/require-consistent-read.ts
2
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
3
+ import getDocumentationUrl from "../get-documentation-url.mjs";
4
+ var ruleId = "require-consistent-read";
5
+ var MESSAGE_ID_CONSISTENT_READ_TRUE = "MESSAGE_ID_CONSISTENT_READ_TRUE";
6
+ var MESSAGE_ID_CONSISTENT_READ_FALSE = "MESSAGE_ID_CONSISTENT_READ_FALSE";
7
+ function getPropertyName(property) {
8
+ if (property.computed) {
9
+ return void 0;
10
+ }
11
+ const propertyKey = property.key;
12
+ return propertyKey.type === AST_NODE_TYPES.Identifier ? propertyKey.name : typeof propertyKey.value === "string" ? propertyKey.value : void 0;
13
+ }
14
+ function extractObjectProperties(objectExpression) {
15
+ const objectProperties = {};
16
+ for (const property of objectExpression.properties) {
17
+ if (property.type !== AST_NODE_TYPES.Property || property.computed) {
18
+ continue;
19
+ }
20
+ const propertyName = getPropertyName(property);
21
+ if (propertyName !== void 0) {
22
+ objectProperties[propertyName] = property;
23
+ }
24
+ }
25
+ return objectProperties;
26
+ }
27
+ function existsRequestItemsProperty(extractedObjectProperties) {
28
+ const requestItemProperty = extractedObjectProperties["RequestItems"];
29
+ if (requestItemProperty?.type !== AST_NODE_TYPES.Property) {
30
+ return false;
31
+ }
32
+ const requestItemValue = requestItemProperty.value;
33
+ if (requestItemValue.type !== AST_NODE_TYPES.ObjectExpression) {
34
+ return false;
35
+ }
36
+ return requestItemValue.properties.some(
37
+ (property) => property.type === AST_NODE_TYPES.Property && property.value.type === AST_NODE_TYPES.ObjectExpression && extractObjectProperties(property.value)["Keys"]?.value.type === AST_NODE_TYPES.ArrayExpression
38
+ );
39
+ }
40
+ function existsKeyProperty(extractedObjectProperties) {
41
+ const keyProperty = extractedObjectProperties["Key"];
42
+ return keyProperty?.type === AST_NODE_TYPES.Property && keyProperty.value.type === AST_NODE_TYPES.ObjectExpression;
43
+ }
44
+ function getReadCommandInfo(objectExpression) {
45
+ const extractedProperties = extractObjectProperties(objectExpression);
46
+ let readCommandInfo;
47
+ if (existsRequestItemsProperty(extractedProperties)) {
48
+ readCommandInfo = { type: "BatchGetItem" };
49
+ } else {
50
+ const hasTableName = "TableName" in extractedProperties;
51
+ const hasKey = existsKeyProperty(extractedProperties);
52
+ if (hasTableName && hasKey) {
53
+ if (!("UpdateExpression" in extractedProperties) && !("ConditionExpression" in extractedProperties)) {
54
+ readCommandInfo = { type: "GetItem" };
55
+ }
56
+ } else {
57
+ const hasKeyCondExpr = extractedProperties["KeyConditionExpression"]?.value.type === AST_NODE_TYPES.Literal;
58
+ const hasLegacyKeyConditions = extractedProperties["KeyConditions"]?.value.type === AST_NODE_TYPES.ObjectExpression;
59
+ if (hasTableName && (hasKeyCondExpr || hasLegacyKeyConditions)) {
60
+ readCommandInfo = { type: "Query" };
61
+ }
62
+ }
63
+ }
64
+ if (readCommandInfo === void 0) {
65
+ return void 0;
66
+ }
67
+ const consistentReadProperty = extractedProperties["ConsistentRead"];
68
+ if (consistentReadProperty?.type === AST_NODE_TYPES.Property && consistentReadProperty.value.type === AST_NODE_TYPES.Literal && typeof consistentReadProperty.value.value === "boolean") {
69
+ readCommandInfo.consistentRead = consistentReadProperty.value.value;
70
+ }
71
+ const indexNameProperty = extractedProperties["IndexName"];
72
+ if (indexNameProperty?.type === AST_NODE_TYPES.Property && indexNameProperty.value.type === AST_NODE_TYPES.Literal && typeof indexNameProperty.value.value === "string") {
73
+ readCommandInfo.usedIndex = true;
74
+ }
75
+ return readCommandInfo;
76
+ }
77
+ var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
78
+ var rule = createRule({
79
+ name: ruleId,
80
+ meta: {
81
+ type: "problem",
82
+ docs: {
83
+ description: "For AWS dynamodb commands Query/GetItem/BatchGetItem, ConsistentRead option should always be set as true unless global index is used. This will make the service more robust at the ignorable cost of RCU."
84
+ },
85
+ messages: {
86
+ [MESSAGE_ID_CONSISTENT_READ_TRUE]: "ConsistentRead option should always be set as true for {{readCommandType}} command.",
87
+ [MESSAGE_ID_CONSISTENT_READ_FALSE]: "ConsistentRead option should not be set as true for {{readCommandType}} command when using a global secondary index."
88
+ },
89
+ schema: []
90
+ },
91
+ defaultOptions: [],
92
+ create(context) {
93
+ const sourceCode = context.sourceCode;
94
+ return {
95
+ ObjectExpression(node) {
96
+ const text = sourceCode.getText(node);
97
+ if (!/TableName|RequestItems|KeyConditionExpression|KeyConditions/u.test(text)) {
98
+ return;
99
+ }
100
+ const readCommandInfo = getReadCommandInfo(node);
101
+ if (readCommandInfo !== void 0) {
102
+ if (readCommandInfo.usedIndex !== true && readCommandInfo.consistentRead !== true) {
103
+ context.report({
104
+ node,
105
+ messageId: MESSAGE_ID_CONSISTENT_READ_TRUE,
106
+ data: { readCommandType: readCommandInfo.type }
107
+ });
108
+ } else if (readCommandInfo.usedIndex === true && readCommandInfo.consistentRead !== false) {
109
+ context.report({
110
+ node,
111
+ messageId: MESSAGE_ID_CONSISTENT_READ_FALSE,
112
+ data: { readCommandType: readCommandInfo.type }
113
+ });
114
+ }
115
+ }
116
+ }
117
+ };
118
+ }
119
+ });
120
+ var require_consistent_read_default = rule;
121
+ export {
122
+ MESSAGE_ID_CONSISTENT_READ_FALSE,
123
+ MESSAGE_ID_CONSISTENT_READ_TRUE,
124
+ require_consistent_read_default as default,
125
+ getReadCommandInfo,
126
+ ruleId
127
+ };
128
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2F3cy9yZXF1aXJlLWNvbnNpc3RlbnQtcmVhZC50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLGdCQUFnQixtQkFBNkI7QUFDdEQsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBQ2YsSUFBTSxrQ0FBa0M7QUFDeEMsSUFBTSxtQ0FBbUM7QUFRaEQsU0FBUyxnQkFBZ0IsVUFBaUQ7QUFDeEUsTUFBSSxTQUFTLFVBQVU7QUFDckIsV0FBTztBQUFBLEVBQ1Q7QUFDQSxRQUFNLGNBQWMsU0FBUztBQUU3QixTQUFPLFlBQVksU0FBUyxlQUFlLGFBQ3ZDLFlBQVksT0FDWixPQUFPLFlBQVksVUFBVSxXQUMzQixZQUFZLFFBQ1o7QUFDUjtBQUVBLFNBQVMsd0JBQXdCLGtCQUFnRjtBQUMvRyxRQUFNLG1CQUFzRCxDQUFDO0FBQzdELGFBQVcsWUFBWSxpQkFBaUIsWUFBWTtBQUNsRCxRQUFJLFNBQVMsU0FBUyxlQUFlLFlBQVksU0FBUyxVQUFVO0FBQ2xFO0FBQUEsSUFDRjtBQUNBLFVBQU0sZUFBZSxnQkFBZ0IsUUFBUTtBQUM3QyxRQUFJLGlCQUFpQixRQUFXO0FBQzlCLHVCQUFpQixZQUFZLElBQUk7QUFBQSxJQUNuQztBQUFBLEVBQ0Y7QUFDQSxTQUFPO0FBQ1Q7QUFFQSxTQUFTLDJCQUEyQiwyQkFBdUU7QUFDekcsUUFBTSxzQkFBc0IsMEJBQTBCLGNBQWM7QUFDcEUsTUFBSSxxQkFBcUIsU0FBUyxlQUFlLFVBQVU7QUFDekQsV0FBTztBQUFBLEVBQ1Q7QUFDQSxRQUFNLG1CQUFtQixvQkFBb0I7QUFDN0MsTUFBSSxpQkFBaUIsU0FBUyxlQUFlLGtCQUFrQjtBQUM3RCxXQUFPO0FBQUEsRUFDVDtBQUVBLFNBQU8saUJBQWlCLFdBQVc7QUFBQSxJQUNqQyxDQUFDLGFBQ0MsU0FBUyxTQUFTLGVBQWUsWUFDakMsU0FBUyxNQUFNLFNBQVMsZUFBZSxvQkFDdkMsd0JBQXdCLFNBQVMsS0FBSyxFQUFFLE1BQU0sR0FB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
@@ -17,7 +17,8 @@ import noServeRuntime, { ruleId as noServeRuntimeRuleId } from "./no-serve-runti
17
17
  import requireServiceCallResponseDeclaration, {
18
18
  ruleId as requireServiceCallResponseDeclarationRuleId
19
19
  } from "./require-service-call-response-declaration.mjs";
20
- import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from "./require-aws-config.mjs";
20
+ import requireConsistentRead, { ruleId as requireConsistentReadRuleId } from "./aws/require-consistent-read.mjs";
21
+ import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from "./aws/require-aws-config.mjs";
21
22
  import filePathComment from "./file-path-comment.mjs";
22
23
  import noCardNumbers from "./no-card-numbers.mjs";
23
24
  import noEnum from "./no-enum.mjs";
@@ -33,7 +34,7 @@ import requireAssertPredicateRejectsThrows from "./require-assert-predicate-reje
33
34
  import requireStrictAssert from "./require-strict-assert.mjs";
34
35
  import requireAssertMessage from "./require-assert-message.mjs";
35
36
  import requireTsExtensionImportsExports from "./require-ts-extension-imports-exports.mjs";
36
- import { default as default2 } from "./is-aws-sdk-v3-used.mjs";
37
+ import { default as default2 } from "./aws/is-aws-sdk-v3-used.mjs";
37
38
  var rules = {
38
39
  "file-path-comment": filePathComment,
39
40
  "no-card-numbers": noCardNumbers,
@@ -60,7 +61,8 @@ var rules = {
60
61
  [requireServiceCallResponseDeclarationRuleId]: requireServiceCallResponseDeclaration,
61
62
  [requireAwsConfigRuleId]: requireAwsConfig,
62
63
  [requireFixedServicesImportRuleId]: requireFixedServicesImport,
63
- [requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports
64
+ [requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports,
65
+ [requireConsistentReadRuleId]: requireConsistentRead
64
66
  };
65
67
  var plugin = {
66
68
  rules
@@ -98,6 +100,7 @@ var configs = {
98
100
  [`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
99
101
  [`@checkdigit/${noServeRuntimeRuleId}`]: "error",
100
102
  [`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "error",
103
+ [`@checkdigit/${requireConsistentReadRuleId}`]: "error",
101
104
  [`@checkdigit/${requireAwsConfigRuleId}`]: "error"
102
105
  }
103
106
  }
@@ -134,6 +137,7 @@ var configs = {
134
137
  [`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
135
138
  [`@checkdigit/${noServeRuntimeRuleId}`]: "off",
136
139
  [`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "off",
140
+ [`@checkdigit/${requireConsistentReadRuleId}`]: "off",
137
141
  [`@checkdigit/${requireAwsConfigRuleId}`]: "off"
138
142
  }
139
143
  }
@@ -148,4 +152,4 @@ export {
148
152
  index_default as default,
149
153
  default2 as isAwsSdkV3Used
150
154
  };
151
- //# sourceMappingURL=data:application/json;base64,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UUFDbEQsQ0FBQyxlQUFlLDJCQUEyQixFQUFFLEdBQUc7QUFBQSxRQUNoRCxDQUFDLGVBQWUsZ0NBQWdDLEVBQUUsR0FBRztBQUFBLFFBQ3JELENBQUMsZUFBZSx5QkFBeUIsRUFBRSxHQUFHO0FBQUEsUUFDOUMsQ0FBQyxlQUFlLGdDQUFnQyxFQUFFLEdBQUc7QUFBQSxRQUNyRCxDQUFDLGVBQWUscUNBQXFDLEVBQUUsR0FBRztBQUFBLFFBQzFELENBQUMsZUFBZSxvQkFBb0IsRUFBRSxHQUFHO0FBQUEsUUFDekMsQ0FBQyxlQUFlLDJDQUEyQyxFQUFFLEdBQUc7QUFBQSxRQUNoRSxDQUFDLGVBQWUsc0JBQXNCLEVBQUUsR0FBRztBQUFBLE1BQzdDO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQSxFQUNBLGFBQWE7QUFBQSxJQUNYO0FBQUEsTUFDRSxPQUFPLENBQUMsU0FBUztBQUFBLE1BQ2pCLFNBQVM7QUFBQSxRQUNQLGVBQWU7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTztBQUFBLFFBQ0wsK0JBQStCO0FBQUEsUUFDL0IsdUJBQXVCO0FBQUEsUUFDdkIsaUNBQWlDO0FBQUEsUUFDakMsaUNBQWlDO0FBQUEsUUFDakMscUNBQXFDO0FBQUEsUUFDckMsdUJBQXVCO0FBQUEsUUFDdkIsdUJBQXVCO0FBQUEsUUFDdkIsc0NBQXNDO0FBQUEsUUFDdEMscUNBQXFDO0FBQUEsUUFDckMsb0RBQW9EO0FBQUEsUUFDcEQsa0NBQWtDO0FBQUEsUUFDbEMsK0JBQStCO0FBQUEsUUFDL0IsMENBQTBDO0FBQUEsUUFDMUMsdURBQXVEO0FBQUEsUUFDdkQsdUNBQXVDO0FBQUEsUUFDdkMsOEJBQThCO0FBQUEsUUFDOUIsQ0FBQyxlQUFlLDBCQUEwQixFQUFFLEdBQUc7QUFBQSxRQUMvQyxDQUFDLGVBQWUsNkJBQTZCLEVBQUUsR0FBRztBQUFBLFFBQ2xELENBQUMsZUFBZSwyQkFBMkIsRUFBRSxHQUFHO0FBQUEsUUFDaEQsQ0FBQyxlQUFlLGdDQUFnQyxFQUFFLEdBQUc7QUFBQSxRQUNyRCxDQUFDLGVBQWUseUJBQXlCLEVBQUUsR0FBRztBQUFBLFFBQzlDLENBQUMsZUFBZSxnQ0FBZ0MsRUFBRSxHQUFHO0FBQUEsUUFDckQsQ0FBQyxlQUFlLHFDQUFxQyxFQUFFLEdBQUc7QUFBQSxRQUMxRCxDQUFDLGVBQWUsb0JBQW9CLEVBQUUsR0FBRztBQUFBLFFBQ3pDLENBQUMsZUFBZSwyQ0FBMkMsRUFBRSxHQUFHO0FBQUEsUUFDaEUsQ0FBQyxlQUFlLHNCQUFzQixFQUFFLEdBQUc7QUFBQSxNQUM3QztBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0Y7QUFFQSxJQUFNLGtCQUVGO0FBQUEsRUFDRixHQUFHO0FBQUEsRUFDSDtBQUNGO0FBQ0EsSUFBTyxnQkFBUTsiLAogICJuYW1lcyI6IFsiZGVmYXVsdCJdCn0K
155
+ //# sourceMappingURL=data:application/json;base64,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
@@ -0,0 +1,12 @@
1
+ import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';
2
+ export declare const ruleId = "require-consistent-read";
3
+ export declare const MESSAGE_ID_CONSISTENT_READ_TRUE = "MESSAGE_ID_CONSISTENT_READ_TRUE";
4
+ export declare const MESSAGE_ID_CONSISTENT_READ_FALSE = "MESSAGE_ID_CONSISTENT_READ_FALSE";
5
+ interface ReadCommandInfo {
6
+ type: 'GetItem' | 'Query' | 'BatchGetItem';
7
+ consistentRead?: boolean;
8
+ usedIndex?: boolean;
9
+ }
10
+ export declare function getReadCommandInfo(objectExpression: TSESTree.ObjectExpression): ReadCommandInfo | undefined;
11
+ declare const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_CONSISTENT_READ_TRUE | typeof MESSAGE_ID_CONSISTENT_READ_FALSE>;
12
+ export default rule;
@@ -1,5 +1,5 @@
1
1
  import type { TSESLint } from '@typescript-eslint/utils';
2
- export { default as isAwsSdkV3Used } from './is-aws-sdk-v3-used.ts';
2
+ export { default as isAwsSdkV3Used } from './aws/is-aws-sdk-v3-used.ts';
3
3
  declare const defaultToExport: Exclude<TSESLint.FlatConfig.Plugin, 'config'> & {
4
4
  configs: Record<string, TSESLint.FlatConfig.Config[]>;
5
5
  };
package/package.json CHANGED
@@ -1,96 +1 @@
1
- {
2
- "name": "@checkdigit/eslint-plugin",
3
- "version": "7.15.0",
4
- "description": "Check Digit eslint plugins",
5
- "keywords": [
6
- "eslint",
7
- "eslintplugin"
8
- ],
9
- "homepage": "https://github.com/checkdigit/eslint-plugin#readme",
10
- "bugs": {
11
- "url": "https://github.com/checkdigit/eslint-plugin/issues"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/checkdigit/eslint-plugin"
16
- },
17
- "license": "MIT",
18
- "author": "Check Digit, LLC",
19
- "sideEffects": false,
20
- "type": "module",
21
- "exports": {
22
- ".": {
23
- "types": "./dist-types/index.d.ts",
24
- "import": "./dist-mjs/index.mjs",
25
- "default": "./dist-mjs/index.mjs"
26
- }
27
- },
28
- "files": [
29
- "src",
30
- "dist-types",
31
- "dist-mjs",
32
- "!src/**/test/**",
33
- "!src/**/*.test.ts",
34
- "!src/**/*.spec.ts",
35
- "!dist-types/**/test/**",
36
- "!dist-types/**/*.test.d.ts",
37
- "!dist-types/**/*.spec.d.ts",
38
- "!dist-mjs/**/test/**",
39
- "!dist-mjs/**/*.test.mjs",
40
- "!dist-mjs/**/*.spec.mjs",
41
- "SECURITY.md"
42
- ],
43
- "scripts": {
44
- "build:dist-mjs": "rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs",
45
- "build:dist-types": "rimraf dist-types && npx builder --type=types --outDir=dist-types",
46
- "ci:compile": "tsc --noEmit",
47
- "ci:coverage": "NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true",
48
- "ci:lint": "npm run lint",
49
- "ci:style": "npm run prettier",
50
- "ci:test": "NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false",
51
- "lint": "eslint --max-warnings 0 .",
52
- "lint:fix": "eslint --max-warnings 0 --fix .",
53
- "prepare": "",
54
- "prepublishOnly": "npm run build:dist-types && npm run build:dist-mjs",
55
- "prettier": "prettier --ignore-path .gitignore --list-different .",
56
- "prettier:fix": "prettier --ignore-path .gitignore --write .",
57
- "test": "npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"
58
- },
59
- "prettier": "@checkdigit/prettier-config",
60
- "jest": {
61
- "preset": "@checkdigit/jest-config"
62
- },
63
- "dependencies": {
64
- "@typescript-eslint/type-utils": "^8.46.0",
65
- "@typescript-eslint/utils": "^8.46.0",
66
- "http-status-codes": "^2.3.0",
67
- "ts-api-utils": "^2.1.0"
68
- },
69
- "devDependencies": {
70
- "@checkdigit/jest-config": "^6.0.2",
71
- "@checkdigit/prettier-config": "^6.1.0",
72
- "@checkdigit/typescript-config": "^9.3.1",
73
- "@eslint/js": "^9.37.0",
74
- "@types/eslint": "^9.6.1",
75
- "@types/eslint-config-prettier": "^6.11.3",
76
- "@typescript-eslint/parser": "^8.46.0",
77
- "@typescript-eslint/rule-tester": "^8.46.0",
78
- "eslint": "^9.37.0",
79
- "eslint-config-prettier": "^10.1.8",
80
- "eslint-import-resolver-typescript": "^4.4.4",
81
- "eslint-plugin-eslint-plugin": "^6.4.0",
82
- "eslint-plugin-import": "^2.32.0",
83
- "eslint-plugin-no-only-tests": "^3.3.0",
84
- "eslint-plugin-no-secrets": "^2.2.1",
85
- "eslint-plugin-node": "^11.1.0",
86
- "eslint-plugin-sonarjs": "1.0.4",
87
- "rimraf": "^6.0.1",
88
- "typescript-eslint": "^8.46.0"
89
- },
90
- "peerDependencies": {
91
- "eslint": ">=9 <10"
92
- },
93
- "engines": {
94
- "node": ">=22.18"
95
- }
96
- }
1
+ {"name":"@checkdigit/eslint-plugin","version":"7.16.0-PR.136-c0c4","description":"Check Digit eslint plugins","keywords":["eslint","eslintplugin"],"homepage":"https://github.com/checkdigit/eslint-plugin#readme","bugs":{"url":"https://github.com/checkdigit/eslint-plugin/issues"},"repository":{"type":"git","url":"https://github.com/checkdigit/eslint-plugin"},"license":"MIT","author":"Check Digit, LLC","sideEffects":false,"type":"module","exports":{".":{"types":"./dist-types/index.d.ts","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-mjs","!src/**/test/**","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/test/**","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-mjs/**/test/**","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-mjs":"rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs","build:dist-types":"rimraf dist-types && npx builder --type=types --outDir=dist-types","ci:compile":"tsc --noEmit","ci:coverage":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false","lint":"eslint --max-warnings 0 .","lint:fix":"eslint --max-warnings 0 --fix .","prepare":"","prepublishOnly":"npm run build:dist-types && npm run build:dist-mjs","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"},"prettier":"@checkdigit/prettier-config","jest":{"preset":"@checkdigit/jest-config"},"dependencies":{"@typescript-eslint/type-utils":"^8.46.0","@typescript-eslint/utils":"^8.46.0","http-status-codes":"^2.3.0","ts-api-utils":"^2.1.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^6.1.0","@checkdigit/typescript-config":"^9.3.2","@eslint/js":"^9.37.0","@types/eslint":"^9.6.1","@types/eslint-config-prettier":"^6.11.3","@typescript-eslint/parser":"^8.46.0","@typescript-eslint/rule-tester":"^8.46.0","eslint":"^9.37.0","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-eslint-plugin":"^6.4.0","eslint-plugin-import":"^2.32.0","eslint-plugin-no-only-tests":"^3.3.0","eslint-plugin-no-secrets":"^2.2.1","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"1.0.4","rimraf":"^6.0.1","typescript-eslint":"^8.46.0"},"peerDependencies":{"eslint":">=9 <10"},"engines":{"node":">=22.18"}}
@@ -1,4 +1,4 @@
1
- // is-aws-sdk-v3-used.ts
1
+ // aws/is-aws-sdk-v3-used.ts
2
2
 
3
3
  import { promises as fs } from 'node:fs';
4
4
 
@@ -1,4 +1,4 @@
1
- // require-aws-config.ts
1
+ // aws/require-aws-config.ts
2
2
 
3
3
  /*
4
4
  * Copyright (c) 2021-2025 Check Digit, LLC
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { AST_NODE_TYPES, ESLintUtils, TSESTree } from '@typescript-eslint/utils';
10
- import getDocumentationUrl from './get-documentation-url.ts';
10
+ import getDocumentationUrl from '../get-documentation-url.ts';
11
11
 
12
12
  export const ruleId = 'require-aws-config';
13
13
  export const MESSAGE_ID_REQUIRE_AWS_CONFIG = 'requireAwsConfig';
@@ -0,0 +1,175 @@
1
+ // aws/require-consistent-read.ts
2
+
3
+ /*
4
+ * Copyright (c) 2021-2025 Check Digit, LLC
5
+ *
6
+ * This code is licensed under the MIT license (see LICENSE.txt for details).
7
+ */
8
+
9
+ import { AST_NODE_TYPES, ESLintUtils, TSESTree } from '@typescript-eslint/utils';
10
+ import getDocumentationUrl from '../get-documentation-url.ts';
11
+
12
+ export const ruleId = 'require-consistent-read';
13
+ export const MESSAGE_ID_CONSISTENT_READ_TRUE = 'MESSAGE_ID_CONSISTENT_READ_TRUE';
14
+ export const MESSAGE_ID_CONSISTENT_READ_FALSE = 'MESSAGE_ID_CONSISTENT_READ_FALSE';
15
+
16
+ interface ReadCommandInfo {
17
+ type: 'GetItem' | 'Query' | 'BatchGetItem';
18
+ consistentRead?: boolean;
19
+ usedIndex?: boolean;
20
+ }
21
+
22
+ function getPropertyName(property: TSESTree.Property): string | undefined {
23
+ if (property.computed) {
24
+ return undefined;
25
+ }
26
+ const propertyKey = property.key;
27
+ // eslint-disable-next-line no-nested-ternary
28
+ return propertyKey.type === AST_NODE_TYPES.Identifier
29
+ ? propertyKey.name
30
+ : typeof propertyKey.value === 'string'
31
+ ? propertyKey.value
32
+ : undefined;
33
+ }
34
+
35
+ function extractObjectProperties(objectExpression: TSESTree.ObjectExpression): Record<string, TSESTree.Property> {
36
+ const objectProperties: Record<string, TSESTree.Property> = {};
37
+ for (const property of objectExpression.properties) {
38
+ if (property.type !== AST_NODE_TYPES.Property || property.computed) {
39
+ continue;
40
+ }
41
+ const propertyName = getPropertyName(property);
42
+ if (propertyName !== undefined) {
43
+ objectProperties[propertyName] = property;
44
+ }
45
+ }
46
+ return objectProperties;
47
+ }
48
+
49
+ function existsRequestItemsProperty(extractedObjectProperties: Record<string, TSESTree.Property>): boolean {
50
+ const requestItemProperty = extractedObjectProperties['RequestItems'];
51
+ if (requestItemProperty?.type !== AST_NODE_TYPES.Property) {
52
+ return false;
53
+ }
54
+ const requestItemValue = requestItemProperty.value;
55
+ if (requestItemValue.type !== AST_NODE_TYPES.ObjectExpression) {
56
+ return false;
57
+ }
58
+ // any table entry with an object having a Keys array
59
+ return requestItemValue.properties.some(
60
+ (property) =>
61
+ property.type === AST_NODE_TYPES.Property &&
62
+ property.value.type === AST_NODE_TYPES.ObjectExpression &&
63
+ extractObjectProperties(property.value)['Keys']?.value.type === AST_NODE_TYPES.ArrayExpression,
64
+ );
65
+ }
66
+
67
+ function existsKeyProperty(extractedObjectProperties: Record<string, TSESTree.Property>): boolean {
68
+ const keyProperty = extractedObjectProperties['Key'];
69
+ // Relaxed: just ensure it's an object (works for both low-level and DocumentClient)
70
+ return keyProperty?.type === AST_NODE_TYPES.Property && keyProperty.value.type === AST_NODE_TYPES.ObjectExpression;
71
+ }
72
+
73
+ export function getReadCommandInfo(objectExpression: TSESTree.ObjectExpression): ReadCommandInfo | undefined {
74
+ const extractedProperties = extractObjectProperties(objectExpression);
75
+ let readCommandInfo: ReadCommandInfo | undefined;
76
+
77
+ if (existsRequestItemsProperty(extractedProperties)) {
78
+ readCommandInfo = { type: 'BatchGetItem' };
79
+ } else {
80
+ const hasTableName = 'TableName' in extractedProperties;
81
+ const hasKey = existsKeyProperty(extractedProperties);
82
+ if (hasTableName && hasKey) {
83
+ // make sure it is not an update or conditional write;
84
+ // we can't really tell if it's a delete, but we simply ignore that case assuming they'll never be used
85
+ if (!('UpdateExpression' in extractedProperties) && !('ConditionExpression' in extractedProperties)) {
86
+ readCommandInfo = { type: 'GetItem' };
87
+ }
88
+ } else {
89
+ const hasKeyCondExpr = extractedProperties['KeyConditionExpression']?.value.type === AST_NODE_TYPES.Literal;
90
+ const hasLegacyKeyConditions =
91
+ extractedProperties['KeyConditions']?.value.type === AST_NODE_TYPES.ObjectExpression;
92
+ if (hasTableName && (hasKeyCondExpr || hasLegacyKeyConditions)) {
93
+ readCommandInfo = { type: 'Query' };
94
+ }
95
+ }
96
+ }
97
+
98
+ if (readCommandInfo === undefined) {
99
+ return undefined;
100
+ }
101
+
102
+ const consistentReadProperty = extractedProperties['ConsistentRead'];
103
+ if (
104
+ consistentReadProperty?.type === AST_NODE_TYPES.Property &&
105
+ consistentReadProperty.value.type === AST_NODE_TYPES.Literal &&
106
+ typeof consistentReadProperty.value.value === 'boolean'
107
+ ) {
108
+ readCommandInfo.consistentRead = consistentReadProperty.value.value;
109
+ }
110
+
111
+ const indexNameProperty = extractedProperties['IndexName'];
112
+ if (
113
+ indexNameProperty?.type === AST_NODE_TYPES.Property &&
114
+ indexNameProperty.value.type === AST_NODE_TYPES.Literal &&
115
+ typeof indexNameProperty.value.value === 'string'
116
+ ) {
117
+ readCommandInfo.usedIndex = true;
118
+ }
119
+
120
+ return readCommandInfo;
121
+ }
122
+
123
+ const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
124
+
125
+ const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_CONSISTENT_READ_TRUE | typeof MESSAGE_ID_CONSISTENT_READ_FALSE> =
126
+ createRule({
127
+ name: ruleId,
128
+ meta: {
129
+ type: 'problem',
130
+ docs: {
131
+ description:
132
+ 'For AWS dynamodb commands Query/GetItem/BatchGetItem, ConsistentRead option should always be set as true unless global index is used. This will make the service more robust at the ignorable cost of RCU.',
133
+ },
134
+ messages: {
135
+ [MESSAGE_ID_CONSISTENT_READ_TRUE]:
136
+ 'ConsistentRead option should always be set as true for {{readCommandType}} command.',
137
+ [MESSAGE_ID_CONSISTENT_READ_FALSE]:
138
+ 'ConsistentRead option should not be set as true for {{readCommandType}} command when using a global secondary index.',
139
+ },
140
+ schema: [],
141
+ },
142
+ defaultOptions: [],
143
+ create(context) {
144
+ const sourceCode = context.sourceCode;
145
+
146
+ return {
147
+ ObjectExpression(node) {
148
+ // Quick prefilter: only look at objects that mention table/read-ish keys
149
+ const text = sourceCode.getText(node);
150
+ if (!/TableName|RequestItems|KeyConditionExpression|KeyConditions/u.test(text)) {
151
+ return;
152
+ }
153
+
154
+ const readCommandInfo = getReadCommandInfo(node);
155
+ if (readCommandInfo !== undefined) {
156
+ if (readCommandInfo.usedIndex !== true && readCommandInfo.consistentRead !== true) {
157
+ context.report({
158
+ node,
159
+ messageId: MESSAGE_ID_CONSISTENT_READ_TRUE,
160
+ data: { readCommandType: readCommandInfo.type },
161
+ });
162
+ } else if (readCommandInfo.usedIndex === true && readCommandInfo.consistentRead !== false) {
163
+ context.report({
164
+ node,
165
+ messageId: MESSAGE_ID_CONSISTENT_READ_FALSE,
166
+ data: { readCommandType: readCommandInfo.type },
167
+ });
168
+ }
169
+ }
170
+ },
171
+ };
172
+ },
173
+ });
174
+
175
+ export default rule;
package/src/index.ts CHANGED
@@ -26,7 +26,8 @@ import noServeRuntime, { ruleId as noServeRuntimeRuleId } from './no-serve-runti
26
26
  import requireServiceCallResponseDeclaration, {
27
27
  ruleId as requireServiceCallResponseDeclarationRuleId,
28
28
  } from './require-service-call-response-declaration.ts';
29
- import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from './require-aws-config.ts';
29
+ import requireConsistentRead, { ruleId as requireConsistentReadRuleId } from './aws/require-consistent-read.ts';
30
+ import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from './aws/require-aws-config.ts';
30
31
  import filePathComment from './file-path-comment.ts';
31
32
  import noCardNumbers from './no-card-numbers.ts';
32
33
  import noEnum from './no-enum.ts';
@@ -43,7 +44,7 @@ import requireStrictAssert from './require-strict-assert.ts';
43
44
  import requireAssertMessage from './require-assert-message';
44
45
  import requireTsExtensionImportsExports from './require-ts-extension-imports-exports.ts';
45
46
 
46
- export { default as isAwsSdkV3Used } from './is-aws-sdk-v3-used.ts';
47
+ export { default as isAwsSdkV3Used } from './aws/is-aws-sdk-v3-used.ts';
47
48
 
48
49
  const rules: Record<string, TSESLint.LooseRuleDefinition> = {
49
50
  'file-path-comment': filePathComment,
@@ -72,6 +73,7 @@ const rules: Record<string, TSESLint.LooseRuleDefinition> = {
72
73
  [requireAwsConfigRuleId]: requireAwsConfig,
73
74
  [requireFixedServicesImportRuleId]: requireFixedServicesImport,
74
75
  [requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports,
76
+ [requireConsistentReadRuleId]: requireConsistentRead,
75
77
  };
76
78
 
77
79
  const plugin: TSESLint.FlatConfig.Plugin = {
@@ -111,6 +113,7 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
111
113
  [`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
112
114
  [`@checkdigit/${noServeRuntimeRuleId}`]: 'error',
113
115
  [`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'error',
116
+ [`@checkdigit/${requireConsistentReadRuleId}`]: 'error',
114
117
  [`@checkdigit/${requireAwsConfigRuleId}`]: 'error',
115
118
  },
116
119
  },
@@ -147,6 +150,7 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
147
150
  [`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
148
151
  [`@checkdigit/${noServeRuntimeRuleId}`]: 'off',
149
152
  [`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'off',
153
+ [`@checkdigit/${requireConsistentReadRuleId}`]: 'off',
150
154
  [`@checkdigit/${requireAwsConfigRuleId}`]: 'off',
151
155
  },
152
156
  },