@checkdigit/eslint-plugin 7.17.1 → 8.0.0-PR.141-56ee
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/aws/is-aws-sdk-v3-used.mjs +7 -3
- package/dist-mjs/aws/require-aws-bare-bones.mjs +23 -5
- package/dist-mjs/aws/require-aws-config.mjs +5 -2
- package/dist-mjs/aws/require-consistent-read.mjs +12 -4
- package/dist-mjs/file-path-comment.mjs +15 -6
- package/dist-mjs/index.mjs +25 -9
- package/dist-mjs/invalid-json-stringify.mjs +8 -3
- package/dist-mjs/library/format.mjs +1 -1
- package/dist-mjs/library/tree.mjs +7 -2
- package/dist-mjs/library/ts-tree.mjs +7 -2
- package/dist-mjs/no-card-numbers.mjs +1 -1
- package/dist-mjs/no-duplicated-imports.mjs +25 -7
- package/dist-mjs/no-legacy-service-typing.mjs +18 -7
- package/dist-mjs/no-promise-instance-method.mjs +1 -1
- package/dist-mjs/no-random-v4-uuid.mjs +5 -2
- package/dist-mjs/no-side-effects.mjs +11 -7
- package/dist-mjs/no-status-code-assert.mjs +5 -2
- package/dist-mjs/no-test-import.mjs +5 -2
- package/dist-mjs/no-util.mjs +1 -1
- package/dist-mjs/no-uuid.mjs +1 -1
- package/dist-mjs/no-wallaby-comment.mjs +25 -7
- package/dist-mjs/object-literal-response.mjs +1 -1
- package/dist-mjs/regular-expression-comment.mjs +4 -2
- package/dist-mjs/require-assert-message.mjs +1 -1
- package/dist-mjs/require-assert-predicate-rejects-throws.mjs +1 -1
- package/dist-mjs/require-fixed-services-import.mjs +21 -6
- package/dist-mjs/require-resolve-full-response.mjs +32 -11
- package/dist-mjs/require-service-call-response-declaration.mjs +12 -4
- package/dist-mjs/require-strict-assert.mjs +5 -2
- package/dist-mjs/require-ts-extension-imports-exports.mjs +1 -1
- package/dist-mjs/require-type-out-of-type-only-imports.mjs +6 -2
- package/dist-types/no-legacy-service-typing.d.ts +3 -1
- package/package.json +1 -96
- package/src/aws/is-aws-sdk-v3-used.ts +6 -2
- package/src/aws/require-aws-bare-bones.ts +65 -42
- package/src/aws/require-aws-config.ts +85 -63
- package/src/aws/require-consistent-read.ts +97 -60
- package/src/file-path-comment.ts +12 -3
- package/src/index.ts +28 -10
- package/src/invalid-json-stringify.ts +9 -3
- package/src/library/format.ts +4 -1
- package/src/library/tree.ts +8 -2
- package/src/library/ts-tree.ts +24 -7
- package/src/no-card-numbers.ts +6 -1
- package/src/no-duplicated-imports.ts +48 -18
- package/src/no-legacy-service-typing.ts +25 -8
- package/src/no-promise-instance-method.ts +8 -3
- package/src/no-random-v4-uuid.ts +36 -11
- package/src/no-side-effects.ts +78 -29
- package/src/no-status-code-assert.ts +21 -7
- package/src/no-test-import.ts +8 -2
- package/src/no-util.ts +3 -1
- package/src/no-uuid.ts +8 -2
- package/src/no-wallaby-comment.ts +40 -9
- package/src/object-literal-response.ts +25 -9
- package/src/regular-expression-comment.ts +9 -3
- package/src/require-assert-message.ts +13 -5
- package/src/require-assert-predicate-rejects-throws.ts +6 -3
- package/src/require-fixed-services-import.ts +31 -10
- package/src/require-resolve-full-response.ts +221 -172
- package/src/require-service-call-response-declaration.ts +23 -8
- package/src/require-strict-assert.ts +21 -8
- package/src/require-ts-extension-imports-exports.ts +19 -6
- package/src/require-type-out-of-type-only-imports.ts +12 -4
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
2
|
export declare const ruleId = "no-legacy-service-typing";
|
|
3
3
|
declare const DISALLOWED_SERVICE_TYPINGS: string[] | undefined;
|
|
4
|
-
declare const rule: ESLintUtils.RuleModule<'noLegacyServiceTyping', [
|
|
4
|
+
declare const rule: ESLintUtils.RuleModule<'noLegacyServiceTyping', [
|
|
5
|
+
typeof DISALLOWED_SERVICE_TYPINGS
|
|
6
|
+
]>;
|
|
5
7
|
export default rule;
|
package/package.json
CHANGED
|
@@ -1,96 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@checkdigit/eslint-plugin",
|
|
3
|
-
"version": "7.17.1",
|
|
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.2",
|
|
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":"8.0.0-PR.141-56ee","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":"rimraf coverage && mkdir coverage && node --disable-warning ExperimentalWarning --experimental-strip-types --experimental-test-module-mocks --test-timeout 600000 --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info --test-reporter spec --test-reporter-destination stdout --test \"src/**/*.spec.ts\"","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"node --disable-warning=ExperimentalWarning --experimental-strip-types --experimental-test-module-mocks --test-timeout 600000 --test \"src/**/*.spec.ts\"","lint":"eslint --max-warnings 0 . --ignore-pattern '**/rule-tester.test.ts'","lint:fix":"eslint --max-warnings 0 --fix . --ignore-pattern '**/rule-tester.test.ts'","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","dependencies":{"@typescript-eslint/type-utils":"^8.57.2","@typescript-eslint/utils":"^8.57.2","http-status-codes":"^2.3.0","ts-api-utils":"^2.5.0"},"devDependencies":{"@checkdigit/prettier-config":"^8.0.0","@checkdigit/typescript-config":"^10.0.1","@eslint/js":"^10.0.1","@types/eslint":"^9.6.1","@types/eslint-config-prettier":"^6.11.3","@typescript-eslint/parser":"^8.57.2","@typescript-eslint/rule-tester":"^8.57.2","eslint":"^10.1.0","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-eslint-plugin":"^7.3.2","eslint-plugin-no-only-tests":"^3.3.0","eslint-plugin-no-secrets":"^2.3.3","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"4.0.2","rimraf":"^6.1.3","typescript-eslint":"^8.57.2"},"peerDependencies":{"eslint":">=10 <11"},"engines":{"node":">=24.13"}}
|
|
@@ -16,9 +16,13 @@ export default async function isAwsSdkV3Used(): Promise<boolean> {
|
|
|
16
16
|
return cachedIsAwsSdkV3Used;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const packageJson = JSON.parse(
|
|
19
|
+
const packageJson = JSON.parse(
|
|
20
|
+
await fs.readFile('package.json', 'utf8'),
|
|
21
|
+
) as PackageJson;
|
|
20
22
|
const dependencies = packageJson.dependencies ?? {};
|
|
21
23
|
// eslint-disable-next-line require-atomic-updates
|
|
22
|
-
cachedIsAwsSdkV3Used = Object.keys(dependencies).some((dependency) =>
|
|
24
|
+
cachedIsAwsSdkV3Used = Object.keys(dependencies).some((dependency) =>
|
|
25
|
+
dependency.startsWith('@aws-sdk/'),
|
|
26
|
+
);
|
|
23
27
|
return cachedIsAwsSdkV3Used;
|
|
24
28
|
}
|
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
// require-aws-bare-bones.ts
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AST_NODE_TYPES,
|
|
5
|
+
ESLintUtils,
|
|
6
|
+
TSESTree,
|
|
7
|
+
} from '@typescript-eslint/utils';
|
|
4
8
|
import getDocumentationUrl from '../get-documentation-url.ts';
|
|
5
9
|
|
|
6
10
|
export const ruleId = 'require-aws-bare-bones';
|
|
7
11
|
export const MESSAGE_ID_AGGREGATED_CLIENT = 'noAggregatedClient';
|
|
8
12
|
|
|
9
|
-
const BARE_BONES_SUFFIXES = [
|
|
10
|
-
|
|
13
|
+
const BARE_BONES_SUFFIXES = [
|
|
14
|
+
'Client',
|
|
15
|
+
'Command',
|
|
16
|
+
'Exception',
|
|
17
|
+
'Input',
|
|
18
|
+
'Output',
|
|
19
|
+
];
|
|
20
|
+
const AWS_LIB_AGGREGATED_SUFFIXES = [
|
|
21
|
+
'Document',
|
|
22
|
+
'Paginator',
|
|
23
|
+
'Utils',
|
|
24
|
+
'Service',
|
|
25
|
+
'Collection',
|
|
26
|
+
'Manager',
|
|
27
|
+
];
|
|
11
28
|
const AWS_SDK_CLIENT = '@aws-sdk/client-';
|
|
12
29
|
const AWS_SDK_LIB = '@aws-sdk/lib-';
|
|
13
30
|
|
|
14
31
|
const createRule = ESLintUtils.RuleCreator(getDocumentationUrl);
|
|
15
32
|
|
|
16
|
-
const isAwsSdkClientModule = ({
|
|
17
|
-
|
|
33
|
+
const isAwsSdkClientModule = ({
|
|
34
|
+
source,
|
|
35
|
+
}: TSESTree.ImportDeclaration): boolean =>
|
|
36
|
+
typeof source.value === 'string' &&
|
|
37
|
+
(source.value.startsWith(AWS_SDK_CLIENT) ||
|
|
38
|
+
source.value.startsWith(AWS_SDK_LIB));
|
|
18
39
|
|
|
19
40
|
const kebabToPascal = (str: string): string =>
|
|
20
41
|
str
|
|
@@ -39,51 +60,53 @@ const isAggregatedClient = (name: string, importSource: string): boolean => {
|
|
|
39
60
|
const pkg = importSource.replace(AWS_SDK_LIB, '');
|
|
40
61
|
const pkgPascal = kebabToPascal(pkg);
|
|
41
62
|
return (
|
|
42
|
-
(name.startsWith(pkgPascal) &&
|
|
63
|
+
(name.startsWith(pkgPascal) &&
|
|
64
|
+
!endsWithAnySuffix(name, BARE_BONES_SUFFIXES)) ||
|
|
43
65
|
endsWithAnySuffix(name, AWS_LIB_AGGREGATED_SUFFIXES)
|
|
44
66
|
);
|
|
45
67
|
}
|
|
46
68
|
return false;
|
|
47
69
|
};
|
|
48
70
|
|
|
49
|
-
const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_AGGREGATED_CLIENT> =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
const rule: ESLintUtils.RuleModule<typeof MESSAGE_ID_AGGREGATED_CLIENT> =
|
|
72
|
+
createRule({
|
|
73
|
+
name: ruleId,
|
|
74
|
+
meta: {
|
|
75
|
+
type: 'problem',
|
|
76
|
+
docs: {
|
|
77
|
+
description:
|
|
78
|
+
'Disallow importing aggregated AWS SDK v3 clients. Use bare-bones pattern (Client/Lib plus Command) for better tree-shaking.',
|
|
79
|
+
},
|
|
80
|
+
messages: {
|
|
81
|
+
[MESSAGE_ID_AGGREGATED_CLIENT]:
|
|
82
|
+
'Do not import aggregated AWS SDK v3 client "{{clientName}}". Use bare-bones pattern ({{clientName}}Client/Lib plus Command) instead.',
|
|
83
|
+
},
|
|
84
|
+
schema: [],
|
|
60
85
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
86
|
+
defaultOptions: [],
|
|
87
|
+
create(context) {
|
|
88
|
+
return {
|
|
89
|
+
ImportDeclaration(node) {
|
|
90
|
+
if (node.importKind === 'type' || !isAwsSdkClientModule(node)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
70
93
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
for (const specifier of node.specifiers) {
|
|
95
|
+
if (
|
|
96
|
+
specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
97
|
+
specifier.importKind !== 'type' &&
|
|
98
|
+
isAggregatedClient(specifier.local.name, node.source.value)
|
|
99
|
+
) {
|
|
100
|
+
context.report({
|
|
101
|
+
node: specifier,
|
|
102
|
+
messageId: MESSAGE_ID_AGGREGATED_CLIENT,
|
|
103
|
+
data: { clientName: specifier.local.name },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
82
106
|
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
});
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
});
|
|
88
111
|
|
|
89
112
|
export default rule;
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
* This code is licensed under the MIT license (see LICENSE.txt for details).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AST_NODE_TYPES,
|
|
11
|
+
ESLintUtils,
|
|
12
|
+
TSESTree,
|
|
13
|
+
} from '@typescript-eslint/utils';
|
|
10
14
|
import getDocumentationUrl from '../get-documentation-url.ts';
|
|
11
15
|
|
|
12
16
|
export const ruleId = 'require-aws-config';
|
|
@@ -14,92 +18,110 @@ export const MESSAGE_ID_REQUIRE_AWS_CONFIG = 'requireAwsConfig';
|
|
|
14
18
|
export const MESSAGE_ID_NO_CHECKDIGIT_AWS = 'noCheckdigitAws';
|
|
15
19
|
const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
16
20
|
|
|
17
|
-
function isAwsSdkClientModule(
|
|
21
|
+
function isAwsSdkClientModule(
|
|
22
|
+
importDeclaration: TSESTree.ImportDeclaration,
|
|
23
|
+
): boolean {
|
|
18
24
|
return importDeclaration.source.value.startsWith('@aws-sdk/client-');
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
function isCheckdigitAwsModule(
|
|
27
|
+
function isCheckdigitAwsModule(
|
|
28
|
+
importDeclaration: TSESTree.ImportDeclaration,
|
|
29
|
+
): boolean {
|
|
22
30
|
return importDeclaration.source.value === '@checkdigit/aws';
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
function isAwsClient(
|
|
33
|
+
function isAwsClient(
|
|
34
|
+
awsClientName: string,
|
|
35
|
+
importedAwsClients?: Set<string>,
|
|
36
|
+
): boolean {
|
|
26
37
|
// for simplicity, just check if it ends with 'Client'
|
|
27
38
|
// we can consider type checking in the future if needed to verify if it actually extends from AWS SDK's Smithy Client class
|
|
28
39
|
return (
|
|
29
|
-
awsClientName.endsWith('Client') &&
|
|
40
|
+
awsClientName.endsWith('Client') &&
|
|
41
|
+
(importedAwsClients === undefined || importedAwsClients.has(awsClientName))
|
|
30
42
|
);
|
|
31
43
|
}
|
|
32
44
|
|
|
33
|
-
const rule: ESLintUtils.RuleModule<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
messages: {
|
|
43
|
-
[MESSAGE_ID_REQUIRE_AWS_CONFIG]:
|
|
44
|
-
'Please apply @checkdigit/aws-config with qualifier/environment instead of creating a new instance of {{awsClientName}} directly.',
|
|
45
|
-
[MESSAGE_ID_NO_CHECKDIGIT_AWS]:
|
|
46
|
-
'No longer import from deprecated module "@checkdigit/aws". Please migrate to the official AWS SDK v3 modules.',
|
|
47
|
-
},
|
|
48
|
-
schema: [],
|
|
45
|
+
const rule: ESLintUtils.RuleModule<
|
|
46
|
+
typeof MESSAGE_ID_REQUIRE_AWS_CONFIG | typeof MESSAGE_ID_NO_CHECKDIGIT_AWS
|
|
47
|
+
> = createRule({
|
|
48
|
+
name: ruleId,
|
|
49
|
+
meta: {
|
|
50
|
+
type: 'problem',
|
|
51
|
+
docs: {
|
|
52
|
+
description:
|
|
53
|
+
'Require applying @checkdigit/aws-config with qualifier/environment instead of creating new AWS client instance directly. Also disallow importing from deprecated @checkdigit/aws module.',
|
|
49
54
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
messages: {
|
|
56
|
+
[MESSAGE_ID_REQUIRE_AWS_CONFIG]:
|
|
57
|
+
'Please apply @checkdigit/aws-config with qualifier/environment instead of creating a new instance of {{awsClientName}} directly.',
|
|
58
|
+
[MESSAGE_ID_NO_CHECKDIGIT_AWS]:
|
|
59
|
+
'No longer import from deprecated module "@checkdigit/aws". Please migrate to the official AWS SDK v3 modules.',
|
|
60
|
+
},
|
|
61
|
+
schema: [],
|
|
62
|
+
},
|
|
63
|
+
defaultOptions: [],
|
|
64
|
+
create(context) {
|
|
65
|
+
const { isAwsSdkV3Used } = context.settings;
|
|
66
|
+
const importedAwsClients = new Set<string>();
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
return {
|
|
69
|
+
ImportDeclaration(node) {
|
|
70
|
+
if (isAwsSdkV3Used !== true) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
if (isCheckdigitAwsModule(node)) {
|
|
75
|
+
context.report({
|
|
76
|
+
node,
|
|
77
|
+
messageId: MESSAGE_ID_NO_CHECKDIGIT_AWS,
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
68
81
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
if (isAwsSdkClientModule(node)) {
|
|
83
|
+
for (const specifier of node.specifiers) {
|
|
84
|
+
if (
|
|
85
|
+
specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
86
|
+
isAwsClient(specifier.local.name)
|
|
87
|
+
) {
|
|
88
|
+
importedAwsClients.add(specifier.local.name);
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
|
-
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
77
93
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
NewExpression(node) {
|
|
95
|
+
if (isAwsSdkV3Used !== true) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
82
98
|
|
|
83
|
-
|
|
99
|
+
if (
|
|
100
|
+
node.callee.type === AST_NODE_TYPES.Identifier &&
|
|
101
|
+
isAwsClient(node.callee.name, importedAwsClients)
|
|
102
|
+
) {
|
|
103
|
+
context.report({
|
|
104
|
+
node,
|
|
105
|
+
messageId: MESSAGE_ID_REQUIRE_AWS_CONFIG,
|
|
106
|
+
data: { awsClientName: node.callee.name },
|
|
107
|
+
});
|
|
108
|
+
} else if (node.callee.type === AST_NODE_TYPES.MemberExpression) {
|
|
109
|
+
// Handle `new AWS.DynamoDBClient()` style (MemberExpression)
|
|
110
|
+
const property = node.callee.property;
|
|
111
|
+
if (
|
|
112
|
+
property.type === AST_NODE_TYPES.Identifier &&
|
|
113
|
+
isAwsClient(property.name, importedAwsClients)
|
|
114
|
+
) {
|
|
84
115
|
context.report({
|
|
85
116
|
node,
|
|
86
117
|
messageId: MESSAGE_ID_REQUIRE_AWS_CONFIG,
|
|
87
|
-
data: { awsClientName:
|
|
118
|
+
data: { awsClientName: property.name },
|
|
88
119
|
});
|
|
89
|
-
} else if (node.callee.type === AST_NODE_TYPES.MemberExpression) {
|
|
90
|
-
// Handle `new AWS.DynamoDBClient()` style (MemberExpression)
|
|
91
|
-
const property = node.callee.property;
|
|
92
|
-
if (property.type === AST_NODE_TYPES.Identifier && isAwsClient(property.name, importedAwsClients)) {
|
|
93
|
-
context.report({
|
|
94
|
-
node,
|
|
95
|
-
messageId: MESSAGE_ID_REQUIRE_AWS_CONFIG,
|
|
96
|
-
data: { awsClientName: property.name },
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
120
|
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
});
|
|
104
126
|
|
|
105
127
|
export default rule;
|