{"version":3,"file":"public.cjs","names":[],"sources":["../../src/utils/public.ts"],"sourcesContent":["import { GraphQLError, type GraphQLResolveInfo } from 'graphql'\nimport {\n  getGloballyExtendedTypes,\n  isEmptyObject,\n  isObject,\n  normalizeFieldConfig,\n  PAGE_ARG_DEFAULT,\n  PER_PAGE_ARG_DEFAULT,\n  QUERY_ORDER_VALUES,\n  type ValidGraphqlType,\n} from 'graphql-gene'\nimport { lookahead, lookDeeper, type UntilHandlerDetails } from 'graphql-lookahead'\nimport type { OrderItem } from 'sequelize'\nimport type { Model } from 'sequelize-typescript'\nimport type { DefaultResolverIncludeOptions, GeneSequelizeWhereOptions } from '../types'\nimport { populateWhereOptions } from './internal'\nimport { isMarkedAsAssociation } from './associationMap'\n\nconst QUERY_TYPE = 'Query'\nconst MUTATION_TYPE = 'Mutation'\n\nexport function isSequelizeFieldConfig<T>(\n  fieldConfigs: T\n): fieldConfigs is T extends typeof Model ? T & Model : T {\n  return (\n    fieldConfigs &&\n    (typeof fieldConfigs === 'object' || typeof fieldConfigs === 'function') &&\n    'sequelize' in fieldConfigs\n  )\n}\n\nfunction getTypeConfig(type: string) {\n  const extendedTypes = getGloballyExtendedTypes()\n  if (!(type in extendedTypes.geneConfig)) return\n\n  return extendedTypes.geneConfig[type as keyof typeof extendedTypes.geneConfig]\n}\n\nfunction getFieldConfig(sourceType: string, field: string) {\n  const extendedTypes = getGloballyExtendedTypes()\n  if (!(sourceType in extendedTypes.config)) return\n\n  const fieldConfigs = extendedTypes.config[sourceType as keyof typeof extendedTypes.config]\n  if (!fieldConfigs) return\n\n  if (field in fieldConfigs) return normalizeFieldConfig(fieldConfigs[field])\n}\n\nfunction untilFindOptions(options: UntilHandlerDetails<DefaultResolverIncludeOptions>) {\n  const { sourceType, type, field } = options\n  const typeConfig = getTypeConfig(type)\n  const fieldConfig = getFieldConfig(sourceType, field)\n\n  if (typeConfig?.findOptions || fieldConfig?.findOptions) {\n    return {\n      afterAllSelections() {\n        if (typeConfig?.findOptions) {\n          options.state.include = options.state.include || []\n          const possibleState = options.state?.include?.find(opt => opt.association === field)\n          const state = possibleState || { association: field }\n          if (!possibleState) options.state.include.push(state)\n\n          typeConfig?.findOptions?.(Object.assign(options, { findOptions: state }))\n        }\n        // Using `Object.assign` instead of object spread operator to prevent executing the\n        // getters if not requested (i.e. `fieldDef`, `args`).\n        fieldConfig?.findOptions?.(Object.assign(options, { findOptions: options.state }))\n      },\n    }\n  }\n  return false\n}\n\nexport function getQueryInclude(info: GraphQLResolveInfo) {\n  const includeOptions: DefaultResolverIncludeOptions = {}\n\n  lookahead({\n    info,\n    state: includeOptions,\n    until: untilFindOptions,\n\n    next({ state, sourceType, field, args, isList }) {\n      if (!isMarkedAsAssociation(sourceType, field)) return {}\n\n      const include = getFieldIncludeOptions({ association: field, args, isList })\n\n      state.include = state.include || []\n      state.include.push(include)\n\n      return include\n    },\n  })\n\n  return isEmptyObject(includeOptions)\n    ? undefined\n    : (includeOptions as Required<Pick<typeof includeOptions, 'include'>>)\n}\n\nexport function getQueryIncludeOf(\n  info: GraphQLResolveInfo,\n  target:\n    | ValidGraphqlType\n    | ((details: UntilHandlerDetails<DefaultResolverIncludeOptions>) => boolean),\n  options: { depth?: number; lookFromOperationRoot?: boolean } = {}\n) {\n  const includeOptions: DefaultResolverIncludeOptions = {}\n  const isMatchingTarget: Exclude<typeof target, string> =\n    typeof target === 'string' ? ({ type }) => type === target : target\n\n  const until = (details: UntilHandlerDetails<DefaultResolverIncludeOptions>) => {\n    if (!isMatchingTarget(details)) return false\n\n    const { type, nextSelectionSet } = details\n    if (!nextSelectionSet) return false\n\n    lookDeeper({\n      info,\n      state: includeOptions,\n      type,\n      until: untilFindOptions,\n      selectionSet: nextSelectionSet,\n\n      next({ state, sourceType, field, args, isList }) {\n        if (!isMarkedAsAssociation(sourceType, field)) return {}\n\n        const include = getFieldIncludeOptions({ association: field, args, isList })\n\n        state.include = state.include || []\n        state.include.push(include)\n\n        return include\n      },\n    })\n    return true\n  }\n\n  const lookDeeperOptions = { info, depth: options.depth, until }\n\n  if (options.lookFromOperationRoot) {\n    lookDeeper({\n      ...lookDeeperOptions,\n      state: {},\n      type: info.operation.operation === 'mutation' ? MUTATION_TYPE : QUERY_TYPE,\n      selectionSet: info.operation.selectionSet,\n    })\n  } else {\n    lookahead(lookDeeperOptions)\n  }\n\n  return isEmptyObject(includeOptions)\n    ? undefined\n    : (includeOptions as Required<Pick<typeof includeOptions, 'include'>>)\n}\n\nexport function getFieldFindOptions(options: {\n  args: { [arg: string]: unknown }\n  isList: boolean\n}) {\n  return getFieldIncludeOptions(options)\n}\n\nexport function getFieldIncludeOptions(options: {\n  association?: string\n  args: { [arg: string]: unknown }\n  isList: boolean\n}) {\n  const includeOptions: DefaultResolverIncludeOptions = {}\n  if (options.association) includeOptions.association = options.association\n\n  const where: GeneSequelizeWhereOptions = {}\n\n  if (!options.isList) {\n    if (options.association) return includeOptions\n\n    if (typeof options.args.id === 'string') {\n      includeOptions.where = where\n      includeOptions.where.id = options.args.id\n    }\n  }\n  // TODO: Possible improvement: Return from here if not using default resolver\n\n  if (isObject(options.args.where)) {\n    includeOptions.where = where\n    populateWhereOptions(options.args.where, where)\n  }\n\n  if (Array.isArray(options.args.order)) {\n    const orderOptions: OrderItem[] = []\n\n    options.args.order.forEach(fieldOrderValue => {\n      if (typeof fieldOrderValue !== 'string') return\n\n      const [, field, orderValue] =\n        fieldOrderValue.match(new RegExp(`^(.+)_(${QUERY_ORDER_VALUES.join('|')})$`)) || []\n      if (field && orderValue) {\n        orderOptions.push([field, orderValue])\n      } else {\n        throw new GraphQLError('Invalid order value.')\n      }\n    })\n    includeOptions.order = orderOptions\n  }\n\n  if (options.isList) {\n    const argPage = typeof options.args.page === 'number' ? options.args.page : PAGE_ARG_DEFAULT\n    const argPerPage =\n      typeof options.args.perPage === 'number' ? options.args.perPage : PER_PAGE_ARG_DEFAULT\n\n    includeOptions.offset = (argPage - 1) * argPerPage\n    includeOptions.limit = argPerPage\n  }\n\n  return includeOptions\n}\n"],"mappings":"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"}