Files
zod-schema-class/src/util.ts
Julien Valverdé 0817f85f5d
All checks were successful
continuous-integration/drone/push Build is passing
0.1.0 (#1)
Co-authored-by: Julien Valverdé <julien.valverde@mailo.com>
Reviewed-on: https://git.jvalver.de/Thilawyn/schemable-class/pulls/1
2024-01-05 00:39:32 +01:00

83 lines
2.0 KiB
TypeScript

import { Effect, pipe } from "effect"
import { mapValues } from "lodash-es"
import { z } from "zod"
/**
* Represents the static members of a class.
* @template C - The class type.
*/
export type StaticMembers<C> = {
[Key in keyof C as Key extends "prototype" ? never : Key]: C[Key]
}
/**
* Removes default values from a ZodObject schema and returns a new schema.
*
* @param schema - The ZodObject schema to process.
* @returns A new ZodObject schema with default values removed.
*/
export const zodObjectRemoveDefaults = <
T extends z.ZodRawShape,
UnknownKeys extends z.UnknownKeysParam,
Catchall extends z.ZodTypeAny,
Output extends {},
Input extends {},
>(
schema: z.ZodObject<
T,
UnknownKeys,
Catchall,
Output,
Input
>
) =>
schema.extend(zodShapeRemoveDefaults(schema.shape))
/**
* Removes default values from a ZodObject shape and returns a new shape.
*
* @param shape - The ZodObject shape to process.
* @returns A new shape with default values removed.
*/
export const zodShapeRemoveDefaults = <
Shape extends z.ZodRawShape
>(
shape: Shape
): {
[K in keyof Shape]:
Shape[K] extends z.ZodDefault<infer T>
? T
: Shape[K]
} =>
mapValues(shape, el =>
el instanceof z.ZodDefault
? el.removeDefault()
: el
)
/**
* Parses a value using a ZodType schema wrapped in an Effect monad.
*
* @param schema - The ZodType schema to use for parsing.
* @param args - The arguments to pass to the `safeParseAsync` method of the schema.
* @returns An Effect monad representing the parsing result.
*/
export const parseZodTypeEffect = <
Output,
Input,
>(
schema: z.ZodType<Output, z.ZodTypeDef, Input>,
...args: Parameters<typeof schema.safeParseAsync>
) => pipe(
Effect.promise(() => schema.safeParseAsync(...args)),
Effect.flatMap(response =>
response.success
? Effect.succeed(response.data)
: Effect.fail(response.error)
),
)