@teamstarter/graphql-sequelize-generator
Version:
A set of tools to easily generate a Graphql API from sequelize models.
119 lines (103 loc) • 3.22 kB
text/typescript
import { argsToFindOptions } from 'graphql-sequelize'
import { GroupedCountResultItem, Model, ModelStatic } from 'sequelize'
import {
CountAfterHook,
GlobalBeforeHook,
GlobalPreCallback,
ModelDeclarationType,
QueryBeforeHook,
} from '../types/types'
export default function countResolver<M extends Model<any>, TContext = any>(
model: ModelStatic<M>,
schemaDeclaration: ModelDeclarationType<M>,
globalPreCallback: GlobalPreCallback
) {
const countResolver =
schemaDeclaration.count && schemaDeclaration.count.resolver
? schemaDeclaration.count.resolver
: undefined
if (countResolver) {
return countResolver
}
const listBefore =
schemaDeclaration.list && schemaDeclaration.list.beforeList
? schemaDeclaration.list.beforeList
: undefined
// Count uses the same before function as the list, except if specified otherwise
const countBefore =
schemaDeclaration.count && schemaDeclaration.count.beforeList
? schemaDeclaration.count.beforeList
: listBefore
return async (source: any, args: any, context: TContext, info: any) => {
if (schemaDeclaration.before) {
const beforeList: GlobalBeforeHook[] = Array.isArray(
schemaDeclaration.before
)
? schemaDeclaration.before
: [schemaDeclaration.before as GlobalBeforeHook]
for (const before of beforeList) {
const handle = globalPreCallback('listGlobalBefore')
await before({ args, context, info })
if (handle) {
handle()
}
}
}
let findOptions = argsToFindOptions.default(
args,
Object.keys(model.getAttributes())
)
if (!findOptions.where) {
findOptions.where = {}
}
if (typeof findOptions.include === 'undefined') {
findOptions.include = []
}
if (countBefore) {
const beforeList: QueryBeforeHook<M>[] = Array.isArray(countBefore)
? countBefore
: [countBefore as QueryBeforeHook<M>]
for (const before of beforeList) {
const handle = globalPreCallback('countBefore')
const resultBefore = await before({
findOptions,
args,
context,
info,
})
if (!resultBefore) {
throw new Error(
'The before hook of the count endpoint must return a value.'
)
}
findOptions = resultBefore
if (handle) {
handle()
}
}
}
const count = await model.count(findOptions)
if (schemaDeclaration.count && schemaDeclaration.count.afterList) {
const afterList: CountAfterHook<M>[] = Array.isArray(
schemaDeclaration.count.afterList
)
? schemaDeclaration.count.afterList
: [schemaDeclaration.count.afterList as CountAfterHook<M>]
let modifiedCount: number | GroupedCountResultItem[] = count
for (const after of afterList) {
const handle = globalPreCallback('countAfter')
modifiedCount = await after({
result: modifiedCount,
args,
context,
info,
})
if (handle) {
handle()
}
}
return modifiedCount
}
return count
}
}