1 | 'use strict'
|
2 |
|
3 | const getDocsUrl = require('./lib/get-docs-url')
|
4 |
|
5 | module.exports = {
|
6 | meta: {
|
7 | type: 'suggestion',
|
8 | docs: {
|
9 | url: getDocsUrl('prefer-await-to-callbacks'),
|
10 | },
|
11 | messages: {
|
12 | error: 'Avoid callbacks. Prefer Async/Await.',
|
13 | },
|
14 | schema: [],
|
15 | },
|
16 | create(context) {
|
17 | function checkLastParamsForCallback(node) {
|
18 | const lastParam = node.params[node.params.length - 1] || {}
|
19 | if (lastParam.name === 'callback' || lastParam.name === 'cb') {
|
20 | context.report({ node: lastParam, messageId: 'error' })
|
21 | }
|
22 | }
|
23 | function isInsideYieldOrAwait() {
|
24 | return context.getAncestors().some((parent) => {
|
25 | return (
|
26 | parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
|
27 | )
|
28 | })
|
29 | }
|
30 | return {
|
31 | CallExpression(node) {
|
32 |
|
33 | if (node.callee.name === 'cb' || node.callee.name === 'callback') {
|
34 | context.report({ node, messageId: 'error' })
|
35 | return
|
36 | }
|
37 |
|
38 |
|
39 | const args = node.arguments
|
40 | const lastArgIndex = args.length - 1
|
41 | const arg = lastArgIndex > -1 && node.arguments[lastArgIndex]
|
42 | if (
|
43 | (arg && arg.type === 'FunctionExpression') ||
|
44 | arg.type === 'ArrowFunctionExpression'
|
45 | ) {
|
46 |
|
47 | if (
|
48 | node.callee.property &&
|
49 | (node.callee.property.name === 'on' ||
|
50 | node.callee.property.name === 'once')
|
51 | ) {
|
52 | return
|
53 | }
|
54 |
|
55 |
|
56 | const arrayMethods = [
|
57 | 'map',
|
58 | 'every',
|
59 | 'forEach',
|
60 | 'some',
|
61 | 'find',
|
62 | 'filter',
|
63 | ]
|
64 | const isLodash =
|
65 | node.callee.object &&
|
66 | ['lodash', 'underscore', '_'].includes(node.callee.object.name)
|
67 | const callsArrayMethod =
|
68 | node.callee.property &&
|
69 | arrayMethods.includes(node.callee.property.name) &&
|
70 | (node.arguments.length === 1 ||
|
71 | (node.arguments.length === 2 && isLodash))
|
72 | const isArrayMethod =
|
73 | node.callee.name &&
|
74 | arrayMethods.includes(node.callee.name) &&
|
75 | node.arguments.length === 2
|
76 | if (callsArrayMethod || isArrayMethod) return
|
77 |
|
78 |
|
79 | if (
|
80 | arg.params &&
|
81 | arg.params[0] &&
|
82 | (arg.params[0].name === 'err' || arg.params[0].name === 'error')
|
83 | ) {
|
84 | if (!isInsideYieldOrAwait()) {
|
85 | context.report({ node: arg, messageId: 'error' })
|
86 | }
|
87 | }
|
88 | }
|
89 | },
|
90 | FunctionDeclaration: checkLastParamsForCallback,
|
91 | FunctionExpression: checkLastParamsForCallback,
|
92 | ArrowFunctionExpression: checkLastParamsForCallback,
|
93 | }
|
94 | },
|
95 | }
|