@checkdigit/eslint-plugin 6.6.0-PR.75-49c9 → 6.6.0-PR.75-bbf4

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 (60) hide show
  1. package/dist-cjs/index.cjs +974 -1035
  2. package/dist-cjs/metafile.json +144 -202
  3. package/dist-mjs/{fixture → agent}/add-url-domain.mjs +2 -2
  4. package/dist-mjs/{fixture → agent}/fetch-response-body-json.mjs +2 -2
  5. package/dist-mjs/agent/fetch-response-header-getter.mjs +117 -0
  6. package/dist-mjs/{fixture → agent}/fetch-then.mjs +5 -5
  7. package/dist-mjs/{fixture → agent}/fetch.mjs +3 -3
  8. package/dist-mjs/{fixture → agent}/no-fixture.mjs +5 -5
  9. package/dist-mjs/{fixture → agent}/no-full-response.mjs +3 -3
  10. package/dist-mjs/{fixture → agent}/no-service-wrapper.mjs +4 -4
  11. package/dist-mjs/{fixture → agent}/no-status-code.mjs +2 -2
  12. package/dist-mjs/{fixture → agent}/response-reference.mjs +3 -3
  13. package/dist-mjs/{fixture → agent}/url.mjs +2 -2
  14. package/dist-mjs/index.mjs +24 -27
  15. package/dist-mjs/library/format.mjs +14 -0
  16. package/dist-mjs/{ast → library}/tree.mjs +2 -2
  17. package/dist-mjs/library/ts-tree.mjs +72 -0
  18. package/dist-mjs/{fixture → library}/variable.mjs +2 -2
  19. package/dist-types/index.d.ts +11 -13
  20. package/dist-types/{ast → library}/ts-tree.d.ts +1 -0
  21. package/package.json +1 -1
  22. package/src/{fixture → agent}/add-url-domain.ts +2 -2
  23. package/src/{fixture/fetch-response-header-getter-ts.ts → agent/fetch-response-header-getter.ts} +32 -21
  24. package/src/{fixture → agent}/fetch-then.ts +3 -3
  25. package/src/{fixture → agent}/fetch.ts +1 -1
  26. package/src/{fixture → agent}/no-fixture.ts +3 -3
  27. package/src/{fixture → agent}/no-full-response.ts +1 -1
  28. package/src/{fixture → agent}/no-service-wrapper.ts +2 -2
  29. package/src/{fixture → agent}/response-reference.ts +1 -1
  30. package/src/index.ts +22 -25
  31. package/src/{ast → library}/ts-tree.ts +11 -0
  32. package/dist-mjs/ast/format.mjs +0 -14
  33. package/dist-mjs/ast/ts-tree.mjs +0 -65
  34. package/dist-mjs/fixture/fetch-header-getter.mjs +0 -71
  35. package/dist-mjs/fixture/fetch-response-header-getter-ts.mjs +0 -110
  36. package/dist-mjs/fixture/ts-tree.mjs +0 -12
  37. package/dist-types/fixture/fetch-header-getter.d.ts +0 -4
  38. package/dist-types/fixture/ts-tree.d.ts +0 -2
  39. package/src/fixture/fetch-header-getter.ts +0 -91
  40. package/src/fixture/ts-tree.ts +0 -14
  41. /package/dist-types/{fixture → agent}/add-url-domain.d.ts +0 -0
  42. /package/dist-types/{fixture → agent}/fetch-response-body-json.d.ts +0 -0
  43. /package/dist-types/{fixture/fetch-response-header-getter-ts.d.ts → agent/fetch-response-header-getter.d.ts} +0 -0
  44. /package/dist-types/{fixture → agent}/fetch-then.d.ts +0 -0
  45. /package/dist-types/{fixture → agent}/fetch.d.ts +0 -0
  46. /package/dist-types/{fixture → agent}/no-fixture.d.ts +0 -0
  47. /package/dist-types/{fixture → agent}/no-full-response.d.ts +0 -0
  48. /package/dist-types/{fixture → agent}/no-service-wrapper.d.ts +0 -0
  49. /package/dist-types/{fixture → agent}/no-status-code.d.ts +0 -0
  50. /package/dist-types/{fixture → agent}/response-reference.d.ts +0 -0
  51. /package/dist-types/{fixture → agent}/url.d.ts +0 -0
  52. /package/dist-types/{ast → library}/format.d.ts +0 -0
  53. /package/dist-types/{ast → library}/tree.d.ts +0 -0
  54. /package/dist-types/{fixture → library}/variable.d.ts +0 -0
  55. /package/src/{fixture → agent}/fetch-response-body-json.ts +0 -0
  56. /package/src/{fixture → agent}/no-status-code.ts +0 -0
  57. /package/src/{fixture → agent}/url.ts +0 -0
  58. /package/src/{ast → library}/format.ts +0 -0
  59. /package/src/{ast → library}/tree.ts +0 -0
  60. /package/src/{fixture → library}/variable.ts +0 -0
@@ -0,0 +1,72 @@
1
+ // src/library/ts-tree.ts
2
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
3
+ function getParent(node) {
4
+ return node.parent;
5
+ }
6
+ function getAncestor(node, matcher, exitMatcher) {
7
+ const parent = getParent(node);
8
+ if (!parent) {
9
+ return void 0;
10
+ } else if (typeof matcher === "string" && parent.type === matcher) {
11
+ return parent;
12
+ } else if (typeof matcher === "function" && matcher(parent)) {
13
+ return parent;
14
+ } else if (typeof exitMatcher === "string" && parent.type === exitMatcher) {
15
+ return void 0;
16
+ } else if (typeof exitMatcher === "function" && exitMatcher(parent)) {
17
+ return void 0;
18
+ }
19
+ return getAncestor(parent, matcher, exitMatcher);
20
+ }
21
+ function isBlockStatement(node) {
22
+ return node.type.endsWith("Statement") || node.type.endsWith("Declaration");
23
+ }
24
+ function getEnclosingStatement(node) {
25
+ return getAncestor(node, isBlockStatement);
26
+ }
27
+ function getEnclosingScopeNode(node) {
28
+ return getAncestor(
29
+ node,
30
+ (parentNode) => ["FunctionExpression", "FunctionDeclaration", "ArrowFunctionExpression", "Program"].includes(parentNode.type)
31
+ );
32
+ }
33
+ function isUsedInArrayOrAsArgument(node) {
34
+ if (isBlockStatement(node)) {
35
+ return false;
36
+ }
37
+ const parent = getParent(node);
38
+ if (!parent) {
39
+ return false;
40
+ }
41
+ if (parent.type === AST_NODE_TYPES.ArrayExpression || parent.type === AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
42
+ return true;
43
+ }
44
+ return isUsedInArrayOrAsArgument(parent);
45
+ }
46
+ function getEnclosingFunction(node) {
47
+ if (node.type === AST_NODE_TYPES.FunctionDeclaration || node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
48
+ return node;
49
+ }
50
+ const parent = getParent(node);
51
+ if (!parent) {
52
+ return;
53
+ }
54
+ return getEnclosingFunction(parent);
55
+ }
56
+ function getTypeParentNode(node) {
57
+ if (!node) {
58
+ return void 0;
59
+ }
60
+ return node.type === AST_NODE_TYPES.TSTypeAnnotation || node.type === AST_NODE_TYPES.TSAsExpression ? node : getTypeParentNode(node.parent);
61
+ }
62
+ export {
63
+ getAncestor,
64
+ getEnclosingFunction,
65
+ getEnclosingScopeNode,
66
+ getEnclosingStatement,
67
+ getParent,
68
+ getTypeParentNode,
69
+ isBlockStatement,
70
+ isUsedInArrayOrAsArgument
71
+ };
72
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2xpYnJhcnkvdHMtdHJlZS50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFRQSxTQUFTLHNCQUFnQztBQVFsQyxTQUFTLFVBQVUsTUFBdUQ7QUFDL0UsU0FBUSxLQUF3QztBQUNsRDtBQUVPLFNBQVMsWUFDZCxNQUNBLFNBQ0EsYUFDMkI7QUFDM0IsUUFBTSxTQUFTLFVBQVUsSUFBSTtBQUM3QixNQUFJLENBQUMsUUFBUTtBQUNYLFdBQU87QUFBQSxFQUNULFdBQVcsT0FBTyxZQUFZLFlBQVksT0FBTyxTQUFTLFNBQVM7QUFDakUsV0FBTztBQUFBLEVBQ1QsV0FBVyxPQUFPLFlBQVksY0FBYyxRQUFRLE1BQU0sR0FBRztBQUMzRCxXQUFPO0FBQUEsRUFDVCxXQUFXLE9BQU8sZ0JBQWdCLFlBQVksT0FBTyxTQUFTLGFBQWE7QUFDekUsV0FBTztBQUFBLEVBQ1QsV0FBVyxPQUFPLGdCQUFnQixjQUFjLFlBQVksTUFBTSxHQUFHO0FBQ25FLFdBQU87QUFBQSxFQUNUO0FBQ0EsU0FBTyxZQUFZLFFBQVEsU0FBUyxXQUFXO0FBQ2pEO0FBRU8sU0FBUyxpQkFBaUIsTUFBcUI7QUFDcEQsU0FBTyxLQUFLLEtBQUssU0FBUyxXQUFXLEtBQUssS0FBSyxLQUFLLFNBQVMsYUFBYTtBQUM1RTtBQUVPLFNBQVMsc0JBQXNCLE1BQXFCO0FBQ3pELFNBQU8sWUFBWSxNQUFNLGdCQUFnQjtBQUMzQztBQUVPLFNBQVMsc0JBQXNCLE1BQXFCO0FBQ3pELFNBQU87QUFBQSxJQUFZO0FBQUEsSUFBTSxDQUFDLGVBQ3hCLENBQUMsc0JBQXNCLHVCQUF1QiwyQkFBMkIsU0FBUyxFQUFFLFNBQVMsV0FBVyxJQUFJO0FBQUEsRUFDOUc7QUFDRjtBQUVPLFNBQVMsMEJBQTBCLE1BQXFCO0FBQzdELE1BQUksaUJBQWlCLElBQUksR0FBRztBQUMxQixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sU0FBUyxVQUFVLElBQUk7QUFDN0IsTUFBSSxDQUFDLFFBQVE7QUFDWCxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQ0UsT0FBTyxTQUFTLGVBQWUsbUJBQzlCLE9BQU8sU0FBUyxlQUFlLGtCQUFrQixPQUFPLFVBQVUsU0FBUyxJQUEyQixHQUN2RztBQUNBLFdBQU87QUFBQSxFQUNUO0FBR0EsU0FBTywwQkFBMEIsTUFBTTtBQUN6QztBQUVPLFNBQVMscUJBQXFCLE1BQXFCO0FBQ3hELE1BQ0UsS0FBSyxTQUFTLGVBQWUsdUJBQzdCLEtBQUssU0FBUyxlQUFlLHNCQUM3QixLQUFLLFNBQVMsZUFBZSx5QkFDN0I7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sU0FBUyxVQUFVLElBQUk7QUFDN0IsTUFBSSxDQUFDLFFBQVE7QUFDWDtBQUFBLEVBQ0Y7QUFDQSxTQUFPLHFCQUFxQixNQUFNO0FBQ3BDO0FBRU8sU0FBUyxrQkFDZCxNQUNpRTtBQUNqRSxNQUFJLENBQUMsTUFBTTtBQUNULFdBQU87QUFBQSxFQUNUO0FBQ0EsU0FBTyxLQUFLLFNBQVMsZUFBZSxvQkFBb0IsS0FBSyxTQUFTLGVBQWUsaUJBQ2pGLE9BQ0Esa0JBQWtCLEtBQUssTUFBTTtBQUNuQzsiLAogICJuYW1lcyI6IFtdCn0K
@@ -1,8 +1,8 @@
1
- // src/fixture/variable.ts
1
+ // src/library/variable.ts
2
2
  function isValidPropertyName(name) {
3
3
  return typeof name === "string" && /^[a-zA-Z_$][a-zA-Z_$0-9]*$/u.test(name);
4
4
  }
5
5
  export {
6
6
  isValidPropertyName
7
7
  };
8
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvdmFyaWFibGUudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRU8sU0FBUyxvQkFBb0IsTUFBZTtBQUNqRCxTQUFPLE9BQU8sU0FBUyxZQUFZLDhCQUE4QixLQUFLLElBQUk7QUFDNUU7IiwKICAibmFtZXMiOiBbXQp9Cg==
8
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2xpYnJhcnkvdmFyaWFibGUudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBRU8sU0FBUyxvQkFBb0IsTUFBZTtBQUNqRCxTQUFPLE9BQU8sU0FBUyxZQUFZLDhCQUE4QixLQUFLLElBQUk7QUFDNUU7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -12,7 +12,6 @@ declare const _default: {
12
12
  "invalid-json-stringify": import("eslint").Rule.RuleModule;
13
13
  "no-promise-instance-method": import("eslint").Rule.RuleModule;
14
14
  "no-fixture": import("eslint").Rule.RuleModule;
15
- "fetch-header-getter": import("eslint").Rule.RuleModule;
16
15
  "fetch-then": import("eslint").Rule.RuleModule;
17
16
  "no-service-wrapper": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "preferNativeFetch" | "invalidOptions", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
18
17
  "no-status-code": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unknownError" | "replaceStatusCode", never[], import("@typescript-eslint/utils/ts-eslint").RuleListener>;
@@ -52,18 +51,17 @@ declare const _default: {
52
51
  "@checkdigit/no-promise-instance-method": string;
53
52
  };
54
53
  };
55
- };
56
- agent: {
57
- rules: {
58
- "@checkdigit/no-fixture": string;
59
- "@checkdigit/fetch-header-getter": string;
60
- "@checkdigit/fetch-then": string;
61
- "@checkdigit/no-service-wrapper": string;
62
- "@checkdigit/no-status-code": string;
63
- "@checkdigit/fetch-response-body-json": string;
64
- "@checkdigit/fetch-response-header-getter-ts": string;
65
- "@checkdigit/add-url-domain": string;
66
- "@checkdigit/no-full-response": string;
54
+ agent: {
55
+ rules: {
56
+ "@checkdigit/no-fixture": string;
57
+ "@checkdigit/fetch-then": string;
58
+ "@checkdigit/no-service-wrapper": string;
59
+ "@checkdigit/no-status-code": string;
60
+ "@checkdigit/fetch-response-body-json": string;
61
+ "@checkdigit/fetch-response-header-getter-ts": string;
62
+ "@checkdigit/add-url-domain": string;
63
+ "@checkdigit/no-full-response": string;
64
+ };
67
65
  };
68
66
  };
69
67
  };
@@ -6,3 +6,4 @@ export declare function getEnclosingStatement(node: TSESTree.Node): TSESTree.Nod
6
6
  export declare function getEnclosingScopeNode(node: TSESTree.Node): TSESTree.Node | undefined;
7
7
  export declare function isUsedInArrayOrAsArgument(node: TSESTree.Node): boolean;
8
8
  export declare function getEnclosingFunction(node: TSESTree.Node): TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression | undefined;
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":"6.6.0-PR.75-49c9","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","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","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 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && 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":"7.18.0","@typescript-eslint/utils":"7.18.0","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/eslint":"^8.56.10","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
1
+ {"name":"@checkdigit/eslint-plugin","version":"6.6.0-PR.75-bbf4","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","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","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 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && 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":"7.18.0","@typescript-eslint/utils":"7.18.0","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/eslint":"^8.56.10","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0","http-status-codes":"^2.3.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
@@ -43,8 +43,8 @@ const rule = createRule({
43
43
  return;
44
44
  }
45
45
 
46
- const urlText = sourceCode.getText(basePathDeclarator.init); /*?*/
47
- const replacement = addBasePathUrlDomain(urlText); /*?*/
46
+ const urlText = sourceCode.getText(basePathDeclarator.init);
47
+ const replacement = addBasePathUrlDomain(urlText);
48
48
 
49
49
  if (replacement !== urlText) {
50
50
  context.report({
@@ -10,6 +10,7 @@ import { AST_NODE_TYPES, ESLintUtils, TSESTree } from '@typescript-eslint/utils'
10
10
  import getDocumentationUrl from '../get-documentation-url';
11
11
 
12
12
  export const ruleId = 'fetch-response-header-getter-ts';
13
+ const HEADER_BUILTIN_FUNCTIONS = Object.keys(Headers.prototype);
13
14
 
14
15
  const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
15
16
 
@@ -34,37 +35,38 @@ const rule = createRule({
34
35
  const sourceCode = context.sourceCode;
35
36
 
36
37
  return {
37
- 'MemberExpression[object.property.name="headers"]': (responseHeadersAccess: TSESTree.MemberExpression) => {
38
+ MemberExpression: (responseHeadersAccess: TSESTree.MemberExpression) => {
38
39
  try {
39
40
  if (
40
41
  responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier &&
41
- responseHeadersAccess.property.name === 'get'
42
+ HEADER_BUILTIN_FUNCTIONS.includes(responseHeadersAccess.property.name)
42
43
  ) {
43
- // getter is already being used
44
+ // skip Headers's built-in function calls
44
45
  return;
45
46
  }
46
47
 
47
48
  const responseHeadersTsNode = parserServices.esTreeNodeToTSNodeMap.get(responseHeadersAccess.object);
48
- const responseType = typeChecker.getTypeAtLocation(responseHeadersTsNode);
49
-
50
- const shouldReplace = responseType.getProperties().some((symbol) => symbol.name === 'get');
51
- if (!shouldReplace) {
49
+ let responseHeadersType = typeChecker.getTypeAtLocation(responseHeadersTsNode);
50
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
51
+ responseHeadersType = responseHeadersType.isUnion() ? responseHeadersType.types[0]! : responseHeadersType;
52
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
53
+ const responseHeadersTypeName = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
54
+ (responseHeadersType.symbol ?? responseHeadersType.aliasSymbol)?.escapedName;
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
56
+ if (responseHeadersTypeName !== 'Headers' && responseHeadersTypeName !== 'HeaderGetter') {
52
57
  return;
53
58
  }
54
59
 
55
- // let replacementText = 'xxx';
56
- // if (responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier) {
57
- // replacementText = `${sourceCode.getText(responseHeadersAccess.object)}.get(${sourceCode.getText(responseHeadersAccess.property)})`;
58
- // }
59
60
  let replacementText: string;
60
- if (responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier) {
61
- replacementText = `${sourceCode.getText(responseHeadersAccess.object)}.get(${sourceCode.getText(responseHeadersAccess.property)})`;
62
- } else if (responseHeadersAccess.property.type === AST_NODE_TYPES.TemplateLiteral) {
61
+ if (!responseHeadersAccess.computed) {
62
+ // e.g. headers.etag
63
+ replacementText = `${sourceCode.getText(responseHeadersAccess.object)}.get('${sourceCode.getText(responseHeadersAccess.property)}')`;
64
+ } else if (
65
+ responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier ||
66
+ responseHeadersAccess.property.type === AST_NODE_TYPES.Literal ||
67
+ responseHeadersAccess.property.type === AST_NODE_TYPES.TemplateLiteral
68
+ ) {
63
69
  replacementText = `${sourceCode.getText(responseHeadersAccess.object)}.get(${sourceCode.getText(responseHeadersAccess.property)})`;
64
- } else if (responseHeadersAccess.property.type === AST_NODE_TYPES.Literal) {
65
- replacementText = responseHeadersAccess.computed
66
- ? `${sourceCode.getText(responseHeadersAccess.object)}.get(${sourceCode.getText(responseHeadersAccess.property)})`
67
- : `${sourceCode.getText(responseHeadersAccess.object)}.get('${sourceCode.getText(responseHeadersAccess.property)}')`;
68
70
  } else {
69
71
  throw new Error(`Unexpected property type: ${responseHeadersAccess.property.type}`);
70
72
  }
@@ -89,14 +91,21 @@ const rule = createRule({
89
91
  });
90
92
  }
91
93
  },
92
- 'CallExpression[callee.property.name="get"]:not([callee.object.name="request"])': (
93
- responseHeadersAccess: TSESTree.CallExpression,
94
- ) => {
94
+
95
+ // convert response.get() to response.headers.get()
96
+ 'CallExpression[callee.property.name="get"]': (responseHeadersAccess: TSESTree.CallExpression) => {
95
97
  try {
96
98
  if (responseHeadersAccess.callee.type !== AST_NODE_TYPES.MemberExpression) {
97
99
  return;
98
100
  }
99
101
 
102
+ // skip request-like calls
103
+ if (
104
+ responseHeadersAccess.callee.object.type !== AST_NODE_TYPES.Identifier ||
105
+ responseHeadersAccess.callee.object.name === 'request'
106
+ ) {
107
+ return;
108
+ }
100
109
  const responseNode = responseHeadersAccess.callee.object;
101
110
  const responseHeadersTsNode = parserServices.esTreeNodeToTSNodeMap.get(responseNode);
102
111
  const responseType = typeChecker.getTypeAtLocation(responseHeadersTsNode);
@@ -104,6 +113,8 @@ const rule = createRule({
104
113
  if (typeName === 'InboundContext' || typeName.endsWith('RequestType')) {
105
114
  return;
106
115
  }
116
+
117
+ // make sure the response type has "headers" property
107
118
  const hasHeadersProperty = responseType.getProperties().some((symbol) => symbol.name === 'headers');
108
119
  if (!hasHeadersProperty) {
109
120
  return;
@@ -8,12 +8,12 @@
8
8
 
9
9
  import type { CallExpression, Expression, MemberExpression, SimpleCallExpression } from 'estree';
10
10
  import { type Rule, type Scope, SourceCode } from 'eslint';
11
- import { getEnclosingFunction, getEnclosingStatement, getParent, isUsedInArrayOrAsArgument } from '../ast/tree';
11
+ import { getEnclosingFunction, getEnclosingStatement, getParent, isUsedInArrayOrAsArgument } from '../library/tree';
12
12
  import { hasAssertions, isInvalidResponseHeadersAccess } from './fetch';
13
13
  import { strict as assert } from 'node:assert';
14
14
  import getDocumentationUrl from '../get-documentation-url';
15
- import { getIndentation } from '../ast/format';
16
- import { isValidPropertyName } from './variable';
15
+ import { getIndentation } from '../library/format';
16
+ import { isValidPropertyName } from '../library/variable';
17
17
  import { replaceEndpointUrlPrefixWithBasePath } from './url';
18
18
 
19
19
  export const ruleId = 'fetch-then';
@@ -1,6 +1,6 @@
1
1
  // fixture/fetch.ts
2
2
 
3
- import { getParent, isBlockStatement } from '../ast/tree';
3
+ import { getParent, isBlockStatement } from '../library/tree';
4
4
  import type { Node } from 'estree';
5
5
 
6
6
  export function getResponseBodyRetrievalText(responseVariableName: string) {
@@ -23,13 +23,13 @@ import {
23
23
  getEnclosingStatement,
24
24
  getParent,
25
25
  isUsedInArrayOrAsArgument,
26
- } from '../ast/tree';
26
+ } from '../library/tree';
27
27
  import { getResponseBodyRetrievalText, hasAssertions } from './fetch';
28
28
  import { analyzeResponseReferences } from './response-reference';
29
29
  import { strict as assert } from 'node:assert';
30
30
  import getDocumentationUrl from '../get-documentation-url';
31
- import { getIndentation } from '../ast/format';
32
- import { isValidPropertyName } from './variable';
31
+ import { getIndentation } from '../library/format';
32
+ import { isValidPropertyName } from '../library/variable';
33
33
  import { replaceEndpointUrlPrefixWithBasePath } from './url';
34
34
 
35
35
  export const ruleId = 'no-fixture';
@@ -9,7 +9,7 @@
9
9
  import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';
10
10
  import { strict as assert } from 'node:assert';
11
11
  import getDocumentationUrl from '../get-documentation-url';
12
- import { getTypeParentNode } from './ts-tree';
12
+ import { getTypeParentNode } from '../library/ts-tree';
13
13
 
14
14
  export const ruleId = 'no-full-response';
15
15
 
@@ -11,8 +11,8 @@ import { DefinitionType, type Scope } from '@typescript-eslint/scope-manager';
11
11
  import { PLAIN_URL_REGEXP, TOKENIZED_URL_REGEXP, replaceEndpointUrlPrefixWithDomain } from './url';
12
12
  import { strict as assert } from 'node:assert';
13
13
  import getDocumentationUrl from '../get-documentation-url';
14
- import { getEnclosingScopeNode } from '../ast/ts-tree';
15
- import { getIndentation } from '../ast/format';
14
+ import { getEnclosingScopeNode } from '../library/ts-tree';
15
+ import { getIndentation } from '../library/format';
16
16
 
17
17
  export const ruleId = 'no-service-wrapper';
18
18
 
@@ -9,7 +9,7 @@
9
9
  import type { MemberExpression, VariableDeclaration } from 'estree';
10
10
  import { type Scope } from 'eslint';
11
11
  import { strict as assert } from 'node:assert';
12
- import { getParent } from '../ast/tree';
12
+ import { getParent } from '../library/tree';
13
13
 
14
14
  /**
15
15
  * analyze response related variables and their references
package/src/index.ts CHANGED
@@ -6,19 +6,18 @@
6
6
  * This code is licensed under the MIT license (see LICENSE.txt for details).
7
7
  */
8
8
 
9
- import addUrlDomain, { ruleId as addUrlDomainRuleId } from './fixture/add-url-domain';
10
- import fetchHeaderGetter, { ruleId as fetchHeaderGetterRuleId } from './fixture/fetch-header-getter';
11
- import fetchResponseBodyJson, { ruleId as fetchResponseBodyJsonRuleId } from './fixture/fetch-response-body-json';
12
- import fetchResponseHeaderGetterTs, {
13
- ruleId as fetchResponseHeaderGetterTsRuleId,
14
- } from './fixture/fetch-response-header-getter-ts';
15
- import fetchThen, { ruleId as fetchThenRuleId } from './fixture/fetch-then';
9
+ import addUrlDomain, { ruleId as addUrlDomainRuleId } from './agent/add-url-domain';
10
+ import fetchResponseBodyJson, { ruleId as fetchResponseBodyJsonRuleId } from './agent/fetch-response-body-json';
11
+ import fetchResponseHeaderGetter, {
12
+ ruleId as fetchResponseHeaderGetterRuleId,
13
+ } from './agent/fetch-response-header-getter';
14
+ import fetchThen, { ruleId as fetchThenRuleId } from './agent/fetch-then';
16
15
  import invalidJsonStringify, { ruleId as invalidJsonStringifyRuleId } from './invalid-json-stringify';
17
- import noFixture, { ruleId as noFixtureRuleId } from './fixture/no-fixture';
18
- import noFullResponse, { ruleId as noFullResponseRuleId } from './fixture/no-full-response';
16
+ import noFixture, { ruleId as noFixtureRuleId } from './agent/no-fixture';
17
+ import noFullResponse, { ruleId as noFullResponseRuleId } from './agent/no-full-response';
19
18
  import noPromiseInstanceMethod, { ruleId as noPromiseInstanceMethodRuleId } from './no-promise-instance-method';
20
- import noServiceWrapper, { ruleId as noServiceWrapperRuleId } from './fixture/no-service-wrapper';
21
- import noStatusCode, { ruleId as noStatusCodeRuleId } from './fixture/no-status-code';
19
+ import noServiceWrapper, { ruleId as noServiceWrapperRuleId } from './agent/no-service-wrapper';
20
+ import noStatusCode, { ruleId as noStatusCodeRuleId } from './agent/no-status-code';
22
21
  import filePathComment from './file-path-comment';
23
22
  import noCardNumbers from './no-card-numbers';
24
23
  import noTestImport from './no-test-import';
@@ -43,12 +42,11 @@ export default {
43
42
  [invalidJsonStringifyRuleId]: invalidJsonStringify,
44
43
  [noPromiseInstanceMethodRuleId]: noPromiseInstanceMethod,
45
44
  [noFixtureRuleId]: noFixture,
46
- [fetchHeaderGetterRuleId]: fetchHeaderGetter,
47
45
  [fetchThenRuleId]: fetchThen,
48
46
  [noServiceWrapperRuleId]: noServiceWrapper,
49
47
  [noStatusCodeRuleId]: noStatusCode,
50
48
  [fetchResponseBodyJsonRuleId]: fetchResponseBodyJson,
51
- [fetchResponseHeaderGetterTsRuleId]: fetchResponseHeaderGetterTs,
49
+ [fetchResponseHeaderGetterRuleId]: fetchResponseHeaderGetter,
52
50
  [addUrlDomainRuleId]: addUrlDomain,
53
51
  [noFullResponseRuleId]: noFullResponse,
54
52
  },
@@ -83,18 +81,17 @@ export default {
83
81
  [`@checkdigit/${noPromiseInstanceMethodRuleId}`]: 'error',
84
82
  },
85
83
  },
86
- },
87
- agent: {
88
- rules: {
89
- [`@checkdigit/${noFixtureRuleId}`]: 'error',
90
- [`@checkdigit/${fetchHeaderGetterRuleId}`]: 'error',
91
- [`@checkdigit/${fetchThenRuleId}`]: 'error',
92
- [`@checkdigit/${noServiceWrapperRuleId}`]: 'error',
93
- [`@checkdigit/${noStatusCodeRuleId}`]: 'error',
94
- [`@checkdigit/${fetchResponseBodyJsonRuleId}`]: 'error',
95
- [`@checkdigit/${fetchResponseHeaderGetterTsRuleId}`]: 'error',
96
- [`@checkdigit/${addUrlDomainRuleId}`]: 'error',
97
- [`@checkdigit/${noFullResponseRuleId}`]: 'error',
84
+ agent: {
85
+ rules: {
86
+ [`@checkdigit/${noFixtureRuleId}`]: 'error',
87
+ [`@checkdigit/${fetchThenRuleId}`]: 'error',
88
+ [`@checkdigit/${noServiceWrapperRuleId}`]: 'error',
89
+ [`@checkdigit/${noStatusCodeRuleId}`]: 'error',
90
+ [`@checkdigit/${fetchResponseBodyJsonRuleId}`]: 'error',
91
+ [`@checkdigit/${fetchResponseHeaderGetterRuleId}`]: 'error',
92
+ [`@checkdigit/${addUrlDomainRuleId}`]: 'error',
93
+ [`@checkdigit/${noFullResponseRuleId}`]: 'error',
94
+ },
98
95
  },
99
96
  },
100
97
  };
@@ -88,3 +88,14 @@ export function getEnclosingFunction(node: TSESTree.Node) {
88
88
  }
89
89
  return getEnclosingFunction(parent);
90
90
  }
91
+
92
+ export function getTypeParentNode(
93
+ node: TSESTree.Node | undefined,
94
+ ): TSESTree.TSTypeAnnotation | TSESTree.TSAsExpression | undefined {
95
+ if (!node) {
96
+ return undefined;
97
+ }
98
+ return node.type === AST_NODE_TYPES.TSTypeAnnotation || node.type === AST_NODE_TYPES.TSAsExpression
99
+ ? node
100
+ : getTypeParentNode(node.parent);
101
+ }
@@ -1,14 +0,0 @@
1
- // src/ast/format.ts
2
- import "@typescript-eslint/utils";
3
- import { strict as assert } from "node:assert";
4
- function getIndentation(node, sourceCode) {
5
- assert.ok(node.loc);
6
- const line = sourceCode.lines[node.loc.start.line - 1];
7
- assert.ok(line !== void 0);
8
- const indentMatch = line.match(/^\s*/u);
9
- return indentMatch ? indentMatch[0] : "";
10
- }
11
- export {
12
- getIndentation
13
- };
14
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FzdC9mb3JtYXQudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBUUEsT0FBbUM7QUFHbkMsU0FBUyxVQUFVLGNBQWM7QUFFMUIsU0FBUyxlQUFlLE1BQTRCLFlBQThDO0FBQ3ZHLFNBQU8sR0FBRyxLQUFLLEdBQUc7QUFDbEIsUUFBTSxPQUFPLFdBQVcsTUFBTSxLQUFLLElBQUksTUFBTSxPQUFPLENBQUM7QUFDckQsU0FBTyxHQUFHLFNBQVMsTUFBUztBQUM1QixRQUFNLGNBQWMsS0FBSyxNQUFNLE9BQU87QUFDdEMsU0FBTyxjQUFjLFlBQVksQ0FBQyxJQUFJO0FBQ3hDOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -1,65 +0,0 @@
1
- // src/ast/ts-tree.ts
2
- import { AST_NODE_TYPES } from "@typescript-eslint/utils";
3
- function getParent(node) {
4
- return node.parent;
5
- }
6
- function getAncestor(node, matcher, exitMatcher) {
7
- const parent = getParent(node);
8
- if (!parent) {
9
- return void 0;
10
- } else if (typeof matcher === "string" && parent.type === matcher) {
11
- return parent;
12
- } else if (typeof matcher === "function" && matcher(parent)) {
13
- return parent;
14
- } else if (typeof exitMatcher === "string" && parent.type === exitMatcher) {
15
- return void 0;
16
- } else if (typeof exitMatcher === "function" && exitMatcher(parent)) {
17
- return void 0;
18
- }
19
- return getAncestor(parent, matcher, exitMatcher);
20
- }
21
- function isBlockStatement(node) {
22
- return node.type.endsWith("Statement") || node.type.endsWith("Declaration");
23
- }
24
- function getEnclosingStatement(node) {
25
- return getAncestor(node, isBlockStatement);
26
- }
27
- function getEnclosingScopeNode(node) {
28
- return getAncestor(
29
- node,
30
- (parentNode) => ["FunctionExpression", "FunctionDeclaration", "ArrowFunctionExpression", "Program"].includes(parentNode.type)
31
- );
32
- }
33
- function isUsedInArrayOrAsArgument(node) {
34
- if (isBlockStatement(node)) {
35
- return false;
36
- }
37
- const parent = getParent(node);
38
- if (!parent) {
39
- return false;
40
- }
41
- if (parent.type === AST_NODE_TYPES.ArrayExpression || parent.type === AST_NODE_TYPES.CallExpression && parent.arguments.includes(node)) {
42
- return true;
43
- }
44
- return isUsedInArrayOrAsArgument(parent);
45
- }
46
- function getEnclosingFunction(node) {
47
- if (node.type === AST_NODE_TYPES.FunctionDeclaration || node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
48
- return node;
49
- }
50
- const parent = getParent(node);
51
- if (!parent) {
52
- return;
53
- }
54
- return getEnclosingFunction(parent);
55
- }
56
- export {
57
- getAncestor,
58
- getEnclosingFunction,
59
- getEnclosingScopeNode,
60
- getEnclosingStatement,
61
- getParent,
62
- isBlockStatement,
63
- isUsedInArrayOrAsArgument
64
- };
65
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FzdC90cy10cmVlLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsc0JBQWdDO0FBUWxDLFNBQVMsVUFBVSxNQUF1RDtBQUMvRSxTQUFRLEtBQXdDO0FBQ2xEO0FBRU8sU0FBUyxZQUNkLE1BQ0EsU0FDQSxhQUMyQjtBQUMzQixRQUFNLFNBQVMsVUFBVSxJQUFJO0FBQzdCLE1BQUksQ0FBQyxRQUFRO0FBQ1gsV0FBTztBQUFBLEVBQ1QsV0FBVyxPQUFPLFlBQVksWUFBWSxPQUFPLFNBQVMsU0FBUztBQUNqRSxXQUFPO0FBQUEsRUFDVCxXQUFXLE9BQU8sWUFBWSxjQUFjLFFBQVEsTUFBTSxHQUFHO0FBQzNELFdBQU87QUFBQSxFQUNULFdBQVcsT0FBTyxnQkFBZ0IsWUFBWSxPQUFPLFNBQVMsYUFBYTtBQUN6RSxXQUFPO0FBQUEsRUFDVCxXQUFXLE9BQU8sZ0JBQWdCLGNBQWMsWUFBWSxNQUFNLEdBQUc7QUFDbkUsV0FBTztBQUFBLEVBQ1Q7QUFDQSxTQUFPLFlBQVksUUFBUSxTQUFTLFdBQVc7QUFDakQ7QUFFTyxTQUFTLGlCQUFpQixNQUFxQjtBQUNwRCxTQUFPLEtBQUssS0FBSyxTQUFTLFdBQVcsS0FBSyxLQUFLLEtBQUssU0FBUyxhQUFhO0FBQzVFO0FBRU8sU0FBUyxzQkFBc0IsTUFBcUI7QUFDekQsU0FBTyxZQUFZLE1BQU0sZ0JBQWdCO0FBQzNDO0FBRU8sU0FBUyxzQkFBc0IsTUFBcUI7QUFDekQsU0FBTztBQUFBLElBQVk7QUFBQSxJQUFNLENBQUMsZUFDeEIsQ0FBQyxzQkFBc0IsdUJBQXVCLDJCQUEyQixTQUFTLEVBQUUsU0FBUyxXQUFXLElBQUk7QUFBQSxFQUM5RztBQUNGO0FBRU8sU0FBUywwQkFBMEIsTUFBcUI7QUFDN0QsTUFBSSxpQkFBaUIsSUFBSSxHQUFHO0FBQzFCLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxTQUFTLFVBQVUsSUFBSTtBQUM3QixNQUFJLENBQUMsUUFBUTtBQUNYLFdBQU87QUFBQSxFQUNUO0FBRUEsTUFDRSxPQUFPLFNBQVMsZUFBZSxtQkFDOUIsT0FBTyxTQUFTLGVBQWUsa0JBQWtCLE9BQU8sVUFBVSxTQUFTLElBQTJCLEdBQ3ZHO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFHQSxTQUFPLDBCQUEwQixNQUFNO0FBQ3pDO0FBRU8sU0FBUyxxQkFBcUIsTUFBcUI7QUFDeEQsTUFDRSxLQUFLLFNBQVMsZUFBZSx1QkFDN0IsS0FBSyxTQUFTLGVBQWUsc0JBQzdCLEtBQUssU0FBUyxlQUFlLHlCQUM3QjtBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxTQUFTLFVBQVUsSUFBSTtBQUM3QixNQUFJLENBQUMsUUFBUTtBQUNYO0FBQUEsRUFDRjtBQUNBLFNBQU8scUJBQXFCLE1BQU07QUFDcEM7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -1,71 +0,0 @@
1
- // src/fixture/fetch-header-getter.ts
2
- import { analyzeResponseReferences } from "./response-reference.mjs";
3
- import { strict as assert } from "node:assert";
4
- import getDocumentationUrl from "../get-documentation-url.mjs";
5
- import { getParent } from "../ast/tree.mjs";
6
- import { isInvalidResponseHeadersAccess } from "./fetch.mjs";
7
- var ruleId = "fetch-header-getter";
8
- var rule = {
9
- meta: {
10
- type: "problem",
11
- docs: {
12
- description: "Make sure getter is used to access response headers.",
13
- url: getDocumentationUrl(ruleId)
14
- },
15
- messages: {
16
- shouldUseHeaderGetter: "Getter should be used to access response headers."
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- create(context) {
22
- const sourceCode = context.sourceCode;
23
- const scopeManager = sourceCode.scopeManager;
24
- return {
25
- 'VariableDeclarator[init.argument.callee.name="fetch"]': (fetchCall) => {
26
- const variableDeclaration = getParent(fetchCall);
27
- assert.ok(variableDeclaration?.type === "VariableDeclaration");
28
- const { variable: responseVariable, headersReferences: responseHeadersReferences } = analyzeResponseReferences(
29
- variableDeclaration,
30
- scopeManager
31
- );
32
- assert.ok(responseVariable);
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) => {
38
- const headersVariable = responseVariable.scope.variables.find((variable) => {
39
- const identifier = variable.identifiers[0];
40
- return identifier?.type === "Identifier" && identifier.name === redefinedHeadersVariableName;
41
- });
42
- return headersVariable?.references.map((reference) => reference.identifier) ?? [];
43
- }).flat();
44
- const invalidHeadersReferences = [...directHeadersReferences, ...indirectHeadersReferences].filter(
45
- isInvalidResponseHeadersAccess
46
- );
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
- }
61
- });
62
- }
63
- };
64
- }
65
- };
66
- var fetch_header_getter_default = rule;
67
- export {
68
- fetch_header_getter_default as default,
69
- ruleId
70
- };
71
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvZmV0Y2gtaGVhZGVyLWdldHRlci50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFVQSxTQUFTLGlDQUFpQztBQUMxQyxTQUFTLFVBQVUsY0FBYztBQUNqQyxPQUFPLHlCQUF5QjtBQUNoQyxTQUFTLGlCQUFpQjtBQUMxQixTQUFTLHNDQUFzQztBQUV4QyxJQUFNLFNBQVM7QUFFdEIsSUFBTSxPQUF3QjtBQUFBLEVBQzVCLE1BQU07QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxNQUNKLGFBQWE7QUFBQSxNQUNiLEtBQUssb0JBQW9CLE1BQU07QUFBQSxJQUNqQztBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsdUJBQXVCO0FBQUEsSUFDekI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLE9BQU8sU0FBUztBQUNkLFVBQU0sYUFBYSxRQUFRO0FBQzNCLFVBQU0sZUFBZSxXQUFXO0FBRWhDLFdBQU87QUFBQSxNQUNMLHlEQUF5RCxDQUFDLGNBQWtDO0FBQzFGLGNBQU0sc0JBQXNCLFVBQVUsU0FBUztBQUMvQyxlQUFPLEdBQUcscUJBQXFCLFNBQVMscUJBQXFCO0FBQzdELGNBQU0sRUFBRSxVQUFVLGtCQUFrQixtQkFBbUIsMEJBQTBCLElBQUk7QUFBQSxVQUNuRjtBQUFBLFVBQ0E7QUFBQSxRQUNGO0FBQ0EsZUFBTyxHQUFHLGdCQUFnQjtBQUUxQixjQUFNLDBCQUEwQiwwQkFBMEIsT0FBTyxDQUFDLHFCQUFxQjtBQUNyRixnQkFBTSxnQkFBZ0IsVUFBVSxnQkFBZ0I7QUFDaEQsaUJBQU8sZUFBZSxTQUFTO0FBQUEsUUFDakMsQ0FBQztBQUVELGNBQU0sNEJBQTRCLDBCQUMvQixJQUFJLFNBQVMsRUFDYixPQUFPLENBQUMsV0FBeUMsUUFBUSxTQUFTLG9CQUFvQixFQUN0RixJQUFJLENBQUMsZUFBZ0IsV0FBVyxHQUFrQixJQUFJLEVBQ3RELElBQUksQ0FBQyxpQ0FBaUM7QUFDckMsZ0JBQU0sa0JBQWtCLGlCQUFpQixNQUFNLFVBQVUsS0FBSyxDQUFDLGFBQWE7QUFDMUUsa0JBQU0sYUFBYSxTQUFTLFlBQVksQ0FBQztBQUN6QyxtQkFBTyxZQUFZLFNBQVMsZ0JBQWdCLFdBQVcsU0FBUztBQUFBLFVBQ2xFLENBQUM7QUFDRCxpQkFBTyxpQkFBaUIsV0FBVyxJQUFJLENBQUMsY0FBYyxVQUFVLFVBQVUsS0FBSyxDQUFDO0FBQUEsUUFDbEYsQ0FBQyxFQUNBLEtBQUs7QUFFUixjQUFNLDJCQUEyQixDQUFDLEdBQUcseUJBQXlCLEdBQUcseUJBQXlCLEVBQUU7QUFBQSxVQUMxRjtBQUFBLFFBQ0Y7QUFFQSxpQ0FBeUIsUUFBUSxDQUFDLHFCQUFxQjtBQUNyRCxnQkFBTSxlQUFlLFVBQVUsZ0JBQWdCO0FBQy9DLGNBQUksY0FBYyxTQUFTLG9CQUFvQjtBQUM3QyxrQkFBTSxpQkFBaUIsYUFBYTtBQUNwQyxrQkFBTSxhQUFhLGFBQWEsV0FDNUIsV0FBVyxRQUFRLGNBQWMsSUFDakMsSUFBSSxXQUFXLFFBQVEsY0FBYyxDQUFDO0FBQzFDLGtCQUFNLGtCQUFrQixHQUFHLFdBQVcsUUFBUSxhQUFhLE1BQU0sQ0FBQyxRQUFRLFVBQVU7QUFFcEYsb0JBQVEsT0FBTztBQUFBLGNBQ2IsTUFBTTtBQUFBLGNBQ04sV0FBVztBQUFBLGNBQ1gsSUFBSSxPQUFPO0FBQ1QsdUJBQU8sTUFBTSxZQUFZLGNBQWMsZUFBZTtBQUFBLGNBQ3hEO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGO0FBRUEsSUFBTyw4QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K