{"version":3,"file":"resolvers.cjs","names":[],"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  parseGetterConfig,\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 =\n        options.isAddingDirectives && !!parseGetterConfig(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(...parseGetterConfig(geneConfig.directives))\n      }\n      if (geneConfig?.aliases && returnTypeName in geneConfig.aliases) {\n        const aliasGeneConfig = geneConfig.aliases[returnTypeName as 'Query']\n        if (aliasGeneConfig?.directives) {\n          directiveConfigs.push(...parseGetterConfig(aliasGeneConfig.directives))\n        }\n      }\n\n      // Field-level directives\n      if (normalizedConfig?.directives) {\n        directiveConfigs.push(...parseGetterConfig(normalizedConfig.directives))\n      }\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"],"mappings":"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"}