import { isThenable, type SchemaTypes } from '@pothos/core'; import type { GraphQLFieldResolver } from 'graphql'; import type { FieldAuthScopes, FieldGrantScopes, ResolveStep, TypeAuthScopes, TypeGrantScopes, } from './types'; export function createTypeAuthScopesStep( authScopes: TypeAuthScopes, type: string, ): ResolveStep { if (typeof authScopes === 'function') { return { run: (state, parent, _args, _context, info) => state.evaluateTypeScopeFunction(authScopes, type, parent, info), errorMessage: `Not authorized to read fields for ${type}`, }; } return { run: (state, _parent, _args, _context, info) => state.evaluateScopeMap(authScopes, info), errorMessage: `Not authorized to read fields for ${type}`, }; } export function createTypeGrantScopesStep( grantScopes: TypeGrantScopes, type: string, forField: boolean, ): ResolveStep { return { run: (state, parent, _args, context, info) => state.grantTypeScopes(type, parent, forField ? info.path.prev : info.path, () => grantScopes(parent, context), ), errorMessage: `Unknown error creating grants for ${type}`, }; } export function createFieldAuthScopesStep( authScopes: FieldAuthScopes, ): ResolveStep { if (typeof authScopes === 'function') { return { errorMessage: (_parent, _args, _context, info) => `Not authorized to resolve ${info.parentType}.${info.fieldName}`, run: (state, parent, args, context, info) => { const scopeMap = authScopes(parent as {}, args, context, info); if (isThenable(scopeMap)) { return scopeMap.then((resolved) => state.evaluateScopeMap(resolved, info)); } return state.evaluateScopeMap(scopeMap, info); }, }; } return { errorMessage: (_parent, _args, _context, info) => `Not authorized to resolve ${info.parentType}.${info.fieldName}`, run: (state, _parent, _args, _context, info) => state.evaluateScopeMap(authScopes, info), }; } export function createFieldGrantScopesStep( grantScopes: FieldGrantScopes, ): ResolveStep { return { errorMessage: (_parent, _args, _context, info) => `Unknown issue generating grants for ${info.parentType}.${info.fieldName}`, run: (state, parent, args, context, info) => { if (typeof grantScopes !== 'function') { state.saveGrantedScopes(grantScopes, info.path); return null; } const result = grantScopes(parent as {}, args, context, info); if (isThenable(result)) { return result.then((resolved) => { state.saveGrantedScopes(resolved, info.path); return null; }); } state.saveGrantedScopes(result, info.path); return null; }, }; } export function createResolveStep( resolver: GraphQLFieldResolver, ): ResolveStep { return { errorMessage: (_parent, _args, _context, info) => `Unknown issue resolving ${info.parentType}.${info.fieldName}`, run: (_state, parent, args, context, info, setResolved) => { const result: unknown = resolver(parent, args, context, info); if (isThenable(result)) { return Promise.resolve(result).then((resolved) => { setResolved(resolved); return null; }); } setResolved(result); return null; }, }; }