@checkdigit/eslint-plugin 7.17.1 → 8.0.0-PR.141-7ea9
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
|
@@ -6,16 +6,22 @@
|
|
|
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
|
|
|
11
|
-
import getDocumentationUrl from './get-documentation-url';
|
|
12
|
-
import { isServiceResponse } from './service';
|
|
15
|
+
import getDocumentationUrl from './get-documentation-url.ts';
|
|
16
|
+
import { isServiceResponse } from './service.ts';
|
|
13
17
|
|
|
14
18
|
export const ruleId = 'require-service-call-response-declaration';
|
|
15
19
|
|
|
16
20
|
const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
17
21
|
|
|
18
|
-
const rule: ESLintUtils.RuleModule<
|
|
22
|
+
const rule: ESLintUtils.RuleModule<
|
|
23
|
+
'unknownError' | 'requireServiceCallResponseDeclaration'
|
|
24
|
+
> = createRule({
|
|
19
25
|
name: ruleId,
|
|
20
26
|
meta: {
|
|
21
27
|
type: 'suggestion',
|
|
@@ -26,7 +32,8 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'requireServiceCallResponseD
|
|
|
26
32
|
messages: {
|
|
27
33
|
requireServiceCallResponseDeclaration:
|
|
28
34
|
'Awaited service call is required to declare variable for its return value which should be examined later on.',
|
|
29
|
-
unknownError:
|
|
35
|
+
unknownError:
|
|
36
|
+
'Unknown error occurred in file "{{fileName}}": {{ error }}.',
|
|
30
37
|
},
|
|
31
38
|
fixable: 'code',
|
|
32
39
|
schema: [],
|
|
@@ -39,7 +46,9 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'requireServiceCallResponseD
|
|
|
39
46
|
return {
|
|
40
47
|
AwaitExpression(serviceCall: TSESTree.AwaitExpression) {
|
|
41
48
|
try {
|
|
42
|
-
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(
|
|
49
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(
|
|
50
|
+
serviceCall.argument,
|
|
51
|
+
);
|
|
43
52
|
const type = typeChecker.getTypeAtLocation(tsNode);
|
|
44
53
|
const awaitedType = typeChecker.getAwaitedType(type);
|
|
45
54
|
if (
|
|
@@ -54,13 +63,19 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'requireServiceCallResponseD
|
|
|
54
63
|
}
|
|
55
64
|
} catch (error) {
|
|
56
65
|
// eslint-disable-next-line no-console
|
|
57
|
-
console.error(
|
|
66
|
+
console.error(
|
|
67
|
+
`Failed to apply ${ruleId} rule for file "${context.filename}":`,
|
|
68
|
+
error,
|
|
69
|
+
);
|
|
58
70
|
context.report({
|
|
59
71
|
node: serviceCall,
|
|
60
72
|
messageId: 'unknownError',
|
|
61
73
|
data: {
|
|
62
74
|
fileName: context.filename,
|
|
63
|
-
error:
|
|
75
|
+
error:
|
|
76
|
+
error instanceof Error
|
|
77
|
+
? error.toString()
|
|
78
|
+
: JSON.stringify(error),
|
|
64
79
|
},
|
|
65
80
|
});
|
|
66
81
|
}
|
|
@@ -15,7 +15,8 @@ export default {
|
|
|
15
15
|
meta: {
|
|
16
16
|
type: 'problem',
|
|
17
17
|
docs: {
|
|
18
|
-
description:
|
|
18
|
+
description:
|
|
19
|
+
'Require importing strict version of node:assert and using non-strict assert functions.',
|
|
19
20
|
url: 'https://github.com/checkdigit/eslint-plugin',
|
|
20
21
|
},
|
|
21
22
|
fixable: 'code',
|
|
@@ -37,23 +38,33 @@ export default {
|
|
|
37
38
|
const importDeclaration = node.parent;
|
|
38
39
|
const defaultSpecifier = importDeclaration.specifiers.find(
|
|
39
40
|
(specifier) =>
|
|
40
|
-
specifier.type === 'ImportDefaultSpecifier' ||
|
|
41
|
+
specifier.type === 'ImportDefaultSpecifier' ||
|
|
42
|
+
specifier.type === 'ImportNamespaceSpecifier',
|
|
41
43
|
);
|
|
42
44
|
|
|
43
45
|
if (defaultSpecifier !== undefined) {
|
|
44
46
|
const importDeclarationRange = importDeclaration.range ?? [0, 0];
|
|
45
|
-
let rangeToReplace =
|
|
47
|
+
let rangeToReplace =
|
|
48
|
+
defaultSpecifier.range ?? importDeclarationRange;
|
|
46
49
|
let correctedText = `{ strict as ${defaultSpecifier.local.name} }`;
|
|
47
50
|
|
|
48
|
-
if (
|
|
49
|
-
|
|
51
|
+
if (
|
|
52
|
+
node.value === NODE_ASSERT_STRICT &&
|
|
53
|
+
defaultSpecifier.range &&
|
|
54
|
+
importDeclaration.source.range
|
|
55
|
+
) {
|
|
56
|
+
rangeToReplace = [
|
|
57
|
+
defaultSpecifier.range[0],
|
|
58
|
+
importDeclaration.source.range[1],
|
|
59
|
+
];
|
|
50
60
|
correctedText = `{ strict as ${defaultSpecifier.local.name} } from '${NODE_ASSERT}'`;
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
context.report({
|
|
54
64
|
node: importDeclaration,
|
|
55
65
|
message: 'Invalid form of strict assertion mode',
|
|
56
|
-
fix: (fixer) =>
|
|
66
|
+
fix: (fixer) =>
|
|
67
|
+
fixer.replaceTextRange(rangeToReplace, correctedText),
|
|
57
68
|
});
|
|
58
69
|
}
|
|
59
70
|
}
|
|
@@ -67,7 +78,8 @@ export default {
|
|
|
67
78
|
callee.object.name !== '' &&
|
|
68
79
|
callee.property.type === 'Identifier' &&
|
|
69
80
|
callee.property.name !== '' &&
|
|
70
|
-
(callee.property.name.includes('strict') ||
|
|
81
|
+
(callee.property.name.includes('strict') ||
|
|
82
|
+
callee.property.name.includes('Strict'))
|
|
71
83
|
) {
|
|
72
84
|
const nodeValue = nodeValues[callee.object.name];
|
|
73
85
|
if (nodeValue === NODE_ASSERT || nodeValue === NODE_ASSERT_STRICT) {
|
|
@@ -84,7 +96,8 @@ export default {
|
|
|
84
96
|
}
|
|
85
97
|
context.report({
|
|
86
98
|
node,
|
|
87
|
-
message:
|
|
99
|
+
message:
|
|
100
|
+
'strict method not required when in strict assertion mode.',
|
|
88
101
|
fix: (fixer) => fixer.replaceText(callee, nonStrictFunctionName),
|
|
89
102
|
});
|
|
90
103
|
}
|
|
@@ -18,8 +18,15 @@ const REQUIRE_TS_EXTENSION_EXPORTS = 'REQUIRE-TS-EXTENSION-EXPORTS';
|
|
|
18
18
|
|
|
19
19
|
const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
20
20
|
|
|
21
|
-
const checkPath = (
|
|
22
|
-
|
|
21
|
+
const checkPath = (
|
|
22
|
+
filename: string,
|
|
23
|
+
filePath: string,
|
|
24
|
+
): { fixedPath: string | null; isFixNeeded: boolean } => {
|
|
25
|
+
if (
|
|
26
|
+
filePath.startsWith('.') &&
|
|
27
|
+
!filePath.endsWith('.ts') &&
|
|
28
|
+
!filePath.endsWith('.json')
|
|
29
|
+
) {
|
|
23
30
|
const absolutePath = path.resolve(path.dirname(filename), filePath);
|
|
24
31
|
const tsPath = `${absolutePath}.ts`;
|
|
25
32
|
const existsPath = [absolutePath, tsPath].find(fs.existsSync);
|
|
@@ -38,13 +45,16 @@ const rule: TSESLint.RuleModule<string, unknown[]> = createRule({
|
|
|
38
45
|
meta: {
|
|
39
46
|
type: 'suggestion',
|
|
40
47
|
docs: {
|
|
41
|
-
description:
|
|
48
|
+
description:
|
|
49
|
+
'Ensure .ts extension is at the end of all imports and exports',
|
|
42
50
|
},
|
|
43
51
|
fixable: 'code',
|
|
44
52
|
schema: [],
|
|
45
53
|
messages: {
|
|
46
|
-
[REQUIRE_TS_EXTENSION_IMPORTS]:
|
|
47
|
-
|
|
54
|
+
[REQUIRE_TS_EXTENSION_IMPORTS]:
|
|
55
|
+
'Import paths should end with .ts extension',
|
|
56
|
+
[REQUIRE_TS_EXTENSION_EXPORTS]:
|
|
57
|
+
'Export paths should end with .ts extension',
|
|
48
58
|
},
|
|
49
59
|
},
|
|
50
60
|
defaultOptions: [],
|
|
@@ -52,7 +62,10 @@ const rule: TSESLint.RuleModule<string, unknown[]> = createRule({
|
|
|
52
62
|
const filename = context.filename;
|
|
53
63
|
|
|
54
64
|
const handleDeclaration = (
|
|
55
|
-
node:
|
|
65
|
+
node:
|
|
66
|
+
| TSESTree.ImportDeclaration
|
|
67
|
+
| TSESTree.ExportNamedDeclaration
|
|
68
|
+
| TSESTree.ExportAllDeclaration,
|
|
56
69
|
) => {
|
|
57
70
|
if (node.source !== null) {
|
|
58
71
|
const importPath = node.source.value;
|
|
@@ -21,7 +21,8 @@ const rule: ESLintUtils.RuleModule<'moveTypeOutside'> = createRule({
|
|
|
21
21
|
description: 'Require "type" to be out side of type-only imports.',
|
|
22
22
|
},
|
|
23
23
|
messages: {
|
|
24
|
-
moveTypeOutside:
|
|
24
|
+
moveTypeOutside:
|
|
25
|
+
'Update the type-only imports to put "type" specifier outside of the curly braces.',
|
|
25
26
|
},
|
|
26
27
|
fixable: 'code',
|
|
27
28
|
schema: [],
|
|
@@ -37,7 +38,8 @@ const rule: ESLintUtils.RuleModule<'moveTypeOutside'> = createRule({
|
|
|
37
38
|
declaration.specifiers.length === 0 ||
|
|
38
39
|
!declaration.specifiers.every(
|
|
39
40
|
(specifier) =>
|
|
40
|
-
specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier &&
|
|
41
|
+
specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier &&
|
|
42
|
+
specifier.importKind === 'type',
|
|
41
43
|
)
|
|
42
44
|
) {
|
|
43
45
|
return;
|
|
@@ -49,8 +51,14 @@ const rule: ESLintUtils.RuleModule<'moveTypeOutside'> = createRule({
|
|
|
49
51
|
*fix(fixer) {
|
|
50
52
|
const moduleName = declaration.source.value;
|
|
51
53
|
const mergedSpecifiers = declaration.specifiers
|
|
52
|
-
.filter(
|
|
53
|
-
|
|
54
|
+
.filter(
|
|
55
|
+
(specifier) =>
|
|
56
|
+
specifier.type !==
|
|
57
|
+
TSESTree.AST_NODE_TYPES.ImportDefaultSpecifier,
|
|
58
|
+
)
|
|
59
|
+
.map((specifier) =>
|
|
60
|
+
sourceCode.getText(specifier).replace('type ', ''),
|
|
61
|
+
);
|
|
54
62
|
const updatedImportDeclaration = `import type { ${mergedSpecifiers.join(', ')} } from '${moduleName}';`;
|
|
55
63
|
|
|
56
64
|
yield fixer.replaceText(declaration, updatedImportDeclaration);
|