diff --git a/src/language-js/clean.js b/src/language-js/clean.js index eba3655c2..d75adffa8 100644 --- a/src/language-js/clean.js +++ b/src/language-js/clean.js @@ -133,12 +133,24 @@ function clean(ast, newObj, parent) { ) { newObj.quasi.quasis.forEach(quasi => delete quasi.value); } - if ( - ast.type === "TemplateLiteral" && - parent.type === "CallExpression" && - parent.callee.name === "graphql" - ) { - newObj.quasis.forEach(quasi => delete quasi.value); + if (ast.type === "TemplateLiteral") { + // This checks for a leading comment that is exactly `/* GraphQL */` + // In order to be in line with other implementations of this comment tag + // we will not trim the comment value and we will expect exactly one space on + // either side of the GraphQL string + // Also see ./embed.js + const hasGraphQLComment = + ast.leadingComments && + ast.leadingComments.some( + comment => + comment.type === "CommentBlock" && comment.value === " GraphQL " + ); + if ( + hasGraphQLComment || + (parent.type === "CallExpression" && parent.callee.name === "graphql") + ) { + newObj.quasis.forEach(quasi => delete quasi.value); + } } } diff --git a/src/language-js/embed.js b/src/language-js/embed.js index c0dec2acf..f0ec27a87 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -48,18 +48,7 @@ function embed(path, print, textToDoc /*, options */) { * This intentionally excludes Relay Classic tags, as Prettier does not * support Relay Classic formatting. */ - if ( - parent && - ((parent.type === "TaggedTemplateExpression" && - ((parent.tag.type === "MemberExpression" && - parent.tag.object.name === "graphql" && - parent.tag.property.name === "experimental") || - (parent.tag.type === "Identifier" && - (parent.tag.name === "gql" || parent.tag.name === "graphql")))) || - (parent.type === "CallExpression" && - parent.callee.type === "Identifier" && - parent.callee.name === "graphql")) - ) { + if (isGraphQL(path)) { const expressionDocs = node.expressions ? path.map(print, "expressions") : []; @@ -421,4 +410,45 @@ function isStyledExtend(node) { return /^[A-Z]/.test(node.object.name) && node.property.name === "extend"; } +/* + * react-relay and graphql-tag + * graphql`...` + * graphql.experimental`...` + * gql`...` + * GraphQL comment block + * + * This intentionally excludes Relay Classic tags, as Prettier does not + * support Relay Classic formatting. + */ +function isGraphQL(path) { + const node = path.getValue(); + const parent = path.getParentNode(); + + // This checks for a leading comment that is exactly `/* GraphQL */` + // In order to be in line with other implementations of this comment tag + // we will not trim the comment value and we will expect exactly one space on + // either side of the GraphQL string + // Also see ./clean.js + const hasGraphQLComment = + node.leadingComments && + node.leadingComments.some( + comment => + comment.type === "CommentBlock" && comment.value === " GraphQL " + ); + + return ( + hasGraphQLComment || + (parent && + ((parent.type === "TaggedTemplateExpression" && + ((parent.tag.type === "MemberExpression" && + parent.tag.object.name === "graphql" && + parent.tag.property.name === "experimental") || + (parent.tag.type === "Identifier" && + (parent.tag.name === "gql" || parent.tag.name === "graphql")))) || + (parent.type === "CallExpression" && + parent.callee.type === "Identifier" && + parent.callee.name === "graphql"))) + ); +} + module.exports = embed; diff --git a/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap b/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap index 4a1ccc373..b8ca5bb68 100644 --- a/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap +++ b/tests/multiparser_js_graphql/__snapshots__/jsfmt.spec.js.snap @@ -17,6 +17,29 @@ gql\` `; +exports[`comment-tag.js 1`] = ` +const query = /* GraphQL */\` + { + user( id : 5 ) { + firstName + + lastName + } + } +\`; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +const query = /* GraphQL */ \` + { + user(id: 5) { + firstName + + lastName + } + } +\`; + +`; + exports[`expressions.js 1`] = ` graphql(schema, \` query allPartsByManufacturerName($name: String!) { diff --git a/tests/multiparser_js_graphql/comment-tag.js b/tests/multiparser_js_graphql/comment-tag.js new file mode 100644 index 000000000..f8a0c18ee --- /dev/null +++ b/tests/multiparser_js_graphql/comment-tag.js @@ -0,0 +1,9 @@ +const query = /* GraphQL */` + { + user( id : 5 ) { + firstName + + lastName + } + } +`;