@checkdigit/eslint-plugin 7.5.0 → 7.6.0-PR.75-1b09

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.
Files changed (69) hide show
  1. package/dist-mjs/agent/add-assert-import.mjs +58 -0
  2. package/dist-mjs/agent/add-base-path-const.mjs +65 -0
  3. package/dist-mjs/agent/add-base-path-import.mjs +60 -0
  4. package/dist-mjs/agent/add-url-domain.mjs +61 -0
  5. package/dist-mjs/agent/agent-test-wiring.mjs +221 -0
  6. package/dist-mjs/agent/fetch-response-body-json.mjs +146 -0
  7. package/dist-mjs/agent/fetch-response-header-getter.mjs +117 -0
  8. package/dist-mjs/agent/fetch-response-status.mjs +66 -0
  9. package/dist-mjs/agent/fetch-then.mjs +269 -0
  10. package/dist-mjs/agent/fetch.mjs +38 -0
  11. package/dist-mjs/agent/file.mjs +43 -0
  12. package/dist-mjs/agent/fix-function-call-arguments.mjs +153 -0
  13. package/dist-mjs/agent/no-fixture.mjs +361 -0
  14. package/dist-mjs/agent/no-mapped-response.mjs +75 -0
  15. package/dist-mjs/agent/no-service-wrapper.mjs +185 -0
  16. package/dist-mjs/agent/no-status-code.mjs +59 -0
  17. package/dist-mjs/agent/no-supertest.mjs +343 -0
  18. package/dist-mjs/agent/no-unused-function-argument.mjs +79 -0
  19. package/dist-mjs/agent/no-unused-imports.mjs +81 -0
  20. package/dist-mjs/agent/no-unused-service-variable.mjs +74 -0
  21. package/dist-mjs/agent/response-reference.mjs +70 -0
  22. package/dist-mjs/agent/url.mjs +32 -0
  23. package/dist-mjs/index.mjs +151 -4
  24. package/dist-types/agent/add-assert-import.d.ts +4 -0
  25. package/dist-types/agent/add-base-path-const.d.ts +4 -0
  26. package/dist-types/agent/add-base-path-import.d.ts +4 -0
  27. package/dist-types/agent/add-url-domain.d.ts +4 -0
  28. package/dist-types/agent/agent-test-wiring.d.ts +4 -0
  29. package/dist-types/agent/fetch-response-body-json.d.ts +4 -0
  30. package/dist-types/agent/fetch-response-header-getter.d.ts +4 -0
  31. package/dist-types/agent/fetch-response-status.d.ts +4 -0
  32. package/dist-types/agent/fetch-then.d.ts +4 -0
  33. package/dist-types/agent/fetch.d.ts +5 -0
  34. package/dist-types/agent/file.d.ts +7 -0
  35. package/dist-types/agent/fix-function-call-arguments.d.ts +9 -0
  36. package/dist-types/agent/no-fixture.d.ts +4 -0
  37. package/dist-types/agent/no-mapped-response.d.ts +4 -0
  38. package/dist-types/agent/no-service-wrapper.d.ts +4 -0
  39. package/dist-types/agent/no-status-code.d.ts +4 -0
  40. package/dist-types/agent/no-supertest.d.ts +4 -0
  41. package/dist-types/agent/no-unused-function-argument.d.ts +4 -0
  42. package/dist-types/agent/no-unused-imports.d.ts +4 -0
  43. package/dist-types/agent/no-unused-service-variable.d.ts +4 -0
  44. package/dist-types/agent/response-reference.d.ts +16 -0
  45. package/dist-types/agent/url.d.ts +4 -0
  46. package/package.json +1 -96
  47. package/src/agent/add-assert-import.ts +74 -0
  48. package/src/agent/add-base-path-const.ts +81 -0
  49. package/src/agent/add-base-path-import.ts +69 -0
  50. package/src/agent/add-url-domain.ts +76 -0
  51. package/src/agent/agent-test-wiring.ts +273 -0
  52. package/src/agent/fetch-response-body-json.ts +197 -0
  53. package/src/agent/fetch-response-header-getter.ts +148 -0
  54. package/src/agent/fetch-response-status.ts +87 -0
  55. package/src/agent/fetch-then.ts +357 -0
  56. package/src/agent/fetch.ts +57 -0
  57. package/src/agent/file.ts +42 -0
  58. package/src/agent/fix-function-call-arguments.ts +200 -0
  59. package/src/agent/no-fixture.ts +521 -0
  60. package/src/agent/no-mapped-response.ts +84 -0
  61. package/src/agent/no-service-wrapper.ts +241 -0
  62. package/src/agent/no-status-code.ts +72 -0
  63. package/src/agent/no-supertest.ts +497 -0
  64. package/src/agent/no-unused-function-argument.ts +98 -0
  65. package/src/agent/no-unused-imports.ts +103 -0
  66. package/src/agent/no-unused-service-variable.ts +93 -0
  67. package/src/agent/response-reference.ts +129 -0
  68. package/src/agent/url.ts +32 -0
  69. package/src/index.ts +147 -0
@@ -0,0 +1,185 @@
1
+ // src/agent/no-service-wrapper.ts
2
+ import { strict as assert } from "node:assert";
3
+ import { DefinitionType } from "@typescript-eslint/scope-manager";
4
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
5
+ import getDocumentationUrl from "../get-documentation-url.mjs";
6
+ import { getEnclosingScopeNode } from "../library/ts-tree.mjs";
7
+ import { getIndentation } from "../library/format.mjs";
8
+ import { isServiceApiCallUrl, replaceEndpointUrlPrefixWithDomain } from "./url.mjs";
9
+ var ruleId = "no-service-wrapper";
10
+ var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
11
+ var rule = createRule({
12
+ name: ruleId,
13
+ meta: {
14
+ type: "suggestion",
15
+ docs: {
16
+ description: "Prefer native fetch over customized service wrapper."
17
+ },
18
+ messages: {
19
+ preferNativeFetch: "Prefer native fetch over customized service wrapper.",
20
+ invalidOptions: '"options" argument should be provided with "resolveWithFullResponse" property set as "true". Otherwise, it indicates that the response body will be obtained without status code assertion which could result in unexpected issue. Please manually convert the usage of customized service wrapper call to native fetch.',
21
+ unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}. Please manually convert the usage of customized service wrapper call to native fetch.'
22
+ },
23
+ fixable: "code",
24
+ schema: []
25
+ },
26
+ defaultOptions: [],
27
+ create(context) {
28
+ const sourceCode = context.sourceCode;
29
+ const scopeManager = sourceCode.scopeManager;
30
+ const parserService = ESLintUtils.getParserServices(context);
31
+ const typeChecker = parserService.program.getTypeChecker();
32
+ function isUrlArgumentValid(urlArgument, scope) {
33
+ if (urlArgument?.type === AST_NODE_TYPES.Literal && typeof urlArgument.value === "string" || urlArgument?.type === AST_NODE_TYPES.TemplateLiteral) {
34
+ const urlText = sourceCode.getText(urlArgument);
35
+ return isServiceApiCallUrl(urlText);
36
+ }
37
+ if (urlArgument?.type === AST_NODE_TYPES.Identifier) {
38
+ const foundVariable = scope.variables.find((variable) => variable.name === urlArgument.name);
39
+ if (foundVariable) {
40
+ const variableDefinition = foundVariable.defs.find((def) => def.type === DefinitionType.Variable);
41
+ if (variableDefinition !== void 0) {
42
+ const variableDefinitionNode = variableDefinition.node;
43
+ assert.ok(variableDefinitionNode.init, "Variable definition node has no init property");
44
+ return isUrlArgumentValid(variableDefinitionNode.init, scope);
45
+ }
46
+ return true;
47
+ }
48
+ }
49
+ return false;
50
+ }
51
+ function getType(identifier) {
52
+ const variable = parserService.esTreeNodeToTSNodeMap.get(identifier);
53
+ const variableType = typeChecker.getTypeAtLocation(variable);
54
+ return typeChecker.typeToString(variableType);
55
+ }
56
+ function isServiceLikeName(name) {
57
+ return /.*[Ss]ervice$/u.test(name);
58
+ }
59
+ function isCalleeServiceWrapper(serviceCall) {
60
+ const callee = serviceCall.callee;
61
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) {
62
+ return false;
63
+ }
64
+ const endpoint = callee.object;
65
+ if (endpoint.type === AST_NODE_TYPES.Identifier) {
66
+ return getType(endpoint) === "Endpoint" || isServiceLikeName(endpoint.name);
67
+ }
68
+ if (endpoint.type !== AST_NODE_TYPES.CallExpression) {
69
+ return false;
70
+ }
71
+ const [contextArgument] = endpoint.arguments;
72
+ if (contextArgument?.type !== AST_NODE_TYPES.Identifier) {
73
+ return false;
74
+ }
75
+ if (contextArgument.name !== "EMPTY_CONTEXT" && getType(contextArgument) !== "InboundContext") {
76
+ return false;
77
+ }
78
+ const service = endpoint.callee;
79
+ if (service.type === AST_NODE_TYPES.Identifier) {
80
+ return getType(service) === "ResolvedService";
81
+ }
82
+ if (service.type !== AST_NODE_TYPES.MemberExpression) {
83
+ return false;
84
+ }
85
+ const services = service.object;
86
+ if (services.type === AST_NODE_TYPES.Identifier) {
87
+ return getType(services) === "ResolvedServices";
88
+ }
89
+ if (services.type !== AST_NODE_TYPES.MemberExpression) {
90
+ return false;
91
+ }
92
+ const configuration = services.object;
93
+ if (configuration.type === AST_NODE_TYPES.Identifier) {
94
+ return ["Configuration", "Configuration<ResolvedServices>"].includes(getType(configuration));
95
+ }
96
+ if (configuration.type !== AST_NODE_TYPES.MemberExpression) {
97
+ return false;
98
+ }
99
+ const fixture = configuration.object;
100
+ if (fixture.type === AST_NODE_TYPES.Identifier) {
101
+ return fixture.name === "fixture" || getType(fixture) === "Fixture";
102
+ }
103
+ return false;
104
+ }
105
+ return {
106
+ "CallExpression[callee.property.name=/^(head|get|put|post|del|patch)$/]": (serviceCall) => {
107
+ try {
108
+ if (!isCalleeServiceWrapper(serviceCall)) {
109
+ return;
110
+ }
111
+ const enclosingScopeNode = getEnclosingScopeNode(serviceCall);
112
+ assert.ok(enclosingScopeNode, "enclosingScopeNode is undefined");
113
+ const scope = scopeManager?.acquire(enclosingScopeNode);
114
+ assert.ok(scope, "scope is undefined");
115
+ const urlArgument = serviceCall.arguments[0];
116
+ if (!isUrlArgumentValid(urlArgument, scope)) {
117
+ return;
118
+ }
119
+ assert.ok(serviceCall.callee.type === AST_NODE_TYPES.MemberExpression);
120
+ assert.ok(serviceCall.callee.property.type === AST_NODE_TYPES.Identifier);
121
+ const method = serviceCall.callee.property.name;
122
+ let requestBodyProperty = ["put", "post", "options"].includes(method) ? serviceCall.arguments[1] : void 0;
123
+ if (requestBodyProperty !== void 0 && requestBodyProperty.type === AST_NODE_TYPES.Identifier && requestBodyProperty.name === "undefined") {
124
+ requestBodyProperty = void 0;
125
+ }
126
+ const optionsArgument = ["get", "head", "del"].includes(method) ? serviceCall.arguments[1] : serviceCall.arguments[2];
127
+ if (optionsArgument === void 0 || optionsArgument.type !== AST_NODE_TYPES.ObjectExpression) {
128
+ context.report({
129
+ node: serviceCall,
130
+ messageId: "invalidOptions"
131
+ });
132
+ return;
133
+ }
134
+ const resolveWithFullResponseProperty = optionsArgument.properties.find(
135
+ (property) => property.type === AST_NODE_TYPES.Property && property.key.type === AST_NODE_TYPES.Identifier && property.key.name === "resolveWithFullResponse"
136
+ );
137
+ if (resolveWithFullResponseProperty?.type !== AST_NODE_TYPES.Property || resolveWithFullResponseProperty.value.type !== AST_NODE_TYPES.Literal || resolveWithFullResponseProperty.value.value !== true) {
138
+ context.report({
139
+ node: optionsArgument,
140
+ messageId: "invalidOptions"
141
+ });
142
+ return;
143
+ }
144
+ const requestHeadersProperty = optionsArgument.properties.find(
145
+ (property) => property.type === AST_NODE_TYPES.Property && property.key.type === AST_NODE_TYPES.Identifier && property.key.name === "headers"
146
+ );
147
+ context.report({
148
+ messageId: "preferNativeFetch",
149
+ node: serviceCall,
150
+ fix(fixer) {
151
+ const url = sourceCode.getText(urlArgument);
152
+ const replacedUrl = replaceEndpointUrlPrefixWithDomain(url);
153
+ const indentation = getIndentation(serviceCall, sourceCode);
154
+ const fetchText = [
155
+ `fetch(${replacedUrl}, {`,
156
+ ` method: '${method.toLowerCase() === "del" ? "DELETE" : method.toUpperCase()}',`,
157
+ ...requestHeadersProperty ? [` ${sourceCode.getText(requestHeadersProperty)},`] : [],
158
+ ...requestBodyProperty ? [` body: JSON.stringify(${sourceCode.getText(requestBodyProperty)}),`] : [],
159
+ "})"
160
+ ].join(`
161
+ ${indentation}`);
162
+ return fixer.replaceText(serviceCall, fetchText);
163
+ }
164
+ });
165
+ } catch (error) {
166
+ console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
167
+ context.report({
168
+ node: serviceCall,
169
+ messageId: "unknownError",
170
+ data: {
171
+ fileName: context.filename,
172
+ error: error instanceof Error ? error.toString() : JSON.stringify(error)
173
+ }
174
+ });
175
+ }
176
+ }
177
+ };
178
+ }
179
+ });
180
+ var no_service_wrapper_default = rule;
181
+ export {
182
+ no_service_wrapper_default as default,
183
+ ruleId
184
+ };
185
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L25vLXNlcnZpY2Utd3JhcHBlci50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLFVBQVUsY0FBYztBQUVqQyxTQUFTLHNCQUFrQztBQUMzQyxTQUFTLGdCQUFnQixtQkFBNkI7QUFFdEQsT0FBTyx5QkFBeUI7QUFDaEMsU0FBUyw2QkFBNkI7QUFDdEMsU0FBUyxzQkFBc0I7QUFDL0IsU0FBUyxxQkFBcUIsMENBQTBDO0FBRWpFLElBQU0sU0FBUztBQUV0QixJQUFNLGFBQWEsWUFBWSxZQUFZLENBQUMsU0FBUyxvQkFBb0IsSUFBSSxDQUFDO0FBRTlFLElBQU0sT0FBd0YsV0FBVztBQUFBLEVBQ3ZHLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxJQUNmO0FBQUEsSUFDQSxVQUFVO0FBQUEsTUFDUixtQkFBbUI7QUFBQSxNQUNuQixnQkFDRTtBQUFBLE1BQ0YsY0FDRTtBQUFBLElBQ0o7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxhQUFhLFFBQVE7QUFDM0IsVUFBTSxlQUFlLFdBQVc7QUFDaEMsVUFBTSxnQkFBZ0IsWUFBWSxrQkFBa0IsT0FBTztBQUMzRCxVQUFNLGNBQWMsY0FBYyxRQUFRLGVBQWU7QUFFekQsYUFBUyxtQkFBbUIsYUFBd0MsT0FBYztBQUNoRixVQUNHLGFBQWEsU0FBUyxlQUFlLFdBQVcsT0FBTyxZQUFZLFVBQVUsWUFDOUUsYUFBYSxTQUFTLGVBQWUsaUJBQ3JDO0FBQ0EsY0FBTSxVQUFVLFdBQVcsUUFBUSxXQUFXO0FBQzlDLGVBQU8sb0JBQW9CLE9BQU87QUFBQSxNQUNwQztBQUVBLFVBQUksYUFBYSxTQUFTLGVBQWUsWUFBWTtBQUNuRCxjQUFNLGdCQUFnQixNQUFNLFVB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
@@ -0,0 +1,59 @@
1
+ // src/agent/no-status-code.ts
2
+ import { ESLintUtils } from "@typescript-eslint/utils";
3
+ import getDocumentationUrl from "../get-documentation-url.mjs";
4
+ var ruleId = "no-status-code";
5
+ var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
6
+ var rule = createRule({
7
+ name: ruleId,
8
+ meta: {
9
+ type: "suggestion",
10
+ docs: {
11
+ description: 'Access the status code property of the fetch Response using "status" instead of "statusCode".'
12
+ },
13
+ messages: {
14
+ replaceStatusCode: 'Replace "statusCode" with "status".',
15
+ unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
16
+ },
17
+ fixable: "code",
18
+ schema: []
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const parserServices = ESLintUtils.getParserServices(context);
23
+ const typeChecker = parserServices.program.getTypeChecker();
24
+ return {
25
+ 'MemberExpression[property.name="statusCode"]': (responseStatusCode) => {
26
+ try {
27
+ const responseNode = parserServices.esTreeNodeToTSNodeMap.get(responseStatusCode.object);
28
+ const responseType = typeChecker.getTypeAtLocation(responseNode);
29
+ const shouldReplace = responseType.getProperties().some((symbol) => symbol.name === "status") && !responseType.getProperties().some((symbol) => symbol.name === "statusCode");
30
+ if (shouldReplace) {
31
+ context.report({
32
+ messageId: "replaceStatusCode",
33
+ node: responseStatusCode.property,
34
+ fix(fixer) {
35
+ return fixer.replaceText(responseStatusCode.property, "status");
36
+ }
37
+ });
38
+ }
39
+ } catch (error) {
40
+ console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
41
+ context.report({
42
+ node: responseStatusCode,
43
+ messageId: "unknownError",
44
+ data: {
45
+ fileName: context.filename,
46
+ error: error instanceof Error ? error.toString() : JSON.stringify(error)
47
+ }
48
+ });
49
+ }
50
+ }
51
+ };
52
+ }
53
+ });
54
+ var no_status_code_default = rule;
55
+ export {
56
+ no_status_code_default as default,
57
+ ruleId
58
+ };
59
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L25vLXN0YXR1cy1jb2RlLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsbUJBQTZCO0FBRXRDLE9BQU8seUJBQXlCO0FBRXpCLElBQU0sU0FBUztBQUV0QixJQUFNLGFBQWEsWUFBWSxZQUFZLENBQUMsU0FBUyxvQkFBb0IsSUFBSSxDQUFDO0FBRTlFLElBQU0sT0FBcUUsV0FBVztBQUFBLEVBQ3BGLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxJQUNmO0FBQUEsSUFDQSxVQUFVO0FBQUEsTUFDUixtQkFBbUI7QUFBQSxNQUNuQixjQUFjO0FBQUEsSUFDaEI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxpQkFBaUIsWUFBWSxrQkFBa0IsT0FBTztBQUM1RCxVQUFNLGNBQWMsZUFBZSxRQUFRLGVBQWU7QUFFMUQsV0FBTztBQUFBLE1BQ0wsZ0RBQWdELENBQUMsdUJBQWtEO0FBQ2pHLFlBQUk7QUFDRixnQkFBTSxlQUFlLGVBQWUsc0JBQXNCLElBQUksbUJBQW1CLE1BQU07QUFDdkYsZ0JBQU0sZUFBZSxZQUFZLGtCQUFrQixZQUFZO0FBRS9ELGdCQUFNLGdCQUNKLGFBQWEsY0FBYyxFQUFFLEtBQUssQ0FBQyxXQUFXLE9BQU8sU0FBUyxRQUFRLEtBQ3RFLENBQUMsYUFBYSxjQUFjLEVBQUUsS0FBSyxDQUFDLFdBQVcsT0FBTyxTQUFTLFlBQVk7QUFFN0UsY0FBSSxlQUFlO0FBQ2pCLG9CQUFRLE9BQU87QUFBQSxjQUNiLFdBQVc7QUFBQSxjQUNYLE1BQU0sbUJBQW1CO0FBQUEsY0FDekIsSUFBSSxPQUFPO0FBQ1QsdUJBQU8sTUFBTSxZQUFZLG1CQUFtQixVQUFVLFFBQVE7QUFBQSxjQUNoRTtBQUFBLFlBQ0YsQ0FBQztBQUFBLFVBQ0g7QUFBQSxRQUNGLFNBQVMsT0FBTztBQUVkLGtCQUFRLE1BQU0sbUJBQW1CLE1BQU0sbUJBQW1CLFFBQVEsUUFBUSxNQUFNLEtBQUs7QUFDckYsa0JBQVEsT0FBTztBQUFBLFlBQ2IsTUFBTTtBQUFBLFlBQ04sV0FBVztBQUFBLFlBQ1gsTUFBTTtBQUFBLGNBQ0osVUFBVSxRQUFRO0FBQUEsY0FDbEIsT0FBTyxpQkFBaUIsUUFBUSxNQUFNLFNBQVMsSUFBSSxLQUFLLFVBQVUsS0FBSztBQUFBLFlBQ3pFO0FBQUEsVUFDRixDQUFDO0FBQUEsUUFDSDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFRCxJQUFPLHlCQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,343 @@
1
+ // src/agent/no-supertest.ts
2
+ import { strict as assert } from "node:assert";
3
+ import "eslint";
4
+ import {
5
+ getEnclosingFunction,
6
+ getEnclosingScopeNode,
7
+ getEnclosingStatement,
8
+ getParent,
9
+ isUsedInArrayOrAsArgument
10
+ } from "../library/tree.mjs";
11
+ import getDocumentationUrl from "../get-documentation-url.mjs";
12
+ import { getIndentation } from "../library/format.mjs";
13
+ import { analyzeResponseReferences } from "./response-reference.mjs";
14
+ import { getResponseBodyRetrievalText, getResponseHeadersRetrievalText } from "./fetch.mjs";
15
+ var ruleId = "no-supertest";
16
+ function analyzeFixtureCall(call, results, sourceCode) {
17
+ const parent = getParent(call);
18
+ assert.ok(parent, "parent should exist for fixture/supertest call node");
19
+ let nextCall;
20
+ if (parent.type === "ReturnStatement") {
21
+ results.fixtureNode = call;
22
+ results.rootNode = parent;
23
+ } else if (parent.type === "ArrayExpression" || parent.type === "CallExpression" || parent.type === "ArrowFunctionExpression") {
24
+ results.fixtureNode = call;
25
+ results.rootNode = call;
26
+ } else if (parent.type === "AwaitExpression") {
27
+ results.fixtureNode = call;
28
+ const enclosingStatement = getEnclosingStatement(parent);
29
+ assert.ok(enclosingStatement);
30
+ const awaitParent = getParent(parent);
31
+ if (awaitParent?.type === "MemberExpression") {
32
+ results.rootNode = parent;
33
+ results.inlineStatementNode = enclosingStatement;
34
+ if (awaitParent.property.type === "Identifier" && awaitParent.property.name === "body") {
35
+ results.inlineBodyReference = awaitParent;
36
+ }
37
+ if (awaitParent.property.type === "Identifier" && (awaitParent.property.name === "header" || awaitParent.property.name === "headers")) {
38
+ results.inlineHeadersReference = awaitParent;
39
+ }
40
+ } else if (enclosingStatement.type === "VariableDeclaration") {
41
+ results.variableDeclaration = enclosingStatement;
42
+ results.rootNode = enclosingStatement;
43
+ } else if (enclosingStatement.type === "ExpressionStatement" && enclosingStatement.expression.type === "AssignmentExpression") {
44
+ results.variableAssignment = enclosingStatement;
45
+ results.rootNode = enclosingStatement;
46
+ } else {
47
+ results.rootNode = parent;
48
+ }
49
+ } else if (parent.type === "MemberExpression" && parent.property.type === "Identifier") {
50
+ if (parent.property.name === "expect") {
51
+ const assertionCall = getParent(parent);
52
+ assert.ok(assertionCall && assertionCall.type === "CallExpression");
53
+ results.assertions = [...results.assertions ?? [], assertionCall.arguments];
54
+ nextCall = assertionCall;
55
+ } else if (parent.property.name === "send") {
56
+ const sendRequestBodyCall = getParent(parent);
57
+ assert.ok(sendRequestBodyCall && sendRequestBodyCall.type === "CallExpression");
58
+ results.requestBody = sendRequestBodyCall.arguments[0];
59
+ nextCall = sendRequestBodyCall;
60
+ } else if (parent.property.name === "set") {
61
+ const setRequestHeaderCall = getParent(parent);
62
+ assert.ok(setRequestHeaderCall && setRequestHeaderCall.type === "CallExpression");
63
+ const [arg1, arg2] = setRequestHeaderCall.arguments;
64
+ if (arg1.type === "ObjectExpression") {
65
+ results.requestHeadersObjectLiteral = arg1;
66
+ } else {
67
+ results.requestHeaders = [...results.requestHeaders ?? [], { name: arg1, value: arg2 }];
68
+ }
69
+ nextCall = setRequestHeaderCall;
70
+ }
71
+ } else {
72
+ throw new Error(`Unexpected expression in fixture/supertest call ${sourceCode.getText(parent)}.`);
73
+ }
74
+ if (nextCall) {
75
+ analyzeFixtureCall(nextCall, results, sourceCode);
76
+ }
77
+ }
78
+ function createResponseAssertions(fixtureCallInformation, sourceCode, responseVariableName, destructuringResponseHeadersVariable) {
79
+ let statusAssertion;
80
+ const nonStatusAssertions = [];
81
+ for (const expectArguments of fixtureCallInformation.assertions ?? []) {
82
+ if (expectArguments.length === 1) {
83
+ const [assertionArgument] = expectArguments;
84
+ assert.ok(assertionArgument);
85
+ if (assertionArgument.type === "MemberExpression" && assertionArgument.object.type === "Identifier" && assertionArgument.object.name === "StatusCodes" || assertionArgument.type === "Literal" || sourceCode.getText(assertionArgument).includes("StatusCodes.")) {
86
+ statusAssertion = `assert.equal(${responseVariableName}.status, ${sourceCode.getText(assertionArgument)})`;
87
+ } else if (assertionArgument.type === "ArrowFunctionExpression") {
88
+ let functionBody = sourceCode.getText(assertionArgument.body);
89
+ const [originalResponseArgument] = assertionArgument.params;
90
+ assert.ok(originalResponseArgument?.type === "Identifier");
91
+ const originalResponseArgumentName = originalResponseArgument.name;
92
+ if (originalResponseArgumentName !== responseVariableName) {
93
+ functionBody = functionBody.replace(
94
+ new RegExp(`\\b${originalResponseArgumentName}\\b`, "ug"),
95
+ responseVariableName
96
+ );
97
+ }
98
+ nonStatusAssertions.push(`assert.doesNotThrow(()=>${functionBody})`);
99
+ } else if (assertionArgument.type === "Identifier") {
100
+ nonStatusAssertions.push(
101
+ `assert.doesNotThrow(()=>${sourceCode.getText(assertionArgument)}(${responseVariableName}))`
102
+ );
103
+ } else if (assertionArgument.type === "ObjectExpression" || assertionArgument.type === "CallExpression") {
104
+ nonStatusAssertions.push(
105
+ `assert.deepEqual(await ${responseVariableName}.json(), ${sourceCode.getText(assertionArgument)})`
106
+ );
107
+ } else {
108
+ throw new Error(`Unexpected Supertest assertion argument: ".expect(${sourceCode.getText(assertionArgument)})`);
109
+ }
110
+ } else if (expectArguments.length === 2) {
111
+ const [headerName, headerValue] = expectArguments;
112
+ assert.ok(headerName && headerValue);
113
+ const headersReference = destructuringResponseHeadersVariable !== void 0 ? destructuringResponseHeadersVariable.name : `${responseVariableName}.headers`;
114
+ if (headerValue.type === "Literal" && headerValue.value instanceof RegExp) {
115
+ nonStatusAssertions.push(
116
+ `assert.ok(${headersReference}.get(${sourceCode.getText(headerName)}).match(${sourceCode.getText(headerValue)}))`
117
+ );
118
+ } else {
119
+ nonStatusAssertions.push(
120
+ `assert.equal(${headersReference}.get(${sourceCode.getText(headerName)}), ${sourceCode.getText(headerValue)})`
121
+ );
122
+ }
123
+ }
124
+ }
125
+ return {
126
+ statusAssertion,
127
+ nonStatusAssertions
128
+ };
129
+ }
130
+ function getResponseVariableNameToUse(scopeManager, fixtureCallInformation, scopeVariablesMap) {
131
+ if (fixtureCallInformation.variableAssignment) {
132
+ assert.ok(
133
+ fixtureCallInformation.variableAssignment.expression.type === "AssignmentExpression" && fixtureCallInformation.variableAssignment.expression.left.type === "Identifier"
134
+ );
135
+ return fixtureCallInformation.variableAssignment.expression.left.name;
136
+ }
137
+ if (fixtureCallInformation.variableDeclaration) {
138
+ const firstDeclaration = fixtureCallInformation.variableDeclaration.declarations[0];
139
+ if (firstDeclaration && firstDeclaration.id.type === "Identifier") {
140
+ return firstDeclaration.id.name;
141
+ }
142
+ }
143
+ const enclosingScopeNode = getEnclosingScopeNode(fixtureCallInformation.rootNode);
144
+ scopeManager.getDeclaredVariables(fixtureCallInformation.rootNode);
145
+ assert.ok(enclosingScopeNode);
146
+ const scope = scopeManager.acquire(enclosingScopeNode);
147
+ assert.ok(scope !== null);
148
+ let scopeVariables = scopeVariablesMap.get(scope);
149
+ if (!scopeVariables) {
150
+ scopeVariables = [...scope.set.keys()];
151
+ scopeVariablesMap.set(scope, scopeVariables);
152
+ }
153
+ let responseVariableCounter = 0;
154
+ let responseVariableNameToUse;
155
+ while (responseVariableNameToUse === void 0) {
156
+ responseVariableCounter++;
157
+ responseVariableNameToUse = `response${responseVariableCounter === 1 ? "" : responseVariableCounter.toString()}`;
158
+ if (scopeVariables.includes(responseVariableNameToUse)) {
159
+ responseVariableNameToUse = void 0;
160
+ }
161
+ }
162
+ scopeVariables.push(responseVariableNameToUse);
163
+ return responseVariableNameToUse;
164
+ }
165
+ function isResponseBodyRedefinition(responseBodyReference) {
166
+ const parent = getParent(responseBodyReference);
167
+ return parent?.type === "VariableDeclarator" && parent.id.type === "Identifier";
168
+ }
169
+ var rule = {
170
+ meta: {
171
+ type: "suggestion",
172
+ docs: {
173
+ description: "Transform supertest assersions to regular node assertions.",
174
+ url: getDocumentationUrl(ruleId)
175
+ },
176
+ messages: {
177
+ preferNativeFetch: "Transform supertest assersions to regular node assertions.",
178
+ unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
179
+ },
180
+ fixable: "code",
181
+ schema: []
182
+ },
183
+ // eslint-disable-next-line max-lines-per-function
184
+ create(context) {
185
+ const sourceCode = context.sourceCode;
186
+ const scopeManager = sourceCode.scopeManager;
187
+ const scopeVariablesMap = /* @__PURE__ */ new Map();
188
+ return {
189
+ // eslint-disable-next-line max-lines-per-function
190
+ 'CallExpression[callee.property.name="expect"]': (supertestCall) => {
191
+ assert.ok(supertestCall.callee.type === "MemberExpression");
192
+ if (supertestCall.callee.object.type === "CallExpression" && supertestCall.callee.object.callee.type === "MemberExpression" && supertestCall.callee.object.callee.property.type === "Identifier" && supertestCall.callee.object.callee.property.name === "expect") {
193
+ return;
194
+ }
195
+ try {
196
+ if (isUsedInArrayOrAsArgument(supertestCall) || getEnclosingFunction(supertestCall)?.async === false) {
197
+ return;
198
+ }
199
+ assert.ok(supertestCall.type === "CallExpression");
200
+ const fixtureFunction = supertestCall.callee.object;
201
+ if (fixtureFunction.type !== "CallExpression") {
202
+ return;
203
+ }
204
+ const indentation = getIndentation(supertestCall, sourceCode);
205
+ const fixtureCallInformation = {};
206
+ analyzeFixtureCall(fixtureFunction, fixtureCallInformation, sourceCode);
207
+ sourceCode.getText(fixtureCallInformation.fixtureNode);
208
+ sourceCode.getText(fixtureCallInformation.rootNode);
209
+ fixtureCallInformation.assertions?.flat().map((ass) => sourceCode.getText(ass));
210
+ const {
211
+ variable: responseVariable,
212
+ bodyReferences: responseBodyReferences,
213
+ headersReferences: responseHeadersReferences,
214
+ statusReferences: responseStatusReferences,
215
+ destructuringBodyVariable: destructuringResponseBodyVariable,
216
+ destructuringHeadersVariable: destructuringResponseHeadersVariable
217
+ } = analyzeResponseReferences(fixtureCallInformation.variableDeclaration, scopeManager);
218
+ const responseVariableNameToUse = getResponseVariableNameToUse(
219
+ scopeManager,
220
+ fixtureCallInformation,
221
+ scopeVariablesMap
222
+ );
223
+ const isResponseBodyVariableRedefinitionNeeded = destructuringResponseBodyVariable !== void 0 || fixtureCallInformation.inlineBodyReference !== void 0 || responseBodyReferences.length > 0 && !responseBodyReferences.some(isResponseBodyRedefinition);
224
+ const redefineResponseBodyVariableName = `${responseVariableNameToUse}Body`;
225
+ const isResponseHeadersVariableRedefinitionNeeded = destructuringResponseHeadersVariable !== void 0 && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
226
+ destructuringResponseHeadersVariable.type === "ObjectPattern" || fixtureCallInformation.inlineHeadersReference !== void 0;
227
+ const redefineResponseHeadersVariableName = `${responseVariableNameToUse}Headers`;
228
+ const isResponseVariableRedefinitionNeeded = fixtureCallInformation.variableAssignment === void 0 && responseVariable === void 0 && fixtureCallInformation.assertions !== void 0 || isResponseBodyVariableRedefinitionNeeded || isResponseHeadersVariableRedefinitionNeeded;
229
+ const responseBodyHeadersVariableRedefineLines = isResponseVariableRedefinitionNeeded ? [
230
+ // eslint-disable-next-line no-nested-ternary
231
+ ...destructuringResponseBodyVariable ? [
232
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
233
+ `${fixtureCallInformation.variableDeclaration?.kind ?? "const"} ${destructuringResponseBodyVariable.type === "ObjectPattern" ? sourceCode.getText(destructuringResponseBodyVariable) : destructuringResponseBodyVariable.name} = ${getResponseBodyRetrievalText(responseVariableNameToUse)}`
234
+ ] : isResponseBodyVariableRedefinitionNeeded ? [
235
+ `const ${redefineResponseBodyVariableName} = ${getResponseBodyRetrievalText(responseVariableNameToUse)}`
236
+ ] : [],
237
+ // eslint-disable-next-line no-nested-ternary
238
+ ...destructuringResponseHeadersVariable ? (
239
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
240
+ destructuringResponseHeadersVariable.type === "ObjectPattern" ? destructuringResponseHeadersVariable.properties.map((property) => {
241
+ assert.ok(property.type === "Property");
242
+ assert.equal(property.value.type, "Identifier");
243
+ return `${fixtureCallInformation.variableDeclaration?.kind ?? "const"} ${property.value.name} = ${getResponseHeadersRetrievalText(responseVariableNameToUse)}.get(${property.key.type === "Literal" ? sourceCode.getText(property.key) : `'${sourceCode.getText(property.key)}'`})`;
244
+ }) : [
245
+ `${fixtureCallInformation.variableDeclaration?.kind ?? "const"} ${destructuringResponseHeadersVariable.name} = ${getResponseHeadersRetrievalText(responseVariableNameToUse)}`
246
+ ]
247
+ ) : isResponseHeadersVariableRedefinitionNeeded ? [
248
+ `const ${redefineResponseHeadersVariableName} = ${getResponseHeadersRetrievalText(responseVariableNameToUse)}`
249
+ ] : []
250
+ ] : [];
251
+ const { statusAssertion, nonStatusAssertions } = createResponseAssertions(
252
+ fixtureCallInformation,
253
+ sourceCode,
254
+ responseVariableNameToUse,
255
+ destructuringResponseHeadersVariable
256
+ );
257
+ const fetchCallText = sourceCode.getText(fixtureFunction);
258
+ const fetchStatementText = !isResponseVariableRedefinitionNeeded ? fetchCallText : `${fixtureCallInformation.variableDeclaration?.kind ?? "const"} ${responseVariableNameToUse} = await ${fetchCallText}`;
259
+ const nodeToReplace = isResponseVariableRedefinitionNeeded ? fixtureCallInformation.rootNode : fixtureCallInformation.fixtureNode;
260
+ const appendingAssignmentAndAssertionText = [
261
+ "",
262
+ ...statusAssertion !== void 0 ? [statusAssertion] : [],
263
+ ...responseBodyHeadersVariableRedefineLines,
264
+ ...nonStatusAssertions
265
+ ].join(`;
266
+ ${indentation}`);
267
+ context.report({
268
+ node: supertestCall,
269
+ messageId: "preferNativeFetch",
270
+ *fix(fixer) {
271
+ if (fixtureCallInformation.inlineStatementNode) {
272
+ const preInlineDeclaration = [
273
+ fetchStatementText,
274
+ `${appendingAssignmentAndAssertionText};
275
+ ${indentation}`
276
+ ].join(``);
277
+ yield fixer.insertTextBefore(fixtureCallInformation.inlineStatementNode, preInlineDeclaration);
278
+ } else {
279
+ yield fixer.replaceText(nodeToReplace, fetchStatementText);
280
+ const needEndingSemiColon = sourceCode.getText(nodeToReplace).endsWith(";");
281
+ yield fixer.insertTextAfter(
282
+ nodeToReplace,
283
+ needEndingSemiColon ? `${appendingAssignmentAndAssertionText};` : appendingAssignmentAndAssertionText
284
+ );
285
+ }
286
+ for (const responseBodyReference of responseBodyReferences) {
287
+ yield fixer.replaceText(
288
+ responseBodyReference,
289
+ isResponseBodyVariableRedefinitionNeeded || !isResponseBodyRedefinition(responseBodyReference) ? redefineResponseBodyVariableName : getResponseBodyRetrievalText(responseVariableNameToUse)
290
+ );
291
+ }
292
+ if (fixtureCallInformation.inlineBodyReference) {
293
+ yield fixer.replaceText(fixtureCallInformation.inlineBodyReference, redefineResponseBodyVariableName);
294
+ }
295
+ for (const responseHeadersReference of responseHeadersReferences) {
296
+ const parent = getParent(responseHeadersReference);
297
+ assert.ok(parent);
298
+ let headerName;
299
+ if (parent.type === "MemberExpression") {
300
+ const headerNameNode = parent.property;
301
+ headerName = parent.computed ? sourceCode.getText(headerNameNode) : `'${sourceCode.getText(headerNameNode)}'`;
302
+ } else if (parent.type === "CallExpression") {
303
+ const headerNameNode = parent.arguments[0];
304
+ headerName = sourceCode.getText(headerNameNode);
305
+ }
306
+ assert.ok(headerName !== void 0);
307
+ yield fixer.replaceText(parent, `${responseVariableNameToUse}.headers.get(${headerName})`);
308
+ }
309
+ for (const responseStatusReference of responseStatusReferences) {
310
+ if (responseStatusReference.property.type === "Identifier" && responseStatusReference.property.name === "statusCode") {
311
+ yield fixer.replaceText(responseStatusReference.property, `status`);
312
+ }
313
+ }
314
+ if (fixtureCallInformation.rootNode.type === "ReturnStatement" && fixtureCallInformation.assertions !== void 0) {
315
+ yield fixer.insertTextAfter(
316
+ fixtureCallInformation.rootNode,
317
+ `
318
+ ${indentation}return ${responseVariableNameToUse};`
319
+ );
320
+ }
321
+ }
322
+ });
323
+ } catch (error) {
324
+ console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
325
+ context.report({
326
+ node: supertestCall,
327
+ messageId: "unknownError",
328
+ data: {
329
+ fileName: context.filename,
330
+ error: error instanceof Error ? error.toString() : JSON.stringify(error)
331
+ }
332
+ });
333
+ }
334
+ }
335
+ };
336
+ }
337
+ };
338
+ var no_supertest_default = rule;
339
+ export {
340
+ no_supertest_default as default,
341
+ ruleId
342
+ };
343
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L25vLXN1cGVydGVzdC50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLFVBQVUsY0FBYztBQWVqQyxPQUFrRDtBQUVsRDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLE9BQU8seUJBQXlCO0FBQ2hDLFNBQVMsc0JBQXNCO0FBQy9CLFNBQVMsaUNBQWlDO0FBQzFDLFNBQVMsOEJBQThCLHVDQUF1QztBQUV2RSxJQUFNLFNBQVM7QUFrQnRCLFNBQVMsbUJBQW1CLE1BQTRCLFNBQWlDLFlBQXdCO0FBQy9HLFFBQU0sU0FBUyxVQUFVLElBQUk7QUFDN0IsU0FBTyxHQUFHLFFBQVEscURBQXFEO0FBRXZFLE1BQUk7QUFDSixNQUFJLE9BQU8sU0FBUyxtQkFBbUI7QUFFckMsWUFBUSxjQUFjO0FBQ3RCLFlBQVEsV0FBVztBQUFBLEVBQ3JCLFdBQ0UsT0FBTyxTQUFTLHFCQUNoQixPQUFPLFNBQVMsb0JBQ2hCLE9BQU8sU0FBUywyQkFDaEI7QUFFQSxZQUFRLGNBQWM7QUFDdEIsWUFBUSxXQUFXO0FBQUEsRUFDckIsV0FBVyxPQUFPLFNBQVMsbUJBQW1CO0FBQzVDLFlBQVEsY0FBYztBQUN0QixVQUFNLHFCQUFxQixzQkFBc0IsTUFBTTtBQUN2RCxXQUFPLEdBQUcsa0JBQWtCO0FBQzVCLFVBQU0sY0FBYyxVQUFVLE1BQU07QUFDcEMsUUFBSSxhQUFhLFNBQVMsb0JBQW9CO0FBQzVDLGNBQVEsV0FBVztBQUNuQixjQUFRLHNCQUFzQjtBQUM5QixVQUFJLFlBQVksU0FBUyxTQUFTLGdCQUFnQixZQUFZLFNBQVMsU0FBUyxRQUFRO0FBQ3RGLGdCQUFRLHNCQUFzQjtBQUFBLE1BQ2hDO0FBQ0EsVUFDRSxZQUFZLFNBQVMsU0FBUyxpQkFDN0IsWUFBWSxTQUFTLFNBQVMsWUFBWSxZQUFZLFNBQVMsU0FBUyxZQUN6RTtBQUNBLGdCQUFRLHlCQUF5QjtB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