Skip to content

Commit 30f7398

Browse files
authored
feat: ES2022 no-top-level-await (#28)
1 parent 4fc74eb commit 30f7398

5 files changed

Lines changed: 91 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ for configuration. Here's some examples:
166166
- [no-regexp-lookbehind](./docs/no-regexp-lookbehind.md)
167167
- [no-regexp-named-group](./docs/no-regexp-named-group.md)
168168
- [no-regexp-s-flag](./docs/no-regexp-s-flag.md)
169+
- [no-top-level-await](./docs/no-top-level-await.md)
169170

170171
## Inspiration
171172

docs/no-top-level-await.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# no-top-level-await
2+
3+
This prevents the use of `await` at the top-level of documents (outside
4+
of an async function context)
5+
6+
```js
7+
await asyncMethod();
8+
9+
const results = await getAsyncResults();
10+
```
11+
12+
These will not be allowed because they are not supported in the following browsers:
13+
14+
- Edge < 89
15+
- Safari < 15
16+
- Firefox < 89
17+
- Chrome < 89
18+
19+
20+
## What is the Fix?
21+
22+
You can wrap your `await` in an async Immediately Invoking Function
23+
Expression (IIFE).
24+
25+
```js
26+
(async () => {
27+
await asyncMethod();
28+
29+
const results = await getAsyncResults();
30+
})();
31+
```

lib/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ createRule(
204204
"disallow static blocks like `static { x = 1 }`",
205205
{ ts: 2022 }
206206
);
207+
createRule(
208+
"no-top-level-await",
209+
"edge < 89, safari < 15, firefox < 89, chrome < 89",
210+
"disallow await keyword outside of async function context",
211+
{ ts: 2022 }
212+
);
207213

208214
// Proposals...
209215
createRule(

lib/rules/no-top-level-await.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
const functionTypes = new Set([
4+
'FunctionDeclaration',
5+
'FunctionExpression',
6+
'ArrowFunctionExpression',
7+
]);
8+
9+
module.exports = (context, badBrowser) => ({
10+
AwaitExpression(node) {
11+
let currentNode = node;
12+
while (currentNode.parent) {
13+
currentNode = currentNode.parent;
14+
if (functionTypes.has(currentNode.type) && currentNode.async) {
15+
return;
16+
}
17+
}
18+
context.report(node, `Top-level await is not supported in ${badBrowser}`)
19+
},
20+
})

test/no-top-level-await.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const rule = require('../lib/index').rules['no-top-level-await']
4+
const RuleTester = require('eslint').RuleTester
5+
6+
const ruleTester = new RuleTester({languageOptions: {ecmaVersion: 2022}})
7+
8+
ruleTester.run('no-top-level-await', rule, {
9+
valid: [
10+
{code: 'async function get () { return await asyncMethod(); }'},
11+
{code: '(async () => { await getAsyncResults(); })();'},
12+
{code: 'const get = async function get () { return await asyncMethod(); }'},
13+
{code: 'const get = async () => { return await asyncMethod(); }'},
14+
],
15+
invalid: [
16+
{
17+
code: 'await asyncMethod();',
18+
errors: [
19+
{
20+
message: 'Top-level await is not supported in undefined'
21+
}
22+
]
23+
},
24+
{
25+
code: 'const results = await getAsyncResults();',
26+
errors: [
27+
{
28+
message: 'Top-level await is not supported in undefined'
29+
}
30+
]
31+
},
32+
]
33+
})

0 commit comments

Comments
 (0)