From 74ac3b41ad88a96fb996ba41f50b513b52e9a2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 22 Mar 2024 01:11:13 +0100 Subject: [PATCH] Schema work --- src/schema/effect/option.ts | 86 ++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/src/schema/effect/option.ts b/src/schema/effect/option.ts index ba6aed1..a3f91aa 100644 --- a/src/schema/effect/option.ts +++ b/src/schema/effect/option.ts @@ -3,23 +3,83 @@ import { identity } from "lodash-es" import { z } from "zod" +type JsonifiedEffectOptionSomeBrand = "@thilawyn/zod-schema-class/JsonifiedEffectOptionSome" + + export const option = (schema: S) => z.union([option.some(schema), option.none(schema)]) -option.some = (schema: S) => z - .custom>>(v => Option.isOption(v) && Option.isSome(v), "Not an Option") + +const some = < + InnerS extends z.ZodTypeAny +>(schema: InnerS) => z + .custom>>(v => Option.isOption(v) && Option.isSome(v), "Not an Option.Some") .pipe(z.object({ value: schema }).passthrough()) - .transform>>(identity) + .transform>>(identity) -option.none = (_schema?: S) => - z.custom - : unknown - >>(v => Option.isOption(v) && Option.isNone(v), "Not an Option") +some.jsonify = < + InnerS extends z.ZodTypeAny, + JsonifiedInnerS extends z.ZodTypeAny = InnerS, +>( + schema: ZodEffectOptionSome, + jsonifySchema: (schema: InnerS) => JsonifiedInnerS = identity, +) => schema + .transform(v => Option.getOrThrow(v)) + .pipe(jsonifySchema(effectOptionSomeInnerSchema(schema))) + .brand() + +some.dejsonify = < + InnerS extends z.ZodTypeAny, + DejsonifiedInnerS extends z.ZodTypeAny = InnerS, +>( + schema: ZodEffectOptionSome, + dejsonifySchema: (schema: InnerS) => DejsonifiedInnerS = identity, +) => z + .custom & z.BRAND>() + .pipe(dejsonifySchema(effectOptionSomeInnerSchema(schema))) + .transform(v => Option.some>(v)) + .pipe(schema) + +option.some = some -export type ZodEffectOption = ReturnType> +const none = < + InnerS extends z.ZodTypeAny | unknown = unknown +>(_schema?: InnerS) => + z.custom< + Option.None< + InnerS extends z.ZodTypeAny + ? z.output + : unknown + > + >(v => Option.isOption(v) && Option.isNone(v), "Not an Option.None") + +none.jsonify = < + InnerS extends z.ZodTypeAny, + JsonifiedInnerS extends z.ZodTypeAny = InnerS, +>( + schema: ZodEffectOptionNone, + _jsonifySchema?: (schema: InnerS) => JsonifiedInnerS, +) => + schema.transform(() => null), + +none.dejsonify = < + InnerS extends z.ZodTypeAny, + DejsonifiedInnerS extends z.ZodTypeAny = InnerS, +>( + schema: ZodEffectOptionNone, + _dejsonifySchema?: (schema: InnerS) => DejsonifiedInnerS, +) => z + .null() + .transform(() => Option.none>()) + .pipe(schema), + +option.none = none + + +export type ZodEffectOption = ReturnType> +export type ZodEffectOptionSome = ReturnType> +export type ZodEffectOptionNone = ReturnType> export const effectOptionSomeSchema = (schema: ZodEffectOption): ZodEffectOptionSome => schema.options[0] @@ -27,11 +87,5 @@ export const effectOptionSomeSchema = (schema: ZodEffect export const effectOptionNoneSchema = (schema: ZodEffectOption): ZodEffectOptionNone => schema.options[1] - -export type ZodEffectOptionSome = ReturnType> - export const effectOptionSomeInnerSchema = (schema: ZodEffectOptionSome): S => schema._def.schema._def.out.shape.value - - -export type ZodEffectOptionNone = ReturnType>