UNPKG

1.96 kBJavaScriptView Raw
1'use strict'
2
3const getDocsUrl = require('./lib/get-docs-url')
4
5module.exports = {
6 meta: {
7 docs: {
8 url: getDocsUrl('prefer-await-to-callbacks')
9 },
10 messages: {
11 error: 'Avoid callbacks. Prefer Async/Await.'
12 }
13 },
14 create(context) {
15 function checkLastParamsForCallback(node) {
16 const lastParam = node.params[node.params.length - 1] || {}
17 if (lastParam.name === 'callback' || lastParam.name === 'cb') {
18 context.report({ node: lastParam, messageId: 'error' })
19 }
20 }
21 function isInsideYieldOrAwait() {
22 return context.getAncestors().some(parent => {
23 return (
24 parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
25 )
26 })
27 }
28 return {
29 CallExpression(node) {
30 // Callbacks aren't allowed.
31 if (node.callee.name === 'cb' || node.callee.name === 'callback') {
32 context.report({ node, messageId: 'error' })
33 return
34 }
35
36 // Then-ables aren't allowed either.
37 const args = node.arguments
38 const lastArgIndex = args.length - 1
39 const arg = lastArgIndex > -1 && node.arguments[lastArgIndex]
40 if (
41 (arg && arg.type === 'FunctionExpression') ||
42 arg.type === 'ArrowFunctionExpression'
43 ) {
44 // Ignore event listener callbacks.
45 if (
46 node.callee.property &&
47 (node.callee.property.name === 'on' ||
48 node.callee.property.name === 'once')
49 ) {
50 return
51 }
52 if (arg.params && arg.params[0] && arg.params[0].name === 'err') {
53 if (!isInsideYieldOrAwait()) {
54 context.report({ node: arg, messageId: 'error' })
55 }
56 }
57 }
58 },
59 FunctionDeclaration: checkLastParamsForCallback,
60 FunctionExpression: checkLastParamsForCallback,
61 ArrowFunctionExpression: checkLastParamsForCallback
62 }
63 }
64}