Last active
July 5, 2019 07:08
-
-
Save StrongerMyself/deeb54428c2eea3524523ed840dec2dc to your computer and use it in GitHub Desktop.
Graphql parser AST query for optimal ORM query. Get relation map by spec relation list.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GraphQLResolveInfo } from 'graphql' | |
const unique = (arr = []) => { | |
let obj = {} | |
for (let i = 0;i < arr.length;i++) { | |
let str = arr[i] | |
if (!!str) obj[str] = true | |
} | |
return Object.keys(obj) | |
} | |
export const schemaRelBySpec = (info: GraphQLResolveInfo, spec = []) => { | |
let rel = [] | |
info.fieldNodes.forEach(node => { | |
rel.push(...nodeMap(node, info.fragments, spec)) | |
}) | |
return unique(rel) | |
} | |
const nodeMap = (node, fragments, spec) => { | |
const { selectionSet } = node | |
const fields = fieldMap(selectionSet as [], fragments) | |
return spec.filter(name => fields.indexOf(name) >= 0) | |
} | |
const fieldMap = (selectionSet, fragments, parent = '') => { | |
let field = [] | |
let value = parent | |
let { selections } = selectionSet | |
selections.forEach(el => { | |
let { kind, name, selectionSet } = el | |
if (kind === 'FragmentSpread') { | |
let { selectionSet } = fragments[name.value] | |
let subField = fieldMap(selectionSet, fragments, value) | |
field.push(...subField) | |
} else { | |
if (name) { | |
value = name.value | |
if (parent) value = `${parent}.${value}` | |
field.push(value) | |
} | |
if (selectionSet) { | |
let subField = fieldMap(selectionSet, fragments, value) | |
field.push(...subField) | |
} | |
} | |
}) | |
return [...field] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { IResolvers } from 'graphql-tools' | |
import { getCustomRepository } from 'typeorm' | |
import { schemaRelBySpec, schemaWhereByArgs } from '../../../utils' | |
import { OrderRepository } from '../' | |
const rp = () => getCustomRepository(OrderRepository) | |
const relationSpec = ['items', 'address'] | |
const resolvers: IResolvers = { | |
Query: { | |
Orders: async (_, args, context, info) => { | |
const relations = schemaRelBySpec(info, relationSpec) | |
const where = schemaWhereByArgs(args) | |
return await rp().find({where, relations}) | |
}, | |
Order: async (_, { id }, context, info) => { | |
const relations = schemaRelBySpec(info, relationSpec) | |
return await rp().findOne(id, {relations}) | |
}, | |
}, | |
} | |
export default resolvers |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment