@checkdigit/eslint-plugin 7.16.0-PR.136-c0c4 → 7.16.0-PR.137-7110
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-mjs/index.mjs +9 -9
- package/dist-mjs/{aws/is-aws-sdk-v3-used.mjs → is-aws-sdk-v3-used.mjs} +2 -2
- package/dist-mjs/require-aws-bare-bones.mjs +51 -0
- package/dist-mjs/{aws/require-aws-config.mjs → require-aws-config.mjs} +3 -3
- package/dist-types/index.d.ts +1 -1
- package/dist-types/require-aws-bare-bones.d.ts +5 -0
- package/package.json +1 -1
- package/src/index.ts +6 -6
- package/src/{aws/is-aws-sdk-v3-used.ts → is-aws-sdk-v3-used.ts} +1 -1
- package/src/require-aws-bare-bones.ts +57 -0
- package/src/{aws/require-aws-config.ts → require-aws-config.ts} +2 -2
- package/dist-mjs/aws/require-consistent-read.mjs +0 -128
- package/dist-types/aws/require-consistent-read.d.ts +0 -12
- package/src/aws/require-consistent-read.ts +0 -175
- /package/dist-types/{aws/is-aws-sdk-v3-used.d.ts → is-aws-sdk-v3-used.d.ts} +0 -0
- /package/dist-types/{aws/require-aws-config.d.ts → require-aws-config.d.ts} +0 -0
package/dist-mjs/index.mjs
CHANGED
|
@@ -17,8 +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
|
|
21
|
-
import
|
|
20
|
+
import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from "./require-aws-config.mjs";
|
|
21
|
+
import requireAWSBareBones, { ruleId as requireAWSBareBonesRuleId } from "./require-aws-bare-bones.mjs";
|
|
22
22
|
import filePathComment from "./file-path-comment.mjs";
|
|
23
23
|
import noCardNumbers from "./no-card-numbers.mjs";
|
|
24
24
|
import noEnum from "./no-enum.mjs";
|
|
@@ -34,7 +34,7 @@ import requireAssertPredicateRejectsThrows from "./require-assert-predicate-reje
|
|
|
34
34
|
import requireStrictAssert from "./require-strict-assert.mjs";
|
|
35
35
|
import requireAssertMessage from "./require-assert-message.mjs";
|
|
36
36
|
import requireTsExtensionImportsExports from "./require-ts-extension-imports-exports.mjs";
|
|
37
|
-
import { default as default2 } from "./
|
|
37
|
+
import { default as default2 } from "./is-aws-sdk-v3-used.mjs";
|
|
38
38
|
var rules = {
|
|
39
39
|
"file-path-comment": filePathComment,
|
|
40
40
|
"no-card-numbers": noCardNumbers,
|
|
@@ -62,7 +62,7 @@ var rules = {
|
|
|
62
62
|
[requireAwsConfigRuleId]: requireAwsConfig,
|
|
63
63
|
[requireFixedServicesImportRuleId]: requireFixedServicesImport,
|
|
64
64
|
[requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports,
|
|
65
|
-
[
|
|
65
|
+
[requireAWSBareBonesRuleId]: requireAWSBareBones
|
|
66
66
|
};
|
|
67
67
|
var plugin = {
|
|
68
68
|
rules
|
|
@@ -100,8 +100,8 @@ var configs = {
|
|
|
100
100
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
|
|
101
101
|
[`@checkdigit/${noServeRuntimeRuleId}`]: "error",
|
|
102
102
|
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "error",
|
|
103
|
-
[`@checkdigit/${
|
|
104
|
-
[`@checkdigit/${
|
|
103
|
+
[`@checkdigit/${requireAwsConfigRuleId}`]: "error",
|
|
104
|
+
[`@checkdigit/${requireAWSBareBonesRuleId}`]: "error"
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
],
|
|
@@ -137,8 +137,8 @@ var configs = {
|
|
|
137
137
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
|
|
138
138
|
[`@checkdigit/${noServeRuntimeRuleId}`]: "off",
|
|
139
139
|
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "off",
|
|
140
|
-
[`@checkdigit/${
|
|
141
|
-
[`@checkdigit/${
|
|
140
|
+
[`@checkdigit/${requireAwsConfigRuleId}`]: "off",
|
|
141
|
+
[`@checkdigit/${requireAWSBareBonesRuleId}`]: "off"
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
]
|
|
@@ -152,4 +152,4 @@ export {
|
|
|
152
152
|
index_default as default,
|
|
153
153
|
default2 as isAwsSdkV3Used
|
|
154
154
|
};
|
|
155
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
155
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVVBLE9BQU8sd0JBQXdCLFVBQVUsa0NBQWtDO0FBQzNFLE9BQU8sdUJBQXVCLFVBQVUsaUNBQWlDO0FBQ3pFLE9BQU8seUJBQXlCLFVBQVUsbUNBQW1DO0FBQzdFLE9BQU8sMkJBQTJCLFVBQVUscUNBQXFDO0FBQ2pGLE9BQU8sd0JBQXdCO0FBQy9CLE9BQU87QUFBQSxFQUNMLFVBQVU7QUFBQSxPQUNMO0FBQ1AsT0FBTztBQUFBLEVBQ0wsVUFBVTtBQUFBLE9BQ0w7QUFDUCxPQUFPO0FBQUEsRUFDTCxVQUFVO0FBQUEsT0FDTDtBQUNQLE9BQU8sa0JBQWtCLFVBQVUsNEJBQTRCO0FBQy9ELE9BQU87QUFBQSxFQUNMLFVBQVU7QUFBQSxPQUNMO0FBQ1AsT0FBTyxvQkFBb0IsVUFBVSw4QkFBOEI7QUFDbkUsT0FBTyx1QkFBdUIsVUFBVSxpQ0FBaUM7QUFDekUsT0FBTyxxQkFBcUI7QUFDNUIsT0FBTyxtQkFBbUI7QUFDMUIsT0FBTyxZQUFZO0FBQ25CLE9BQU8sbUJBQW1CO0FBQzFCLE9BQU8sb0JBQW9CO0FBQzNCLE9BQU8sa0JBQWtCO0FBQ3pCLE9BQU8sWUFBWTtBQUNuQixPQUFPLFlBQVk7QUFDbkIsT0FBTyxzQkFBc0I7QUFDN0IsT0FBTywyQkFBMkI7QUFDbEMsT0FBTyxrQkFBa0I7QUFDekIsT0FBTyx5Q0FBeUM7QUFDaEQsT0FBTyx5QkFBeUI7QUFDaEMsT0FBTywwQkFBMEI7QUFDakMsT0FBTyxzQ0FBc0M7QUFFN0MsU0FBb0IsV0FBWEEsZ0JBQWlDO0FBRTFDLElBQU0sUUFBc0Q7QUFBQSxFQUMxRCxxQkFBcUI7QUFBQSxFQUNyQixtQkFBbUI7QUFBQSxFQUNuQixXQUFXO0FBQUEsRUFDWCxxQkFBcUI7QUFBQSxFQUNyQix5QkFBeUI7QUFBQSxFQUN6QixXQUFXO0FBQUEsRUFDWCxXQUFXO0FBQUEsRUFDWCwwQkFBMEI7QUFBQSxFQUMxQix5QkFBeUI7QUFBQSxFQUN6Qix3Q0FBd0M7QUFBQSxFQUN4QyxrQkFBa0I7QUFBQSxFQUNsQixzQkFBc0I7QUFBQSxFQUN0QixtQkFBbUI7QUFBQSxFQUNuQiw4QkFBOEI7QUFBQSxFQUM5QiwyQ0FBMkM7QUFBQSxFQUMzQywyQkFBMkI7QUFBQSxFQUMzQixDQUFDLDBCQUEwQixHQUFHO0FBQUEsRUFDOUIsQ0FBQyw2QkFBNkIsR0FBRztBQUFBLEVBQ2pDLENBQUMsMkJBQTJCLEdBQUc7QUFBQSxFQUMvQixDQUFDLGdDQUFnQyxHQUFHO0FBQUEsRUFDcEMsQ0FBQyx5QkFBeUIsR0FBRztBQUFBLEVBQzdCLENBQUMsb0JBQW9CLEdBQUc7QUFBQSxFQUN4QixDQUFDLDJDQUEyQyxHQUFHO0FBQUEsRUFDL0MsQ0FBQyxzQkFBc0IsR0FBRztBQUFBLEVBQzFCLENBQUMsZ0NBQWdDLEdBQUc7QUFBQSxFQUNwQyxDQUFDLHFDQUFxQyxHQUFHO0FBQUEsRUFDekMsQ0FBQyx5QkFBeUIsR0FBRztBQUMvQjtBQUVBLElBQU0sU0FBcUM7QUFBQSxFQUN6QztBQUNGO0FBRUEsSUFBTSxVQUF3RDtBQUFBLEVBQzVELEtBQUs7QUFBQSxJQUNIO0FBQUEsTUFDRSxPQUFPLENBQUMsU0FBUztBQUFBLE1BQ2pCLFNBQVM7QUFBQSxRQUNQLGVBQWU7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTztBQUFBLFFBQ0wsK0JBQStCO0FBQUEsUUFDL0IsdUJBQXVCO0FBQUEsUUFDdkIsaUNBQWlDO0FBQUEsUUFDakMsaUNBQWlDO0FBQUEsUUFDakMscUNBQXFDO0FBQUEsUUFDckMsdUJBQXVCO0FBQUEsUUFDdkIsdUJBQXVCO0FBQUEsUUFDdkIsc0NBQXNDO0FBQUEsUUFDdEMscUNBQXFDO0FBQUEsUUFDckMsb0RBQW9EO0FBQUEsUUFDcEQsa0NBQWtDO0FBQUEsUUFDbEMsK0JBQStCO0FBQUEsUUFDL0IsMENBQTBDO0FBQUEsUUFDMUMsdURBQXVEO0FBQUEsUUFDdkQsdUNBQXVDO0FBQUEsUUFDdkMsOEJBQThCO0FBQUEsUUFDOUIsQ0FBQyxlQUFlLDBCQUEwQixFQUFFLEdBQUc7QUFBQSxRQUMvQyxDQUFDLGVBQWUsNkJBQTZCLEVBQUUsR0FBRztBQUFBLFFBQ2xELENBQUMsZUFBZSwyQkFBMkIsRUFBRSxHQUFHO0FBQUEsUUFDaEQsQ0FBQyxlQUFlLGdDQUFnQyxFQUFFLEdBQUc7QUFBQSxRQUNyRCxDQUFDLGVBQWUseUJBQXlCLEVBQUUsR0FBRztBQUFBLFFBQzlDLENBQUMsZUFBZSxnQ0FBZ0MsRUFBRSxHQUFHO0FBQUEsUUFDckQsQ0FBQyxlQUFlLHFDQUFxQyxFQUFFLEdBQUc7QUFBQSxRQUMxRCxDQUFDLGVBQWUsb0JBQW9CLEVBQUUsR0FBRztBQUFBLFFBQ3pDLENBQUMsZUFBZSwyQ0FBMkMsRUFBRSxHQUFHO0FBQUEsUUFDaEUsQ0FBQyxlQUFlLHNCQUFzQixFQUFFLEdBQUc7QUFBQSxRQUMzQyxDQUFDLGVBQWUseUJBQXlCLEVBQUUsR0FBRztBQUFBLE1BQ2hEO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQSxFQUNBLGFBQWE7QUFBQSxJQUNYO0FBQUEsTUFDRSxPQUFPLENBQUMsU0FBUztBQUFBLE1BQ2pCLFNBQVM7QUFBQSxRQUNQLGVBQWU7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTztBQUFBLFFBQ0wsK0JBQStCO0FBQUEsUUFDL0IsdUJBQXVCO0FBQUEsUUFDdkIsaUNBQWlDO0FBQUEsUUFDakMsaUNBQWlDO0FBQUEsUUFDakMscUNBQXFDO0FBQUEsUUFDckMsdUJBQXVCO0FBQUEsUUFDdkIsdUJBQXVCO0FBQUEsUUFDdkIsc0NBQXNDO0FBQUEsUUFDdEMscUNBQXFDO0FBQUEsUUFDckMsb0RBQW9EO0FBQUEsUUFDcEQsa0NBQWtDO0FBQUEsUUFDbEMsK0JBQStCO0FBQUEsUUFDL0IsMENBQTBDO0FBQUEsUUFDMUMsdURBQXVEO0FBQUEsUUFDdkQsdUNBQXVDO0FBQUEsUUFDdkMsOEJBQThCO0FBQUEsUUFDOUIsQ0FBQyxlQUFlLDBCQUEwQixFQUFFLEdBQUc7QUFBQSxRQUMvQyxDQUFDLGVBQWUsNkJBQTZCLEVBQUUsR0FBRztBQUFBLFFBQ2xELENBQUMsZUFBZSwyQkFBMkIsRUFBRSxHQUFHO0FBQUEsUUFDaEQsQ0FBQyxlQUFlLGdDQUFnQyxFQUFFLEdBQUc7QUFBQSxRQUNyRCxDQUFDLGVBQWUseUJBQXlCLEVBQUUsR0FBRztBQUFBLFFBQzlDLENBQUMsZUFBZSxnQ0FBZ0MsRUFBRSxHQUFHO0FBQUEsUUFDckQsQ0FBQyxlQUFlLHFDQUFxQyxFQUFFLEdBQUc7QUFBQSxRQUMxRCxDQUFDLGVBQWUsb0JBQW9CLEVBQUUsR0FBRztBQUFBLFFBQ3pDLENBQUMsZUFBZSwyQ0FBMkMsRUFBRSxHQUFHO0FBQUEsUUFDaEUsQ0FBQyxlQUFlLHNCQUFzQixFQUFFLEdBQUc7QUFBQSxRQUMzQyxDQUFDLGVBQWUseUJBQXlCLEVBQUUsR0FBRztBQUFBLE1BQ2hEO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjtBQUVBLElBQU0sa0JBRUY7QUFBQSxFQUNGLEdBQUc7QUFBQSxFQUNIO0FBQ0Y7QUFDQSxJQUFPLGdCQUFROyIsCiAgIm5hbWVzIjogWyJkZWZhdWx0Il0KfQo=
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/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,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2lzLWF3cy1zZGstdjMtdXNlZC50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFFQSxTQUFTLFlBQVksVUFBVTtBQVMvQixJQUFJO0FBRUosZUFBTyxpQkFBMEQ7QUFDL0QsTUFBSSx5QkFBeUIsUUFBVztBQUN0QyxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sY0FBYyxLQUFLLE1BQU0sTUFBTSxHQUFHLFNBQVMsZ0JBQWdCLE1BQU0sQ0FBQztBQUN4RSxRQUFNLGVBQWUsWUFBWSxnQkFBZ0IsQ0FBQztBQUVsRCx5QkFBdUIsT0FBTyxLQUFLLFlBQVksRUFBRSxLQUFLLENBQUMsZUFBZSxXQUFXLFdBQVcsV0FBVyxDQUFDO0FBQ3hHLFNBQU87QUFDVDsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/require-aws-bare-bones.ts
|
|
2
|
+
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
3
|
+
import getDocumentationUrl from "./get-documentation-url.mjs";
|
|
4
|
+
var ruleId = "require-aws-bare-bones";
|
|
5
|
+
var MESSAGE_ID_AGGREGATED_CLIENT = "noAggregatedClient";
|
|
6
|
+
var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
7
|
+
function isAwsSdkClientModule(importDeclaration) {
|
|
8
|
+
return typeof importDeclaration.source.value === "string" && importDeclaration.source.value.startsWith("@aws-sdk/client-");
|
|
9
|
+
}
|
|
10
|
+
function isAggregatedClient(name) {
|
|
11
|
+
return !name.endsWith("Client") && !name.endsWith("Command");
|
|
12
|
+
}
|
|
13
|
+
var rule = createRule({
|
|
14
|
+
name: ruleId,
|
|
15
|
+
meta: {
|
|
16
|
+
type: "problem",
|
|
17
|
+
docs: {
|
|
18
|
+
description: "Disallow importing aggregated AWS SDK v3 clients. Use bare-bones pattern (Client + Command) for better tree-shaking."
|
|
19
|
+
},
|
|
20
|
+
messages: {
|
|
21
|
+
[MESSAGE_ID_AGGREGATED_CLIENT]: 'Do not import aggregated AWS SDK v3 client "{{clientName}}". Use bare-bones pattern ({{clientName}}Client + Command) instead.'
|
|
22
|
+
},
|
|
23
|
+
schema: []
|
|
24
|
+
},
|
|
25
|
+
defaultOptions: [],
|
|
26
|
+
create(context) {
|
|
27
|
+
return {
|
|
28
|
+
ImportDeclaration(node) {
|
|
29
|
+
if (!isAwsSdkClientModule(node)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const specifier of node.specifiers) {
|
|
33
|
+
if (specifier.type === AST_NODE_TYPES.ImportSpecifier && isAggregatedClient(specifier.local.name)) {
|
|
34
|
+
context.report({
|
|
35
|
+
node: specifier,
|
|
36
|
+
messageId: MESSAGE_ID_AGGREGATED_CLIENT,
|
|
37
|
+
data: { clientName: specifier.local.name }
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
var require_aws_bare_bones_default = rule;
|
|
46
|
+
export {
|
|
47
|
+
MESSAGE_ID_AGGREGATED_CLIENT,
|
|
48
|
+
require_aws_bare_bones_default as default,
|
|
49
|
+
ruleId
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlcXVpcmUtYXdzLWJhcmUtYm9uZXMudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsU0FBUyxnQkFBZ0IsbUJBQTZCO0FBQ3RELE9BQU8seUJBQXlCO0FBRXpCLElBQU0sU0FBUztBQUNmLElBQU0sK0JBQStCO0FBRTVDLElBQU0sYUFBYSxZQUFZLFlBQVksQ0FBQyxTQUFTLG9CQUFvQixJQUFJLENBQUM7QUFFOUUsU0FBUyxxQkFBcUIsbUJBQXdEO0FBQ3BGLFNBQ0UsT0FBTyxrQkFBa0IsT0FBTyxVQUFVLFlBQVksa0JBQWtCLE9BQU8sTUFBTSxXQUFXLGtCQUFrQjtBQUV0SDtBQUVBLFNBQVMsbUJBQW1CLE1BQXVCO0FBQ2pELFNBQU8sQ0FBQyxLQUFLLFNBQVMsUUFBUSxLQUFLLENBQUMsS0FBSyxTQUFTLFNBQVM7QUFDN0Q7QUFFQSxJQUFNLE9BQW9FLFdBQVc7QUFBQSxFQUNuRixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUNFO0FBQUEsSUFDSjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsQ0FBQyw0QkFBNEIsR0FDM0I7QUFBQSxJQUNKO0FBQUEsSUFDQSxRQUFRLENBQUM7QUFBQSxFQUNYO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQztBQUFBLEVBQ2pCLE9BQU8sU0FBUztBQUNkLFdBQU87QUFBQSxNQUNMLGtCQUFrQixNQUFNO0FBQ3RCLFlBQUksQ0FBQyxxQkFBcUIsSUFBSSxHQUFHO0FBQy9CO0FBQUEsUUFDRjtBQUVBLG1CQUFXLGFBQWEsS0FBSyxZQUFZO0FBQ3ZDLGNBQUksVUFBVSxTQUFTLGVBQWUsbUJBQW1CLG1CQUFtQixVQUFVLE1BQU0sSUFBSSxHQUFHO0FBQ2pHLG9CQUFRLE9BQU87QUFBQSxjQUNiLE1BQU07QUFBQSxjQUNOLFdBQVc7QUFBQSxjQUNYLE1BQU0sRUFBRSxZQUFZLFVBQVUsTUFBTSxLQUFLO0FBQUEsWUFDM0MsQ0FBQztBQUFBLFVBQ0g7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8saUNBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/require-aws-config.ts
|
|
2
2
|
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
3
|
-
import getDocumentationUrl from "
|
|
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,
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlcXVpcmUtYXdzLWNvbmZpZy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLGdCQUFnQixtQkFBNkI7QUFDdEQsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBQ2YsSUFBTSxnQ0FBZ0M7QUFDdEMsSUFBTSwrQkFBK0I7QUFDNUMsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxTQUFTLHFCQUFxQixtQkFBd0Q7QUFDcEYsU0FBTyxrQkFBa0IsT0FBTyxNQUFNLFdBQVcsa0JBQWtCO0FBQ3JFO0FBRUEsU0FBUyxzQkFBc0IsbUJBQXdEO0FBQ3JGLFNBQU8sa0JBQWtCLE9BQU8sVUFBVTtBQUM1QztBQUVBLFNBQVMsWUFBWSxlQUF1QixvQkFBMkM7QUFHckYsU0FDRSxjQUFjLFNBQVMsUUFBUSxNQUFNLHVCQUF1QixVQUFhLG1CQUFtQixJQUFJLGFBQWE7QUFFakg7QUFFQSxJQUFNLE9BQ0osV0FBVztBQUFBLEVBQ1QsTUFBTTtBQUFBLEVBQ04sTUFBTTtBQUFBLElBQ0osTUFBTTtBQUFBLElBQ04sTUFBTTtBQUFBLE1BQ0osYUFDRTtBQUFBLElBQ0o7QUFBQSxJQUNBLFVBQVU7QUFBQSxNQUNSLENBQUMsNkJBQTZCLEdBQzVCO0FBQUEsTUFDRixDQUFDLDRCQUE0QixHQUMzQjtBQUFBLElBQ0o7QUFBQSxJQUNBLFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxFQUFFLGVBQWUsSUFBSSxRQUFRO0FBQ25DLFVBQU0scUJBQXFCLG9CQUFJLElBQVk7QUFFM0MsV0FBTztBQUFBLE1BQ0wsa0JBQWtCLE1BQU07QUFDdEIsWUFBSSxtQkFBbUIsTUFBTTtBQUMzQjtBQUFBLFFBQ0Y7QUFFQSxZQUFJLHNCQUFzQixJQUFJLEdBQUc7QUFDL0Isa0JBQVEsT0FBTztBQUFBLFlBQ2I7QUFBQSxZQUNBLFdBQVc7QUFBQSxVQUNiLENBQUM7QUFDRDtBQUFBLFFBQ0Y7QUFFQSxZQUFJLHFCQUFxQixJQUFJLEdBQUc7QUFDOUIscUJBQVcsYUFBYSxLQUFLLFlBQVk7QUFDdkMsZ0JBQUksVUFBVSxTQUFTLGVBQWUsbUJBQW1CLFlBQVksVUFBVSxNQUFNLElBQUksR0FBRztBQUMxRixpQ0FBbUIsSUFBSSxVQUFVLE1BQU0sSUFBSTtBQUFBLFlBQzdDO0FBQUEsVUFDRjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsTUFFQSxjQUFjLE1BQU07QUFDbEIsWUFBSSxtQkFBbUIsTUFBTTtBQUMzQjtBQUFBLFFBQ0Y7QUFFQSxZQUFJLEtBQUssT0FBTyxTQUFTLGVBQWUsY0FBYyxZQUFZLEtBQUssT0FBTyxNQUFNLGtCQUFrQixHQUFHO0FBQ3ZHLGtCQUFRLE9BQU87QUFBQSxZQUNiO0FBQUEsWUFDQSxXQUFXO0FBQUEsWUFDWCxNQUFNLEVBQUUsZUFBZSxLQUFLLE9BQU8sS0FBSztBQUFBLFVBQzFDLENBQUM7QUFBQSxRQUNILFdBQVcsS0FBSyxPQUFPLFNBQVMsZUFBZSxrQkFBa0I7QUFFL0QsZ0JBQU0sV0FBVyxLQUFLLE9BQU87QUFDN0IsY0FBSSxTQUFTLFNBQVMsZUFBZSxjQUFjLFlBQVksU0FBUyxNQUFNLGtCQUFrQixHQUFHO0FBQ2pHLG9CQUFRLE9BQU87QUFBQSxjQUNiO0FBQUEsY0FDQSxXQUFXO0FBQUEsY0FDWCxNQUFNLEVBQUUsZUFBZSxTQUFTLEtBQUs7QUFBQSxZQUN2QyxDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRixDQUFDO0FBRUgsSUFBTyw2QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K
|
package/dist-types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
-
export { default as isAwsSdkV3Used } from './
|
|
2
|
+
export { default as isAwsSdkV3Used } from './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
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
export declare const ruleId = "require-aws-bare-bones";
|
|
3
|
+
export declare const MESSAGE_ID_AGGREGATED_CLIENT = "noAggregatedClient";
|
|
4
|
+
declare const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_AGGREGATED_CLIENT>;
|
|
5
|
+
export default rule;
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@checkdigit/eslint-plugin","version":"7.16.0-PR.
|
|
1
|
+
{"name":"@checkdigit/eslint-plugin","version":"7.16.0-PR.137-7110","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.1","@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"}}
|
package/src/index.ts
CHANGED
|
@@ -26,8 +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
|
|
30
|
-
import
|
|
29
|
+
import requireAwsConfig, { ruleId as requireAwsConfigRuleId } from './require-aws-config.ts';
|
|
30
|
+
import requireAWSBareBones, { ruleId as requireAWSBareBonesRuleId } from './require-aws-bare-bones.ts';
|
|
31
31
|
import filePathComment from './file-path-comment.ts';
|
|
32
32
|
import noCardNumbers from './no-card-numbers.ts';
|
|
33
33
|
import noEnum from './no-enum.ts';
|
|
@@ -44,7 +44,7 @@ import requireStrictAssert from './require-strict-assert.ts';
|
|
|
44
44
|
import requireAssertMessage from './require-assert-message';
|
|
45
45
|
import requireTsExtensionImportsExports from './require-ts-extension-imports-exports.ts';
|
|
46
46
|
|
|
47
|
-
export { default as isAwsSdkV3Used } from './
|
|
47
|
+
export { default as isAwsSdkV3Used } from './is-aws-sdk-v3-used.ts';
|
|
48
48
|
|
|
49
49
|
const rules: Record<string, TSESLint.LooseRuleDefinition> = {
|
|
50
50
|
'file-path-comment': filePathComment,
|
|
@@ -73,7 +73,7 @@ const rules: Record<string, TSESLint.LooseRuleDefinition> = {
|
|
|
73
73
|
[requireAwsConfigRuleId]: requireAwsConfig,
|
|
74
74
|
[requireFixedServicesImportRuleId]: requireFixedServicesImport,
|
|
75
75
|
[requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports,
|
|
76
|
-
[
|
|
76
|
+
[requireAWSBareBonesRuleId]: requireAWSBareBones,
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
const plugin: TSESLint.FlatConfig.Plugin = {
|
|
@@ -113,8 +113,8 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
|
|
|
113
113
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
|
|
114
114
|
[`@checkdigit/${noServeRuntimeRuleId}`]: 'error',
|
|
115
115
|
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'error',
|
|
116
|
-
[`@checkdigit/${requireConsistentReadRuleId}`]: 'error',
|
|
117
116
|
[`@checkdigit/${requireAwsConfigRuleId}`]: 'error',
|
|
117
|
+
[`@checkdigit/${requireAWSBareBonesRuleId}`]: 'error',
|
|
118
118
|
},
|
|
119
119
|
},
|
|
120
120
|
],
|
|
@@ -150,8 +150,8 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
|
|
|
150
150
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
|
|
151
151
|
[`@checkdigit/${noServeRuntimeRuleId}`]: 'off',
|
|
152
152
|
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'off',
|
|
153
|
-
[`@checkdigit/${requireConsistentReadRuleId}`]: 'off',
|
|
154
153
|
[`@checkdigit/${requireAwsConfigRuleId}`]: 'off',
|
|
154
|
+
[`@checkdigit/${requireAWSBareBonesRuleId}`]: 'off',
|
|
155
155
|
},
|
|
156
156
|
},
|
|
157
157
|
],
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// require-aws-bare-bones.ts
|
|
2
|
+
|
|
3
|
+
import { AST_NODE_TYPES, ESLintUtils, TSESTree } from '@typescript-eslint/utils';
|
|
4
|
+
import getDocumentationUrl from './get-documentation-url.ts';
|
|
5
|
+
|
|
6
|
+
export const ruleId = 'require-aws-bare-bones';
|
|
7
|
+
export const MESSAGE_ID_AGGREGATED_CLIENT = 'noAggregatedClient';
|
|
8
|
+
|
|
9
|
+
const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
10
|
+
|
|
11
|
+
function isAwsSdkClientModule(importDeclaration: TSESTree.ImportDeclaration): boolean {
|
|
12
|
+
return (
|
|
13
|
+
typeof importDeclaration.source.value === 'string' && importDeclaration.source.value.startsWith('@aws-sdk/client-')
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isAggregatedClient(name: string): boolean {
|
|
18
|
+
return !name.endsWith('Client') && !name.endsWith('Command');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_AGGREGATED_CLIENT> = createRule({
|
|
22
|
+
name: ruleId,
|
|
23
|
+
meta: {
|
|
24
|
+
type: 'problem',
|
|
25
|
+
docs: {
|
|
26
|
+
description:
|
|
27
|
+
'Disallow importing aggregated AWS SDK v3 clients. Use bare-bones pattern (Client + Command) for better tree-shaking.',
|
|
28
|
+
},
|
|
29
|
+
messages: {
|
|
30
|
+
[MESSAGE_ID_AGGREGATED_CLIENT]:
|
|
31
|
+
'Do not import aggregated AWS SDK v3 client "{{clientName}}". Use bare-bones pattern ({{clientName}}Client + Command) instead.',
|
|
32
|
+
},
|
|
33
|
+
schema: [],
|
|
34
|
+
},
|
|
35
|
+
defaultOptions: [],
|
|
36
|
+
create(context) {
|
|
37
|
+
return {
|
|
38
|
+
ImportDeclaration(node) {
|
|
39
|
+
if (!isAwsSdkClientModule(node)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (const specifier of node.specifiers) {
|
|
44
|
+
if (specifier.type === AST_NODE_TYPES.ImportSpecifier && isAggregatedClient(specifier.local.name)) {
|
|
45
|
+
context.report({
|
|
46
|
+
node: specifier,
|
|
47
|
+
messageId: MESSAGE_ID_AGGREGATED_CLIENT,
|
|
48
|
+
data: { clientName: specifier.local.name },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export default rule;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// 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 '
|
|
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';
|
|
@@ -1,128 +0,0 @@
|
|
|
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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
|
|
@@ -1,12 +0,0 @@
|
|
|
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,175 +0,0 @@
|
|
|
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;
|
|
File without changes
|
|
File without changes
|