Repository: prettier/prettier (JavaScript)

Issue:
Unnecessary whitespace around `await` in multi-line chain passed to a function
**Prettier 2.8.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEBLAtgBwgJxgAmHxzgEMATc1HfAX3wDMcJ18AdEBgZwHpNn0qLnC4cA3GyiTSAd1KoCABQFC4AOlIAbTQApJ+fDtnyCJClRx6QXHGA4BKe2vSlMRrgE8oYQ5lIwAC3t8AF4APkJ9A3wMbDwdAAM1HgASYD9A2gT7CSgDWntJHMkQABoQCEwYVGguZFBSHGYZRUaEOpQtOQ868oAjHFIwAGs4GABlUnQ4ABlUKDhkBi1hfsGRsfG-MHmAc2QYHABXOHK4dD64SiuZ0ihdo9JduAAxXBcYavvkEFIjmAgZRAARg6E0AHUAgoRNs4ON2gpUAA3BQeH5gLi9NBQYR4ZRPFxLFanEAAKy4AA9xntNHAAIpHCDwImaVYgPw4XE-PqkS6aIH8eYwcGociBZAADgADOV+BBhODBpgfvwRHAcEjFuUAI6M+DKSodX5cAC0CyuVyBJF11Dg+N2hKQy1ZJOEggOx1dNLgAEFPjhUH1-nb1XMFiy2VxvQymYsncTyjBeSKxQFkAAmRODVCaPYAYRYjpAIgArECjsIACq8jrOtlIk4ASSg5AQEzAAaqPpb4xgHlpEbgtFoQA)
<!-- prettier-ignore -->
```sh
--parser babel
```

**Input:**
<!-- prettier-ignore -->
```jsx
import { readdir } from "fs/promises";

await Promise.all(
  (await readdir("src")).map(async (path) => {
    import(`./${path}`);
  })
);

```

**Output:**
<!-- prettier-ignore -->
```jsx
import { readdir } from "fs/promises";

await Promise.all(
  (
    await readdir("src")
  ).map(async (path) => {
    import(`./${path}`);
  })
);

```

**Expected behavior:**

Preserve formatting to keep chained `await` on the first line of the chain. This is what is supposed to happen if you don't have a multi-line chain or don't pass it to a function.

**Note:**

It's important that Prettier preserves the parentheses around `await readdir("src")`, otherwise it would be parsed like `await (readdir("src").chain())`, which would break because `path` would be `Promise<string>` instead of `string`.


Hints:

Patch:
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -29,6 +29,7 @@ import {
   markerForIfWithoutBlockAndSameLineComment,
   isArrayOrTupleExpression,
   isObjectOrRecordExpression,
+  startsWithNoLookaheadToken,
 } from "./utils/index.js";
 import { locStart, locEnd } from "./loc.js";
 import isBlockComment from "./utils/is-block-comment.js";
@@ -324,11 +325,18 @@ function printPathNoParens(path, options, print, args) {
           (isMemberExpression(parent) && parent.object === node)
         ) {
           parts = [indent([softline, ...parts]), softline];
+          // avoid printing `await (await` on one line
           const parentAwaitOrBlock = path.findAncestor(
             (node) =>
               node.type === "AwaitExpression" || node.type === "BlockStatement"
           );
-          if (parentAwaitOrBlock?.type !== "AwaitExpression") {
+          if (
+            parentAwaitOrBlock?.type !== "AwaitExpression" ||
+            !startsWithNoLookaheadToken(
+              parentAwaitOrBlock.argument,
+              (leftmostNode) => leftmostNode === node
+            )
+          ) {
             return group(parts);
           }
         }


Test patch:
diff --git a/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap
@@ -198,6 +198,31 @@ const getAccountCount = async () =>
 ================================================================================
 `;
 
+exports[`nested2.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+async function f() {
+await Promise.all(
+  (await readdir("src")).map(async (path) => {
+    import(\`./\${path}\`);
+  })
+);}
+
+=====================================output=====================================
+async function f() {
+  await Promise.all(
+    (await readdir("src")).map(async (path) => {
+      import(\`./\${path}\`);
+    }),
+  );
+}
+
+================================================================================
+`;
+
 exports[`parens.js format 1`] = `
 ====================================options=====================================
 parsers: ["babel", "flow", "typescript"]
diff --git a/tests/format/js/async/nested2.js b/tests/format/js/async/nested2.js
new file mode 100644
--- /dev/null
+++ b/tests/format/js/async/nested2.js
@@ -0,0 +1,6 @@
+async function f() {
+await Promise.all(
+  (await readdir("src")).map(async (path) => {
+    import(`./${path}`);
+  })
+);}