UNPKG

graphql-gene

Version:

Generates automatically an executable schema out of your ORM models

1 lines 10.3 kB
{"version":3,"file":"resolvers.cjs","sources":["../src/resolvers.ts"],"sourcesContent":["import { defaultFieldResolver, GraphQLSchema } from 'graphql'\nimport type {\n GeneConfig,\n GeneDefaultResolverArgs,\n ExtendedTypes,\n GeneTypeConfig,\n} from './defineConfig'\nimport {\n lookDeepInSchema,\n isUsingDefaultResolver,\n normalizeFieldConfig,\n isArrayFieldConfig,\n getGeneConfigFromOptions,\n getGloballyExtendedTypes,\n getReturnTypeName,\n} from './utils'\nimport type { GenePlugin, AnyObject, GraphqlTypes, TypeDefLines } from './types'\n\nexport function addResolversToSchema<SchemaTypes extends AnyObject>(options: {\n typeDefLines: TypeDefLines\n schema: GraphQLSchema\n plugins: GenePlugin[]\n types: SchemaTypes\n}) {\n let schema = options.schema\n\n Object.entries(options.types).forEach(([, model]) => {\n const modifiedSchema = forEachModel({\n typeDefLines: options.typeDefLines,\n schema,\n types: options.types,\n plugins: options.plugins,\n model,\n })\n if (modifiedSchema) schema = modifiedSchema\n })\n const globallyExtendedTypes = getGloballyExtendedTypes()\n\n const modifiedSchema = defineResolvers({\n typeDefLines: options.typeDefLines,\n schema,\n types: options.types,\n plugins: options.plugins,\n typeConfig: globallyExtendedTypes.config,\n isAddingDirectives: true,\n })\n if (modifiedSchema) schema = modifiedSchema\n\n return schema\n}\n\nfunction forEachModel<M, SchemaTypes extends AnyObject>(options: {\n typeDefLines: TypeDefLines\n geneConfig?: GeneConfig<M>\n schema: GraphQLSchema\n types: SchemaTypes\n plugins: GenePlugin<M>[]\n model: M\n}): GraphQLSchema | undefined {\n const geneConfig = getGeneConfigFromOptions(options)\n const { types: typeConfig } = geneConfig || {}\n\n let modifiedSchema = defineResolvers({ ...options, typeConfig })\n\n Object.entries(geneConfig?.aliases || {}).forEach(([, geneConfig]) => {\n const { types: typeConfig } = geneConfig || {}\n modifiedSchema = defineResolvers({ ...options, typeConfig })\n })\n return modifiedSchema\n}\n\nfunction defineResolvers<SchemaTypes extends AnyObject>(options: {\n typeDefLines: TypeDefLines\n schema: GraphQLSchema\n types: SchemaTypes\n plugins: GenePlugin[]\n typeConfig: ExtendedTypes | undefined\n isAddingDirectives?: boolean\n}): GraphQLSchema | undefined {\n const geneConfigByTpe = getGloballyExtendedTypes().geneConfig\n const typeConfig = options.typeConfig || {}\n\n lookDeepInSchema({\n schema: options.schema,\n each({ type, field, fieldDef, parentType }) {\n const geneConfig = geneConfigByTpe[type]\n const hasTypeDirectives = options.isAddingDirectives && !!geneConfig?.directives?.length\n\n const isFieldInTypeConfig = () =>\n parentType in typeConfig &&\n typeConfig[parentType as 'Query'] &&\n field in typeConfig[parentType as 'Query']!\n\n if (!hasTypeDirectives && !isFieldInTypeConfig()) return\n\n let normalizedConfig: GeneTypeConfig | undefined\n const currentTypeConfig = typeConfig[parentType as keyof typeof typeConfig]\n\n if (currentTypeConfig && !isArrayFieldConfig(currentTypeConfig)) {\n const config = (\n currentTypeConfig as Record<string, Parameters<typeof normalizeFieldConfig>[0]>\n )[field]\n normalizedConfig = config ? normalizeFieldConfig(config) : undefined\n }\n\n const returnTypeName = getReturnTypeName(\n normalizedConfig?.returnType || options.typeDefLines[parentType]?.lines[field]?.typeDef\n )\n const model = options.types[returnTypeName] as GraphqlTypes[keyof GraphqlTypes] | undefined\n\n if (type !== returnTypeName) return\n\n const plugin = model ? options.plugins.find(plugin => plugin.isMatching(model)) : undefined\n\n if (normalizedConfig?.resolver) {\n fieldDef.resolve = async (source, args, context, info) => {\n if (normalizedConfig.resolver && typeof normalizedConfig.resolver !== 'string') {\n return normalizedConfig.resolver({ source, args, context, info })\n }\n\n if (isUsingDefaultResolver(normalizedConfig) && plugin?.defaultResolver) {\n return await plugin.defaultResolver({\n model,\n modelKey: returnTypeName,\n config: normalizedConfig,\n args: args as GeneDefaultResolverArgs<typeof model>,\n info,\n })\n }\n }\n }\n if (!options.isAddingDirectives) return\n\n const directiveConfigs: GeneConfig<Record<string, unknown> | undefined>['directives'] = []\n\n // Type-level directives\n if (geneConfig?.directives) {\n directiveConfigs.push(...geneConfig.directives)\n }\n if (geneConfig?.aliases && returnTypeName in geneConfig.aliases) {\n const aliasGeneConfig = geneConfig.aliases[returnTypeName as 'Query']\n if (aliasGeneConfig?.directives) directiveConfigs.push(...aliasGeneConfig.directives)\n }\n\n // Field-level directives\n if (normalizedConfig?.directives) directiveConfigs.push(...normalizedConfig.directives)\n\n if (directiveConfigs.length) {\n // Reverse the order so that the first directive you defined will be executed first\n // (middleware pattern).\n const reversedConfigs = [...directiveConfigs].reverse()\n\n reversedConfigs.forEach(directive => {\n fieldDef.resolve = fieldDef.resolve || defaultFieldResolver\n const previousResolve = fieldDef.resolve\n\n fieldDef.resolve = async (source, args, context, info) => {\n let hasCalledResolve = false\n let result: unknown\n\n const resolve = async () => {\n hasCalledResolve = true\n result = await previousResolve(source, args, context, info)\n return result\n }\n await directive.handler({\n source,\n args,\n context,\n info,\n field,\n filter: getFilterFunction({ source, field }),\n resolve,\n })\n if (!hasCalledResolve) await resolve()\n\n return result\n }\n })\n }\n },\n })\n return options.schema\n}\n\nfunction getFilterFunction<TSource>(options: { source: TSource; field: string }) {\n const { field } = options\n\n return <TValue>(callback: (value: TValue) => unknown) => {\n const source = options.source as unknown as Record<string, TValue | TValue[] | undefined | null>\n\n if (Array.isArray(source[field])) {\n source[field] = source[field].filter(callback)\n } else {\n if (source[field] && !callback(source[field])) source[field] = null\n }\n }\n}\n"],"names":["addResolversToSchema","options","schema","model","modifiedSchema","forEachModel","globallyExtendedTypes","getGloballyExtendedTypes","defineResolvers","geneConfig","getGeneConfigFromOptions","typeConfig","geneConfigByTpe","lookDeepInSchema","type","field","fieldDef","parentType","normalizedConfig","currentTypeConfig","isArrayFieldConfig","config","normalizeFieldConfig","returnTypeName","getReturnTypeName","plugin","source","args","context","info","isUsingDefaultResolver","directiveConfigs","aliasGeneConfig","directive","defaultFieldResolver","previousResolve","hasCalledResolve","result","resolve","getFilterFunction","callback"],"mappings":"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"}