@checkdigit/eslint-plugin 7.11.0-PR.45-5dba → 7.12.0-PR.45-1e1c
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 -3
- package/dist-mjs/library/ts-tree.mjs +1 -1
- package/dist-mjs/require-assert-message.mjs +12 -7
- package/dist-mjs/require-service-call-response-declaration.mjs +57 -0
- package/dist-mjs/service.mjs +9 -0
- package/dist-types/library/ts-tree.d.ts +1 -1
- package/dist-types/require-service-call-response-declaration.d.ts +4 -0
- package/dist-types/service.d.ts +2 -0
- package/package.json +1 -1
- package/src/index.ts +6 -0
- package/src/library/ts-tree.ts +1 -5
- package/src/require-assert-message.ts +11 -6
- package/src/require-service-call-response-declaration.ts +72 -0
- package/src/service.ts +11 -0
package/dist-mjs/index.mjs
CHANGED
|
@@ -14,6 +14,9 @@ import requireTypeOutOfTypeOnlyImports, {
|
|
|
14
14
|
ruleId as requireTypeOutOfTypeOnlyImportsRuleId
|
|
15
15
|
} from "./require-type-out-of-type-only-imports.mjs";
|
|
16
16
|
import noServeRuntime, { ruleId as noServeRuntimeRuleId } from "./no-serve-runtime.mjs";
|
|
17
|
+
import requireServiceCallResponseDeclaration, {
|
|
18
|
+
ruleId as requireServiceCallResponseDeclarationRuleId
|
|
19
|
+
} from "./require-service-call-response-declaration.mjs";
|
|
17
20
|
import filePathComment from "./file-path-comment.mjs";
|
|
18
21
|
import noCardNumbers from "./no-card-numbers.mjs";
|
|
19
22
|
import noEnum from "./no-enum.mjs";
|
|
@@ -50,6 +53,7 @@ var rules = {
|
|
|
50
53
|
[requireResolveFullResponseRuleId]: requireResolveFullResponse,
|
|
51
54
|
[noDuplicatedImportsRuleId]: noDuplicatedImports,
|
|
52
55
|
[noServeRuntimeRuleId]: noServeRuntime,
|
|
56
|
+
[requireServiceCallResponseDeclarationRuleId]: requireServiceCallResponseDeclaration,
|
|
53
57
|
[requireFixedServicesImportRuleId]: requireFixedServicesImport,
|
|
54
58
|
[requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports
|
|
55
59
|
};
|
|
@@ -89,7 +93,8 @@ var configs = {
|
|
|
89
93
|
[`@checkdigit/${noDuplicatedImportsRuleId}`]: "error",
|
|
90
94
|
[`@checkdigit/${requireFixedServicesImportRuleId}`]: "error",
|
|
91
95
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
|
|
92
|
-
[`@checkdigit/${noServeRuntimeRuleId}`]: "error"
|
|
96
|
+
[`@checkdigit/${noServeRuntimeRuleId}`]: "error",
|
|
97
|
+
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "error"
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
100
|
],
|
|
@@ -122,7 +127,8 @@ var configs = {
|
|
|
122
127
|
[`@checkdigit/${noDuplicatedImportsRuleId}`]: "error",
|
|
123
128
|
[`@checkdigit/${requireFixedServicesImportRuleId}`]: "off",
|
|
124
129
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: "error",
|
|
125
|
-
[`@checkdigit/${noServeRuntimeRuleId}`]: "off"
|
|
130
|
+
[`@checkdigit/${noServeRuntimeRuleId}`]: "off",
|
|
131
|
+
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: "off"
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
134
|
]
|
|
@@ -135,4 +141,4 @@ var src_default = defaultToExport;
|
|
|
135
141
|
export {
|
|
136
142
|
src_default as default
|
|
137
143
|
};
|
|
138
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVVBLE9BQU8sd0JBQXdCLFVBQVUsa0NBQWtDO0FBQzNFLE9BQU8sdUJBQXVCLFVBQVUsaUNBQWlDO0FBQ3pFLE9BQU8seUJBQXlCLFVBQVUsbUNBQW1DO0FBQzdFLE9BQU8sMkJBQTJCLFVBQVUscUNBQXFDO0FBQ2pGLE9BQU8sd0JBQXdCO0FBQy9CLE9BQU87QUFBQSxFQUNMLFVBQVU7QUFBQSxPQUNMO0FBQ1AsT0FBTztBQUFBLEVBQ0wsVUFBVTtBQUFBLE9BQ0w7QUFDUCxPQUFPO0FBQUEsRUFDTCxVQUFVO0FBQUEsT0FDTDtBQUNQLE9BQU8sa0JBQWtCLFVBQVUsNEJBQTRCO0FBQy9ELE9BQU87QUFBQSxFQUNMLFVBQVU7QUFBQSxPQUNMO0FBQ1AsT0FBTyxxQkFBcUI7QUFDNUIsT0FBTyxtQkFBbUI7QUFDMUIsT0FBTyxZQUFZO0FBQ25CLE9BQU8sbUJBQW1CO0FBQzFCLE9BQU8sb0JBQW9CO0FBQzNCLE9BQU8sa0JBQWtCO0FBQ3pCLE9BQU8sWUFBWTtBQUNuQixPQUFPLHNCQUFzQjtBQUM3QixPQUFPLDJCQUEyQjtBQUNsQyxPQUFPLGtCQUFrQjtBQUN6QixPQUFPLHlDQUF5QztBQUNoRCxPQUFPLHlCQUF5QjtBQUNoQyxPQUFPLDBCQUEwQjtBQUNqQyxPQUFPLHNDQUFzQztBQUU3QyxJQUFNLFFBQXNEO0FBQUEsRUFDMUQscUJBQXFCO0FBQUEsRUFDckIsbUJBQW1CO0FBQUEsRUFDbkIsV0FBVztBQUFBLEVBQ1gscUJBQXFCO0FBQUEsRUFDckIseUJBQXlCO0FBQUEsRUFDekIsV0FBVztBQUFBLEVBQ1gsMEJBQTBCO0FBQUEsRUFDMUIseUJBQXlCO0FBQUEsRUFDekIsd0NBQXdDO0FBQUEsRUFDeEMsa0JBQWtCO0FBQUEsRUFDbEIsc0JBQXNCO0FBQUEsRUFDdEIsbUJBQW1CO0FBQUEsRUFDbkIsOEJBQThCO0FBQUEsRUFDOUIsMkNBQTJDO0FBQUEsRUFDM0MsMkJBQTJCO0FBQUEsRUFDM0IsQ0FBQywwQkFBMEIsR0FBRztBQUFBLEVBQzlCLENBQUMsNkJBQTZCLEdBQUc7QUFBQSxFQUNqQyxDQUFDLDJCQUEyQixHQUFHO0FBQUEsRUFDL0IsQ0FBQyxnQ0FBZ0MsR0FBRztBQUFBLEVBQ3BDLENBQUMseUJBQXlCLEdBQUc7QUFBQSxFQUM3QixDQUFDLG9CQUFvQixHQUFHO0FBQUEsRUFDeEIsQ0FBQywyQ0FBMkMsR0FBRztBQUFBLEVBQy9DLENBQUMsZ0NBQWdDLEdBQUc7QUFBQSxFQUNwQyxDQUFDLHFDQUFxQyxHQUFHO0FBQzNDO0FBRUEsSUFBTSxTQUFxQztBQUFBLEVBQ3pDO0FBQ0Y7QUFFQSxJQUFNLFVBQXdEO0FBQUEsRUFDNUQsS0FBSztBQUFBLElBQ0g7QUFBQSxNQUNFLE9BQU8sQ0FBQyxTQUFTO0FBQUEsTUFDakIsU0FBUztBQUFBLFFBQ1AsZUFBZTtBQUFBLE1BQ2pCO0FBQUEsTUFDQSxPQUFPO0FBQUEsUUFDTCwrQkFBK0I7QUFBQSxRQUMvQix1QkFBdUI7QUFBQSxRQUN2QixpQ0FBaUM7QUFBQSxRQUNqQyxpQ0FBaUM7QUFBQSxRQUNqQyxxQ0FBcUM7QUFBQSxRQUNyQyx1QkFBdUI7QUFBQSxRQUN2QixzQ0FBc0M7QUFBQSxRQUN0QyxxQ0FBcUM7QUFBQSxRQUNyQyxvREFBb0Q7QUFBQSxRQUNwRCxrQ0FBa0M7QUFBQSxRQUNsQywrQkFBK0I7QUFBQSxVQUM3QjtBQUFBLFVBQ0EsRUFBRSxxQkFBcUIsQ0FBQyxVQUFVLFNBQVMsT0FBTyxhQUFhLFlBQVksRUFBRTtBQUFBLFFBQy9FO0FBQUEsUUFDQSwwQ0FBMEM7QUFBQSxRQUMxQyx1REFBdUQ7QUFBQSxRQUN2RCx1Q0FBdUM7QUFBQSxRQUN2Qyw4QkFBOEI7QUFBQSxRQUM5QixDQUFDLGVBQWUsMEJBQTBCLEVBQUUsR0FBRztBQUFBLFFBQy9DLENBQUMsZUFBZSw2QkFBNkIsRUFBRSxHQUFHO0FBQUEsUUFDbEQsQ0FBQyxlQUFlLDJCQUEyQixFQUFFLEdBQUc7QUFBQSxRQUNoRCxDQUFDLGVBQWUsZ0NBQWdDLEVBQUUsR0FBRztBQUFBLFFBQ3JELENBQUMsZUFBZSx5QkFBeUIsRUFBRSxHQUFHO0FBQUEsUUFDOUMsQ0FBQyxlQUFlLGdDQUFnQyxFQUFFLEdBQUc7QUFBQSxRQUNyRCxDQUFDLGVBQWUscUNBQXFDLEVBQUUsR0FBRztBQUFBLFFBQzFELENBQUMsZUFBZSxvQkFBb0IsRUFBRSxHQUFHO0FBQUEsUUFDekMsQ0FBQyxlQUFlLDJDQUEyQyxFQUFFLEdBQUc7QUFBQSxNQUNsRTtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFDQSxhQUFhO0FBQUEsSUFDWDtBQUFBLE1BQ0UsT0FBTyxDQUFDLFNBQVM7QUFBQSxNQUNqQixTQUFTO0FBQUEsUUFDUCxlQUFlO0FBQUEsTUFDakI7QUFBQSxNQUNBLE9BQU87QUFBQSxRQUNMLCtCQUErQjtBQUFBLFFBQy9CLHVCQUF1QjtBQUFBLFFBQ3ZCLGlDQUFpQztBQUFBLFFBQ2pDLGlDQUFpQztBQUFBLFFBQ2pDLHFDQUFxQztBQUFBLFFBQ3JDLHVCQUF1QjtBQUFBLFFBQ3ZCLHNDQUFzQztBQUFBLFFBQ3RDLHFDQUFxQztBQUFBLFFBQ3JDLG9EQUFvRDtBQUFBLFFBQ3BELGtDQUFrQztBQUFBLFFBQ2xDLCtCQUErQjtBQUFBLFFBQy9CLDBDQUEwQztBQUFBLFFBQzFDLHVEQUF1RDtBQUFBLFFBQ3ZELHVDQUF1QztBQUFBLFFBQ3ZDLDhCQUE4QjtBQUFBLFFBQzlCLENBQUMsZUFBZSwwQkFBMEIsRUFBRSxHQUFHO0FBQUEsUUFDL0MsQ0FBQyxlQUFlLDZCQUE2QixFQUFFLEdBQUc7QUFBQSxRQUNsRCxDQUFDLGVBQWUsMkJBQTJCLEVBQUUsR0FBRztBQUFBLFFBQ2hELENBQUMsZUFBZSxnQ0FBZ0MsRUFBRSxHQUFHO0FBQUEsUUFDckQsQ0FBQyxlQUFlLHlCQUF5QixFQUFFLEdBQUc7QUFBQSxRQUM5QyxDQUFDLGVBQWUsZ0NBQWdDLEVBQUUsR0FBRztBQUFBLFFBQ3JELENBQUMsZUFBZSxxQ0FBcUMsRUFBRSxHQUFHO0FBQUEsUUFDMUQsQ0FBQyxlQUFlLG9CQUFvQixFQUFFLEdBQUc7QUFBQSxRQUN6QyxDQUFDLGVBQWUsMkNBQTJDLEVBQUUsR0FBRztBQUFBLE1BQ2xFO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjtBQUVBLElBQU0sa0JBRUY7QUFBQSxFQUNGLEdBQUc7QUFBQSxFQUNIO0FBQ0Y7QUFDQSxJQUFPLGNBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -69,4 +69,4 @@ export {
|
|
|
69
69
|
isBlockStatement,
|
|
70
70
|
isUsedInArrayOrAsArgument
|
|
71
71
|
};
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2xpYnJhcnkvdHMtdHJlZS50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLHNCQUFnQztBQVFsQyxTQUFTLFVBQVUsTUFBdUQ7QUFDL0UsU0FBUSxLQUF3QztBQUNsRDtBQUVPLFNBQVMsWUFDZCxNQUNBLFNBQ0EsYUFDMkI7QUFDM0IsUUFBTSxTQUFTLFVBQVUsSUFBSTtBQUM3QixNQUFJLENBQUMsUUFBUTtBQUNYLFdBQU87QUFBQSxFQUNULFdBQVcsT0FBTyxZQUFZLFlBQVksT0FBTyxTQUFTLFNBQVM7QUFDakUsV0FBTztBQUFBLEVBQ1QsV0FBVyxPQUFPLFlBQVksY0FBYyxRQUFRLE1BQU0sR0FBRztBQUMzRCxXQUFPO0FBQUEsRUFDVCxXQUFXLE9BQU8sZ0JBQWdCLFlBQVksT0FBTyxTQUFTLGFBQWE7QUFDekUsV0FBTztBQUFBLEVBQ1QsV0FBVyxPQUFPLGdCQUFnQixjQUFjLFlBQVksTUFBTSxHQUFHO0FBQ25FLFdBQU87QUFBQSxFQUNUO0FBQ0EsU0FBTyxZQUFZLFFBQVEsU0FBUyxXQUFXO0FBQ2pEO0FBRU8sU0FBUyxpQkFBaUIsTUFBOEI7QUFDN0QsU0FBTyxLQUFLLEtBQUssU0FBUyxXQUFXLEtBQUssS0FBSyxLQUFLLFNBQVMsYUFBYTtBQUM1RTtBQUVPLFNBQVMsc0JBQXNCLE1BQWdEO0FBQ3BGLFNBQU8sWUFBWSxNQUFNLGdCQUFnQjtBQUMzQztBQUVPLFNBQVMsc0JBQXNCLE1BQWdEO0FBQ3BGLFNBQU87QUFBQSxJQUFZO0FBQUEsSUFBTSxDQUFDLGVBQ3hCLENBQUMsc0JBQXNCLHVCQUF1QiwyQkFBMkIsU0FBUyxFQUFFLFNBQVMsV0FBVyxJQUFJO0FBQUEsRUFDOUc7QUFDRjtBQUVPLFNBQVMsMEJBQTBCLE1BQThCO0FBQ3RFLE1BQUksaUJBQWlCLElBQUksR0FBRztBQUMxQixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sU0FBUyxVQUFVLElBQUk7QUFDN0IsTUFBSSxDQUFDLFFBQVE7QUFDWCxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQ0UsT0FBTyxTQUFTLGVBQWUsbUJBQzlCLE9BQU8sU0FBUyxlQUFlLGtCQUFrQixPQUFPLFVBQVUsU0FBUyxJQUEyQixHQUN2RztBQUNBLFdBQU87QUFBQSxFQUNUO0FBR0EsU0FBTywwQkFBMEIsTUFBTTtBQUN6QztBQUVPLFNBQVMscUJBQ2QsTUFDMkc7QUFDM0csTUFDRSxLQUFLLFNBQVMsZUFBZSx1QkFDN0IsS0FBSyxTQUFTLGVBQWUsc0JBQzdCLEtBQUssU0FBUyxlQUFlLHlCQUM3QjtBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxTQUFTLFVBQVUsSUFBSTtBQUM3QixNQUFJLENBQUMsUUFBUTtBQUNYO0FBQUEsRUFDRjtBQUNBLFNBQU8scUJBQXFCLE1BQU07QUFDcEM7QUFFTyxTQUFTLGtCQUNkLE1BQ2lFO0FBQ2pFLE1BQUksQ0FBQyxNQUFNO0FBQ1QsV0FBTztBQUFBLEVBQ1Q7QUFDQSxTQUFPLEtBQUssU0FBUyxlQUFlLG9CQUFvQixLQUFLLFNBQVMsZUFBZSxpQkFDakYsT0FDQSxrQkFBa0IsS0FBSyxNQUFNO0FBQ25DOyIsCiAgIm5hbWVzIjogW10KfQo=
|
|
@@ -22,6 +22,9 @@ var rule = createRule({
|
|
|
22
22
|
defaultOptions: [],
|
|
23
23
|
create(context) {
|
|
24
24
|
let assertAlias = "assert";
|
|
25
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
26
|
+
const checker = parserServices.program.getTypeChecker();
|
|
27
|
+
const messageIndexCache = {};
|
|
25
28
|
return {
|
|
26
29
|
ImportDeclaration(node) {
|
|
27
30
|
if (node.source.value === "node:assert") {
|
|
@@ -39,12 +42,14 @@ var rule = createRule({
|
|
|
39
42
|
const objectName = callee.object.name;
|
|
40
43
|
const methodName = callee.property.name;
|
|
41
44
|
if (objectName === assertAlias && methodsRequiringMessage.includes(methodName)) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (!(methodName in messageIndexCache)) {
|
|
46
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
|
47
|
+
const signature = checker.getResolvedSignature(tsNode);
|
|
48
|
+
const messageParameterIndex = signature?.getParameters().findIndex((param) => param.name === "message");
|
|
49
|
+
messageIndexCache[methodName] = messageParameterIndex ?? 2;
|
|
50
|
+
}
|
|
51
|
+
const messageIndex = messageIndexCache[methodName];
|
|
52
|
+
if (messageIndex !== void 0 && node.arguments.length <= messageIndex) {
|
|
48
53
|
context.report({
|
|
49
54
|
node,
|
|
50
55
|
messageId: MISSING_ASSERT_MESSAGE,
|
|
@@ -72,4 +77,4 @@ export {
|
|
|
72
77
|
require_assert_message_default as default,
|
|
73
78
|
ruleId
|
|
74
79
|
};
|
|
75
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlcXVpcmUtYXNzZXJ0LW1lc3NhZ2UudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBUUEsU0FBUyxVQUFVLGNBQWM7QUFDakMsU0FBUyxtQkFBNkI7QUFDdEMsU0FBUyxnQkFBZ0I7QUFDekIsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBQ3RCLElBQU0seUJBQXlCO0FBRS9CLElBQU0sMEJBQTBCLE9BQU8sS0FBSyxNQUFNLEVBQUUsT0FBTyxDQUFDLFFBQVEsT0FBUSxPQUFpQixHQUFHLE1BQU0sVUFBVTtBQUVoSCxJQUFNLGFBQWEsWUFBWSxZQUFZLENBQUMsU0FBUyxvQkFBb0IsSUFBSSxDQUFDO0FBQzlFLElBQU0sT0FBK0MsV0FBVztBQUFBLEVBQzlELE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxJQUNmO0FBQUEsSUFDQSxRQUFRLENBQUM7QUFBQSxJQUNULFVBQVU7QUFBQSxNQUNSLENBQUMsc0JBQXNCLEdBQUc7QUFBQSxJQUM1QjtBQUFBLEVBQ0Y7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsUUFBSSxjQUFjO0FBQ2xCLFVBQU0saUJBQWlCLFlBQVksa0JBQWtCLE9BQU87QUFDNUQsVUFBTSxVQUFVLGVBQWUsUUFBUSxlQUFlO0FBQ3RELFVBQU0sb0JBQTRDLENBQUM7QUFFbkQsV0FBTztBQUFBLE1BQ0wsa0JBQWtCLE1BQWtDO0FBQ2xELFlBQUksS0FBSyxPQUFPLFVBQVUsZUFBZTtBQUN2QyxnQkFBTSxZQUFZLEtBQUssV0FBVztBQUFBLFlBQ2hDLENBQUMsb0JBQ0MsZ0JBQWdCLFNBQVMsU0FBUyxlQUFlLDBCQUNqRCxnQkFBZ0IsU0FBUyxTQUFTLGVBQWU7QUFBQSxVQUNyRDtBQUNBLGNBQUksV0FBVztBQUNiLDBCQUFjLFVBQVUsTUFBTTtBQUFBLFVBQ2hDO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxNQUNBLGVBQWUsTUFBK0I7QUFDNUMsY0FBTSxTQUFTLEtBQUs7QUFDcEIsWUFDRSxPQUFPLFNBQVMsU0FBUyxlQUFlLG9CQUN4QyxPQUFPLE9BQU8sU0FBUyxTQUFTLGVBQWUsY0FDL0MsT0FBTyxTQUFTLFNBQVMsU0FBUyxlQUFlLFlBQ2pEO0FBQ0EsZ0JBQU0sYUFBYSxPQUFPLE9BQU87QUFDakMsZ0JBQU0sYUFBYSxPQUFPLFNBQVM7QUFFbkMsY0FBSSxlQUFlLGVBQWUsd0JBQXdCLFNBQVMsVUFBVSxHQUFHO0FBQzlFLGdCQUFJLEVBQUUsY0FBYyxvQkFBb0I7QUFDdEMsb0JBQU0sU0FBUyxlQUFlLHNCQUFzQixJQUFJLElBQUk7QUFDNUQsb0JBQU0sWUFBWSxRQUFRLHFCQUFxQixNQUFNO0FBQ3JELG9CQUFNLHdCQUF3QixXQUFXLGNBQWMsRUFBRSxVQUFVLENBQUMsVUFBVSxNQUFNLFNBQVMsU0FBUztBQUN0RyxnQ0FBa0IsVUFBVSxJQUFJLHlCQUF5QjtBQUFBLFlBQzNEO0FBRUEsa0JBQU0sZUFBZSxrQkFBa0IsVUFBVTtBQUNqRCxnQkFBSSxpQkFBaUIsVUFBYSxLQUFLLFVBQVUsVUFBVSxjQUFjO0FBQ3ZFLHNCQUFRLE9BQU87QUFBQSxnQkFDYjtBQUFBLGdCQUNBLFdBQVc7QUFBQSxnQkFDWCxNQUFNO0FBQUEsa0JBQ0o7QUFBQSxnQkFDRjtBQUFBLGNBQ0YsQ0FBQztBQUFBLFlBQ0g7QUFBQSxVQUNGO0FBQUEsUUFDRixXQUNFLE9BQU8sU0FBUyxTQUFTLGVBQWUsY0FDeEMsT0FBTyxTQUFTLGVBQ2hCLEtBQUssVUFBVSxTQUFTLEdBQ3hCO0FBQ0Esa0JBQVEsT0FBTztBQUFBLFlBQ2I7QUFBQSxZQUNBLFdBQVc7QUFBQSxZQUNYLE1BQU07QUFBQSxjQUNKLFlBQVk7QUFBQSxZQUNkO0FBQUEsVUFDRixDQUFDO0FBQUEsUUFDSDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFRCxJQUFPLGlDQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/require-service-call-response-declaration.ts
|
|
2
|
+
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
3
|
+
import getDocumentationUrl from "./get-documentation-url.mjs";
|
|
4
|
+
import { isServiceResponse } from "./service.mjs";
|
|
5
|
+
var ruleId = "require-service-call-response-declaration";
|
|
6
|
+
var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
7
|
+
var rule = createRule({
|
|
8
|
+
name: ruleId,
|
|
9
|
+
meta: {
|
|
10
|
+
type: "suggestion",
|
|
11
|
+
docs: {
|
|
12
|
+
description: "Awaited service call is required to declare variable for its return value which should be examined later on."
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
requireServiceCallResponseDeclaration: "Awaited service call is required to declare variable for its return value which should be examined later on.",
|
|
16
|
+
unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
|
|
17
|
+
},
|
|
18
|
+
fixable: "code",
|
|
19
|
+
schema: []
|
|
20
|
+
},
|
|
21
|
+
defaultOptions: [],
|
|
22
|
+
create(context) {
|
|
23
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
24
|
+
const typeChecker = parserServices.program.getTypeChecker();
|
|
25
|
+
return {
|
|
26
|
+
AwaitExpression(serviceCall) {
|
|
27
|
+
try {
|
|
28
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(serviceCall.argument);
|
|
29
|
+
const type = typeChecker.getTypeAtLocation(tsNode);
|
|
30
|
+
const awaitedType = typeChecker.getAwaitedType(type);
|
|
31
|
+
if (awaitedType !== void 0 && isServiceResponse(awaitedType) && serviceCall.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
|
|
32
|
+
context.report({
|
|
33
|
+
node: serviceCall,
|
|
34
|
+
messageId: "requireServiceCallResponseDeclaration"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
|
|
39
|
+
context.report({
|
|
40
|
+
node: serviceCall,
|
|
41
|
+
messageId: "unknownError",
|
|
42
|
+
data: {
|
|
43
|
+
fileName: context.filename,
|
|
44
|
+
error: error instanceof Error ? error.toString() : JSON.stringify(error)
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
var require_service_call_response_declaration_default = rule;
|
|
53
|
+
export {
|
|
54
|
+
require_service_call_response_declaration_default as default,
|
|
55
|
+
ruleId
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlcXVpcmUtc2VydmljZS1jYWxsLXJlc3BvbnNlLWRlY2xhcmF0aW9uLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsZ0JBQWdCLG1CQUE2QjtBQUV0RCxPQUFPLHlCQUF5QjtBQUNoQyxTQUFTLHlCQUF5QjtBQUUzQixJQUFNLFNBQVM7QUFFdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxJQUFNLE9BQXlGLFdBQVc7QUFBQSxFQUN4RyxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUNFO0FBQUEsSUFDSjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsdUNBQ0U7QUFBQSxNQUNGLGNBQWM7QUFBQSxJQUNoQjtBQUFBLElBQ0EsU0FBUztBQUFBLElBQ1QsUUFBUSxDQUFDO0FBQUEsRUFDWDtBQUFBLEVBQ0EsZ0JBQWdCLENBQUM7QUFBQSxFQUNqQixPQUFPLFNBQVM7QUFDZCxVQUFNLGlCQUFpQixZQUFZLGtCQUFrQixPQUFPO0FBQzVELFVBQU0sY0FBYyxlQUFlLFFBQVEsZUFBZTtBQUUxRCxXQUFPO0FBQUEsTUFDTCxnQkFBZ0IsYUFBdUM7QUFDckQsWUFBSTtBQUNGLGdCQUFNLFNBQVMsZUFBZSxzQkFBc0IsSUFBSSxZQUFZLFFBQVE7QUFDNUUsZ0JBQU0sT0FBTyxZQUFZLGtCQUFrQixNQUFNO0FBQ2pELGdCQUFNLGNBQWMsWUFBWSxlQUFlLElBQUk7QUFDbkQsY0FDRSxnQkFBZ0IsVUFDaEIsa0JBQWtCLFdBQVcsS0FDN0IsWUFBWSxPQUFPLFNBQVMsZUFBZSxvQkFDM0M7QUFDQSxvQkFBUSxPQUFPO0FBQUEsY0FDYixNQUFNO0FBQUEsY0FDTixXQUFXO0FBQUEsWUFDYixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsU0FBUyxPQUFPO0FBRWQsa0JBQVEsTUFBTSxtQkFBbUIsTUFBTSxtQkFBbUIsUUFBUSxRQUFRLE1BQU0sS0FBSztBQUNyRixrQkFBUSxPQUFPO0FBQUEsWUFDYixNQUFNO0FBQUEsWUFDTixXQUFXO0FBQUEsWUFDWCxNQUFNO0FBQUEsY0FDSixVQUFVLFFBQVE7QUFBQSxjQUNsQixPQUFPLGlCQUFpQixRQUFRLE1BQU0sU0FBUyxJQUFJLEtBQUssVUFBVSxLQUFLO0FBQUEsWUFDekU7QUFBQSxVQUNGLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8sb0RBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// src/service.ts
|
|
2
|
+
import "typescript";
|
|
3
|
+
function isServiceResponse(type) {
|
|
4
|
+
return type.getProperties().some((symbol) => symbol.name === "status") && type.getProperties().some((symbol) => symbol.name === "headers") && type.getProperties().some((symbol) => symbol.name === "body");
|
|
5
|
+
}
|
|
6
|
+
export {
|
|
7
|
+
isServiceResponse
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NlcnZpY2UudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsT0FBZTtBQUVSLFNBQVMsa0JBQWtCLE1BQXdCO0FBQ3hELFNBQ0UsS0FBSyxjQUFjLEVBQUUsS0FBSyxDQUFDLFdBQVcsT0FBTyxTQUFTLFFBQVEsS0FDOUQsS0FBSyxjQUFjLEVBQUUsS0FBSyxDQUFDLFdBQVcsT0FBTyxTQUFTLFNBQVMsS0FDL0QsS0FBSyxjQUFjLEVBQUUsS0FBSyxDQUFDLFdBQVcsT0FBTyxTQUFTLE1BQU07QUFFaEU7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -5,5 +5,5 @@ export declare function isBlockStatement(node: TSESTree.Node): boolean;
|
|
|
5
5
|
export declare function getEnclosingStatement(node: TSESTree.Node): TSESTree.Node | undefined;
|
|
6
6
|
export declare function getEnclosingScopeNode(node: TSESTree.Node): TSESTree.Node | undefined;
|
|
7
7
|
export declare function isUsedInArrayOrAsArgument(node: TSESTree.Node): boolean;
|
|
8
|
-
export declare function getEnclosingFunction(node: TSESTree.Node): TSESTree.ArrowFunctionExpression | TSESTree.
|
|
8
|
+
export declare function getEnclosingFunction(node: TSESTree.Node): TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | undefined;
|
|
9
9
|
export declare function getTypeParentNode(node: TSESTree.Node | undefined): TSESTree.TSTypeAnnotation | TSESTree.TSAsExpression | undefined;
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@checkdigit/eslint-plugin","version":"7.
|
|
1
|
+
{"name":"@checkdigit/eslint-plugin","version":"7.12.0-PR.45-1e1c","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.23.0","@typescript-eslint/utils":"^8.23.0","http-status-codes":"^2.3.0","ts-api-utils":"^2.0.1"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^6.1.0","@checkdigit/typescript-config":"^9.0.0","@eslint/js":"^9.19.0","@types/eslint":"^9.6.1","@types/eslint-config-prettier":"^6.11.3","@typescript-eslint/parser":"^8.23.0","@typescript-eslint/rule-tester":"^8.23.0","eslint":"^9.19.0","eslint-config-prettier":"^10.0.1","eslint-import-resolver-typescript":"^3.7.0","eslint-plugin-eslint-plugin":"^6.4.0","eslint-plugin-import":"^2.31.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.23.0"},"peerDependencies":{"eslint":">=9 <10"},"engines":{"node":">=22.11"}}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,9 @@ import requireTypeOutOfTypeOnlyImports, {
|
|
|
23
23
|
ruleId as requireTypeOutOfTypeOnlyImportsRuleId,
|
|
24
24
|
} from './require-type-out-of-type-only-imports.ts';
|
|
25
25
|
import noServeRuntime, { ruleId as noServeRuntimeRuleId } from './no-serve-runtime.ts';
|
|
26
|
+
import requireServiceCallResponseDeclaration, {
|
|
27
|
+
ruleId as requireServiceCallResponseDeclarationRuleId,
|
|
28
|
+
} from './require-service-call-response-declaration.ts';
|
|
26
29
|
import filePathComment from './file-path-comment.ts';
|
|
27
30
|
import noCardNumbers from './no-card-numbers.ts';
|
|
28
31
|
import noEnum from './no-enum.ts';
|
|
@@ -60,6 +63,7 @@ const rules: Record<string, TSESLint.LooseRuleDefinition> = {
|
|
|
60
63
|
[requireResolveFullResponseRuleId]: requireResolveFullResponse,
|
|
61
64
|
[noDuplicatedImportsRuleId]: noDuplicatedImports,
|
|
62
65
|
[noServeRuntimeRuleId]: noServeRuntime,
|
|
66
|
+
[requireServiceCallResponseDeclarationRuleId]: requireServiceCallResponseDeclaration,
|
|
63
67
|
[requireFixedServicesImportRuleId]: requireFixedServicesImport,
|
|
64
68
|
[requireTypeOutOfTypeOnlyImportsRuleId]: requireTypeOutOfTypeOnlyImports,
|
|
65
69
|
};
|
|
@@ -102,6 +106,7 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
|
|
|
102
106
|
[`@checkdigit/${requireFixedServicesImportRuleId}`]: 'error',
|
|
103
107
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
|
|
104
108
|
[`@checkdigit/${noServeRuntimeRuleId}`]: 'error',
|
|
109
|
+
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'error',
|
|
105
110
|
},
|
|
106
111
|
},
|
|
107
112
|
],
|
|
@@ -135,6 +140,7 @@ const configs: Record<string, TSESLint.FlatConfig.Config[]> = {
|
|
|
135
140
|
[`@checkdigit/${requireFixedServicesImportRuleId}`]: 'off',
|
|
136
141
|
[`@checkdigit/${requireTypeOutOfTypeOnlyImportsRuleId}`]: 'error',
|
|
137
142
|
[`@checkdigit/${noServeRuntimeRuleId}`]: 'off',
|
|
143
|
+
[`@checkdigit/${requireServiceCallResponseDeclarationRuleId}`]: 'off',
|
|
138
144
|
},
|
|
139
145
|
},
|
|
140
146
|
],
|
package/src/library/ts-tree.ts
CHANGED
|
@@ -75,11 +75,7 @@ export function isUsedInArrayOrAsArgument(node: TSESTree.Node): boolean {
|
|
|
75
75
|
|
|
76
76
|
export function getEnclosingFunction(
|
|
77
77
|
node: TSESTree.Node,
|
|
78
|
-
):
|
|
79
|
-
| TSESTree.ArrowFunctionExpression
|
|
80
|
-
| TSESTree.FunctionDeclarationWithOptionalName
|
|
81
|
-
| TSESTree.FunctionExpression
|
|
82
|
-
| undefined {
|
|
78
|
+
): TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | undefined {
|
|
83
79
|
if (
|
|
84
80
|
node.type === AST_NODE_TYPES.FunctionDeclaration ||
|
|
85
81
|
node.type === AST_NODE_TYPES.FunctionExpression ||
|
|
@@ -32,6 +32,9 @@ const rule: TSESLint.RuleModule<string, unknown[]> = createRule({
|
|
|
32
32
|
defaultOptions: [],
|
|
33
33
|
create(context) {
|
|
34
34
|
let assertAlias = 'assert';
|
|
35
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
36
|
+
const checker = parserServices.program.getTypeChecker();
|
|
37
|
+
const messageIndexCache: Record<string, number> = {};
|
|
35
38
|
|
|
36
39
|
return {
|
|
37
40
|
ImportDeclaration(node: TSESTree.ImportDeclaration) {
|
|
@@ -57,13 +60,15 @@ const rule: TSESLint.RuleModule<string, unknown[]> = createRule({
|
|
|
57
60
|
const methodName = callee.property.name;
|
|
58
61
|
|
|
59
62
|
if (objectName === assertAlias && methodsRequiringMessage.includes(methodName)) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
if (!(methodName in messageIndexCache)) {
|
|
64
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
|
65
|
+
const signature = checker.getResolvedSignature(tsNode);
|
|
66
|
+
const messageParameterIndex = signature?.getParameters().findIndex((param) => param.name === 'message');
|
|
67
|
+
messageIndexCache[methodName] = messageParameterIndex ?? 2;
|
|
68
|
+
}
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
const messageIndex = messageIndexCache[methodName];
|
|
71
|
+
if (messageIndex !== undefined && node.arguments.length <= messageIndex) {
|
|
67
72
|
context.report({
|
|
68
73
|
node,
|
|
69
74
|
messageId: MISSING_ASSERT_MESSAGE,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// require-service-call-response-declaration.ts
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2021-2024 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
|
+
|
|
11
|
+
import getDocumentationUrl from './get-documentation-url';
|
|
12
|
+
import { isServiceResponse } from './service';
|
|
13
|
+
|
|
14
|
+
export const ruleId = 'require-service-call-response-declaration';
|
|
15
|
+
|
|
16
|
+
const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
|
|
17
|
+
|
|
18
|
+
const rule: ESLintUtils.RuleModule<'unknownError' | 'requireServiceCallResponseDeclaration'> = createRule({
|
|
19
|
+
name: ruleId,
|
|
20
|
+
meta: {
|
|
21
|
+
type: 'suggestion',
|
|
22
|
+
docs: {
|
|
23
|
+
description:
|
|
24
|
+
'Awaited service call is required to declare variable for its return value which should be examined later on.',
|
|
25
|
+
},
|
|
26
|
+
messages: {
|
|
27
|
+
requireServiceCallResponseDeclaration:
|
|
28
|
+
'Awaited service call is required to declare variable for its return value which should be examined later on.',
|
|
29
|
+
unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.',
|
|
30
|
+
},
|
|
31
|
+
fixable: 'code',
|
|
32
|
+
schema: [],
|
|
33
|
+
},
|
|
34
|
+
defaultOptions: [],
|
|
35
|
+
create(context) {
|
|
36
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
37
|
+
const typeChecker = parserServices.program.getTypeChecker();
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
AwaitExpression(serviceCall: TSESTree.AwaitExpression) {
|
|
41
|
+
try {
|
|
42
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(serviceCall.argument);
|
|
43
|
+
const type = typeChecker.getTypeAtLocation(tsNode);
|
|
44
|
+
const awaitedType = typeChecker.getAwaitedType(type);
|
|
45
|
+
if (
|
|
46
|
+
awaitedType !== undefined &&
|
|
47
|
+
isServiceResponse(awaitedType) &&
|
|
48
|
+
serviceCall.parent.type !== AST_NODE_TYPES.VariableDeclarator
|
|
49
|
+
) {
|
|
50
|
+
context.report({
|
|
51
|
+
node: serviceCall,
|
|
52
|
+
messageId: 'requireServiceCallResponseDeclaration',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
|
|
58
|
+
context.report({
|
|
59
|
+
node: serviceCall,
|
|
60
|
+
messageId: 'unknownError',
|
|
61
|
+
data: {
|
|
62
|
+
fileName: context.filename,
|
|
63
|
+
error: error instanceof Error ? error.toString() : JSON.stringify(error),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export default rule;
|
package/src/service.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// service.ts
|
|
2
|
+
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
|
|
5
|
+
export function isServiceResponse(type: ts.Type): boolean {
|
|
6
|
+
return (
|
|
7
|
+
type.getProperties().some((symbol) => symbol.name === 'status') &&
|
|
8
|
+
type.getProperties().some((symbol) => symbol.name === 'headers') &&
|
|
9
|
+
type.getProperties().some((symbol) => symbol.name === 'body')
|
|
10
|
+
);
|
|
11
|
+
}
|