@checkdigit/eslint-plugin 6.6.0-PR.75-20dc → 6.6.0-PR.75-66d8
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-cjs/index.cjs +781 -501
- package/dist-cjs/metafile.json +152 -43
- package/dist-mjs/fixture/concurrent-promises.mjs +261 -0
- package/dist-mjs/fixture/fetch-header-getter.mjs +24 -17
- package/dist-mjs/fixture/fetch.mjs +20 -0
- package/dist-mjs/fixture/no-fixture.mjs +9 -10
- package/dist-mjs/fixture/response-reference.mjs +4 -4
- package/dist-mjs/fixture/url.mjs +8 -0
- package/dist-mjs/fixture/variable.mjs +8 -0
- package/dist-mjs/index.mjs +6 -3
- package/dist-types/fixture/concurrent-promises.d.ts +4 -0
- package/dist-types/fixture/fetch.d.ts +3 -0
- package/dist-types/fixture/url.d.ts +1 -0
- package/dist-types/fixture/variable.d.ts +1 -0
- package/dist-types/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/fixture/concurrent-promises.ts +341 -0
- package/src/fixture/fetch-header-getter.ts +28 -27
- package/src/fixture/fetch.ts +30 -0
- package/src/fixture/no-fixture.ts +10 -15
- package/src/fixture/response-reference.ts +4 -12
- package/src/fixture/url.ts +6 -0
- package/src/fixture/variable.ts +5 -0
- package/src/index.ts +3 -0
package/dist-cjs/metafile.json
CHANGED
|
@@ -8149,19 +8149,42 @@
|
|
|
8149
8149
|
"imports": [],
|
|
8150
8150
|
"format": "esm"
|
|
8151
8151
|
},
|
|
8152
|
-
"
|
|
8153
|
-
"bytes":
|
|
8152
|
+
"package.json": {
|
|
8153
|
+
"bytes": 2685,
|
|
8154
|
+
"imports": [],
|
|
8155
|
+
"format": "esm",
|
|
8156
|
+
"with": {
|
|
8157
|
+
"type": "json"
|
|
8158
|
+
}
|
|
8159
|
+
},
|
|
8160
|
+
"src/get-documentation-url.ts": {
|
|
8161
|
+
"bytes": 262,
|
|
8154
8162
|
"imports": [
|
|
8155
8163
|
{
|
|
8156
|
-
"path": "
|
|
8164
|
+
"path": "package.json",
|
|
8157
8165
|
"kind": "import-statement",
|
|
8158
|
-
"original": "
|
|
8159
|
-
|
|
8166
|
+
"original": "../package.json",
|
|
8167
|
+
"with": {
|
|
8168
|
+
"type": "json"
|
|
8169
|
+
}
|
|
8170
|
+
}
|
|
8171
|
+
],
|
|
8172
|
+
"format": "esm"
|
|
8173
|
+
},
|
|
8174
|
+
"src/ast/format.ts": {
|
|
8175
|
+
"bytes": 546,
|
|
8176
|
+
"imports": [
|
|
8160
8177
|
{
|
|
8161
8178
|
"path": "node:assert",
|
|
8162
8179
|
"kind": "import-statement",
|
|
8163
8180
|
"external": true
|
|
8164
|
-
}
|
|
8181
|
+
}
|
|
8182
|
+
],
|
|
8183
|
+
"format": "esm"
|
|
8184
|
+
},
|
|
8185
|
+
"src/fixture/fetch.ts": {
|
|
8186
|
+
"bytes": 968,
|
|
8187
|
+
"imports": [
|
|
8165
8188
|
{
|
|
8166
8189
|
"path": "src/ast/tree.ts",
|
|
8167
8190
|
"kind": "import-statement",
|
|
@@ -8170,30 +8193,85 @@
|
|
|
8170
8193
|
],
|
|
8171
8194
|
"format": "esm"
|
|
8172
8195
|
},
|
|
8173
|
-
"
|
|
8174
|
-
"bytes":
|
|
8196
|
+
"src/fixture/variable.ts": {
|
|
8197
|
+
"bytes": 158,
|
|
8175
8198
|
"imports": [],
|
|
8176
|
-
"format": "esm"
|
|
8177
|
-
"with": {
|
|
8178
|
-
"type": "json"
|
|
8179
|
-
}
|
|
8199
|
+
"format": "esm"
|
|
8180
8200
|
},
|
|
8181
|
-
"src/
|
|
8182
|
-
"bytes":
|
|
8201
|
+
"src/fixture/url.ts": {
|
|
8202
|
+
"bytes": 221,
|
|
8203
|
+
"imports": [],
|
|
8204
|
+
"format": "esm"
|
|
8205
|
+
},
|
|
8206
|
+
"src/fixture/concurrent-promises.ts": {
|
|
8207
|
+
"bytes": 14705,
|
|
8183
8208
|
"imports": [
|
|
8184
8209
|
{
|
|
8185
|
-
"path": "
|
|
8210
|
+
"path": "node_modules/eslint/lib/api.js",
|
|
8186
8211
|
"kind": "import-statement",
|
|
8187
|
-
"original": "
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8212
|
+
"original": "eslint"
|
|
8213
|
+
},
|
|
8214
|
+
{
|
|
8215
|
+
"path": "src/ast/tree.ts",
|
|
8216
|
+
"kind": "import-statement",
|
|
8217
|
+
"original": "../ast/tree"
|
|
8218
|
+
},
|
|
8219
|
+
{
|
|
8220
|
+
"path": "node:assert",
|
|
8221
|
+
"kind": "import-statement",
|
|
8222
|
+
"external": true
|
|
8223
|
+
},
|
|
8224
|
+
{
|
|
8225
|
+
"path": "src/get-documentation-url.ts",
|
|
8226
|
+
"kind": "import-statement",
|
|
8227
|
+
"original": "../get-documentation-url"
|
|
8228
|
+
},
|
|
8229
|
+
{
|
|
8230
|
+
"path": "src/ast/format.ts",
|
|
8231
|
+
"kind": "import-statement",
|
|
8232
|
+
"original": "../ast/format"
|
|
8233
|
+
},
|
|
8234
|
+
{
|
|
8235
|
+
"path": "src/fixture/fetch.ts",
|
|
8236
|
+
"kind": "import-statement",
|
|
8237
|
+
"original": "./fetch"
|
|
8238
|
+
},
|
|
8239
|
+
{
|
|
8240
|
+
"path": "src/fixture/variable.ts",
|
|
8241
|
+
"kind": "import-statement",
|
|
8242
|
+
"original": "./variable"
|
|
8243
|
+
},
|
|
8244
|
+
{
|
|
8245
|
+
"path": "src/fixture/url.ts",
|
|
8246
|
+
"kind": "import-statement",
|
|
8247
|
+
"original": "./url"
|
|
8248
|
+
}
|
|
8249
|
+
],
|
|
8250
|
+
"format": "esm"
|
|
8251
|
+
},
|
|
8252
|
+
"src/fixture/response-reference.ts": {
|
|
8253
|
+
"bytes": 4003,
|
|
8254
|
+
"imports": [
|
|
8255
|
+
{
|
|
8256
|
+
"path": "node_modules/eslint/lib/api.js",
|
|
8257
|
+
"kind": "import-statement",
|
|
8258
|
+
"original": "eslint"
|
|
8259
|
+
},
|
|
8260
|
+
{
|
|
8261
|
+
"path": "node:assert",
|
|
8262
|
+
"kind": "import-statement",
|
|
8263
|
+
"external": true
|
|
8264
|
+
},
|
|
8265
|
+
{
|
|
8266
|
+
"path": "src/ast/tree.ts",
|
|
8267
|
+
"kind": "import-statement",
|
|
8268
|
+
"original": "../ast/tree"
|
|
8191
8269
|
}
|
|
8192
8270
|
],
|
|
8193
8271
|
"format": "esm"
|
|
8194
8272
|
},
|
|
8195
8273
|
"src/fixture/fetch-header-getter.ts": {
|
|
8196
|
-
"bytes":
|
|
8274
|
+
"bytes": 3432,
|
|
8197
8275
|
"imports": [
|
|
8198
8276
|
{
|
|
8199
8277
|
"path": "src/fixture/response-reference.ts",
|
|
@@ -8214,6 +8292,11 @@
|
|
|
8214
8292
|
"path": "src/ast/tree.ts",
|
|
8215
8293
|
"kind": "import-statement",
|
|
8216
8294
|
"original": "../ast/tree"
|
|
8295
|
+
},
|
|
8296
|
+
{
|
|
8297
|
+
"path": "src/fixture/fetch.ts",
|
|
8298
|
+
"kind": "import-statement",
|
|
8299
|
+
"original": "./fetch"
|
|
8217
8300
|
}
|
|
8218
8301
|
],
|
|
8219
8302
|
"format": "esm"
|
|
@@ -8229,19 +8312,8 @@
|
|
|
8229
8312
|
],
|
|
8230
8313
|
"format": "esm"
|
|
8231
8314
|
},
|
|
8232
|
-
"src/ast/format.ts": {
|
|
8233
|
-
"bytes": 546,
|
|
8234
|
-
"imports": [
|
|
8235
|
-
{
|
|
8236
|
-
"path": "node:assert",
|
|
8237
|
-
"kind": "import-statement",
|
|
8238
|
-
"external": true
|
|
8239
|
-
}
|
|
8240
|
-
],
|
|
8241
|
-
"format": "esm"
|
|
8242
|
-
},
|
|
8243
8315
|
"src/fixture/no-fixture.ts": {
|
|
8244
|
-
"bytes":
|
|
8316
|
+
"bytes": 19362,
|
|
8245
8317
|
"imports": [
|
|
8246
8318
|
{
|
|
8247
8319
|
"path": "node_modules/eslint/lib/api.js",
|
|
@@ -8272,6 +8344,21 @@
|
|
|
8272
8344
|
"path": "src/ast/format.ts",
|
|
8273
8345
|
"kind": "import-statement",
|
|
8274
8346
|
"original": "../ast/format"
|
|
8347
|
+
},
|
|
8348
|
+
{
|
|
8349
|
+
"path": "src/fixture/fetch.ts",
|
|
8350
|
+
"kind": "import-statement",
|
|
8351
|
+
"original": "./fetch"
|
|
8352
|
+
},
|
|
8353
|
+
{
|
|
8354
|
+
"path": "src/fixture/variable.ts",
|
|
8355
|
+
"kind": "import-statement",
|
|
8356
|
+
"original": "./variable"
|
|
8357
|
+
},
|
|
8358
|
+
{
|
|
8359
|
+
"path": "src/fixture/url.ts",
|
|
8360
|
+
"kind": "import-statement",
|
|
8361
|
+
"original": "./url"
|
|
8275
8362
|
}
|
|
8276
8363
|
],
|
|
8277
8364
|
"format": "esm"
|
|
@@ -8333,8 +8420,13 @@
|
|
|
8333
8420
|
"format": "esm"
|
|
8334
8421
|
},
|
|
8335
8422
|
"src/index.ts": {
|
|
8336
|
-
"bytes":
|
|
8423
|
+
"bytes": 3353,
|
|
8337
8424
|
"imports": [
|
|
8425
|
+
{
|
|
8426
|
+
"path": "src/fixture/concurrent-promises.ts",
|
|
8427
|
+
"kind": "import-statement",
|
|
8428
|
+
"original": "./fixture/concurrent-promises"
|
|
8429
|
+
},
|
|
8338
8430
|
{
|
|
8339
8431
|
"path": "src/fixture/fetch-header-getter.ts",
|
|
8340
8432
|
"kind": "import-statement",
|
|
@@ -8907,6 +8999,11 @@
|
|
|
8907
8999
|
"kind": "require-call",
|
|
8908
9000
|
"external": true
|
|
8909
9001
|
},
|
|
9002
|
+
{
|
|
9003
|
+
"path": "node:assert",
|
|
9004
|
+
"kind": "require-call",
|
|
9005
|
+
"external": true
|
|
9006
|
+
},
|
|
8910
9007
|
{
|
|
8911
9008
|
"path": "node:assert",
|
|
8912
9009
|
"kind": "require-call",
|
|
@@ -10558,31 +10655,43 @@
|
|
|
10558
10655
|
"bytesInOutput": 772
|
|
10559
10656
|
},
|
|
10560
10657
|
"src/index.ts": {
|
|
10561
|
-
"bytesInOutput":
|
|
10658
|
+
"bytesInOutput": 2271
|
|
10562
10659
|
},
|
|
10563
10660
|
"src/ast/tree.ts": {
|
|
10564
10661
|
"bytesInOutput": 981
|
|
10565
10662
|
},
|
|
10566
|
-
"src/fixture/response-reference.ts": {
|
|
10567
|
-
"bytesInOutput": 2772
|
|
10568
|
-
},
|
|
10569
10663
|
"package.json": {
|
|
10570
10664
|
"bytesInOutput": 2774
|
|
10571
10665
|
},
|
|
10572
10666
|
"src/get-documentation-url.ts": {
|
|
10573
10667
|
"bytesInOutput": 146
|
|
10574
10668
|
},
|
|
10669
|
+
"src/ast/format.ts": {
|
|
10670
|
+
"bytesInOutput": 331
|
|
10671
|
+
},
|
|
10672
|
+
"src/fixture/fetch.ts": {
|
|
10673
|
+
"bytesInOutput": 802
|
|
10674
|
+
},
|
|
10675
|
+
"src/fixture/variable.ts": {
|
|
10676
|
+
"bytesInOutput": 118
|
|
10677
|
+
},
|
|
10678
|
+
"src/fixture/url.ts": {
|
|
10679
|
+
"bytesInOutput": 129
|
|
10680
|
+
},
|
|
10681
|
+
"src/fixture/concurrent-promises.ts": {
|
|
10682
|
+
"bytesInOutput": 12177
|
|
10683
|
+
},
|
|
10684
|
+
"src/fixture/response-reference.ts": {
|
|
10685
|
+
"bytesInOutput": 2671
|
|
10686
|
+
},
|
|
10575
10687
|
"src/fixture/fetch-header-getter.ts": {
|
|
10576
|
-
"bytesInOutput":
|
|
10688
|
+
"bytesInOutput": 2809
|
|
10577
10689
|
},
|
|
10578
10690
|
"src/invalid-json-stringify.ts": {
|
|
10579
10691
|
"bytesInOutput": 2473
|
|
10580
10692
|
},
|
|
10581
|
-
"src/ast/format.ts": {
|
|
10582
|
-
"bytesInOutput": 334
|
|
10583
|
-
},
|
|
10584
10693
|
"src/fixture/no-fixture.ts": {
|
|
10585
|
-
"bytesInOutput":
|
|
10694
|
+
"bytesInOutput": 16300
|
|
10586
10695
|
},
|
|
10587
10696
|
"src/no-promise-instance-method.ts": {
|
|
10588
10697
|
"bytesInOutput": 1275
|
|
@@ -10615,7 +10724,7 @@
|
|
|
10615
10724
|
"bytesInOutput": 3362
|
|
10616
10725
|
}
|
|
10617
10726
|
},
|
|
10618
|
-
"bytes":
|
|
10727
|
+
"bytes": 3851620
|
|
10619
10728
|
}
|
|
10620
10729
|
}
|
|
10621
10730
|
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// src/fixture/concurrent-promises.ts
|
|
2
|
+
import "eslint";
|
|
3
|
+
import { getEnclosingStatement, getParent } from "../ast/tree.mjs";
|
|
4
|
+
import { strict as assert } from "node:assert";
|
|
5
|
+
import getDocumentationUrl from "../get-documentation-url.mjs";
|
|
6
|
+
import { getIndentation } from "../ast/format.mjs";
|
|
7
|
+
import { isInvalidResponseHeadersAccess } from "./fetch.mjs";
|
|
8
|
+
import { isValidPropertyName } from "./variable.mjs";
|
|
9
|
+
import { replaceEndpointUrlPrefixWithBasePath } from "./url.mjs";
|
|
10
|
+
var ruleId = "concurrent-promises";
|
|
11
|
+
function analyzeFixtureCall(call, results, sourceCode) {
|
|
12
|
+
const parent = getParent(call);
|
|
13
|
+
if (!parent) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let nextCall;
|
|
17
|
+
if (parent.type === "ArrayExpression") {
|
|
18
|
+
results.fixtureNode = call;
|
|
19
|
+
} else if (parent.type === "MemberExpression" && parent.property.type === "Identifier") {
|
|
20
|
+
if (parent.property.name === "expect") {
|
|
21
|
+
const assertionCall = getParent(parent);
|
|
22
|
+
assert.ok(assertionCall && assertionCall.type === "CallExpression");
|
|
23
|
+
results.assertions = [...results.assertions ?? [], assertionCall.arguments];
|
|
24
|
+
nextCall = assertionCall;
|
|
25
|
+
} else if (parent.property.name === "send") {
|
|
26
|
+
const sendRequestBodyCall = getParent(parent);
|
|
27
|
+
assert.ok(sendRequestBodyCall && sendRequestBodyCall.type === "CallExpression");
|
|
28
|
+
results.requestBody = sendRequestBodyCall.arguments[0];
|
|
29
|
+
nextCall = sendRequestBodyCall;
|
|
30
|
+
} else if (parent.property.name === "set") {
|
|
31
|
+
const setRequestHeaderCall = getParent(parent);
|
|
32
|
+
assert.ok(setRequestHeaderCall && setRequestHeaderCall.type === "CallExpression");
|
|
33
|
+
const [name, value] = setRequestHeaderCall.arguments;
|
|
34
|
+
results.requestHeaders = [...results.requestHeaders ?? [], { name, value }];
|
|
35
|
+
nextCall = setRequestHeaderCall;
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error(`Unexpected expression in fixture/supertest call ${sourceCode.getText(parent)}.`);
|
|
39
|
+
}
|
|
40
|
+
if (nextCall) {
|
|
41
|
+
analyzeFixtureCall(nextCall, results, sourceCode);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function createResponseAssertions(fixtureCallInformation, sourceCode, responseVariableName) {
|
|
45
|
+
let statusAssertion;
|
|
46
|
+
const nonStatusAssertions = [];
|
|
47
|
+
for (const expectArguments of fixtureCallInformation.assertions ?? []) {
|
|
48
|
+
if (expectArguments.length === 1) {
|
|
49
|
+
const [assertionArgument] = expectArguments;
|
|
50
|
+
assert.ok(assertionArgument);
|
|
51
|
+
if (assertionArgument.type === "MemberExpression" && assertionArgument.object.type === "Identifier" && assertionArgument.object.name === "StatusCodes" || assertionArgument.type === "Literal" || sourceCode.getText(assertionArgument).includes("StatusCodes.")) {
|
|
52
|
+
statusAssertion = `assert.equal(${responseVariableName}.status, ${sourceCode.getText(assertionArgument)})`;
|
|
53
|
+
} else if (assertionArgument.type === "ArrowFunctionExpression") {
|
|
54
|
+
let functionBody = sourceCode.getText(assertionArgument.body);
|
|
55
|
+
const [originalResponseArgument] = assertionArgument.params;
|
|
56
|
+
assert.ok(originalResponseArgument?.type === "Identifier");
|
|
57
|
+
const originalResponseArgumentName = originalResponseArgument.name;
|
|
58
|
+
if (originalResponseArgumentName !== responseVariableName) {
|
|
59
|
+
functionBody = functionBody.replace(
|
|
60
|
+
new RegExp(`\\b${originalResponseArgumentName}\\b`, "ug"),
|
|
61
|
+
responseVariableName
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
nonStatusAssertions.push(`assert.ok(${functionBody})`);
|
|
65
|
+
} else if (assertionArgument.type === "Identifier") {
|
|
66
|
+
nonStatusAssertions.push(`assert.ok(${sourceCode.getText(assertionArgument)}(${responseVariableName}))`);
|
|
67
|
+
} else if (assertionArgument.type === "ObjectExpression" || assertionArgument.type === "CallExpression") {
|
|
68
|
+
nonStatusAssertions.push(
|
|
69
|
+
`assert.deepEqual(await ${responseVariableName}.json(), ${sourceCode.getText(assertionArgument)})`
|
|
70
|
+
);
|
|
71
|
+
} else {
|
|
72
|
+
throw new Error(`Unexpected Supertest assertion argument: ".expect(${sourceCode.getText(assertionArgument)})`);
|
|
73
|
+
}
|
|
74
|
+
} else if (expectArguments.length === 2) {
|
|
75
|
+
const [headerName, headerValue] = expectArguments;
|
|
76
|
+
assert.ok(headerName && headerValue);
|
|
77
|
+
const headersReference = `${responseVariableName}.headers`;
|
|
78
|
+
if (headerValue.type === "Literal" && headerValue.value instanceof RegExp) {
|
|
79
|
+
nonStatusAssertions.push(
|
|
80
|
+
`assert.ok(${headersReference}.get(${sourceCode.getText(headerName)}).match(${sourceCode.getText(headerValue)}))`
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
nonStatusAssertions.push(
|
|
84
|
+
`assert.equal(${headersReference}.get(${sourceCode.getText(headerName)}), ${sourceCode.getText(headerValue)})`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
statusAssertion,
|
|
91
|
+
nonStatusAssertions
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function getResponseHeadersAccesses(responseVariables, scopeManager, sourceCode) {
|
|
95
|
+
const responseHeadersAccesses = [];
|
|
96
|
+
for (const responseVariable of responseVariables) {
|
|
97
|
+
for (const responseReference of responseVariable.references) {
|
|
98
|
+
const responseAccess = getParent(responseReference.identifier);
|
|
99
|
+
if (!responseAccess || responseAccess.type !== "MemberExpression") {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const responseAccessParent = getParent(responseAccess);
|
|
103
|
+
if (!responseAccessParent) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (responseAccessParent.type === "CallExpression" && responseAccessParent.arguments[0]?.type === "ArrowFunctionExpression") {
|
|
107
|
+
responseHeadersAccesses.push(
|
|
108
|
+
...getResponseHeadersAccesses(
|
|
109
|
+
scopeManager.getDeclaredVariables(responseAccessParent.arguments[0]),
|
|
110
|
+
scopeManager,
|
|
111
|
+
sourceCode
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (responseAccess.computed && responseAccess.property.type === "Literal" && responseAccessParent.type === "MemberExpression") {
|
|
117
|
+
responseHeadersAccesses.push(responseAccessParent);
|
|
118
|
+
} else {
|
|
119
|
+
responseHeadersAccesses.push(responseAccess);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return responseHeadersAccesses;
|
|
124
|
+
}
|
|
125
|
+
var rule = {
|
|
126
|
+
meta: {
|
|
127
|
+
type: "suggestion",
|
|
128
|
+
docs: {
|
|
129
|
+
description: "Prefer native fetch API over customized fixture API.",
|
|
130
|
+
url: getDocumentationUrl(ruleId)
|
|
131
|
+
},
|
|
132
|
+
messages: {
|
|
133
|
+
preferNativeFetch: "Prefer native fetch API over customized fixture API.",
|
|
134
|
+
shouldUseHeaderGetter: "Getter should be used to access response headers.",
|
|
135
|
+
unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}. Please manually convert the fixture API call to fetch API call.'
|
|
136
|
+
},
|
|
137
|
+
fixable: "code",
|
|
138
|
+
schema: []
|
|
139
|
+
},
|
|
140
|
+
// eslint-disable-next-line max-lines-per-function
|
|
141
|
+
create(context) {
|
|
142
|
+
const sourceCode = context.sourceCode;
|
|
143
|
+
const scopeManager = sourceCode.scopeManager;
|
|
144
|
+
return {
|
|
145
|
+
// eslint-disable-next-line max-lines-per-function
|
|
146
|
+
'CallExpression[callee.object.name="Promise"] > ArrayExpression CallExpression[callee.object.object.name="fixture"][callee.object.property.name="api"]': (fixtureCall) => {
|
|
147
|
+
try {
|
|
148
|
+
assert.ok(fixtureCall.type === "CallExpression");
|
|
149
|
+
const fixtureFunction = fixtureCall.callee;
|
|
150
|
+
assert.ok(fixtureFunction.type === "MemberExpression");
|
|
151
|
+
const indentation = getIndentation(fixtureCall, sourceCode);
|
|
152
|
+
const [urlArgumentNode] = fixtureCall.arguments;
|
|
153
|
+
assert.ok(urlArgumentNode !== void 0);
|
|
154
|
+
const fixtureCallInformation = {};
|
|
155
|
+
analyzeFixtureCall(fixtureCall, fixtureCallInformation, sourceCode);
|
|
156
|
+
const originalUrlArgumentText = sourceCode.getText(urlArgumentNode);
|
|
157
|
+
const fetchUrlArgumentText = replaceEndpointUrlPrefixWithBasePath(originalUrlArgumentText);
|
|
158
|
+
const methodNode = fixtureFunction.property;
|
|
159
|
+
assert.ok(methodNode.type === "Identifier");
|
|
160
|
+
const fetchRequestArgumentLines = [
|
|
161
|
+
"{",
|
|
162
|
+
` method: '${methodNode.name.toUpperCase()}',`,
|
|
163
|
+
...fixtureCallInformation.requestBody ? [` body: JSON.stringify(${sourceCode.getText(fixtureCallInformation.requestBody)}),`] : [],
|
|
164
|
+
...fixtureCallInformation.requestHeaders ? [
|
|
165
|
+
` headers: {`,
|
|
166
|
+
...fixtureCallInformation.requestHeaders.map(
|
|
167
|
+
({ name, value }) => (
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, no-nested-ternary, sonarjs/no-nested-template-literals
|
|
169
|
+
` ${name.type === "Literal" ? isValidPropertyName(name.value) ? name.value : `'${name.value}'` : `[${sourceCode.getText(name)}]`}: ${sourceCode.getText(value)},`
|
|
170
|
+
)
|
|
171
|
+
),
|
|
172
|
+
` },`
|
|
173
|
+
] : [],
|
|
174
|
+
"}"
|
|
175
|
+
].join(`
|
|
176
|
+
${indentation}`);
|
|
177
|
+
const responseVariableNameToUse = "res";
|
|
178
|
+
const { statusAssertion, nonStatusAssertions } = createResponseAssertions(
|
|
179
|
+
fixtureCallInformation,
|
|
180
|
+
sourceCode,
|
|
181
|
+
responseVariableNameToUse
|
|
182
|
+
);
|
|
183
|
+
const disableLintComment = "// eslint-disable-next-line @checkdigit/no-promise-instance-method";
|
|
184
|
+
const fetchCallText = `fetch(${fetchUrlArgumentText}, ${fetchRequestArgumentLines})`;
|
|
185
|
+
const appendingAssignmentAndAssertionText = [
|
|
186
|
+
...statusAssertion !== void 0 ? [statusAssertion] : [],
|
|
187
|
+
...nonStatusAssertions
|
|
188
|
+
].join(`;
|
|
189
|
+
${indentation}`);
|
|
190
|
+
const replacementText = fixtureCallInformation.assertions ? [
|
|
191
|
+
disableLintComment,
|
|
192
|
+
`${fetchCallText}.then((${responseVariableNameToUse}) => {`,
|
|
193
|
+
appendingAssignmentAndAssertionText === "" ? "" : ` ${appendingAssignmentAndAssertionText};`,
|
|
194
|
+
` return ${responseVariableNameToUse};`,
|
|
195
|
+
`})`
|
|
196
|
+
].join(`
|
|
197
|
+
${indentation}`) : fetchCallText;
|
|
198
|
+
context.report({
|
|
199
|
+
node: fixtureCall,
|
|
200
|
+
messageId: "preferNativeFetch",
|
|
201
|
+
fix(fixer) {
|
|
202
|
+
return fixer.replaceText(fixtureCallInformation.fixtureNode, replacementText);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
const responsesVariable = getEnclosingStatement(fixtureCallInformation.fixtureNode);
|
|
206
|
+
if (!responsesVariable) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const responseVariableReferences = scopeManager.getDeclaredVariables(responsesVariable);
|
|
210
|
+
const responseHeadersAccesses = getResponseHeadersAccesses(
|
|
211
|
+
responseVariableReferences,
|
|
212
|
+
scopeManager,
|
|
213
|
+
sourceCode
|
|
214
|
+
);
|
|
215
|
+
for (const responseHeadersAccess of responseHeadersAccesses) {
|
|
216
|
+
if (isInvalidResponseHeadersAccess(responseHeadersAccess)) {
|
|
217
|
+
const headerAccess = getParent(responseHeadersAccess);
|
|
218
|
+
if (headerAccess?.type === "MemberExpression") {
|
|
219
|
+
const headerNameNode = headerAccess.property;
|
|
220
|
+
const headerName = headerAccess.computed ? sourceCode.getText(headerNameNode) : `'${sourceCode.getText(headerNameNode)}'`;
|
|
221
|
+
const headerAccessReplacementText = `${sourceCode.getText(headerAccess.object)}.get(${headerName})`;
|
|
222
|
+
context.report({
|
|
223
|
+
node: headerAccess,
|
|
224
|
+
messageId: "shouldUseHeaderGetter",
|
|
225
|
+
fix(fixer) {
|
|
226
|
+
return fixer.replaceText(headerAccess, headerAccessReplacementText);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
} else if (headerAccess?.type === "CallExpression" && responseHeadersAccess.property.type === "Identifier" && responseHeadersAccess.property.name === "get") {
|
|
230
|
+
const headerAccessReplacementText = `${sourceCode.getText(responseHeadersAccess.object)}.headers.get(${sourceCode.getText(headerAccess.arguments[0])})`;
|
|
231
|
+
context.report({
|
|
232
|
+
node: headerAccess,
|
|
233
|
+
messageId: "shouldUseHeaderGetter",
|
|
234
|
+
fix(fixer) {
|
|
235
|
+
return fixer.replaceText(headerAccess, headerAccessReplacementText);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
|
|
243
|
+
context.report({
|
|
244
|
+
node: fixtureCall,
|
|
245
|
+
messageId: "unknownError",
|
|
246
|
+
data: {
|
|
247
|
+
fileName: context.filename,
|
|
248
|
+
error: error instanceof Error ? error.toString() : JSON.stringify(error)
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
var concurrent_promises_default = rule;
|
|
257
|
+
export {
|
|
258
|
+
concurrent_promises_default as default,
|
|
259
|
+
ruleId
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvY29uY3VycmVudC1wcm9taXNlcy50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFTQSxPQUFrRDtBQUNsRCxTQUFTLHVCQUF1QixpQkFBaUI7QUFDakQsU0FBUyxVQUFVLGNBQWM7QUFDakMsT0FBTyx5QkFBeUI7QUFDaEMsU0FBUyxzQkFBc0I7QUFDL0IsU0FBUyxzQ0FBc0M7QUFDL0MsU0FBUywyQkFBMkI7QUFDcEMsU0FBUyw0Q0FBNEM7QUFFOUMsSUFBTSxTQUFTO0FBVXRCLFNBQVMsbUJBQW1CLE1BQTRCLFNBQWlDLFlBQXdCO0FBQy9HLFFBQU0sU0FBUyxVQUFVLElBQUk7QUFDN0IsTUFBSSxDQUFDLFFBQVE7QUFDWDtBQUFBLEVBQ0Y7QUFFQSxNQUFJO0FBQ0osTUFBSSxPQUFPLFNBQVMsbUJBQW1CO0FBQ3JDLFlBQVEsY0FBYztBQUFBLEVBQ3hCLFdBQVcsT0FBTyxTQUFTLHNCQUFzQixPQUFPLFNBQVMsU0FBUyxjQUFjO0FBQ3RGLFFBQUksT0FBTyxTQUFTLFNBQVMsVUFBVTtBQUVyQyxZQUFNLGdCQUFnQixVQUFVLE1BQU07QUFDdEMsYUFBTyxHQUFHLGlCQUFpQixjQUFjLFNBQVMsZ0JBQWdCO0FBQ2xFLGNBQVEsYUFBYSxDQUFDLEdBQUksUUFBUSxjQUFjLENBQUMsR0FBSSxjQUFjLFNBQXlCO0FBQzVGLGlCQUFXO0FBQUEsSUFDYixXQUFXLE9BQU8sU0FBUyxTQUFTLFFBQVE7QUFFMUMsWUFBTSxzQkFBc0IsVUFBVSxNQUFNO0FBQzVDLGFBQU8sR0FBRyx1QkFBdUIsb0JBQW9CLFNBQVMsZ0JBQWdCO0FBQzlFLGNBQVEsY0FBYyxvQkFBb0IsVUFBVSxDQUFDO0FBQ3JELGlCQUFXO0FBQUEsSUFDYixXQUFXLE9BQU8sU0FBUyxTQUFTLE9BQU87QUFFekMsWUFBTSx1QkFBdUIsVUFBVSxNQUFNO0FBQzdDLGFBQU8sR0FBRyx3QkFBd0IscUJBQXFCLFNBQVMsZ0JBQWdCO0FBQ2hGLFlBQU0sQ0FBQyxN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
|
|
@@ -3,6 +3,7 @@ import { analyzeResponseReferences } from "./response-reference.mjs";
|
|
|
3
3
|
import { strict as assert } from "node:assert";
|
|
4
4
|
import getDocumentationUrl from "../get-documentation-url.mjs";
|
|
5
5
|
import { getParent } from "../ast/tree.mjs";
|
|
6
|
+
import { isInvalidResponseHeadersAccess } from "./fetch.mjs";
|
|
6
7
|
var ruleId = "fetch-header-getter";
|
|
7
8
|
var rule = {
|
|
8
9
|
meta: {
|
|
@@ -29,28 +30,34 @@ var rule = {
|
|
|
29
30
|
scopeManager
|
|
30
31
|
);
|
|
31
32
|
assert.ok(responseVariable);
|
|
32
|
-
const
|
|
33
|
-
|
|
33
|
+
const directHeadersReferences = responseHeadersReferences.filter((headersReference) => {
|
|
34
|
+
const headersAccess = getParent(headersReference);
|
|
35
|
+
return headersAccess?.type !== "VariableDeclarator";
|
|
36
|
+
});
|
|
37
|
+
const indirectHeadersReferences = responseHeadersReferences.map(getParent).filter((parent) => parent?.type === "VariableDeclarator").map((declarator) => declarator.id.name).map((redefinedHeadersVariableName) => {
|
|
34
38
|
const headersVariable = responseVariable.scope.variables.find((variable) => {
|
|
35
39
|
const identifier = variable.identifiers[0];
|
|
36
40
|
return identifier?.type === "Identifier" && identifier.name === redefinedHeadersVariableName;
|
|
37
41
|
});
|
|
38
|
-
return headersVariable?.references.map((reference) =>
|
|
42
|
+
return headersVariable?.references.map((reference) => reference.identifier) ?? [];
|
|
39
43
|
}).flat();
|
|
40
|
-
const
|
|
41
|
-
|
|
44
|
+
const invalidHeadersReferences = [...directHeadersReferences, ...indirectHeadersReferences].filter(
|
|
45
|
+
isInvalidResponseHeadersAccess
|
|
42
46
|
);
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
invalidHeadersReferences.forEach((headersReference) => {
|
|
48
|
+
const headerAccess = getParent(headersReference);
|
|
49
|
+
if (headerAccess?.type === "MemberExpression") {
|
|
50
|
+
const headerNameNode = headerAccess.property;
|
|
51
|
+
const headerName = headerAccess.computed ? sourceCode.getText(headerNameNode) : `'${sourceCode.getText(headerNameNode)}'`;
|
|
52
|
+
const replacementText = `${sourceCode.getText(headerAccess.object)}.get(${headerName})`;
|
|
53
|
+
context.report({
|
|
54
|
+
node: headerAccess,
|
|
55
|
+
messageId: "shouldUseHeaderGetter",
|
|
56
|
+
fix(fixer) {
|
|
57
|
+
return fixer.replaceText(headerAccess, replacementText);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
54
61
|
});
|
|
55
62
|
}
|
|
56
63
|
};
|
|
@@ -61,4 +68,4 @@ export {
|
|
|
61
68
|
fetch_header_getter_default as default,
|
|
62
69
|
ruleId
|
|
63
70
|
};
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvZmV0Y2gtaGVhZGVyLWdldHRlci50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFVQSxTQUFTLGlDQUFpQztBQUMxQyxTQUFTLFVBQVUsY0FBYztBQUNqQyxPQUFPLHlCQUF5QjtBQUNoQyxTQUFTLGlCQUFpQjtBQUMxQixTQUFTLHNDQUFzQztBQUV4QyxJQUFNLFNBQVM7QUFFdEIsSUFBTSxPQUF3QjtBQUFBLEVBQzVCLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxNQUNiLEtBQUssb0JBQW9CLE1BQU07QUFBQSxJQUNqQztBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsdUJBQXVCO0FBQUEsSUFDekI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLE9BQU8sU0FBUztBQUNkLFVBQU0sYUFBYSxRQUFRO0FBQzNCLFVBQU0sZUFBZSxXQUFXO0FBRWhDLFdBQU87QUFBQSxNQUNMLHlEQUF5RCxDQUFDLGNBQWtDO0FBQzFGLGNBQU0sc0JBQXNCLFVBQVUsU0FBUztBQUMvQyxlQUFPLEdBQUcscUJBQXFCLFNBQVMscUJBQXFCO0FBQzdELGNBQU0sRUFBRSxVQUFVLGtCQUFrQixtQkFBbUIsMEJBQTBCLElBQUk7QUFBQSxVQUNuRjtBQUFBLFVBQ0E7QUFBQSxRQUNGO0FBQ0EsZUFBTyxHQUFHLGdCQUFnQjtBQUUxQixjQUFNLDBCQUEwQiwwQkFBMEIsT0FBTyxDQUFDLHFCQUFxQjtBQUNyRixnQkFBTSxnQkFBZ0IsVUFBVSxnQkFBZ0I7QUFDaEQsaUJBQU8sZUFBZSxTQUFTO0FBQUEsUUFDakMsQ0FBQztBQUVELGNBQU0sNEJBQTRCLDBCQUMvQixJQUFJLFNBQVMsRUFDYixPQUFPLENBQUMsV0FBeUMsUUFBUSxTQUFTLG9CQUFvQixFQUN0RixJQUFJLENBQUMsZUFBZ0IsV0FBVyxHQUFrQixJQUFJLEVBQ3RELElBQUksQ0FBQyxpQ0FBaUM7QUFDckMsZ0JBQU0sa0JBQWtCLGlCQUFpQixNQUFNLFVBQVUsS0FBSyxDQUFDLGFBQWE7QUFDMUUsa0JBQU0sYUFBYSxTQUFTLFlBQVksQ0FBQztBQUN6QyxtQkFBTyxZQUFZLFNBQVMsZ0JBQWdCLFdBQVcsU0FBUztBQUFBLFVBQ2xFLENBQUM7QUFDRCxpQkFBTyxpQkFBaUIsV0FBVyxJQUFJLENBQUMsY0FBYyxVQUFVLFVBQVUsS0FBSyxDQUFDO0FBQUEsUUFDbEYsQ0FBQyxFQUNBLEtBQUs7QUFFUixjQUFNLDJCQUEyQixDQUFDLEdBQUcseUJBQXlCLEdBQUcseUJBQXlCLEVBQUU7QUFBQSxVQUMxRjtBQUFBLFFBQ0Y7QUFFQSxpQ0FBeUIsUUFBUSxDQUFDLHFCQUFxQjtBQUNyRCxnQkFBTSxlQUFlLFVBQVUsZ0JBQWdCO0FBQy9DLGNBQUksY0FBYyxTQUFTLG9CQUFvQjtBQUM3QyxrQkFBTSxpQkFBaUIsYUFBYTtBQUNwQyxrQkFBTSxhQUFhLGFBQWEsV0FDNUIsV0FBVyxRQUFRLGNBQWMsSUFDakMsSUFBSSxXQUFXLFFBQVEsY0FBYyxDQUFDO0FBQzFDLGtCQUFNLGtCQUFrQixHQUFHLFdBQVcsUUFBUSxhQUFhLE1BQU0sQ0FBQyxRQUFRLFVBQVU7QUFFcEYsb0JBQVEsT0FBTztBQUFBLGNBQ2IsTUFBTTtBQUFBLGNBQ04sV0FBVztBQUFBLGNBQ1gsSUFBSSxPQUFPO0FBQ1QsdUJBQU8sTUFBTSxZQUFZLGNBQWMsZUFBZTtBQUFBLGNBQ3hEO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGO0FBRUEsSUFBTyw4QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/fixture/fetch.ts
|
|
2
|
+
import { getParent } from "../ast/tree.mjs";
|
|
3
|
+
function getResponseBodyRetrievalText(responseVariableName) {
|
|
4
|
+
return `await ${responseVariableName}.json()`;
|
|
5
|
+
}
|
|
6
|
+
function isInvalidResponseHeadersAccess(responseHeadersAccess) {
|
|
7
|
+
const responseHeaderAccessParent = getParent(responseHeadersAccess);
|
|
8
|
+
if (responseHeaderAccessParent?.type === "VariableDeclarator") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (responseHeaderAccessParent?.type === "CallExpression" && responseHeaderAccessParent.callee.type === "MemberExpression" && responseHeaderAccessParent.callee.property.type === "Identifier" && responseHeaderAccessParent.callee.property.name === "get") {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return !(responseHeaderAccessParent?.type === "MemberExpression" && responseHeaderAccessParent.property.type === "Identifier" && responseHeaderAccessParent.property.name === "get");
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
getResponseBodyRetrievalText,
|
|
18
|
+
isInvalidResponseHeadersAccess
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvZmV0Y2gudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBR0EsU0FBUyxpQkFBaUI7QUFFbkIsU0FBUyw2QkFBNkIsc0JBQThCO0FBQ3pFLFNBQU8sU0FBUyxvQkFBb0I7QUFDdEM7QUFFTyxTQUFTLCtCQUErQix1QkFBNkI7QUFDMUUsUUFBTSw2QkFBNkIsVUFBVSxxQkFBcUI7QUFDbEUsTUFBSSw0QkFBNEIsU0FBUyxzQkFBc0I7QUFDN0QsV0FBTztBQUFBLEVBQ1Q7QUFFQSxNQUNFLDRCQUE0QixTQUFTLG9CQUNyQywyQkFBMkIsT0FBTyxTQUFTLHNCQUMzQywyQkFBMkIsT0FBTyxTQUFTLFNBQVMsZ0JBQ3BELDJCQUEyQixPQUFPLFNBQVMsU0FBUyxPQUNwRDtBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTyxFQUNMLDRCQUE0QixTQUFTLHNCQUNyQywyQkFBMkIsU0FBUyxTQUFTLGdCQUM3QywyQkFBMkIsU0FBUyxTQUFTO0FBRWpEOyIsCiAgIm5hbWVzIjogW10KfQo=
|