-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[New]
async-server-action
: Add rule to require that server actions …
…be async
- Loading branch information
1 parent
e4ecbcf
commit 561edf4
Showing
6 changed files
with
2,363 additions
and
1,439 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Require functions with the `use server` directive to be async (`react/async-server-action`) | ||
|
||
💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs). | ||
|
||
<!-- end auto-generated rule header --> | ||
|
||
Require Server Actions (functions with the `use server` directive) to be async, as mandated by the `use server` [spec](https://react.dev/reference/react/use-server). | ||
|
||
This must be the case even if the function does not use `await` or `return` a promise. | ||
|
||
## Rule Details | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```jsx | ||
<form | ||
action={() => { | ||
'use server'; | ||
... | ||
}} | ||
> | ||
... | ||
</form> | ||
``` | ||
|
||
```jsx | ||
function action() { | ||
'use server'; | ||
... | ||
} | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```jsx | ||
<form | ||
action={async () => { | ||
'use server'; | ||
... | ||
}} | ||
> | ||
... | ||
</form> | ||
``` | ||
|
||
```jsx | ||
async function action() { | ||
'use server'; | ||
... | ||
} | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you are not using React Server Components. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* @fileoverview Require functions with the `use server` directive to be async | ||
* @author Jorge Zreik | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const docsUrl = require('../util/docsUrl'); | ||
const report = require('../util/report'); | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
const messages = { | ||
asyncServerAction: 'Your server action should be async', | ||
}; | ||
|
||
/** | ||
* Detects a `use server` directive in a given AST node | ||
* @param {ASTNode} node The node to search. | ||
* @returns {boolean} Whether the node given has a `use server` directive. | ||
*/ | ||
function hasUseServerDirective(node) { | ||
if (node.body.type !== 'BlockStatement') return false; | ||
|
||
const functionBody = node.body.body; | ||
if (functionBody.length === 0) return false; | ||
|
||
const potentialDirectiveStatement = functionBody[0]; | ||
if (potentialDirectiveStatement.type !== 'ExpressionStatement') return false; | ||
|
||
const potentialDirectiveExpression = potentialDirectiveStatement.expression; | ||
if (potentialDirectiveExpression.type !== 'Literal') return false; | ||
|
||
return potentialDirectiveExpression.value === 'use server'; | ||
} | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: | ||
'Require functions with the `use server` directive to be async', | ||
category: 'Possible Errors', | ||
recommended: true, | ||
url: docsUrl('async-server-action'), | ||
}, | ||
|
||
messages, | ||
|
||
fixable: 'code', | ||
|
||
schema: [], | ||
}, | ||
|
||
create(context) { | ||
/** | ||
* Validates that given AST node is async if it has the `use server` directive | ||
* @param {ASTNode} node The node to search. | ||
* @returns {void} | ||
*/ | ||
function validate(node) { | ||
if (hasUseServerDirective(node) && !node.async) { | ||
report(context, messages.asyncServerAction, 'asyncServerAction', { | ||
node, | ||
fix(fixer) { | ||
return fixer.insertTextBefore(node, 'async '); | ||
}, | ||
}); | ||
} | ||
} | ||
|
||
return { | ||
FunctionDeclaration(node) { | ||
validate(node); | ||
}, | ||
FunctionExpression(node) { | ||
validate(node); | ||
}, | ||
ArrowFunctionExpression(node) { | ||
validate(node); | ||
}, | ||
}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.