feat(SW-2863): Move contentstack router to trpc package * Add exports to packages and lint rule to prevent relative imports * Add env to trpc package * Add eslint to trpc package * Apply lint rules * Use direct imports from trpc package * Add lint-staged config to trpc * Move lang enum to common * Restructure trpc package folder structure * WIP first step * update internal imports in trpc * Fix most errors in scandic-web Just 100 left... * Move Props type out of trpc * Fix CategorizedFilters types * Move more schemas in hotel router * Fix deps * fix getNonContentstackUrls * Fix import error * Fix entry error handling * Fix generateMetadata metrics * Fix alertType enum * Fix duplicated types * lint:fix * Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package * Fix broken imports * Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package Approved-by: Linus Flood
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { z } from "zod"
|
|
|
|
import type { ZodDiscriminatedUnionOption, ZodError } from "zod"
|
|
|
|
export interface DiscriminatedUnionError {
|
|
error: ZodError<unknown>
|
|
}
|
|
|
|
export interface Option extends ZodDiscriminatedUnionOption<"__typename"> {}
|
|
|
|
/**
|
|
* 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<R>(options: Option[]) {
|
|
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)
|
|
})
|
|
.transform((data) => {
|
|
if (data.__typename === "undefined" || data.__typename === undefined) {
|
|
return null
|
|
}
|
|
return data as R
|
|
})
|
|
}
|
|
|
|
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>>
|
|
}
|