diff --git a/components/BeerById/BeerCommentForm.tsx b/components/BeerById/BeerCommentForm.tsx index 25314ef..3cd4099 100644 --- a/components/BeerById/BeerCommentForm.tsx +++ b/components/BeerById/BeerCommentForm.tsx @@ -1,7 +1,7 @@ import sendCreateBeerCommentRequest from '@/requests/sendCreateBeerCommentRequest'; import { BeerCommentQueryResultArrayT } from '@/services/BeerComment/schema/BeerCommentQueryResult'; import BeerCommentValidationSchema from '@/services/BeerComment/schema/CreateBeerCommentValidationSchema'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import { zodResolver } from '@hookform/resolvers/zod'; import { useRouter } from 'next/router'; import { Dispatch, SetStateAction, FunctionComponent, useState, useEffect } from 'react'; diff --git a/components/BeerById/BeerInfoHeader.tsx b/components/BeerById/BeerInfoHeader.tsx index b89e61a..49f970b 100644 --- a/components/BeerById/BeerInfoHeader.tsx +++ b/components/BeerById/BeerInfoHeader.tsx @@ -2,7 +2,7 @@ import Link from 'next/link'; import formatDistanceStrict from 'date-fns/formatDistanceStrict'; import format from 'date-fns/format'; import { FC, useContext, useEffect, useState } from 'react'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import UserContext from '@/contexts/userContext'; import BeerPostLikeButton from './BeerPostLikeButton'; diff --git a/components/BeerForm.tsx b/components/BeerForm.tsx index 5620e20..0de1c57 100644 --- a/components/BeerForm.tsx +++ b/components/BeerForm.tsx @@ -1,5 +1,5 @@ import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest'; -import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; +import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult'; import { zodResolver } from '@hookform/resolvers/zod'; import { BeerType } from '@prisma/client'; @@ -17,7 +17,7 @@ import FormSelect from './ui/forms/FormSelect'; import FormTextArea from './ui/forms/FormTextArea'; import FormTextInput from './ui/forms/FormTextInput'; -type BeerPostT = z.infer; +type BeerPostT = z.infer; interface BeerFormProps { formType: 'edit' | 'create'; @@ -38,7 +38,7 @@ const BeerForm: FunctionComponent = ({ handleSubmit, formState: { errors }, } = useForm({ - resolver: zodResolver(BeerPostValidationSchema), + resolver: zodResolver(CreateBeerPostValidationSchema), defaultValues: { name: defaultValues?.name, description: defaultValues?.description, diff --git a/components/BeerIndex/BeerCard.tsx b/components/BeerIndex/BeerCard.tsx index 0741ce7..86341d5 100644 --- a/components/BeerIndex/BeerCard.tsx +++ b/components/BeerIndex/BeerCard.tsx @@ -1,7 +1,7 @@ import Link from 'next/link'; import { FC } from 'react'; import Image from 'next/image'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; const BeerCard: FC<{ post: BeerPostQueryResult }> = ({ post }) => { return ( diff --git a/pages/api/beers/create.ts b/pages/api/beers/create.ts index 22d907f..e068774 100644 --- a/pages/api/beers/create.ts +++ b/pages/api/beers/create.ts @@ -2,7 +2,7 @@ import { UserExtendedNextApiRequest } from '@/config/auth/types'; import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import { createRouter } from 'next-connect'; import createNewBeerPost from '@/services/BeerPost/createNewBeerPost'; -import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; +import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiResponse } from 'next'; import { z } from 'zod'; @@ -10,7 +10,7 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions'; import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser'; interface CreateBeerPostRequest extends UserExtendedNextApiRequest { - body: z.infer; + body: z.infer; } const createBeerPost = async ( @@ -43,7 +43,7 @@ const router = createRouter< >(); router.post( - validateRequest({ bodySchema: BeerPostValidationSchema }), + validateRequest({ bodySchema: CreateBeerPostValidationSchema }), getCurrentUser, createBeerPost, ); diff --git a/pages/beers/[id].tsx b/pages/beers/[id].tsx index 3c8a956..5dc5183 100644 --- a/pages/beers/[id].tsx +++ b/pages/beers/[id].tsx @@ -9,7 +9,7 @@ import getAllBeerComments from '@/services/BeerComment/getAllBeerComments'; import { BeerCommentQueryResultArrayT } from '@/services/BeerComment/schema/BeerCommentQueryResult'; import getBeerPostById from '@/services/BeerPost/getBeerPostById'; import getBeerRecommendations from '@/services/BeerPost/getBeerRecommendations'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import { BeerPost } from '@prisma/client'; import { NextPage, GetServerSideProps } from 'next'; import Head from 'next/head'; diff --git a/pages/beers/index.tsx b/pages/beers/index.tsx index 24361a9..aee56cd 100644 --- a/pages/beers/index.tsx +++ b/pages/beers/index.tsx @@ -6,7 +6,7 @@ import DBClient from '@/prisma/DBClient'; import Layout from '@/components/ui/Layout'; import Pagination from '@/components/BeerIndex/Pagination'; import BeerCard from '@/components/BeerIndex/BeerCard'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import Head from 'next/head'; interface BeerPageProps { diff --git a/pages/breweries/[id].tsx b/pages/breweries/[id].tsx index 33a519d..13d42bc 100644 --- a/pages/breweries/[id].tsx +++ b/pages/breweries/[id].tsx @@ -1,4 +1,4 @@ -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import getBreweryPostById from '@/services/BreweryPost/getBreweryPostById'; import { GetServerSideProps, NextPage } from 'next'; diff --git a/requests/sendCreateBeerPostRequest.ts b/requests/sendCreateBeerPostRequest.ts index b40200e..0cfefc5 100644 --- a/requests/sendCreateBeerPostRequest.ts +++ b/requests/sendCreateBeerPostRequest.ts @@ -1,9 +1,10 @@ -import BeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; +import { beerPostQueryResultSchema } from '@/services/BeerPost/schema/BeerPostQueryResult'; +import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { z } from 'zod'; const sendCreateBeerPostRequest = async ( - data: z.infer, + data: z.infer, ) => { const response = await fetch('/api/beers/create', { method: 'POST', @@ -23,18 +24,13 @@ const sendCreateBeerPostRequest = async ( throw new Error(message); } - if ( - !( - payload && - typeof payload === 'object' && - 'id' in payload && - typeof payload.id === 'string' - ) - ) { + const parsedPayload = beerPostQueryResultSchema.safeParse(payload); + + if (!parsedPayload.success) { throw new Error('Invalid API response'); } - return payload; + return parsedPayload.data; }; export default sendCreateBeerPostRequest; diff --git a/services/BeerComment/getAllBeerComments.ts b/services/BeerComment/getAllBeerComments.ts index f293eb3..b01d576 100644 --- a/services/BeerComment/getAllBeerComments.ts +++ b/services/BeerComment/getAllBeerComments.ts @@ -1,5 +1,5 @@ import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from '../BeerPost/schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; import { BeerCommentQueryResultArrayT } from './schema/BeerCommentQueryResult'; const getAllBeerComments = async ( diff --git a/services/BeerPost/createNewBeerPost.ts b/services/BeerPost/createNewBeerPost.ts index afc2188..8a0b77f 100644 --- a/services/BeerPost/createNewBeerPost.ts +++ b/services/BeerPost/createNewBeerPost.ts @@ -1,8 +1,9 @@ import DBClient from '@/prisma/DBClient'; import { z } from 'zod'; -import BeerPostValidationSchema from './schema/CreateBeerPostValidationSchema'; +import { BeerPostQueryResult } from './schema/BeerPostQueryResult'; +import CreateBeerPostValidationSchema from './schema/CreateBeerPostValidationSchema'; -const CreateBeerPostWithUserSchema = BeerPostValidationSchema.extend({ +const CreateBeerPostWithUserSchema = CreateBeerPostValidationSchema.extend({ userId: z.string().uuid(), }); @@ -15,7 +16,7 @@ const createNewBeerPost = async ({ breweryId, userId, }: z.infer) => { - const newBeerPost = await DBClient.instance.beerPost.create({ + const newBeerPost: BeerPostQueryResult = await DBClient.instance.beerPost.create({ data: { name, description, @@ -25,6 +26,18 @@ const createNewBeerPost = async ({ postedBy: { connect: { id: userId } }, brewery: { connect: { id: breweryId } }, }, + select: { + id: true, + name: true, + description: true, + abv: true, + ibu: true, + createdAt: true, + beerImages: { select: { id: true, path: true, caption: true, alt: true } }, + brewery: { select: { id: true, name: true } }, + type: { select: { id: true, name: true } }, + postedBy: { select: { id: true, username: true } }, + }, }); return newBeerPost; }; diff --git a/services/BeerPost/getAllBeerPosts.ts b/services/BeerPost/getAllBeerPosts.ts index 23fc233..381bd4a 100644 --- a/services/BeerPost/getAllBeerPosts.ts +++ b/services/BeerPost/getAllBeerPosts.ts @@ -1,5 +1,5 @@ import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from './schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; const prisma = DBClient.instance; diff --git a/services/BeerPost/getBeerPostById.ts b/services/BeerPost/getBeerPostById.ts index ba64cb3..eb255c1 100644 --- a/services/BeerPost/getBeerPostById.ts +++ b/services/BeerPost/getBeerPostById.ts @@ -1,5 +1,5 @@ import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from './schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; const prisma = DBClient.instance; diff --git a/services/BeerPost/getBeerRecommendations.ts b/services/BeerPost/getBeerRecommendations.ts index a64b3ba..93ffa37 100644 --- a/services/BeerPost/getBeerRecommendations.ts +++ b/services/BeerPost/getBeerRecommendations.ts @@ -1,5 +1,5 @@ import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from './schema/BeerPostQueryResult'; +import { BeerPostQueryResult } from '@/services/BeerPost/schema/BeerPostQueryResult'; const getBeerRecommendations = async ( beerPost: Pick, diff --git a/services/BeerPost/schema/BeerPostQueryResult.ts b/services/BeerPost/schema/BeerPostQueryResult.ts index 7585da3..50500f9 100644 --- a/services/BeerPost/schema/BeerPostQueryResult.ts +++ b/services/BeerPost/schema/BeerPostQueryResult.ts @@ -1,28 +1,36 @@ -export default interface BeerPostQueryResult { - id: string; - name: string; - brewery: { - id: string; - name: string; - }; - description: string; - beerImages: { - path: string; - caption: string; - id: string; - alt: string; - }[]; +import { z } from 'zod'; - ibu: number; - abv: number; - type: { - id: string; - name: string; - }; - postedBy: { - id: string; - username: string; - }; +export const beerPostQueryResultSchema = z.object({ + id: z.string(), + name: z.string(), + brewery: z.object({ + id: z.string(), + name: z.string(), + }), + description: z.string(), + beerImages: z.array( + z.object({ + path: z.string(), + caption: z.string(), + id: z.string(), + alt: z.string(), + }), + ), + ibu: z.number(), + abv: z.number(), + type: z.object({ + id: z.string(), + name: z.string(), + }), + postedBy: z.object({ + id: z.string(), + username: z.string(), + }), + createdAt: z.date(), +}); - createdAt: Date; -} +export const beerPostQueryResultArraySchema = z.array(beerPostQueryResultSchema); + +export type BeerPostQueryResult = z.infer; + +export type BeerPostQueryResultArray = z.infer; diff --git a/services/BeerPost/schema/CreateBeerPostValidationSchema.ts b/services/BeerPost/schema/CreateBeerPostValidationSchema.ts index 71ee029..5325920 100644 --- a/services/BeerPost/schema/CreateBeerPostValidationSchema.ts +++ b/services/BeerPost/schema/CreateBeerPostValidationSchema.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -const BeerPostValidationSchema = z.object({ +const CreateBeerPostValidationSchema = z.object({ name: z .string({ required_error: 'Beer name is required.', @@ -40,4 +40,4 @@ const BeerPostValidationSchema = z.object({ .uuid({ message: 'Invalid brewery id.' }), }); -export default BeerPostValidationSchema; +export default CreateBeerPostValidationSchema;