feat(SW-66, SW-348): search functionality and ui
This commit is contained in:
48
lib/discriminatedUnion.ts
Normal file
48
lib/discriminatedUnion.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import type {
|
||||
DiscriminatedUnionError,
|
||||
Option,
|
||||
} from "@/types/discriminatedUnion"
|
||||
|
||||
/**
|
||||
* This file is created to handle our discriminated unions
|
||||
* validations primarily for union returns from Contentstacks
|
||||
* GraphQL server.
|
||||
*
|
||||
* In the case of a new block being added to the union in Contenstack,
|
||||
* Zod will throw because that typename is not expected ("invalid_union_discriminator").
|
||||
* Therefore we add a safety that we return everytime we stumble upon
|
||||
* the issue and then we filter it out in the transform.
|
||||
*
|
||||
* This replaces the `cleanEmptyObjects` function that would require
|
||||
* everyone to never make a mistake in adding __typename to root
|
||||
* anywhere (or any other potentially global fields in case the return type
|
||||
* is an Interface e.g).
|
||||
*/
|
||||
|
||||
export function discriminatedUnion<T extends Option>(options: T[]) {
|
||||
return z
|
||||
.discriminatedUnion("__typename", [
|
||||
z.object({ __typename: z.literal(undefined) }),
|
||||
...options,
|
||||
])
|
||||
.catch(({ error }: DiscriminatedUnionError) => {
|
||||
if (
|
||||
error.issues.find(
|
||||
(issue) => issue.code === "invalid_union_discriminator"
|
||||
)
|
||||
) {
|
||||
return { __typename: undefined }
|
||||
}
|
||||
throw new Error(error.message)
|
||||
})
|
||||
}
|
||||
|
||||
export function discriminatedUnionArray<T extends Option>(options: T[]) {
|
||||
return z
|
||||
.array(discriminatedUnion(options))
|
||||
.transform((blocks) =>
|
||||
blocks.filter((block) => !!block)
|
||||
) as unknown as z.ZodEffects<z.ZodArray<T>>
|
||||
}
|
||||
Reference in New Issue
Block a user