import { inputObjectType, mutationField, arg, FieldResolver } from '@nexus/schema'; import { ForbiddenError } from '@casl/ability'; import { UserInputError } from 'apollo-server-micro'; import { authenticateQuery } from '../../../schema/authenticate-query'; import { RecipeCollection, RecipeCollectionType } from '../collection-model'; import { RecipeCollectionET, RecipeFilterActionET, RecipeFilterAttributeET, } from '.'; import { ManualRecipeCollection } from '../manual-collection-model'; import { SmartRecipeCollection } from '../smart-collection-model'; export const RecpeFilterIT = inputObjectType({ name: 'RecipeFilterInput', definition(t) { t.field('attribute', { type: RecipeFilterAttributeET }); t.field('action', { type: RecipeFilterActionET }); t.string('value', {}); }, }); export const CreateRecipeCollectionIT = inputObjectType({ name: 'CreateRecipeCollectionInput', definition(t) { t.field('type', { type: RecipeCollectionET }); t.string('name'); t.list.id('recipes', { description: 'Array of Recipe IDs' }); t.list.field('filters', { type: 'RecipeFilterInput', description: 'Array of Filters', }); }, }); export const createRecipeCollection: FieldResolver< 'Mutation', 'createRecipeCollection' > = async (root, args, ctx, info) => { // Auth authenticateQuery(ctx); const input = args.input || {}; const { recipes = [], type = RecipeCollectionType.MANUAL, ...collectionProps } = input; // ** Validate if (!ctx.state.abilities.can('create', RecipeCollection)) { throw new ForbiddenError( 'You do not have permission to create a Collection' ); } if ( type === RecipeCollectionType.SMART && input && input.recipes !== undefined ) { throw new UserInputError( 'Recipes can not be included when creating a Smart Collection' ); } if ( type !== RecipeCollectionType.SMART && input && input.filters !== undefined ) { throw new UserInputError( 'Filters can only be included when creating a Smart Collection' ); } // ** Execute const formattedRecipes = recipes.map(r => ({ recipe: r, })); // TODO: Validate Recipe Id's are valid const props = { nodes: formattedRecipes, ownerId: ctx.state.user.id, ...collectionProps, }; let collection: RecipeCollection; // create RecipeCollection if (type === RecipeCollectionType.SMART) { collection = await SmartRecipeCollection.create(props); } else { collection = await ManualRecipeCollection.create(props); } return collection.populate({ path: 'nodes.recipe' }).execPopulate(); }; /** * Create a new RecipeCollection */ export const createRecipeCollectionMF = mutationField( 'createRecipeCollection', { type: 'RecipeCollection', args: { input: arg({ type: CreateRecipeCollectionIT, }), }, resolve: createRecipeCollection, } );