Skip to content

Commit 550524f

Browse files
authored
feat(no-promise-in-callback): add exemptDeclarations option (#513)
1 parent 7219528 commit 550524f

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

__tests__/no-promise-in-callback.js

+13
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ ruleTester.run('no-promise-in-callback', rule, {
3838

3939
// weird case, we assume it's not a big deal if you return (even though you may be cheating)
4040
'a(function(err) { return doThing().then(a) })',
41+
42+
{
43+
code: `
44+
function fn(err) {
45+
return { promise: Promise.resolve(err) };
46+
}
47+
`,
48+
options: [
49+
{
50+
exemptDeclarations: true,
51+
},
52+
],
53+
},
4154
],
4255

4356
invalid: [

docs/rules/no-promise-in-callback.md

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ promisify(doSomething)()
3030
.catch(console.error)
3131
```
3232

33+
## Options
34+
35+
### `exemptDeclarations`
36+
37+
Whether or not to exempt function declarations. Defaults to `false`.
38+
3339
## When Not To Use It
3440

3541
If you do not want to be notified when using promises inside of callbacks, you

rules/lib/is-inside-callback.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
const isInsidePromise = require('./is-inside-promise')
44

5-
function isInsideCallback(node) {
5+
/**
6+
* @param {import('eslint').Rule.Node} node
7+
* @param {boolean} [exemptDeclarations]
8+
*/
9+
function isInsideCallback(node, exemptDeclarations) {
610
const isFunction =
711
node.type === 'FunctionExpression' ||
812
node.type === 'ArrowFunctionExpression' ||
9-
node.type === 'FunctionDeclaration' // this may be controversial
13+
(!exemptDeclarations && node.type === 'FunctionDeclaration') // this may be controversial
1014

1115
// it's totally fine to use promises inside promises
1216
if (isInsidePromise(node)) return

rules/no-promise-in-callback.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,23 @@ module.exports = {
1717
description: 'Disallow using promises inside of callbacks.',
1818
url: getDocsUrl('no-promise-in-callback'),
1919
},
20-
schema: [],
20+
schema: [
21+
{
22+
type: 'object',
23+
properties: {
24+
exemptDeclarations: {
25+
type: 'boolean',
26+
},
27+
},
28+
additionalProperties: false,
29+
},
30+
],
2131
messages: {
2232
avoidPromiseInCallback: 'Avoid using promises inside of callbacks.',
2333
},
2434
},
2535
create(context) {
36+
const { exemptDeclarations = false } = context.options[0] || {}
2637
return {
2738
CallExpression(node) {
2839
if (!isPromise(node)) return
@@ -34,7 +45,11 @@ module.exports = {
3445
// what about if the parent is an ArrowFunctionExpression
3546
// would that imply an implicit return?
3647

37-
if (getAncestors(context, node).some(isInsideCallback)) {
48+
if (
49+
getAncestors(context, node).some((ancestor) => {
50+
return isInsideCallback(ancestor, exemptDeclarations)
51+
})
52+
) {
3853
context.report({
3954
node: node.callee,
4055
messageId: 'avoidPromiseInCallback',

0 commit comments

Comments
 (0)