This commit is contained in:
@@ -6,75 +6,91 @@ import { z } from "zod"
|
|||||||
type JsonifiedEffectOptionSomeBrand = "@thilawyn/zod-schema-class/JsonifiedEffectOptionSome"
|
type JsonifiedEffectOptionSomeBrand = "@thilawyn/zod-schema-class/JsonifiedEffectOptionSome"
|
||||||
|
|
||||||
|
|
||||||
export const option = <S extends z.ZodTypeAny>(schema: S) =>
|
export function option<S extends z.ZodTypeAny>(schema: S) {
|
||||||
z.union([option.some(schema), option.none(schema)])
|
return z.union([option.some(schema), option.none(schema)])
|
||||||
|
}
|
||||||
|
|
||||||
|
export module option {
|
||||||
|
export function some<
|
||||||
|
InnerS extends z.ZodTypeAny
|
||||||
|
>(
|
||||||
|
schema: InnerS
|
||||||
|
) {
|
||||||
|
return z
|
||||||
|
.custom<Option.Some<z.output<InnerS>>>(v => Option.isOption(v) && Option.isSome(v), "Not an Option.Some")
|
||||||
|
.pipe(z.object({ value: schema }).passthrough())
|
||||||
|
.transform<Option.Some<z.output<InnerS>>>(identity)
|
||||||
|
}
|
||||||
|
|
||||||
|
export module some {
|
||||||
|
export function jsonify<
|
||||||
|
InnerS extends z.ZodTypeAny,
|
||||||
|
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||||
|
>(
|
||||||
|
schema: ZodEffectOptionSome<InnerS>,
|
||||||
|
jsonifySchema: (schema: InnerS) => JsonifiedInnerS = identity,
|
||||||
|
) {
|
||||||
|
return schema
|
||||||
|
.transform(v => Option.getOrThrow(v))
|
||||||
|
.pipe(jsonifySchema(effectOptionSomeInnerSchema(schema)))
|
||||||
|
.brand<JsonifiedEffectOptionSomeBrand>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dejsonify<
|
||||||
|
InnerS extends z.ZodTypeAny,
|
||||||
|
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||||
|
>(
|
||||||
|
schema: ZodEffectOptionSome<InnerS>,
|
||||||
|
dejsonifySchema: (schema: InnerS) => DejsonifiedInnerS = identity,
|
||||||
|
) {
|
||||||
|
return z
|
||||||
|
.custom<z.input<DejsonifiedInnerS> & z.BRAND<JsonifiedEffectOptionSomeBrand>>()
|
||||||
|
.pipe(dejsonifySchema(effectOptionSomeInnerSchema(schema)))
|
||||||
|
.transform(v => Option.some<z.output<DejsonifiedInnerS>>(v))
|
||||||
|
.pipe(schema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const some = <
|
export function none<
|
||||||
InnerS extends z.ZodTypeAny
|
InnerS extends z.ZodTypeAny | unknown = unknown
|
||||||
>(schema: InnerS) => z
|
>(
|
||||||
.custom<Option.Some<z.output<InnerS>>>(v => Option.isOption(v) && Option.isSome(v), "Not an Option.Some")
|
_schema?: InnerS
|
||||||
.pipe(z.object({ value: schema }).passthrough())
|
) {
|
||||||
.transform<Option.Some<z.output<InnerS>>>(identity)
|
return z.custom<
|
||||||
|
Option.None<
|
||||||
|
InnerS extends z.ZodTypeAny
|
||||||
|
? z.output<InnerS>
|
||||||
|
: unknown
|
||||||
|
>
|
||||||
|
>(v => Option.isOption(v) && Option.isNone(v), "Not an Option.None")
|
||||||
|
}
|
||||||
|
|
||||||
some.jsonify = <
|
export module none {
|
||||||
InnerS extends z.ZodTypeAny,
|
export function jsonify<
|
||||||
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
InnerS extends z.ZodTypeAny,
|
||||||
>(
|
JsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||||
schema: ZodEffectOptionSome<InnerS>,
|
>(
|
||||||
jsonifySchema: (schema: InnerS) => JsonifiedInnerS = identity,
|
schema: ZodEffectOptionNone<InnerS>,
|
||||||
) => schema
|
_jsonifySchema?: (schema: InnerS) => JsonifiedInnerS,
|
||||||
.transform(v => Option.getOrThrow(v))
|
) {
|
||||||
.pipe(jsonifySchema(effectOptionSomeInnerSchema(schema)))
|
return schema.transform(() => null)
|
||||||
.brand<JsonifiedEffectOptionSomeBrand>()
|
}
|
||||||
|
|
||||||
some.dejsonify = <
|
export function dejsonify<
|
||||||
InnerS extends z.ZodTypeAny,
|
InnerS extends z.ZodTypeAny,
|
||||||
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
||||||
>(
|
>(
|
||||||
schema: ZodEffectOptionSome<InnerS>,
|
schema: ZodEffectOptionNone<InnerS>,
|
||||||
dejsonifySchema: (schema: InnerS) => DejsonifiedInnerS = identity,
|
_dejsonifySchema?: (schema: InnerS) => DejsonifiedInnerS,
|
||||||
) => z
|
) {
|
||||||
.custom<z.input<DejsonifiedInnerS> & z.BRAND<JsonifiedEffectOptionSomeBrand>>()
|
return z
|
||||||
.pipe(dejsonifySchema(effectOptionSomeInnerSchema(schema)))
|
.null()
|
||||||
.transform(v => Option.some<z.output<DejsonifiedInnerS>>(v))
|
.transform(() => Option.none<z.output<DejsonifiedInnerS>>())
|
||||||
.pipe(schema)
|
.pipe(schema)
|
||||||
|
}
|
||||||
option.some = some
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const none = <
|
|
||||||
InnerS extends z.ZodTypeAny | unknown = unknown
|
|
||||||
>(_schema?: InnerS) =>
|
|
||||||
z.custom<
|
|
||||||
Option.None<
|
|
||||||
InnerS extends z.ZodTypeAny
|
|
||||||
? z.output<InnerS>
|
|
||||||
: 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<InnerS>,
|
|
||||||
_jsonifySchema?: (schema: InnerS) => JsonifiedInnerS,
|
|
||||||
) =>
|
|
||||||
schema.transform(() => null),
|
|
||||||
|
|
||||||
none.dejsonify = <
|
|
||||||
InnerS extends z.ZodTypeAny,
|
|
||||||
DejsonifiedInnerS extends z.ZodTypeAny = InnerS,
|
|
||||||
>(
|
|
||||||
schema: ZodEffectOptionNone<InnerS>,
|
|
||||||
_dejsonifySchema?: (schema: InnerS) => DejsonifiedInnerS,
|
|
||||||
) => z
|
|
||||||
.null()
|
|
||||||
.transform(() => Option.none<z.output<DejsonifiedInnerS>>())
|
|
||||||
.pipe(schema),
|
|
||||||
|
|
||||||
option.none = none
|
|
||||||
|
|
||||||
|
|
||||||
export type ZodEffectOption<S extends z.ZodTypeAny> = ReturnType<typeof option<S>>
|
export type ZodEffectOption<S extends z.ZodTypeAny> = ReturnType<typeof option<S>>
|
||||||
|
|||||||
Reference in New Issue
Block a user