import { SafeParseReturnType, z, ZodType } from 'zod'; import { IFeedbackFormStructure } from './types'; import { DropdownSchema } from './components/dropdown'; import { FacesRatingBarSchema } from './components/faces-rating-bar'; import { SegmentedToggleSchema } from './components/segmented-toggle'; import { TextInputSchema } from './components/text-input'; import { ThumbnailsSchema } from './components/thumbnails'; import { MarkdownSchema } from './components/markdown'; const schema = z.object({ id: z.string(), title: z.string(), components: z .array( z.discriminatedUnion('type', [ DropdownSchema, FacesRatingBarSchema, SegmentedToggleSchema, TextInputSchema, ThumbnailsSchema, MarkdownSchema, ]), ) .min(1) .superRefine((val, ctx) => { const uniqueQuestionIds = new Set(); const allQuestionIds = []; val.forEach((component) => { if ('questionId' in component) { uniqueQuestionIds.add(component.questionId); allQuestionIds.push(component.questionId); } }); if (allQuestionIds.length === 0) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'You are required to provide at least one component that defines a question', }); } if (allQuestionIds.length !== uniqueQuestionIds.size) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Question ids must be unique', }); } }), }) satisfies ZodType; export const validate = (structure: IFeedbackFormStructure) => { const result = schema.safeParse(structure) as SafeParseReturnType< IFeedbackFormStructure, IFeedbackFormStructure >; if (!result.success) { console.error(result.error); } return result; };