Skip to content

Commit

Permalink
Added support for magic gql quotes
Browse files Browse the repository at this point in the history
  • Loading branch information
dotansimha authored and DAB0mB committed Dec 17, 2018
1 parent 9a30606 commit 4ecdd00
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 5 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ gqlPluck.fromCodeString(codeString, {
})
```

Template literals leaded by magic comments will also be extracted :-)

```js
/* GraphQL */ `
enum MessageTypes {
text
media
draftjs
}
`
```

supported file extensions are: `.js`, `.jsx`, `.ts`, `.tsx`, `.flow`, `.flow.js`, `.flow.jsx`, `.graphqls`, `.graphql`, `.gqls`, `.gql`.

### License
Expand Down
52 changes: 52 additions & 0 deletions src/graphql-tag-pluck.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,58 @@ describe('graphql-tag-pluck', () => {
`))
})

it('should pluck graphql-tag template literals leaded by a magic comment from .js file', async () => {
const file = await tmp.file({
unsafeCleanup: true,
template: '/tmp/tmp-XXXXXX.js',
})

await fs.writeFile(file.name, freeText(`
const Message = /* GraphQL */ \`
enum MessageTypes {
text
media
draftjs
}\`
`))

const gqlString = await gqlPluck.fromFile(file.name)

expect(gqlString).toEqual(freeText(`
enum MessageTypes {
text
media
draftjs
}
`))
})

it('should pluck graphql-tag template literals leaded by a lower cased non space separated magic comment from .js file', async () => {
const file = await tmp.file({
unsafeCleanup: true,
template: '/tmp/tmp-XXXXXX.js',
})

await fs.writeFile(file.name, freeText(`
const Message = /* graphql */\`
enum MessageTypes {
text
media
draftjs
}\`
`))

const gqlString = await gqlPluck.fromFile(file.name)

expect(gqlString).toEqual(freeText(`
enum MessageTypes {
text
media
draftjs
}
`))
})

it(`should NOT pluck other template literals from a .js file`, async () => {
const file = await tmp.file({
unsafeCleanup: true,
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const gqlPluckFromCodeString = (codeString, options = {}) => {
const out = {}
const config = new Config(options)
const ast = babelParse(codeString, config)
const visitor = createVisitor(codeString, out)
const visitor = createVisitor(codeString, ast.comments, out)

babelTraverse(ast, visitor)

Expand Down
42 changes: 38 additions & 4 deletions src/visitor.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import * as t from '@babel/types'
import { freeText } from './utils'

export default (code, out) => {
const defaultGqlIdentifierName = 'gql'
const gqlMagicCommentValue = 'graphql'
const gqlPackName = 'graphql-tag'

export default (code, comments, out) => {
// Will accumulate all template literals
const gqlTemplateLiterals = []
// By default, we will look for `gql` calls
let gqlIdentifierName = 'gql'
let gqlIdentifierName = defaultGqlIdentifierName

// /* GraphQL */
const gqlMagicComments = comments.filter(comment => {
if (comment.type == 'CommentBlock') {
const value = comment.value.toLowerCase().trim()

return value == gqlMagicCommentValue
}

return false
})

const pluckStringFromFile = ({ start, end }) => {
return freeText(code
Expand All @@ -24,7 +39,7 @@ export default (code, out) => {
// e.g. import gql from 'graphql-tag' -> gql
if (
path.node.callee.name == 'require' &&
path.node.arguments[0].value == 'graphql-tag'
path.node.arguments[0].value == gqlPackName
) {
if (!t.isVariableDeclarator(path.parent)) return
if (!t.isIdentifier(path.parent.id)) return
Expand Down Expand Up @@ -58,7 +73,7 @@ export default (code, out) => {
enter(path) {
// Find the identifier name used from graphql-tag, es6
// e.g. import gql from 'graphql-tag' -> gql
if (path.node.source.value != 'graphql-tag') return
if (path.node.source.value != gqlPackName) return

const gqlImportSpecifier = path.node.specifiers.find((importSpecifier) => {
return t.isImportDefaultSpecifier(importSpecifier)
Expand All @@ -70,6 +85,25 @@ export default (code, out) => {
},
},

TemplateLiteral: {
exit(path) {
// Push all template literals leaded by graphql magic comment
// e.g. /* GraphQL */ `query myQuery {}` -> query myQuery {}
const leadedByMagicComment = gqlMagicComments.some(comment =>
comment.end === path.node.start ||
comment.end === path.node.start - 1
)

if (!leadedByMagicComment) return

const gqlTemplateLiteral = pluckStringFromFile(path.node)

if (gqlTemplateLiteral) {
gqlTemplateLiterals.push(gqlTemplateLiteral)
}
},
},

TaggedTemplateExpression: {
exit(path) {
// Push all template literals provided to the found identifier name
Expand Down

0 comments on commit 4ecdd00

Please sign in to comment.