import { isThenable, type MaybePromise, type SchemaTypes } from '@pothos/core'; import type { GraphQLIsTypeOfFn, GraphQLResolveInfo } from 'graphql'; import type { PothosScopeAuthPlugin, ResolveStep, UnauthorizedForTypeErrorFn } from '.'; import { ForbiddenError } from './errors'; import RequestCache from './request-cache'; export function isTypeOfHelper( steps: ResolveStep[], plugin: PothosScopeAuthPlugin, isTypeOf: GraphQLIsTypeOfFn | undefined, ) { const globalUnauthorizedError = plugin.builder.options.scopeAuth?.unauthorizedError; const createError: UnauthorizedForTypeErrorFn = (parent, context, info, result) => globalUnauthorizedError ? globalUnauthorizedError(parent, context, info, result) : result.message; return (parent: unknown, context: Types['Context'], info: GraphQLResolveInfo) => { const cache = RequestCache.fromContext(context, plugin.builder); function runSteps(index: number): MaybePromise { for (let i = index; i < steps.length; i += 1) { const { run, errorMessage } = steps[i]; const stepResult = run(cache, parent, {}, context, info, () => {}); if (isThenable(stepResult)) { return stepResult.then((result) => { if (result) { const error = createError(parent as object, context, info, { message: typeof errorMessage === 'function' ? errorMessage(parent, {}, context, info) : errorMessage, failure: result, }); throw typeof error === 'string' ? new ForbiddenError(error, result) : error; } return runSteps(i + 1); }); } if (stepResult) { const error = createError(parent as object, context, info, { message: typeof errorMessage === 'function' ? errorMessage(parent, {}, context, info) : errorMessage, failure: stepResult, }); throw typeof error === 'string' ? new ForbiddenError(error, stepResult) : error; } } return isTypeOf ? isTypeOf(parent, context, info) : true; } return runSteps(0); }; }