UNPKG

@onn-software/ddl-to-gql

Version:

Convert a SQL DDL to a GraphQL implementation with all relations.

3 lines (2 loc) 7.11 kB
export declare const main = "import {allGqlQueryResolvers, allGqlTypeResolvers, allGqlMutationResolvers, OnnResolverHooks} from './resolvers';\nimport {QueryBuilder, QueryOperator, Clause, MutationResult, OnnContext, MemCache} from './model';\nimport {OnnBaseRepo} from './repos';\n\nexport interface GqlParams<GraphQLResolveInfo = any> {\n parent: any;\n args: Record<string, any>;\n context: OnnContext | any;\n info: GraphQLResolveInfo;\n}\n\nexport interface OnnResolverWrapper {\n before: (resolverName:string, tableName :string, gqlParams: GqlParams) => Promise<any | undefined | null>;\n after: (resolverName:string, tableName :string, result: any, gqlParams: GqlParams) => Promise<any>;\n}\n\nexport type OnnExecute = (knexQb: Knex.QueryBuilder, action: string, options: any, context: OnnContext | any) => Promise<Knex.QueryBuilder | any>;\n\nexport class OnnDdlToGql<GraphQLResolveInfo = any> {\n constructor(queryBuilderFactory: <T extends {}>(context: OnnContext | any) => QueryBuilder<T>, options?: { onnWrapperBuilder?: () => OnnResolverWrapper }) {\n OnnBaseRepo.BUILDER_FACTORY = queryBuilderFactory;\n \n if (options?.onnWrapperBuilder) {\n OnnResolverHooks.buildWrapper = options.onnWrapperBuilder;\n }\n }\n\n getAllTypeResolvers = () => allGqlTypeResolvers;\n getAllQueryResolvers = () => allGqlQueryResolvers;\n getAllGqlMutationResolvers = () => allGqlMutationResolvers;\n}\n\nexport const SimpleOnExecute: OnnExecute = async (knexQb, action, options, context = {}) => {\n return knexQb;\n}\n\nexport const contextCachingOnExecute: OnnExecute = async (knexQb, action, options, context = {}) => {\n if(context?.onn?.extras?.transacting){\n knexQb = knexQb.transacting(context.onn.extras.transacting)\n }\n if(['QUERY', 'COUNT'].indexOf(action) < 0) return knexQb;\n if (!context.onn) context.onn = {};\n if (context.onn.skipCache) return knexQb;\n if (!context.onn.cache) {\n context.onn.cache = new MemCache();\n } \n \n let res = await context.onn.cache.get(options);\n if (!res) {\n res = await knexQb;\n await context.onn.cache.set(options, res);\n }\n return res;\n};\n\n__FACTORY__\n"; export declare const knexFactrory = "import { Knex } from 'knex';\n\nexport interface KnexQueryBuilderOptions {\n table: string;\n where: Clause[];\n orderBy?: { field: string; direction: 'asc' | 'desc' };\n distinct: string[];\n limit?: number;\n offset?: number;\n select?: string | string[];\n}\n\nexport const knexQueryBuilderFactory =\n (\n knex: Knex,\n onExecute: OnnExecute = contextCachingOnExecute\n ) =>\n <T extends {}>(context: OnnContext | any) =>\n new KnexQueryBuilder<T>(context, knex, onExecute);\n\nexport class KnexQueryBuilder<TYPE extends {}> implements QueryBuilder<TYPE, Knex> {\n private options: KnexQueryBuilderOptions = {\n table: '',\n where: [],\n distinct: [],\n };\n\n constructor(private context: OnnContext | any, private knex: Knex, private onExecute: OnnExecute) {}\n\n private build(): Knex.QueryBuilder<TYPE> {\n let qb = this.knex<TYPE>(this.options.table) as Knex.QueryBuilder<TYPE>;\n \n this.options.where.forEach((clause) => {\n const safeField = this.options.table + \".\" + clause.field;\n switch (clause.operator) {\n case QueryOperator.EQUALS:\n qb.where(safeField, clause.value);\n break;\n case QueryOperator.IN:\n qb.whereIn(safeField, clause.value);\n break;\n case QueryOperator.BETWEEN:\n qb.whereBetween(safeField, clause.value);\n break;\n case QueryOperator.LIKE:\n qb.whereLike(safeField, clause.value);\n break;\n case QueryOperator.NULL:\n qb.whereNull(safeField);\n break;\n case QueryOperator.NOT_EQUALS:\n qb.whereNot(safeField, clause.value);\n break;\n case QueryOperator.NOT_IN:\n qb.whereNotIn(safeField, clause.value);\n break;\n case QueryOperator.NOT_BETWEEN:\n qb.whereNotBetween(safeField, clause.value);\n break;\n case QueryOperator.NOT_NULL:\n qb.whereNotNull(safeField);\n break;\n }\n });\n \n if(this.options.orderBy?.field) {\n qb.orderBy(this.options.table + \".\" + this.options.orderBy.field, this.options.orderBy.direction);\n }\n \n return qb;\n }\n\n async executeQuery(): Promise<TYPE[]> {\n const qb = this.build();\n if (this.options.offset) {\n qb.offset(this.options.offset);\n }\n if (this.options.limit) {\n qb.limit(this.options.limit);\n }\n if(this.options.distinct.length > 0) {\n qb.distinct(...this.options.distinct).select(...this.options.distinct);\n } else if (this.options.select) {\n qb.select(this.options.select);\n }\n \n return this.onExecute(qb, 'QUERY', this.options, this.context);\n }\n\n async executeCount(): Promise<number> {\n const count = await this.onExecute(this.build().count(), 'COUNT', this.options, this.context);\n return Object.values(count[0])[0] as number;\n }\n \n async executeInsert(value: any): Promise<MutationResult> {\n try {\n const [res] = await this.onExecute(this.build().insert(value), 'INSERT', this.options, this.context);\n return {rows: res ? 1 : 0, res: `${res}`}\n } catch (e: any) {\n return {rows: 0, res: '', error: e.message ?? e.toString()}\n }\n }\n \n async executeUpdate(value: any): Promise<MutationResult> {\n try {\n const rows = await this.onExecute(this.build().update(value), 'UPDATE', this.options, this.context);\n return {rows, res: '', error: rows > 0 ? undefined : 'Nothing matches clauses'}\n } catch (e: any) {\n return {rows: 0, res: '', error: e.message ?? e.toString()}\n }\n }\n \n async executeDelete(): Promise<MutationResult> {\n try {\n const rows = await this.onExecute(this.build().delete(), 'DELETE', this.options, this.context);\n return {rows, res: '', error: rows > 0 ? undefined : 'Nothing matches clauses'}\n } catch (e: any) {\n return {rows: 0, res: '', error: e.message ?? e.toString()}\n }\n }\n\n limit(limit: number): QueryBuilder<TYPE, Knex> {\n this.options.limit = limit;\n return this;\n }\n\n offset(offset: number): QueryBuilder<TYPE, Knex> {\n this.options.offset = offset;\n return this;\n }\n\n select(fields: string | string[]): QueryBuilder<TYPE, Knex> {\n this.options.select = fields;\n return this;\n }\n\n table(tableName: string): QueryBuilder<TYPE, Knex> {\n this.options.table = tableName;\n return this;\n }\n\n orderBy(orderBy?: {field: string, direction: 'asc' | 'desc'}): QueryBuilder<TYPE, Knex> {\n this.options.orderBy = orderBy;\n return this;\n }\n\n distinct(distinct: string[] = []): QueryBuilder<TYPE, Knex> {\n this.options.distinct = distinct;\n return this;\n }\n\n where(...clauses: Clause[]): QueryBuilder<TYPE, Knex> {\n this.options.where.push(...clauses);\n return this;\n }\n}\n\n";