await-async-query.js 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RULE_NAME = void 0;
  4. const utils_1 = require("@typescript-eslint/utils");
  5. const create_testing_library_rule_1 = require("../create-testing-library-rule");
  6. const node_utils_1 = require("../node-utils");
  7. exports.RULE_NAME = 'await-async-query';
  8. exports.default = (0, create_testing_library_rule_1.createTestingLibraryRule)({
  9. name: exports.RULE_NAME,
  10. meta: {
  11. type: 'problem',
  12. docs: {
  13. description: 'Enforce promises from async queries to be handled',
  14. recommendedConfig: {
  15. dom: 'error',
  16. angular: 'error',
  17. react: 'error',
  18. vue: 'error',
  19. marko: 'error',
  20. },
  21. },
  22. messages: {
  23. awaitAsyncQuery: 'promise returned from `{{ name }}` query must be handled',
  24. asyncQueryWrapper: 'promise returned from `{{ name }}` wrapper over async query must be handled',
  25. },
  26. schema: [],
  27. },
  28. defaultOptions: [],
  29. create(context, _, helpers) {
  30. const functionWrappersNames = [];
  31. function detectAsyncQueryWrapper(node) {
  32. const innerFunction = (0, node_utils_1.getInnermostReturningFunction)(context, node);
  33. if (innerFunction) {
  34. functionWrappersNames.push((0, node_utils_1.getFunctionName)(innerFunction));
  35. }
  36. }
  37. return {
  38. CallExpression(node) {
  39. const identifierNode = (0, node_utils_1.getDeepestIdentifierNode)(node);
  40. if (!identifierNode) {
  41. return;
  42. }
  43. if (helpers.isAsyncQuery(identifierNode)) {
  44. detectAsyncQueryWrapper(identifierNode);
  45. const closestCallExpressionNode = (0, node_utils_1.findClosestCallExpressionNode)(node, true);
  46. if (!(closestCallExpressionNode === null || closestCallExpressionNode === void 0 ? void 0 : closestCallExpressionNode.parent)) {
  47. return;
  48. }
  49. const references = (0, node_utils_1.getVariableReferences)(context, closestCallExpressionNode.parent);
  50. if (references.length === 0) {
  51. if (!(0, node_utils_1.isPromiseHandled)(identifierNode)) {
  52. context.report({
  53. node: identifierNode,
  54. messageId: 'awaitAsyncQuery',
  55. data: { name: identifierNode.name },
  56. });
  57. return;
  58. }
  59. }
  60. for (const reference of references) {
  61. if (utils_1.ASTUtils.isIdentifier(reference.identifier) &&
  62. !(0, node_utils_1.isPromiseHandled)(reference.identifier)) {
  63. context.report({
  64. node: identifierNode,
  65. messageId: 'awaitAsyncQuery',
  66. data: { name: identifierNode.name },
  67. });
  68. return;
  69. }
  70. }
  71. }
  72. else if (functionWrappersNames.includes(identifierNode.name) &&
  73. !(0, node_utils_1.isPromiseHandled)(identifierNode)) {
  74. context.report({
  75. node: identifierNode,
  76. messageId: 'asyncQueryWrapper',
  77. data: { name: identifierNode.name },
  78. });
  79. }
  80. },
  81. };
  82. },
  83. });