diff --git a/src/controllers/form.ts b/src/controllers/form.ts index ad09102..71056aa 100644 --- a/src/controllers/form.ts +++ b/src/controllers/form.ts @@ -1,17 +1,23 @@ -import { PrismaClient } from "@prisma/client" -import { ApolloError } from "apollo-server-express" +import { PrismaClient } from '@prisma/client' +import { ApolloError } from 'apollo-server-express' -import { getDBForm, getDBFormByUser } from "../db" -import { FullForm } from "../db/types" -import { Form as GraphqlForm, FormSubmission } from "../typeDefs/typeDefs.gen" +import { createDBForm, getDBForm, getDBFormByUser } from '../db' +import { FullForm } from '../db/types' +import { + ChoisesQuestion, + Form as GraphqlForm, + FormSubmission, + InputQuestion, + MutationCreateFormArgs, + Question +} from '../typeDefs/typeDefs.gen' -const getForm = async ( - db: PrismaClient, - id: number -): Promise => { +import { createChoises, newForm } from './types' + +const getForm = async (db: PrismaClient, id: number) => { const dbForm: FullForm = await getDBForm(db, id) - if (dbForm == null) throw new ApolloError("Not found") + if (dbForm == null) throw new ApolloError('Not found') const form: GraphqlForm = { id: dbForm.id, @@ -21,18 +27,15 @@ const getForm = async ( submissions: dbForm.submissions.map((submission) => ({ answers: submission.answers, date: submission.date.toString(), - id: submission.id, + id: submission.id })), - author: dbForm.author, + author: dbForm.author } return form } -const getForms = async ( - db: PrismaClient, - userId: number -): Promise => { +const getForms = async (db: PrismaClient, userId: number) => { const dbForms = await getDBFormByUser(db, userId) const forms = [ @@ -44,12 +47,55 @@ const getForms = async ( submissions: form.submissions.map((submission) => ({ answers: submission.answers, date: submission.date.toString(), - id: submission.id, - })), - })), + id: submission.id + })) + })) ] return forms } -export { getForm, getForms } +const createFormFrom = async ( + db: PrismaClient, + params: MutationCreateFormArgs, + id: number +) => { + const parsedQuestions = JSON.parse(params.questions) + const newForm: newForm = { + title: params.title, + inputQuestions: { + create: parsedQuestions.filter( + (val: InputQuestion | ChoisesQuestion, index) => { + if (!('type' in val)) + return { + number: index, + title: val.title + } + } + ) + }, + choisesQuestions: { + create: parsedQuestions.flatMap( + (val: InputQuestion | ChoisesQuestion, index) => { + if ('type' in val) { + return [ + { + number: index, + title: val.title, + type: val.type, + variants: { create: val.variants } + } + ] + } + { + return [] + } + } + ) + } + } + + return createDBForm(db, newForm, id) +} + +export { getForm, getForms, createFormFrom } diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 69f7403..f438d4d 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,4 +1,11 @@ -import { getForm, getForms } from "./form" -import { checkRightsAndResolve, getFormAuthor } from "./auth" +import { getForm, getForms, createFormFrom } from './form' +import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth' -export { checkRightsAndResolve, getForm, getFormAuthor, getForms } +export { + checkRightsAndResolve, + getForm, + getFormAuthor, + getForms, + createFormFrom, + sendTokenEmail +} diff --git a/src/controllers/types.ts b/src/controllers/types.ts index b92478f..50ee251 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -1,3 +1,8 @@ +import { + ChoisesQuestion, + InputQuestion, + Variant +} from '../typeDefs/typeDefs.gen' import { JwtPayloadType } from '../types' type expectedType = { @@ -15,4 +20,16 @@ type CheckRightsAndResolve = ( params: ICheckRightsAndResolve ) => Promise -export { CheckRightsAndResolve } +type newForm = { + title: string + choisesQuestions: { + create: createChoises[] + } + inputQuestions: { create: InputQuestion[] } +} + +type createChoises = Omit & { + variants: { create: Variant[] } +} + +export { CheckRightsAndResolve, newForm, createChoises } diff --git a/src/db/index.ts b/src/db/index.ts index e0ec7a3..36fd46a 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -1,5 +1,6 @@ import { PrismaClient } from '@prisma/client' import { UserInputError } from 'apollo-server-express' +import { newForm } from '../controllers/types' import { MutationRegisterArgs } from '../typeDefs/typeDefs.gen' import { IFindUserParams } from './types' @@ -69,7 +70,7 @@ const getDBFormAuthor = async (db: PrismaClient, id: number) => { }) } -const createUser = async ( +const createDBUser = async ( db: PrismaClient, { email, name }: MutationRegisterArgs ) => { @@ -78,7 +79,7 @@ const createUser = async ( }) } -const findUserBy = async (db: PrismaClient, params: IFindUserParams) => { +const findDBUserBy = async (db: PrismaClient, params: IFindUserParams) => { const user = await db.user.findOne({ where: { ...params @@ -89,4 +90,28 @@ const findUserBy = async (db: PrismaClient, params: IFindUserParams) => { return user } -export { getDBForm, getDBFormByUser, getDBFormAuthor, createUser, findUserBy } +const createDBForm = async ( + db: PrismaClient, + { title, inputQuestions, choisesQuestions }: newForm, + id: number +) => { + console.log(title, inputQuestions, choisesQuestions) + + return await db.form.create({ + data: { + author: { connect: { id } }, + title, + choisesQuestions, + inputQuestions + } + }) +} + +export { + getDBForm, + getDBFormByUser, + getDBFormAuthor, + createDBUser, + findDBUserBy, + createDBForm +} diff --git a/src/resolvers/Form.ts b/src/resolvers/Form.ts index 56e9b23..f890ed1 100644 --- a/src/resolvers/Form.ts +++ b/src/resolvers/Form.ts @@ -2,14 +2,16 @@ import { checkRightsAndResolve, getForm, getFormAuthor, - getForms + getForms, + createFormFrom } from '../controllers' import { Form, QueryFormArgs, QuestionResolvers, Resolver, - AnswerResolvers + AnswerResolvers, + MutationCreateFormArgs } from '../typeDefs/typeDefs.gen' import { ApolloContextType } from '../types' @@ -60,6 +62,29 @@ const formsQuery: Resolver = async ( } } +const createForm: Resolver< + Form, + {}, + ApolloContextType, + MutationCreateFormArgs +> = async (_, { questions, title }, { db, user }) => { + const createNewForm = (id: number) => + createFormFrom( + db, + { + title, + questions + }, + id + ) + + return await checkRightsAndResolve({ + user, + expected: { id: 0, self: true }, + controller: createNewForm + }) +} + const QuestionResolver: QuestionResolvers = { __resolveType(obj: any) { if (obj.type) { @@ -78,4 +103,4 @@ const AnswerResolver: AnswerResolvers = { } } -export { formQuery, formsQuery, QuestionResolver, AnswerResolver } +export { formQuery, formsQuery, QuestionResolver, AnswerResolver, createForm } diff --git a/src/resolvers/User.ts b/src/resolvers/User.ts index 5219e04..faf77e3 100644 --- a/src/resolvers/User.ts +++ b/src/resolvers/User.ts @@ -1,7 +1,7 @@ import { UserInputError } from 'apollo-server-express' -import { checkRightsAndResolve, sendTokenEmail } from '../controllers/auth' -import { createUser, findUserBy } from '../db' +import { checkRightsAndResolve, sendTokenEmail } from '../controllers' +import { createDBUser, findDBUserBy } from '../db' import { MutationLoginArgs, MutationRegisterArgs, @@ -19,7 +19,7 @@ const loginResolver: Resolver< MutationLoginArgs > = async (_, { email }, { db }) => { try { - const user = await findUserBy(db, { email }) + const user = await findDBUserBy(db, { email }) if (!user) throw new UserInputError('No such user') @@ -38,7 +38,7 @@ const registerResolver: Resolver< MutationRegisterArgs > = async (_, { email, name }, { db }) => { try { - const user = await createUser(db, { email, name }) + const user = await createDBUser(db, { email, name }) await sendTokenEmail(email, user) @@ -54,7 +54,7 @@ const userResolver: Resolver< ApolloContextType, QueryUserArgs > = async (_, { id }, { db, user }) => { - const findUserById = (id: number) => findUserBy(db, { id }) + const findUserById = (id: number) => findDBUserBy(db, { id }) try { return await checkRightsAndResolve({ diff --git a/src/resolvers/index.ts b/src/resolvers/index.ts index a2c4e54..6f5fd71 100644 --- a/src/resolvers/index.ts +++ b/src/resolvers/index.ts @@ -4,7 +4,8 @@ import { formQuery as form, QuestionResolver as Question, AnswerResolver as Answer, - formsQuery as forms + formsQuery as forms, + createForm } from './Form' import { loginResolver as login, @@ -20,7 +21,8 @@ const resolvers: Resolvers = { }, Mutation: { login, - register + register, + createForm }, Question, Answer diff --git a/src/typeDefs/index.ts b/src/typeDefs/index.ts index 7546391..88dfa57 100644 --- a/src/typeDefs/index.ts +++ b/src/typeDefs/index.ts @@ -1,8 +1,8 @@ -import { gql } from "apollo-server-express" -import fs from "fs" +import { gql } from 'apollo-server-express' +import fs from 'fs' const typeDefs = gql( - fs.readFileSync(__dirname.concat("/typeDefs.gql"), { encoding: "utf-8" }) + fs.readFileSync(__dirname.concat('/typeDefs.gql'), { encoding: 'utf-8' }) ) export default typeDefs diff --git a/src/typeDefs/typeDefs.gql b/src/typeDefs/typeDefs.gql index 0750c66..ab3205b 100644 --- a/src/typeDefs/typeDefs.gql +++ b/src/typeDefs/typeDefs.gql @@ -7,6 +7,7 @@ type Query { type Mutation { login(email: String!): LoginResult register(name: String!, email: String!): LoginResult + createForm(title: String!, questions: String!): Form! } type Form { @@ -25,7 +26,7 @@ interface Question { type ChoisesQuestion implements Question { title: String! - variants: [Variant!] + variants: [Variant!]! type: ChoiseType! number: Int! }