Repository: prettier/prettier (JavaScript)

Issue:
Prettier GraphQL `description` leading space bug
**Prettier 2.6.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAdNGAEApCALKTAEQjk3QrVgE8AHMgBTgCcBnaTYVQzKAQwC2cJJgDKMZgEsoAc24BfEABoQEWjEnRWyUH2bMIAdwZ6E2lHwA2hvtW0qARsz5gA1nBijBcADLS4yABmVqxwjs5uHqK0LtIyyBIArmEgcAIOcAAmmVk+fLKJfDJwAGIQzAJ8MBqyyCB8iTAQyiB4MAKWAOp4kvCsMWBwoma9kgBuvdR1YKz2INKhzDAMzjKVQSEpAFasAB6icZZwAIqJEPAblqEqMWwsdTLOtHgAjpYttFKwnZKZMHjIAAcAAYbgZQp0nnVPnBFmMAioXmd4Cs1OZ6qwALRQOBZLItZhwJGSQkrIrrJDBK4pUICSQJZjJFSsQ4nZEBSmbFQwPgOH5-AFIABM3OckkscQAwhABBTUqwAKwtRKhAAqvPMVOuIDGyQAklAcrBRGApOoAIKG8TUI6XULyeRAA)
<!-- prettier-ignore -->
```sh
--parser graphql
```

**Input:**
<!-- prettier-ignore -->
```graphql
""" Customer """
type Person {
  name: String
}
```

**Output:**
<!-- prettier-ignore -->
```graphql
"""
 Customer
"""
type Person {
  name: String
}

```

**Second Output:**
<!-- prettier-ignore -->
```graphql
"""
Customer
"""
type Person {
  name: String
}

```

**Expected behavior:**

```gql
"""
Customer
"""
type Person {
  name: String
}
```

Seems like the leading space in the GraphQL `description` is not removed.
Running `prettier` twice (2x) will yield the expected result.

Also created a tiny repo with this bug: https://github.com/chimurai/prettier-graphql-comment-bug


Hints:

Patch:
diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js
--- a/src/language-graphql/printer-graphql.js
+++ b/src/language-graphql/printer-graphql.js
@@ -125,13 +125,15 @@ function genericPrint(path, options, print) {
     }
     case "StringValue": {
       if (node.block) {
-        return [
-          '"""',
-          hardline,
-          join(hardline, node.value.replace(/"""/g, "\\$&").split("\n")),
+        const lines = node.value.replace(/"""/g, "\\$&").split("\n");
+        if (lines.length === 1) {
+          lines[0] = lines[0].trim();
+        }
+
+        return join(
           hardline,
-          '"""',
-        ];
+          ['"""', ...(lines.length > 0 ? lines : []), '"""'].filter(Boolean)
+        );
       }
       return [
         '"',
@@ -572,7 +574,13 @@ function printInterfaces(path, options, print) {
   return parts;
 }
 
-function clean(/*node, newNode , parent*/) {}
+function clean(node, newNode /* , parent */) {
+  // We print single line `""" string """` as multiple line string,
+  // and the parser ignores space in multiple line string
+  if (node.kind === "StringValue" && node.block && !node.value.includes("\n")) {
+    newNode.value = newNode.value.trim();
+  }
+}
 clean.ignoredProperties = new Set(["loc", "comments"]);
 
 function hasPrettierIgnore(path) {


Test patch:
diff --git a/tests/format/graphql/string/__snapshots__/jsfmt.spec.js.snap b/tests/format/graphql/string/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/graphql/string/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/graphql/string/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,82 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`description.graphql format 1`] = `
+====================================options=====================================
+parsers: ["graphql"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+""" Customer """
+type Person {name: String}
+
+""" Customer """
+type Person {name: String}
+
+"""
+
+    Customer
+
+
+"""
+type Person {name: String}
+
+""""""
+type Person {name: String}
+
+"""    """
+type Person {name: String}
+
+"""
+    1
+  2
+"""
+type Person {name: String}
+
+=====================================output=====================================
+"""
+Customer
+"""
+type Person {
+  name: String
+}
+
+"""
+Customer
+"""
+type Person {
+  name: String
+}
+
+"""
+Customer
+"""
+type Person {
+  name: String
+}
+
+"""
+"""
+type Person {
+  name: String
+}
+
+"""
+"""
+type Person {
+  name: String
+}
+
+"""
+  1
+2
+"""
+type Person {
+  name: String
+}
+
+================================================================================
+`;
+
 exports[`string.graphql format 1`] = `
 ====================================options=====================================
 parsers: ["graphql"]
@@ -59,6 +136,14 @@ one: string
   foo(input: {multiline: "ab\\ncd"}) { id }
 }
 
+{
+  foo(input: {multiline: """    foo    """}) { id }
+}
+
+{
+  foo(input: {multiline: """    """}) { id }
+}
+
 =====================================output=====================================
 query X($a: Int) @relay(meta: "{\\"lowPri\\": true}") {
   a
@@ -129,5 +214,28 @@ input Input {
   }
 }
 
+{
+  foo(
+    input: {
+      multiline: """
+      foo
+      """
+    }
+  ) {
+    id
+  }
+}
+
+{
+  foo(
+    input: {
+      multiline: """
+      """
+    }
+  ) {
+    id
+  }
+}
+
 ================================================================================
 `;
diff --git a/tests/format/graphql/string/description.graphql b/tests/format/graphql/string/description.graphql
new file mode 100644
--- /dev/null
+++ b/tests/format/graphql/string/description.graphql
@@ -0,0 +1,25 @@
+""" Customer """
+type Person {name: String}
+
+""" Customer """
+type Person {name: String}
+
+"""
+
+    Customer
+
+
+"""
+type Person {name: String}
+
+""""""
+type Person {name: String}
+
+"""    """
+type Person {name: String}
+
+"""
+    1
+  2
+"""
+type Person {name: String}
diff --git a/tests/format/graphql/string/string.graphql b/tests/format/graphql/string/string.graphql
--- a/tests/format/graphql/string/string.graphql
+++ b/tests/format/graphql/string/string.graphql
@@ -50,3 +50,11 @@ one: string
 {
   foo(input: {multiline: "ab\ncd"}) { id }
 }
+
+{
+  foo(input: {multiline: """    foo    """}) { id }
+}
+
+{
+  foo(input: {multiline: """    """}) { id }
+}