-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathindex.js
64 lines (57 loc) · 2.4 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { delimiter } from 'path'
import { existsSync } from 'fs'
import { transformSync } from '@babel/core'
import { requireGql, defaultResolve } from './requireGql'
let resolve
export default ({ types: t }) => ({
manipulateOptions({ resolveModuleSource }) {
if (!resolve) {
resolve = resolveModuleSource || defaultResolve
}
},
visitor: {
ImportDeclaration: {
exit(curPath, { file: { opts: { filename: babelPath } }, opts: { nodePath } }) {
const importNames = curPath.node.specifiers
const importPath = curPath.node.source.value
if (importPath.endsWith('.graphql') || importPath.endsWith('.gql')) {
// Find the file, using node resolution/NODE_PATH if necessary.
const fallbackPaths = nodePath ? nodePath.split(delimiter) : process.env.NODE_PATH
let absPath = resolve(importPath, babelPath)
if (!existsSync(absPath)) absPath = require.resolve(importPath, { paths: fallbackPaths })
// Analyze the file, returning either schema source (str) or a docs object containing ops.
const result = requireGql(absPath, { resolve, nowrap: false })
if (typeof result === 'string') {
curPath.replaceWith(buildVariableAST(result, importNames[0].local.name))
} else {
const replacements = buildReplacements(result, importNames)
replacements.length > 1
? curPath.replaceWithMultiple(replacements)
: curPath.replaceWith(replacements[0])
}
}
function buildReplacements(docs, specifiers) {
return specifiers.map(({ type, imported, local }) => {
switch (type) {
case 'ImportDefaultSpecifier':
return buildVariableAST(docs.default, local.name)
case 'ImportSpecifier':
return buildVariableAST(docs[imported.name] || docs.default, local.name)
case 'ImportNamespaceSpecifier':
return buildVariableAST(docs, local.name)
default:
throw new Error(`Unexpected import specifier type: ${type}`)
}
})
}
function buildVariableAST(graphqlAST, importName) {
const { ast } = transformSync(`var ${importName} = ${JSON.stringify(graphqlAST)}`, {
ast: true
})
return ast.program.body[0]
}
}
}
}
})
export { requireGql }