From 51154c49d8e7cc5706cf7a2670d7b05ee8f76010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 11:49:03 -0500 Subject: [PATCH 01/50] chore(zui): inverse relation between native type kinds and schemas (#14946) --- .../zui/src/transforms/common/json-schema.ts | 10 +- .../zui-to-json-schema-legacy/parseDef.ts | 6 +- .../zodToJsonSchema.ts | 6 +- packages/zui/src/ui/types.ts | 24 +-- packages/zui/src/z/types/any/index.ts | 15 +- packages/zui/src/z/types/array/index.ts | 5 +- packages/zui/src/z/types/basetype/index.ts | 18 +- packages/zui/src/z/types/bigint/index.ts | 5 +- packages/zui/src/z/types/boolean/index.ts | 5 +- packages/zui/src/z/types/branded/index.ts | 4 +- packages/zui/src/z/types/catch/index.ts | 5 +- packages/zui/src/z/types/date/index.ts | 5 +- packages/zui/src/z/types/default/index.ts | 5 +- packages/zui/src/z/types/defs.ts | 182 ------------------ .../src/z/types/discriminatedUnion/index.ts | 5 +- packages/zui/src/z/types/enum/index.ts | 5 +- packages/zui/src/z/types/function/index.ts | 5 +- packages/zui/src/z/types/index.ts | 2 +- .../zui/src/z/types/intersection/index.ts | 5 +- packages/zui/src/z/types/lazy/index.ts | 5 +- packages/zui/src/z/types/literal/index.ts | 5 +- packages/zui/src/z/types/map/index.ts | 5 +- packages/zui/src/z/types/nan/index.ts | 5 +- .../z/types/{defs.test.ts => native.test.ts} | 2 +- packages/zui/src/z/types/native.ts | 139 +++++++++++++ packages/zui/src/z/types/nativeEnum/index.ts | 5 +- packages/zui/src/z/types/never/index.ts | 5 +- packages/zui/src/z/types/null/index.ts | 5 +- packages/zui/src/z/types/nullable/index.ts | 5 +- packages/zui/src/z/types/number/index.ts | 5 +- packages/zui/src/z/types/object/index.ts | 15 +- packages/zui/src/z/types/optional/index.ts | 5 +- packages/zui/src/z/types/pipeline/index.ts | 15 +- packages/zui/src/z/types/promise/index.ts | 5 +- packages/zui/src/z/types/readonly/index.ts | 5 +- packages/zui/src/z/types/record/index.ts | 7 +- packages/zui/src/z/types/ref/index.ts | 5 +- packages/zui/src/z/types/set/index.ts | 5 +- packages/zui/src/z/types/string/index.ts | 5 +- packages/zui/src/z/types/symbol/index.ts | 5 +- packages/zui/src/z/types/transformer/index.ts | 9 +- packages/zui/src/z/types/tuple/index.ts | 5 +- packages/zui/src/z/types/undefined/index.ts | 5 +- packages/zui/src/z/types/union/index.ts | 5 +- packages/zui/src/z/types/unknown/index.ts | 15 +- packages/zui/src/z/types/void/index.ts | 5 +- packages/zui/src/z/z.ts | 41 ---- 47 files changed, 259 insertions(+), 401 deletions(-) delete mode 100644 packages/zui/src/z/types/defs.ts rename packages/zui/src/z/types/{defs.test.ts => native.test.ts} (99%) create mode 100644 packages/zui/src/z/types/native.ts diff --git a/packages/zui/src/transforms/common/json-schema.ts b/packages/zui/src/transforms/common/json-schema.ts index c708d2fab98..834cf79ad4c 100644 --- a/packages/zui/src/transforms/common/json-schema.ts +++ b/packages/zui/src/transforms/common/json-schema.ts @@ -9,12 +9,12 @@ import { util } from '../../z/types/utils' * Mutiple zui schemas map to the same JSON schema; undefined/never, any/unknown, union/discriminated-union * Adding some ZodDef to the ZuiExtension allows us to differentiate between them */ -type NullableDef = util.Satisfies<{ typeName: z.ZodFirstPartyTypeKind.ZodNullable }, Partial> -type OptionalDef = util.Satisfies<{ typeName: z.ZodFirstPartyTypeKind.ZodOptional }, Partial> -type UndefinedDef = util.Satisfies<{ typeName: z.ZodFirstPartyTypeKind.ZodUndefined }, Partial> -type UnknownDef = util.Satisfies<{ typeName: z.ZodFirstPartyTypeKind.ZodUnknown }, Partial> +type NullableDef = util.Satisfies<{ typeName: 'ZodNullable' }, Partial> +type OptionalDef = util.Satisfies<{ typeName: 'ZodOptional' }, Partial> +type UndefinedDef = util.Satisfies<{ typeName: 'ZodUndefined' }, Partial> +type UnknownDef = util.Satisfies<{ typeName: 'ZodUnknown' }, Partial> type DiscriminatedUnionDef = util.Satisfies< - { typeName: z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion; discriminator?: string }, + { typeName: 'ZodDiscriminatedUnion'; discriminator?: string }, Partial > diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts index 808e462fa14..e141ffeaead 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts @@ -1,5 +1,5 @@ import { zuiKey } from '../../ui/constants' -import { ZodFirstPartyTypeKind, ZodTypeDef } from '../../z/index' +import { ZodFirstPartyTypeKind, ZodDef } from '../../z/index' import { JsonSchema7AnyType, parseAnyDef } from './parsers/any' import { JsonSchema7ArrayType, parseArrayDef } from './parsers/array' import { JsonSchema7BigintType, parseBigintDef } from './parsers/bigint' @@ -68,7 +68,7 @@ export type JsonSchema7TypeUnion = export type JsonSchema7Type = JsonSchema7TypeUnion & JsonSchema7Meta export function parseDef( - def: ZodTypeDef, + def: ZodDef, refs: Refs, forceResolution = false // Forces a new schema to be instantiated even though its def has been seen. Used for improving refs in definitions. See https://github.com/StefanTerdell/zod-to-json-schema/pull/61. ): JsonSchema7Type | undefined { @@ -212,7 +212,7 @@ const selectParser = (def: any, typeName: ZodFirstPartyTypeKind, refs: Refs): Js } } -export const addMeta = (def: ZodTypeDef, refs: Refs, jsonSchema: S): S => { +export const addMeta = (def: ZodDef, refs: Refs, jsonSchema: S): S => { if (def.description) { jsonSchema.description = def.description diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts index 9ea4c7d496a..4a28b896cdc 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts @@ -1,4 +1,4 @@ -import type { ZodSchema } from '../../z/index' +import type { ZodDef, ZodSchema } from '../../z/index' import { Options, Targets } from './Options' import { JsonSchema7Type, parseDef } from './parseDef' import { getRefs } from './Refs' @@ -25,7 +25,7 @@ const zodToJsonSchema = ( ...acc, [name]: parseDef( - schema._def, + schema._def as ZodDef, { ...refs, currentPath: [...refs.basePath, refs.definitionPath, name], @@ -41,7 +41,7 @@ const zodToJsonSchema = ( const main = parseDef( - schema._def, + schema._def as ZodDef, name === undefined ? refs : { diff --git a/packages/zui/src/ui/types.ts b/packages/zui/src/ui/types.ts index dec0f18d727..1977edf113d 100644 --- a/packages/zui/src/ui/types.ts +++ b/packages/zui/src/ui/types.ts @@ -1,4 +1,4 @@ -import { ZodEnumDef, z } from '../z' +import { ZodEnumDef, ZodNativeSchemaDef, z } from '../z' export type ZuiMetadata = string | number | boolean | null | undefined | ZuiMetadata[] | { [key: string]: ZuiMetadata } @@ -28,29 +28,29 @@ export type UIComponentDefinitions = { } } -export type ZodKindToBaseType = T extends infer U - ? U extends { typeName: z.ZodFirstPartyTypeKind.ZodString } +export type ZodKindToBaseType = T extends infer U + ? U extends { typeName: 'ZodString' } ? 'string' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodNumber } + : U extends { typeName: 'ZodNumber' } ? 'number' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodBoolean } + : U extends { typeName: 'ZodBoolean' } ? 'boolean' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodArray } + : U extends { typeName: 'ZodArray' } ? 'array' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodObject } + : U extends { typeName: 'ZodObject' } ? 'object' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodTuple } + : U extends { typeName: 'ZodTuple' } ? never : U extends ZodEnumDef ? 'string' - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodDefault; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodDefault'; innerType: z.ZodTypeAny } ? ZodKindToBaseType - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodOptional; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodOptional'; innerType: z.ZodTypeAny } ? ZodKindToBaseType - : U extends { typeName: z.ZodFirstPartyTypeKind.ZodNullable; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodNullable'; innerType: z.ZodTypeAny } ? ZodKindToBaseType : U extends { - typeName: z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion + typeName: 'ZodDiscriminatedUnion' options: z.ZodDiscriminatedUnionOption[] } ? 'discriminatedUnion' diff --git a/packages/zui/src/z/types/any/index.ts b/packages/zui/src/z/types/any/index.ts index 652247e1295..7e5176ad02a 100644 --- a/packages/zui/src/z/types/any/index.ts +++ b/packages/zui/src/z/types/any/index.ts @@ -1,16 +1,7 @@ -import { - RawCreateParams, - ZodFirstPartyTypeKind, - ZodType, - ZodTypeDef, - OK, - ParseInput, - ParseReturnType, - processCreateParams, -} from '../index' +import { RawCreateParams, ZodType, ZodTypeDef, OK, ParseInput, ParseReturnType, processCreateParams } from '../index' export type ZodAnyDef = { - typeName: ZodFirstPartyTypeKind.ZodAny + typeName: 'ZodAny' } & ZodTypeDef export class ZodAny extends ZodType { @@ -21,7 +12,7 @@ export class ZodAny extends ZodType { } static create = (params?: RawCreateParams): ZodAny => { return new ZodAny({ - typeName: ZodFirstPartyTypeKind.ZodAny, + typeName: 'ZodAny', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index b1adaa3c87f..575a0c985a2 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -3,7 +3,6 @@ import { ZodIssueCode, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -19,7 +18,7 @@ import { export type ZodArrayDef = { type: T - typeName: ZodFirstPartyTypeKind.ZodArray + typeName: 'ZodArray' exactLength: { value: number; message?: string } | null minLength: { value: number; message?: string } | null maxLength: { value: number; message?: string } | null @@ -178,7 +177,7 @@ export class ZodArray = { readonly _input: Input } +type Cast = A extends B ? A : B + export type RefinementCtx = { addIssue: (arg: IssueData) => void path: (string | number)[] @@ -75,7 +77,7 @@ export type { TypeOf as infer } export type Maskable = boolean | ((shape: T | null) => util.DeepPartialBoolean | boolean) export type CustomErrorParams = Partial> export type ZodTypeDef = { - typeName: ZodFirstPartyTypeKind + typeName: string errorMap?: ZodErrorMap description?: string [zuiKey]?: ZuiExtensionObject @@ -365,7 +367,7 @@ export abstract class ZodType['refinement']): ZodEffects { return new ZodEffects({ schema: this, - typeName: ZodFirstPartyTypeKind.ZodEffects, + typeName: 'ZodEffects', effect: { type: 'refinement', refinement }, }) } @@ -456,7 +458,7 @@ export abstract class ZodType(brand?: B): ZodBranded brand(): ZodBranded { return new ZodBranded({ - typeName: ZodFirstPartyTypeKind.ZodBranded, + typeName: 'ZodBranded', type: this, ...processCreateParams(this._def), }) @@ -490,7 +492,7 @@ export abstract class ZodType, + Type extends BaseType = ZodKindToBaseType>, >(options: ParseSchema): this { return this.metadata({ displayAs: [options.id, options.params] }) } diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 0dbbefccf7f..187215e4331 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -7,7 +7,6 @@ import { ParseStatus, ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -24,7 +23,7 @@ export type ZodBigIntCheck = export type ZodBigIntDef = { checks: ZodBigIntCheck[] - typeName: ZodFirstPartyTypeKind.ZodBigInt + typeName: 'ZodBigInt' coerce: boolean } & ZodTypeDef @@ -95,7 +94,7 @@ export class ZodBigInt extends ZodType { static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBigInt => { return new ZodBigInt({ checks: [], - typeName: ZodFirstPartyTypeKind.ZodBigInt, + typeName: 'ZodBigInt', coerce: params?.coerce ?? false, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index 6aff5ab7ba1..bb644eeff1b 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -14,7 +13,7 @@ import { } from '../index' export type ZodBooleanDef = { - typeName: ZodFirstPartyTypeKind.ZodBoolean + typeName: 'ZodBoolean' coerce: boolean } & ZodTypeDef @@ -39,7 +38,7 @@ export class ZodBoolean extends ZodType { static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBoolean => { return new ZodBoolean({ - typeName: ZodFirstPartyTypeKind.ZodBoolean, + typeName: 'ZodBoolean', coerce: params?.coerce || false, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/branded/index.ts b/packages/zui/src/z/types/branded/index.ts index 5147d37a947..161096f181d 100644 --- a/packages/zui/src/z/types/branded/index.ts +++ b/packages/zui/src/z/types/branded/index.ts @@ -1,10 +1,10 @@ -import { ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, ParseInput, ParseReturnType } from '../index' +import { ZodType, ZodTypeAny, ZodTypeDef, ParseInput, ParseReturnType } from '../index' type Key = string | number | symbol export type ZodBrandedDef = { type: T - typeName: ZodFirstPartyTypeKind.ZodBranded + typeName: 'ZodBranded' } & ZodTypeDef export const BRAND: unique symbol = Symbol('zod_brand') diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index 9fd6e625269..f8ca3b666df 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -1,7 +1,6 @@ import { ZodError, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -17,7 +16,7 @@ export type CatchFn = (ctx: { error: ZodError; input: unknown }) => Y export type ZodCatchDef = { innerType: T catchValue: CatchFn - typeName: ZodFirstPartyTypeKind.ZodCatch + typeName: 'ZodCatch' } & ZodTypeDef export class ZodCatch extends ZodType< @@ -88,7 +87,7 @@ export class ZodCatch extends ZodType< ): ZodCatch => { return new ZodCatch({ innerType: type, - typeName: ZodFirstPartyTypeKind.ZodCatch, + typeName: 'ZodCatch', catchValue: typeof params.catch === 'function' ? params.catch : () => params.catch, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index 2179beb471f..3e28979d0db 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -4,7 +4,6 @@ import { util, ZodParsedType, errorUtil, - ZodFirstPartyTypeKind, ZodTypeDef, addIssueToContext, INVALID, @@ -23,7 +22,7 @@ export type ZodDateCheck = export type ZodDateDef = { checks: ZodDateCheck[] coerce: boolean - typeName: ZodFirstPartyTypeKind.ZodDate + typeName: 'ZodDate' } & ZodTypeDef export class ZodDate extends ZodType { @@ -141,7 +140,7 @@ export class ZodDate extends ZodType { return new ZodDate({ checks: [], coerce: params?.coerce || false, - typeName: ZodFirstPartyTypeKind.ZodDate, + typeName: 'ZodDate', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 2a37987bc0c..2927ba5e8d2 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -2,7 +2,6 @@ import { isEqual } from 'lodash-es' import { RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -16,7 +15,7 @@ import { export type ZodDefaultDef = { innerType: T defaultValue: () => util.noUndefined - typeName: ZodFirstPartyTypeKind.ZodDefault + typeName: 'ZodDefault' } & ZodTypeDef export class ZodDefault extends ZodType< @@ -66,7 +65,7 @@ export class ZodDefault extends ZodType< ): ZodDefault => { return new ZodDefault({ innerType: type, - typeName: ZodFirstPartyTypeKind.ZodDefault, + typeName: 'ZodDefault', defaultValue: typeof value === 'function' ? value : () => value, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/defs.ts b/packages/zui/src/z/types/defs.ts deleted file mode 100644 index d6cfcef6e36..00000000000 --- a/packages/zui/src/z/types/defs.ts +++ /dev/null @@ -1,182 +0,0 @@ -import type { - ZodAnyDef, - ZodArrayDef, - ZodBigIntDef, - ZodBooleanDef, - ZodBrandedDef, - ZodCatchDef, - ZodDateDef, - ZodDefaultDef, - ZodDiscriminatedUnionDef, - ZodEnumDef, - ZodFunctionDef, - ZodIntersectionDef, - ZodLazyDef, - ZodLiteralDef, - ZodMapDef, - ZodNativeEnumDef, - ZodNeverDef, - ZodNullDef, - ZodNullableDef, - ZodNumberDef, - ZodObjectDef, - ZodOptionalDef, - ZodPipelineDef, - ZodPromiseDef, - ZodReadonlyDef, - ZodRecordDef, - ZodStringDef, - ZodEffectsDef, - ZodTupleDef, - ZodUndefinedDef, - ZodUnionDef, - ZodUnknownDef, - ZodVoidDef, - ZodRefDef, - ZodSetDef, -} from './index' - -export type ZodDef = - | ZodStringDef - | ZodNumberDef - | ZodBigIntDef - | ZodBooleanDef - | ZodDateDef - | ZodUndefinedDef - | ZodNullDef - | ZodDefaultDef // contains functions - | ZodCatchDef // contains functions - | ZodReadonlyDef - | ZodDiscriminatedUnionDef - | ZodBrandedDef - | ZodPipelineDef - | ZodAnyDef - | ZodUnknownDef - | ZodNeverDef - | ZodVoidDef - | ZodArrayDef - | ZodObjectDef // contains functions - | ZodUnionDef - | ZodIntersectionDef - | ZodTupleDef - | ZodRecordDef - | ZodMapDef - | ZodFunctionDef - | ZodLazyDef // contains functions - | ZodLiteralDef - | ZodEnumDef - | ZodEffectsDef // contains functions - | ZodNativeEnumDef - | ZodOptionalDef - | ZodNullableDef - | ZodPromiseDef - | ZodRefDef - | ZodSetDef - -export enum ZodFirstPartyTypeKind { - ZodString = 'ZodString', - ZodNumber = 'ZodNumber', - ZodNaN = 'ZodNaN', - ZodBigInt = 'ZodBigInt', - ZodBoolean = 'ZodBoolean', - ZodDate = 'ZodDate', - ZodSymbol = 'ZodSymbol', - ZodUndefined = 'ZodUndefined', - ZodNull = 'ZodNull', - ZodAny = 'ZodAny', - ZodUnknown = 'ZodUnknown', - ZodNever = 'ZodNever', - ZodVoid = 'ZodVoid', - ZodArray = 'ZodArray', - ZodObject = 'ZodObject', - ZodUnion = 'ZodUnion', - ZodDiscriminatedUnion = 'ZodDiscriminatedUnion', - ZodIntersection = 'ZodIntersection', - ZodTuple = 'ZodTuple', - ZodRecord = 'ZodRecord', - ZodRef = 'ZodRef', - ZodMap = 'ZodMap', - ZodSet = 'ZodSet', - ZodFunction = 'ZodFunction', - ZodLazy = 'ZodLazy', - ZodLiteral = 'ZodLiteral', - ZodEnum = 'ZodEnum', - ZodEffects = 'ZodEffects', - ZodNativeEnum = 'ZodNativeEnum', - ZodOptional = 'ZodOptional', - ZodNullable = 'ZodNullable', - ZodDefault = 'ZodDefault', - ZodCatch = 'ZodCatch', - ZodPromise = 'ZodPromise', - ZodBranded = 'ZodBranded', - ZodPipeline = 'ZodPipeline', - ZodReadonly = 'ZodReadonly', -} - -export type KindToDef = T extends ZodFirstPartyTypeKind.ZodString - ? ZodStringDef - : T extends ZodFirstPartyTypeKind.ZodNumber - ? ZodNumberDef - : T extends ZodFirstPartyTypeKind.ZodBigInt - ? ZodBigIntDef - : T extends ZodFirstPartyTypeKind.ZodBoolean - ? ZodBooleanDef - : T extends ZodFirstPartyTypeKind.ZodDate - ? ZodDateDef - : T extends ZodFirstPartyTypeKind.ZodUndefined - ? ZodUndefinedDef - : T extends ZodFirstPartyTypeKind.ZodNull - ? ZodNullDef - : T extends ZodFirstPartyTypeKind.ZodAny - ? ZodAnyDef - : T extends ZodFirstPartyTypeKind.ZodUnknown - ? ZodUnknownDef - : T extends ZodFirstPartyTypeKind.ZodNever - ? ZodNeverDef - : T extends ZodFirstPartyTypeKind.ZodVoid - ? ZodVoidDef - : T extends ZodFirstPartyTypeKind.ZodArray - ? ZodArrayDef - : T extends ZodFirstPartyTypeKind.ZodObject - ? ZodObjectDef - : T extends ZodFirstPartyTypeKind.ZodUnion - ? ZodUnionDef - : T extends ZodFirstPartyTypeKind.ZodIntersection - ? ZodIntersectionDef - : T extends ZodFirstPartyTypeKind.ZodTuple - ? ZodTupleDef - : T extends ZodFirstPartyTypeKind.ZodRecord - ? ZodRecordDef - : T extends ZodFirstPartyTypeKind.ZodMap - ? ZodMapDef - : T extends ZodFirstPartyTypeKind.ZodFunction - ? ZodFunctionDef - : T extends ZodFirstPartyTypeKind.ZodLazy - ? ZodLazyDef - : T extends ZodFirstPartyTypeKind.ZodLiteral - ? ZodLiteralDef - : T extends ZodFirstPartyTypeKind.ZodEnum - ? ZodEnumDef - : T extends ZodFirstPartyTypeKind.ZodEffects - ? ZodEffectsDef - : T extends ZodFirstPartyTypeKind.ZodNativeEnum - ? ZodNativeEnumDef - : T extends ZodFirstPartyTypeKind.ZodOptional - ? ZodOptionalDef - : T extends ZodFirstPartyTypeKind.ZodNullable - ? ZodNullableDef - : T extends ZodFirstPartyTypeKind.ZodPromise - ? ZodPromiseDef - : T extends ZodFirstPartyTypeKind.ZodDiscriminatedUnion - ? ZodDiscriminatedUnionDef - : T extends ZodFirstPartyTypeKind.ZodCatch - ? ZodCatchDef - : T extends ZodFirstPartyTypeKind.ZodDefault - ? ZodDefaultDef - : T extends ZodFirstPartyTypeKind.ZodBranded - ? ZodBrandedDef - : T extends ZodFirstPartyTypeKind.ZodPipeline - ? ZodPipelineDef - : T extends ZodFirstPartyTypeKind.ZodReadonly - ? ZodReadonlyDef - : never diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index 3be7c9ad00d..0d8cd3e8d4f 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -8,7 +8,6 @@ import { input, output, RawCreateParams, - ZodFirstPartyTypeKind, ZodRawShape, ZodType, ZodTypeAny, @@ -81,7 +80,7 @@ export type ZodDiscriminatedUnionDef< discriminator: Discriminator options: Options optionsMap: Map> - typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion + typeName: 'ZodDiscriminatedUnion' } & ZodTypeDef export class ZodDiscriminatedUnion< @@ -193,7 +192,7 @@ export class ZodDiscriminatedUnion< // DiscriminatorValue, Types >({ - typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion, + typeName: 'ZodDiscriminatedUnion', discriminator, options, optionsMap, diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index bc8716c565a..5dfd69a96e7 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -25,7 +24,7 @@ export type Values = { export type ZodEnumDef = { values: T - typeName: ZodFirstPartyTypeKind.ZodEnum + typeName: 'ZodEnum' } & ZodTypeDef export type Writeable = { @@ -50,7 +49,7 @@ export function createZodEnum(values: T export function createZodEnum(values: [string, ...string[]], params?: RawCreateParams) { return new ZodEnum({ values, - typeName: ZodFirstPartyTypeKind.ZodEnum, + typeName: 'ZodEnum', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 7fbdcfb5b49..9dc8dd42c56 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -7,7 +7,6 @@ import { ZodIssue, ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -28,7 +27,7 @@ import { export type ZodFunctionDef = ZodTuple, Returns extends ZodTypeAny = ZodTypeAny> = { args: Args returns: Returns - typeName: ZodFirstPartyTypeKind.ZodFunction + typeName: 'ZodFunction' } & ZodTypeDef export type OuterTypeOfFunction, Returns extends ZodTypeAny> = @@ -201,7 +200,7 @@ export class ZodFunction< return new ZodFunction({ args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()), returns: returns || ZodUnknown.create(), - typeName: ZodFirstPartyTypeKind.ZodFunction, + typeName: 'ZodFunction', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index ea98bb568d4..288033bc624 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -5,7 +5,7 @@ */ export * from './basetype' -export * from './defs' +export * from './native' export * from './utils' export * from './utils/parseUtil' export * from './utils/enumUtil' diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 2d0a4154a60..404ebf26a47 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -2,7 +2,6 @@ import { unique } from '../../utils' import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -23,7 +22,7 @@ import { CustomSet } from '../utils/custom-set' export type ZodIntersectionDef = { left: T right: U - typeName: ZodFirstPartyTypeKind.ZodIntersection + typeName: 'ZodIntersection' } & ZodTypeDef function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: false } { @@ -160,7 +159,7 @@ export class ZodIntersection = { getter: () => T - typeName: ZodFirstPartyTypeKind.ZodLazy + typeName: 'ZodLazy' } & ZodTypeDef export class ZodLazy extends ZodType, ZodLazyDef, input> { @@ -48,7 +47,7 @@ export class ZodLazy extends ZodType(getter: () => T, params?: RawCreateParams): ZodLazy => { return new ZodLazy({ getter, - typeName: ZodFirstPartyTypeKind.ZodLazy, + typeName: 'ZodLazy', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index c263f38813d..da8df95a4a7 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -3,7 +3,6 @@ import { isEqual } from 'lodash-es' import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -16,7 +15,7 @@ import { export type ZodLiteralDef = { value: T - typeName: ZodFirstPartyTypeKind.ZodLiteral + typeName: 'ZodLiteral' } & ZodTypeDef export class ZodLiteral extends ZodType> { @@ -40,7 +39,7 @@ export class ZodLiteral extends ZodType(value: T, params?: RawCreateParams): ZodLiteral => { return new ZodLiteral({ value, - typeName: ZodFirstPartyTypeKind.ZodLiteral, + typeName: 'ZodLiteral', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index 6374d6aedc2..e6fece73477 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -3,7 +3,6 @@ import { ZodIssueCode, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -19,7 +18,7 @@ import { export type ZodMapDef = { valueType: Value keyType: Key - typeName: ZodFirstPartyTypeKind.ZodMap + typeName: 'ZodMap' } & ZodTypeDef export class ZodMap extends ZodType< @@ -119,7 +118,7 @@ export class ZodMap { @@ -34,7 +33,7 @@ export class ZodNaN extends ZodType { static create = (params?: RawCreateParams): ZodNaN => { return new ZodNaN({ - typeName: ZodFirstPartyTypeKind.ZodNaN, + typeName: 'ZodNaN', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/defs.test.ts b/packages/zui/src/z/types/native.test.ts similarity index 99% rename from packages/zui/src/z/types/defs.test.ts rename to packages/zui/src/z/types/native.test.ts index 963f9b91286..4f5d4eed67d 100644 --- a/packages/zui/src/z/types/defs.test.ts +++ b/packages/zui/src/z/types/native.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import { ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind } from '..' +import { ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind } from './native' import * as z from '../index' import { util } from './utils' diff --git a/packages/zui/src/z/types/native.ts b/packages/zui/src/z/types/native.ts new file mode 100644 index 00000000000..77eb1bbcd2b --- /dev/null +++ b/packages/zui/src/z/types/native.ts @@ -0,0 +1,139 @@ +import { + ZodAny, + ZodArray, + ZodBigInt, + ZodBoolean, + ZodBranded, + ZodCatch, + ZodDate, + ZodDefault, + ZodDiscriminatedUnion, + ZodEffects, + ZodEnum, + ZodFunction, + ZodIntersection, + ZodLazy, + ZodLiteral, + ZodMap, + ZodNaN, + ZodNativeEnum, + ZodNever, + ZodNull, + ZodNullable, + ZodNumber, + ZodObject, + ZodOptional, + ZodPipeline, + ZodPromise, + ZodReadonly, + ZodRecord, + ZodRef, + ZodSet, + ZodString, + ZodSymbol, + ZodTuple, + ZodUndefined, + ZodUnion, + ZodUnknown, + ZodVoid, +} from '.' + +/** + * @deprecated - use ZodNativeSchema instead + */ +export type ZodFirstPartySchemaTypes = ZodNativeSchema +export type ZodNativeSchema = + | ZodString + | ZodNumber + | ZodNaN + | ZodBigInt + | ZodBoolean + | ZodDate + | ZodUndefined + | ZodNull + | ZodAny + | ZodUnknown + | ZodNever + | ZodVoid + | ZodArray + | ZodObject + | ZodUnion + | ZodDiscriminatedUnion + | ZodIntersection + | ZodTuple + | ZodRecord + | ZodMap + | ZodSet + | ZodFunction + | ZodLazy + | ZodLiteral + | ZodEnum + | ZodEffects + | ZodNativeEnum + | ZodOptional + | ZodNullable + | ZodDefault + | ZodCatch + | ZodPromise + | ZodBranded + | ZodPipeline + | ZodReadonly + | ZodSymbol + | ZodRef + +/** + * @deprecated - use ZodNativeSchemaDef instead + */ +export type ZodDef = ZodNativeSchemaDef +export type ZodNativeSchemaDef = ZodNativeSchema['_def'] + +/** + * @deprecated - use ZodNativeSchemaType instead + */ +export type ZodFirstPartyTypeKind = ZodNativeSchemaType +export type ZodNativeSchemaType = ZodNativeSchemaDef['typeName'] + +/** + * @deprecated - use ZodNativeSchemaType instead + */ +export const ZodFirstPartyTypeKind = { + ZodString: 'ZodString', + ZodNumber: 'ZodNumber', + ZodNaN: 'ZodNaN', + ZodBigInt: 'ZodBigInt', + ZodBoolean: 'ZodBoolean', + ZodDate: 'ZodDate', + ZodSymbol: 'ZodSymbol', + ZodUndefined: 'ZodUndefined', + ZodNull: 'ZodNull', + ZodAny: 'ZodAny', + ZodUnknown: 'ZodUnknown', + ZodNever: 'ZodNever', + ZodVoid: 'ZodVoid', + ZodArray: 'ZodArray', + ZodObject: 'ZodObject', + ZodUnion: 'ZodUnion', + ZodDiscriminatedUnion: 'ZodDiscriminatedUnion', + ZodIntersection: 'ZodIntersection', + ZodTuple: 'ZodTuple', + ZodRecord: 'ZodRecord', + ZodRef: 'ZodRef', + ZodMap: 'ZodMap', + ZodSet: 'ZodSet', + ZodFunction: 'ZodFunction', + ZodLazy: 'ZodLazy', + ZodLiteral: 'ZodLiteral', + ZodEnum: 'ZodEnum', + ZodEffects: 'ZodEffects', + ZodNativeEnum: 'ZodNativeEnum', + ZodOptional: 'ZodOptional', + ZodNullable: 'ZodNullable', + ZodDefault: 'ZodDefault', + ZodCatch: 'ZodCatch', + ZodPromise: 'ZodPromise', + ZodBranded: 'ZodBranded', + ZodPipeline: 'ZodPipeline', + ZodReadonly: 'ZodReadonly', +} satisfies { + [K in ZodNativeSchemaType]: K +} diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index bd4630a07b6..3b3942c5d9e 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -3,7 +3,6 @@ import { isEqual } from 'lodash-es' import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -18,7 +17,7 @@ import { export type ZodNativeEnumDef = { values: T - typeName: ZodFirstPartyTypeKind.ZodNativeEnum + typeName: 'ZodNativeEnum' } & ZodTypeDef export type EnumLike = { [k: string]: string | number; [nu: number]: string } @@ -58,7 +57,7 @@ export class ZodNativeEnum extends ZodType(values: T, params?: RawCreateParams): ZodNativeEnum => { return new ZodNativeEnum({ values, - typeName: ZodFirstPartyTypeKind.ZodNativeEnum, + typeName: 'ZodNativeEnum', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/never/index.ts b/packages/zui/src/z/types/never/index.ts index 97e33c7c853..3d150cb51c8 100644 --- a/packages/zui/src/z/types/never/index.ts +++ b/packages/zui/src/z/types/never/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -13,7 +12,7 @@ import { } from '../index' export type ZodNeverDef = { - typeName: ZodFirstPartyTypeKind.ZodNever + typeName: 'ZodNever' } & ZodTypeDef export class ZodNever extends ZodType { @@ -28,7 +27,7 @@ export class ZodNever extends ZodType { } static create = (params?: RawCreateParams): ZodNever => { return new ZodNever({ - typeName: ZodFirstPartyTypeKind.ZodNever, + typeName: 'ZodNever', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index e7c96131460..ae2e7b53feb 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -14,7 +13,7 @@ import { } from '../index' export type ZodNullDef = { - typeName: ZodFirstPartyTypeKind.ZodNull + typeName: 'ZodNull' } & ZodTypeDef export class ZodNull extends ZodType { @@ -33,7 +32,7 @@ export class ZodNull extends ZodType { } static create = (params?: RawCreateParams): ZodNull => { return new ZodNull({ - typeName: ZodFirstPartyTypeKind.ZodNull, + typeName: 'ZodNull', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/nullable/index.ts b/packages/zui/src/z/types/nullable/index.ts index b0674e6ed3a..72b092b5e63 100644 --- a/packages/zui/src/z/types/nullable/index.ts +++ b/packages/zui/src/z/types/nullable/index.ts @@ -3,7 +3,6 @@ import { ParseInput, ParseReturnType, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -13,7 +12,7 @@ import { export type ZodNullableDef = { innerType: T - typeName: ZodFirstPartyTypeKind.ZodNullable + typeName: 'ZodNullable' } & ZodTypeDef export type ZodNullableType = ZodNullable @@ -56,7 +55,7 @@ export class ZodNullable extends ZodType< static create = (type: T, params?: RawCreateParams): ZodNullable => { return new ZodNullable({ innerType: type, - typeName: ZodFirstPartyTypeKind.ZodNullable, + typeName: 'ZodNullable', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 5dec13b48ce..c4c505bc137 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -35,7 +34,7 @@ function floatSafeRemainder(val: number, step: number) { export type ZodNumberDef = { checks: ZodNumberCheck[] - typeName: ZodFirstPartyTypeKind.ZodNumber + typeName: 'ZodNumber' coerce: boolean } & ZodTypeDef @@ -128,7 +127,7 @@ export class ZodNumber extends ZodType { static create = (params?: RawCreateParams & { coerce?: boolean }): ZodNumber => { return new ZodNumber({ checks: [], - typeName: ZodFirstPartyTypeKind.ZodNumber, + typeName: 'ZodNumber', coerce: params?.coerce || false, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index f36843e6ae5..d84db29e225 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -16,7 +16,6 @@ import { ZodParsedType, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodRawShape, ZodType, ZodTypeAny, @@ -37,7 +36,7 @@ export type ZodObjectDef< T extends ZodRawShape = ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, > = { - typeName: ZodFirstPartyTypeKind.ZodObject + typeName: 'ZodObject' shape: () => T unknownKeys: UnknownKeys } & ZodTypeDef @@ -404,7 +403,7 @@ export class ZodObject< ...this._def.shape(), ...merging._def.shape(), }), - typeName: ZodFirstPartyTypeKind.ZodObject, + typeName: 'ZodObject', }) return merged } @@ -439,7 +438,7 @@ export class ZodObject< // catchall: merging._def.catchall, // shape: () => // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), - // typeName: ZodFirstPartyTypeKind.ZodObject, + // typeName: 'ZodObject', // }); // return merged; // } @@ -476,7 +475,7 @@ export class ZodObject< // catchall: merging._def.catchall, // shape: () => // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), - // typeName: ZodFirstPartyTypeKind.ZodObject, + // typeName: 'ZodObject', // }); // return merged; // } @@ -643,7 +642,7 @@ export class ZodObject< return new ZodObject({ shape: () => shape, unknownKeys: 'strip', - typeName: ZodFirstPartyTypeKind.ZodObject, + typeName: 'ZodObject', ...processCreateParams(params), }) } @@ -652,7 +651,7 @@ export class ZodObject< return new ZodObject({ shape: () => shape, unknownKeys: 'strict', - typeName: ZodFirstPartyTypeKind.ZodObject, + typeName: 'ZodObject', ...processCreateParams(params), }) } @@ -661,7 +660,7 @@ export class ZodObject< return new ZodObject({ shape, unknownKeys: 'strip', - typeName: ZodFirstPartyTypeKind.ZodObject, + typeName: 'ZodObject', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/optional/index.ts b/packages/zui/src/z/types/optional/index.ts index ccd29d272f3..155d6c1c758 100644 --- a/packages/zui/src/z/types/optional/index.ts +++ b/packages/zui/src/z/types/optional/index.ts @@ -2,7 +2,6 @@ import { processCreateParams, ZodParsedType, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -13,7 +12,7 @@ import { export type ZodOptionalDef = { innerType: T - typeName: ZodFirstPartyTypeKind.ZodOptional + typeName: 'ZodOptional' } & ZodTypeDef export type ZodOptionalType = ZodOptional @@ -56,7 +55,7 @@ export class ZodOptional extends ZodType< static create = (type: T, params?: RawCreateParams): ZodOptional => { return new ZodOptional({ innerType: type, - typeName: ZodFirstPartyTypeKind.ZodOptional, + typeName: 'ZodOptional', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index 992e9dda912..95ea4377f4d 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,19 +1,10 @@ import { unique } from '../../utils' -import { - ZodFirstPartyTypeKind, - ZodType, - ZodTypeAny, - ZodTypeDef, - DIRTY, - INVALID, - ParseInput, - ParseReturnType, -} from '../index' +import { ZodType, ZodTypeAny, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../index' export type ZodPipelineDef = { in: A out: B - typeName: ZodFirstPartyTypeKind.ZodPipeline + typeName: 'ZodPipeline' } & ZodTypeDef export class ZodPipeline extends ZodType< @@ -90,7 +81,7 @@ export class ZodPipeline = { type: T - typeName: ZodFirstPartyTypeKind.ZodPromise + typeName: 'ZodPromise' } & ZodTypeDef export class ZodPromise extends ZodType< @@ -72,7 +71,7 @@ export class ZodPromise extends ZodType< static create = (schema: T, params?: RawCreateParams): ZodPromise => { return new ZodPromise({ type: schema, - typeName: ZodFirstPartyTypeKind.ZodPromise, + typeName: 'ZodPromise', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/readonly/index.ts b/packages/zui/src/z/types/readonly/index.ts index 58998da8296..450bcdabf10 100644 --- a/packages/zui/src/z/types/readonly/index.ts +++ b/packages/zui/src/z/types/readonly/index.ts @@ -1,7 +1,6 @@ import { processCreateParams, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -34,7 +33,7 @@ type MakeReadonly = export type ZodReadonlyDef = { innerType: T - typeName: ZodFirstPartyTypeKind.ZodReadonly + typeName: 'ZodReadonly' } & ZodTypeDef export class ZodReadonly extends ZodType< @@ -71,7 +70,7 @@ export class ZodReadonly extends ZodType< static create = (type: T, params?: RawCreateParams): ZodReadonly => { return new ZodReadonly({ innerType: type, - typeName: ZodFirstPartyTypeKind.ZodReadonly, + typeName: 'ZodReadonly', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 0f337a36412..fc1815f32e5 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -4,7 +4,6 @@ import { ZodIssueCode, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -21,7 +20,7 @@ import { export type ZodRecordDef = { valueType: Value keyType: Key - typeName: ZodFirstPartyTypeKind.ZodRecord + typeName: 'ZodRecord' } & ZodTypeDef export type KeySchema = ZodType @@ -118,7 +117,7 @@ export class ZodRecord { static create = (uri: string): ZodRef => { return new ZodRef({ - typeName: ZodFirstPartyTypeKind.ZodRef, + typeName: 'ZodRef', uri, }) } diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 32b887e68c8..6f9686327c4 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -2,7 +2,6 @@ import { ZodIssueCode, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -18,7 +17,7 @@ import { export type ZodSetDef = { valueType: Value - typeName: ZodFirstPartyTypeKind.ZodSet + typeName: 'ZodSet' minSize: { value: number; message?: string } | null maxSize: { value: number; message?: string } | null } & ZodTypeDef @@ -140,7 +139,7 @@ export class ZodSet extends ZodType< valueType, minSize: null, maxSize: null, - typeName: ZodFirstPartyTypeKind.ZodSet, + typeName: 'ZodSet', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 314c47a23b2..5887234f7ff 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -3,7 +3,6 @@ import { StringValidation, ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -49,7 +48,7 @@ export type ZodStringCheck = export type ZodStringDef = { checks: ZodStringCheck[] - typeName: ZodFirstPartyTypeKind.ZodString + typeName: 'ZodString' coerce: boolean } & ZodTypeDef export const cuidRegex = /^c[^\s-]{8,}$/i @@ -521,7 +520,7 @@ export class ZodString extends ZodType { static create = (params?: RawCreateParams & { coerce?: true }): ZodString => { return new ZodString({ checks: [], - typeName: ZodFirstPartyTypeKind.ZodString, + typeName: 'ZodString', coerce: params?.coerce ?? false, ...processCreateParams({ ...params, supportsExtensions: ['secret'] }), }) diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index 93deb8e6885..07f0c83ff3d 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -14,7 +13,7 @@ import { } from '../index' export type ZodSymbolDef = { - typeName: ZodFirstPartyTypeKind.ZodSymbol + typeName: 'ZodSymbol' } & ZodTypeDef export class ZodSymbol extends ZodType { @@ -35,7 +34,7 @@ export class ZodSymbol extends ZodType { static create = (params?: RawCreateParams): ZodSymbol => { return new ZodSymbol({ - typeName: ZodFirstPartyTypeKind.ZodSymbol, + typeName: 'ZodSymbol', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 90f82f12316..686d1f047fb 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -4,7 +4,6 @@ import { output, RawCreateParams, RefinementCtx, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -37,7 +36,7 @@ export type Effect = RefinementEffect | TransformEffect | PreprocessEff export type ZodEffectsDef = { schema: T - typeName: ZodFirstPartyTypeKind.ZodEffects + typeName: 'ZodEffects' effect: Effect } & ZodTypeDef @@ -54,7 +53,7 @@ export class ZodEffects, I * @deprecated use naked() instead */ sourceType(): T { - return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects + return this._def.schema._def.typeName === 'ZodEffects' ? (this._def.schema as unknown as ZodEffects).sourceType() : (this._def.schema as T) } @@ -204,7 +203,7 @@ export class ZodEffects, I ): ZodEffects => { return new ZodEffects({ schema, - typeName: ZodFirstPartyTypeKind.ZodEffects, + typeName: 'ZodEffects', effect, ...processCreateParams(params), }) @@ -218,7 +217,7 @@ export class ZodEffects, I return new ZodEffects({ schema, effect: { type: 'preprocess', transform: preprocess }, - typeName: ZodFirstPartyTypeKind.ZodEffects, + typeName: 'ZodEffects', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index b4ae0423b42..43164d5ac04 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -3,7 +3,6 @@ import { ZodIssueCode, ParseInputLazyPath, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -39,7 +38,7 @@ export type InputTypeOfTupleWithRest< export type ZodTupleDef = { items: T rest: Rest - typeName: ZodFirstPartyTypeKind.ZodTuple + typeName: 'ZodTuple' } & ZodTypeDef export type AnyZodTuple = ZodTuple<[ZodTypeAny, ...ZodTypeAny[]] | [], ZodTypeAny | null> @@ -147,7 +146,7 @@ export class ZodTuple< } return new ZodTuple({ items: schemas, - typeName: ZodFirstPartyTypeKind.ZodTuple, + typeName: 'ZodTuple', rest: null, ...processCreateParams(params), }) diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index a39f3638737..cdb3a3fb7c8 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -15,7 +14,7 @@ import { } from '../index' export type ZodUndefinedDef = { - typeName: ZodFirstPartyTypeKind.ZodUndefined + typeName: 'ZodUndefined' } & ZodTypeDef export class ZodUndefined extends ZodType { @@ -36,7 +35,7 @@ export class ZodUndefined extends ZodType { static create = (params?: RawCreateParams): ZodUndefined => { return new ZodUndefined({ - typeName: ZodFirstPartyTypeKind.ZodUndefined, + typeName: 'ZodUndefined', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index b7cf3d4e512..e481b2db2c4 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,7 +1,6 @@ import { unique } from '../../utils' import { RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeAny, ZodTypeDef, @@ -25,7 +24,7 @@ type DefaultZodUnionOptions = Readonly<[ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]] export type ZodUnionOptions = Readonly<[ZodTypeAny, ...ZodTypeAny[]]> export type ZodUnionDef = { options: T - typeName: ZodFirstPartyTypeKind.ZodUnion + typeName: 'ZodUnion' } & ZodTypeDef export class ZodUnion extends ZodType< @@ -166,7 +165,7 @@ export class ZodUnion extend ): ZodUnion => { return new ZodUnion({ options: types, - typeName: ZodFirstPartyTypeKind.ZodUnion, + typeName: 'ZodUnion', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/unknown/index.ts b/packages/zui/src/z/types/unknown/index.ts index a2c98a38a7d..a22aa6486a4 100644 --- a/packages/zui/src/z/types/unknown/index.ts +++ b/packages/zui/src/z/types/unknown/index.ts @@ -1,16 +1,7 @@ -import { - RawCreateParams, - ZodFirstPartyTypeKind, - ZodType, - ZodTypeDef, - processCreateParams, - OK, - ParseInput, - ParseReturnType, -} from '../index' +import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, OK, ParseInput, ParseReturnType } from '../index' export type ZodUnknownDef = { - typeName: ZodFirstPartyTypeKind.ZodUnknown + typeName: 'ZodUnknown' } & ZodTypeDef export class ZodUnknown extends ZodType { @@ -22,7 +13,7 @@ export class ZodUnknown extends ZodType { static create = (params?: RawCreateParams): ZodUnknown => { return new ZodUnknown({ - typeName: ZodFirstPartyTypeKind.ZodUnknown, + typeName: 'ZodUnknown', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index 57d2c81cf67..e876ef545de 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,7 +1,6 @@ import { ZodIssueCode, RawCreateParams, - ZodFirstPartyTypeKind, ZodType, ZodTypeDef, processCreateParams, @@ -14,7 +13,7 @@ import { } from '../index' export type ZodVoidDef = { - typeName: ZodFirstPartyTypeKind.ZodVoid + typeName: 'ZodVoid' } & ZodTypeDef export class ZodVoid extends ZodType { @@ -34,7 +33,7 @@ export class ZodVoid extends ZodType { static create = (params?: RawCreateParams): ZodVoid => { return new ZodVoid({ - typeName: ZodFirstPartyTypeKind.ZodVoid, + typeName: 'ZodVoid', ...processCreateParams(params), }) } diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index fabb6e67d88..d1ec30e25af 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -6,8 +6,6 @@ import { ZodArray, ZodBigInt, ZodBoolean, - ZodBranded, - ZodCatch, ZodDate, ZodDefault, ZodDiscriminatedUnion, @@ -48,45 +46,6 @@ export const late = { object: ZodObject.lazycreate, } -export type ZodFirstPartySchemaTypes = - | ZodString - | ZodNumber - | ZodNaN - | ZodBigInt - | ZodBoolean - | ZodDate - | ZodUndefined - | ZodNull - | ZodAny - | ZodUnknown - | ZodNever - | ZodVoid - | ZodArray - | ZodObject - | ZodUnion - | ZodDiscriminatedUnion - | ZodIntersection - | ZodTuple - | ZodRecord - | ZodMap - | ZodSet - | ZodFunction - | ZodLazy - | ZodLiteral - | ZodEnum - | ZodEffects - | ZodNativeEnum - | ZodOptional - | ZodNullable - | ZodDefault - | ZodCatch - | ZodPromise - | ZodBranded - | ZodPipeline - | ZodReadonly - | ZodSymbol - | ZodRef - // requires TS 4.4+ abstract class Class { constructor(..._: any[]) {} From 2842994f71b0fc239728134d35d183c029098f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 13:26:59 -0500 Subject: [PATCH 02/50] feat(zui): allow discriminating directly on zui schema (#14948) --- .../transforms/zui-to-json-schema/index.ts | 249 +++++++++--------- .../zui-to-typescript-schema/index.ts | 191 +++++++------- .../zui-to-typescript-type/index.ts | 171 ++++++------ packages/zui/src/z/types/basetype/index.ts | 4 + packages/zui/src/z/types/native.test.ts | 44 +++- 5 files changed, 348 insertions(+), 311 deletions(-) diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index 1cdeac1d210..9f1489595b8 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -13,69 +13,68 @@ import { zodTupleToJsonTuple } from './type-processors/tuple' * @returns ZUI flavored JSON schema */ export function toJSONSchema(schema: z.Schema): json.Schema { - const schemaTyped = schema as z.ZodFirstPartySchemaTypes - const def = schemaTyped._def + const s = schema as z.ZodNativeSchema - switch (def.typeName) { - case z.ZodFirstPartyTypeKind.ZodString: - return zodStringToJsonString(schemaTyped as z.ZodString) satisfies json.StringSchema + switch (s.typeName) { + case 'ZodString': + return zodStringToJsonString(s) satisfies json.StringSchema - case z.ZodFirstPartyTypeKind.ZodNumber: - return zodNumberToJsonNumber(schemaTyped as z.ZodNumber) satisfies json.NumberSchema + case 'ZodNumber': + return zodNumberToJsonNumber(s) satisfies json.NumberSchema - case z.ZodFirstPartyTypeKind.ZodNaN: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodNaN) + case 'ZodNaN': + throw new err.UnsupportedZuiToJSONSchemaError('ZodNaN') - case z.ZodFirstPartyTypeKind.ZodBigInt: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodBigInt, { + case 'ZodBigInt': + throw new err.UnsupportedZuiToJSONSchemaError('ZodBigInt', { suggestedAlternative: 'serialize bigint to string', }) - case z.ZodFirstPartyTypeKind.ZodBoolean: + case 'ZodBoolean': return { type: 'boolean', - description: def.description, - 'x-zui': def['x-zui'], + description: s.description, + 'x-zui': s._def['x-zui'], } satisfies json.BooleanSchema - case z.ZodFirstPartyTypeKind.ZodDate: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodDate, { + case 'ZodDate': + throw new err.UnsupportedZuiToJSONSchemaError('ZodDate', { suggestedAlternative: 'use z.string().datetime() instead', }) - case z.ZodFirstPartyTypeKind.ZodUndefined: - return undefinedSchema(def) + case 'ZodUndefined': + return undefinedSchema(s) - case z.ZodFirstPartyTypeKind.ZodNull: - return nullSchema(def) + case 'ZodNull': + return nullSchema(s) - case z.ZodFirstPartyTypeKind.ZodAny: + case 'ZodAny': return { - description: def.description, - 'x-zui': def['x-zui'], + description: s.description, + 'x-zui': s._def['x-zui'], } satisfies json.AnySchema - case z.ZodFirstPartyTypeKind.ZodUnknown: + case 'ZodUnknown': return { - description: def.description, - 'x-zui': { ...def['x-zui'], def: { typeName: z.ZodFirstPartyTypeKind.ZodUnknown } }, + description: s.description, + 'x-zui': { ...s._def['x-zui'], def: { typeName: 'ZodUnknown' } }, } - case z.ZodFirstPartyTypeKind.ZodNever: + case 'ZodNever': return { not: true, - description: def.description, - 'x-zui': def['x-zui'], + description: s.description, + 'x-zui': s._def['x-zui'], } satisfies json.NeverSchema - case z.ZodFirstPartyTypeKind.ZodVoid: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodVoid) + case 'ZodVoid': + throw new err.UnsupportedZuiToJSONSchemaError('ZodVoid') - case z.ZodFirstPartyTypeKind.ZodArray: - return zodArrayToJsonArray(schemaTyped as z.ZodArray, toJSONSchema) satisfies json.ArraySchema + case 'ZodArray': + return zodArrayToJsonArray(s, toJSONSchema) satisfies json.ArraySchema - case z.ZodFirstPartyTypeKind.ZodObject: - const shape = Object.entries(def.shape()) + case 'ZodObject': + const shape = Object.entries(s.shape) const requiredProperties = shape.filter(([_, value]) => !value.isOptional()) const required = requiredProperties.length ? requiredProperties.map(([key]) => key) : undefined const properties = shape @@ -83,41 +82,41 @@ export function toJSONSchema(schema: z.Schema): json.Schema { .map(([key, value]) => [key, toJSONSchema(value)] satisfies [string, json.Schema]) let additionalProperties: json.ObjectSchema['additionalProperties'] = false - if (def.unknownKeys instanceof z.ZodType) { - additionalProperties = toJSONSchema(def.unknownKeys) - } else if (def.unknownKeys === 'passthrough') { + if (s._def.unknownKeys instanceof z.ZodType) { + additionalProperties = toJSONSchema(s._def.unknownKeys) + } else if (s._def.unknownKeys === 'passthrough') { additionalProperties = true } return { type: 'object', - description: def.description, + description: s.description, properties: Object.fromEntries(properties), required, additionalProperties, - 'x-zui': def['x-zui'], + 'x-zui': s._def['x-zui'], } satisfies json.ObjectSchema - case z.ZodFirstPartyTypeKind.ZodUnion: + case 'ZodUnion': return { - description: def.description, - anyOf: def.options.map((option) => toJSONSchema(option)), - 'x-zui': def['x-zui'], + description: s.description, + anyOf: s.options.map((option) => toJSONSchema(option)), + 'x-zui': s._def['x-zui'], } satisfies json.UnionSchema - case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: + case 'ZodDiscriminatedUnion': return { - description: def.description, - anyOf: def.options.map((option) => toJSONSchema(option)), + description: s.description, + anyOf: s.options.map((option) => toJSONSchema(option)), 'x-zui': { - ...def['x-zui'], - def: { typeName: z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion, discriminator: def.discriminator }, + ...s._def['x-zui'], + def: { typeName: 'ZodDiscriminatedUnion', discriminator: s.discriminator }, }, } satisfies json.DiscriminatedUnionSchema - case z.ZodFirstPartyTypeKind.ZodIntersection: - const left = toJSONSchema(def.left) - const right = toJSONSchema(def.right) + case 'ZodIntersection': + const left = toJSONSchema(s._def.left) + const right = toJSONSchema(s._def.right) /** * TODO: Potential conflict between `additionalProperties` in the left and right schemas. @@ -136,145 +135,145 @@ export function toJSONSchema(schema: z.Schema): json.Schema { } return { - description: def.description, + description: s.description, allOf: [left, right], - 'x-zui': def['x-zui'], + 'x-zui': s._def['x-zui'], } satisfies json.IntersectionSchema - case z.ZodFirstPartyTypeKind.ZodTuple: - return zodTupleToJsonTuple(schemaTyped as z.ZodTuple, toJSONSchema) satisfies json.TupleSchema + case 'ZodTuple': + return zodTupleToJsonTuple(s, toJSONSchema) satisfies json.TupleSchema - case z.ZodFirstPartyTypeKind.ZodRecord: + case 'ZodRecord': return { type: 'object', - description: def.description, - additionalProperties: toJSONSchema(def.valueType), - 'x-zui': def['x-zui'], + description: s.description, + additionalProperties: toJSONSchema(s._def.valueType), + 'x-zui': s._def['x-zui'], } satisfies json.RecordSchema - case z.ZodFirstPartyTypeKind.ZodMap: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodMap) + case 'ZodMap': + throw new err.UnsupportedZuiToJSONSchemaError('ZodMap') - case z.ZodFirstPartyTypeKind.ZodSet: - return zodSetToJsonSet(schemaTyped as z.ZodSet, toJSONSchema) satisfies json.SetSchema + case 'ZodSet': + return zodSetToJsonSet(s, toJSONSchema) satisfies json.SetSchema - case z.ZodFirstPartyTypeKind.ZodFunction: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodFunction) + case 'ZodFunction': + throw new err.UnsupportedZuiToJSONSchemaError('ZodFunction') - case z.ZodFirstPartyTypeKind.ZodLazy: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodLazy) + case 'ZodLazy': + throw new err.UnsupportedZuiToJSONSchemaError('ZodLazy') - case z.ZodFirstPartyTypeKind.ZodLiteral: - if (typeof def.value === 'string') { + case 'ZodLiteral': + if (typeof s.value === 'string') { return { type: 'string', - description: def.description, - const: def.value, - 'x-zui': def['x-zui'], + description: s.description, + const: s.value, + 'x-zui': s._def['x-zui'], } satisfies json.LiteralStringSchema - } else if (typeof def.value === 'number') { + } else if (typeof s.value === 'number') { return { type: 'number', - description: def.description, - const: def.value, - 'x-zui': def['x-zui'], + description: s.description, + const: s.value, + 'x-zui': s._def['x-zui'], } satisfies json.LiteralNumberSchema - } else if (typeof def.value === 'boolean') { + } else if (typeof s.value === 'boolean') { return { type: 'boolean', - description: def.description, - const: def.value, - 'x-zui': def['x-zui'], + description: s.description, + const: s.value, + 'x-zui': s._def['x-zui'], } satisfies json.LiteralBooleanSchema - } else if (def.value === null) { - return nullSchema(def) - } else if (def.value === undefined) { - return undefinedSchema(def) + } else if (s.value === null) { + return nullSchema(s._def) + } else if (s.value === undefined) { + return undefinedSchema(s._def) } else { - z.util.assertEqual(true) - const unsupportedLiteral = typeof def.value + z.util.assertEqual(true) + const unsupportedLiteral = typeof s.value throw new err.ZuiToJSONSchemaError(`Unsupported literal type: "${unsupportedLiteral}"`) } - case z.ZodFirstPartyTypeKind.ZodEnum: + case 'ZodEnum': return { type: 'string', - description: def.description, - enum: def.values, - 'x-zui': def['x-zui'], + description: s.description, + enum: s._def.values, + 'x-zui': s._def['x-zui'], } satisfies json.EnumSchema - case z.ZodFirstPartyTypeKind.ZodEffects: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodEffects) + case 'ZodEffects': + throw new err.UnsupportedZuiToJSONSchemaError('ZodEffects') - case z.ZodFirstPartyTypeKind.ZodNativeEnum: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodNativeEnum) + case 'ZodNativeEnum': + throw new err.UnsupportedZuiToJSONSchemaError('ZodNativeEnum') - case z.ZodFirstPartyTypeKind.ZodOptional: + case 'ZodOptional': return { - description: def.description, - anyOf: [toJSONSchema(def.innerType), undefinedSchema()], + description: s.description, + anyOf: [toJSONSchema(s._def.innerType), undefinedSchema()], 'x-zui': { - ...def['x-zui'], - def: { typeName: z.ZodFirstPartyTypeKind.ZodOptional }, + ...s._def['x-zui'], + def: { typeName: 'ZodOptional' }, }, } satisfies json.OptionalSchema - case z.ZodFirstPartyTypeKind.ZodNullable: + case 'ZodNullable': return { - anyOf: [toJSONSchema(def.innerType), nullSchema()], + anyOf: [toJSONSchema(s._def.innerType), nullSchema()], 'x-zui': { - ...def['x-zui'], - def: { typeName: z.ZodFirstPartyTypeKind.ZodNullable }, + ...s._def['x-zui'], + def: { typeName: 'ZodNullable' }, }, } satisfies json.NullableSchema - case z.ZodFirstPartyTypeKind.ZodDefault: + case 'ZodDefault': // ZodDefault is not treated as a metadata root so we don't need to preserve x-zui return { - ...toJSONSchema(def.innerType), - default: def.defaultValue(), + ...toJSONSchema(s._def.innerType), + default: s._def.defaultValue(), } - case z.ZodFirstPartyTypeKind.ZodCatch: + case 'ZodCatch': // TODO: could be supported using if-else json schema - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodCatch) + throw new err.UnsupportedZuiToJSONSchemaError('ZodCatch') - case z.ZodFirstPartyTypeKind.ZodPromise: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodPromise) + case 'ZodPromise': + throw new err.UnsupportedZuiToJSONSchemaError('ZodPromise') - case z.ZodFirstPartyTypeKind.ZodBranded: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodBranded) + case 'ZodBranded': + throw new err.UnsupportedZuiToJSONSchemaError('ZodBranded') - case z.ZodFirstPartyTypeKind.ZodPipeline: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodPipeline) + case 'ZodPipeline': + throw new err.UnsupportedZuiToJSONSchemaError('ZodPipeline') - case z.ZodFirstPartyTypeKind.ZodSymbol: - throw new err.UnsupportedZuiToJSONSchemaError(z.ZodFirstPartyTypeKind.ZodPipeline) + case 'ZodSymbol': + throw new err.UnsupportedZuiToJSONSchemaError('ZodPipeline') - case z.ZodFirstPartyTypeKind.ZodReadonly: + case 'ZodReadonly': // ZodReadonly is not treated as a metadata root so we don't need to preserve x-zui return { - ...toJSONSchema(def.innerType), + ...toJSONSchema(s._def.innerType), readOnly: true, } - case z.ZodFirstPartyTypeKind.ZodRef: + case 'ZodRef': return { - $ref: def.uri, - description: def.description, - 'x-zui': def['x-zui'], + $ref: s._def.uri, + description: s.description, + 'x-zui': s._def['x-zui'], } default: - z.util.assertNever(def) + z.util.assertNever(s) } } const undefinedSchema = (def?: z.ZodTypeDef): json.UndefinedSchema => ({ not: true, description: def?.description, - 'x-zui': { ...def?.['x-zui'], def: { typeName: z.ZodFirstPartyTypeKind.ZodUndefined } }, + 'x-zui': { ...def?.['x-zui'], def: { typeName: 'ZodUndefined' } }, }) const nullSchema = (def?: z.ZodTypeDef): json.NullSchema => ({ diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts index 9a8b8422339..988e10ad93f 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts @@ -28,151 +28,150 @@ export function toTypescriptSchema(schema: z.Schema): string { } function sUnwrapZod(schema: z.Schema): string { - const schemaTyped = schema as z.ZodFirstPartySchemaTypes - const def = schemaTyped._def + const s = schema as z.ZodNativeSchema - switch (def.typeName) { - case z.ZodFirstPartyTypeKind.ZodString: - return `z.string()${generateStringChecks(def)}${_addMetadata(def)}`.trim() + switch (s.typeName) { + case 'ZodString': + return `z.string()${generateStringChecks(s._def)}${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodNumber: - return `z.number()${generateNumberChecks(def)}${_addMetadata(def)}`.trim() + case 'ZodNumber': + return `z.number()${generateNumberChecks(s._def)}${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodNaN: - return `z.nan()${_addMetadata(def)}`.trim() + case 'ZodNaN': + return `z.nan()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodBigInt: - return `z.bigint()${generateBigIntChecks(def)}${_addMetadata(def)}`.trim() + case 'ZodBigInt': + return `z.bigint()${generateBigIntChecks(s._def)}${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodBoolean: - return `z.boolean()${_addMetadata(def)}`.trim() + case 'ZodBoolean': + return `z.boolean()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodDate: - return `z.date()${generateDateChecks(def)}${_addMetadata(def)}`.trim() + case 'ZodDate': + return `z.date()${generateDateChecks(s._def)}${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodUndefined: - return `z.undefined()${_addMetadata(def)}`.trim() + case 'ZodUndefined': + return `z.undefined()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodNull: - return `z.null()${_addMetadata(def)}`.trim() + case 'ZodNull': + return `z.null()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodAny: - return `z.any()${_addMetadata(def)}`.trim() + case 'ZodAny': + return `z.any()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodUnknown: - return `z.unknown()${_addMetadata(def)}`.trim() + case 'ZodUnknown': + return `z.unknown()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodNever: - return `z.never()${_addMetadata(def)}`.trim() + case 'ZodNever': + return `z.never()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodVoid: - return `z.void()${_addMetadata(def)}`.trim() + case 'ZodVoid': + return `z.void()${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodArray: - return `z.array(${sUnwrapZod(def.type)})${generateArrayChecks(def)}${_addMetadata(def, def.type)}` + case 'ZodArray': + return `z.array(${sUnwrapZod(s._def.type)})${generateArrayChecks(s._def)}${_addMetadata(s._def, s._def.type)}` - case z.ZodFirstPartyTypeKind.ZodObject: - const props = mapValues(def.shape(), sUnwrapZod) - const catchall = (schema as z.ZodObject).additionalProperties() + case 'ZodObject': + const props = mapValues(s.shape, sUnwrapZod) + const catchall = s.additionalProperties() const catchallString = catchall ? `.catchall(${sUnwrapZod(catchall)})` : '' return [ // 'z.object({', ...Object.entries(props).map(([key, value]) => ` ${key}: ${value},`), - `})${catchallString}${_addMetadata(def)}`, + `})${catchallString}${_addMetadata(s._def)}`, ] .join('\n') .trim() - case z.ZodFirstPartyTypeKind.ZodUnion: - const options = def.options.map(sUnwrapZod) - return `z.union([${options.join(', ')}])${_addMetadata(def)}`.trim() + case 'ZodUnion': + const options = s._def.options.map(sUnwrapZod) + return `z.union([${options.join(', ')}])${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: - const opts = (def.options as z.ZodSchema[]).map(sUnwrapZod) - const discriminator = primitiveToTypescriptValue(def.discriminator) - return `z.discriminatedUnion(${discriminator}, [${opts.join(', ')}])${_addMetadata(def)}`.trim() + case 'ZodDiscriminatedUnion': + const opts = s._def.options.map(sUnwrapZod) + const discriminator = primitiveToTypescriptValue(s._def.discriminator) + return `z.discriminatedUnion(${discriminator}, [${opts.join(', ')}])${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodIntersection: - const left: string = sUnwrapZod(def.left) - const right: string = sUnwrapZod(def.right) - return `z.intersection(${left}, ${right})${_addMetadata(def)}`.trim() + case 'ZodIntersection': + const left: string = sUnwrapZod(s._def.left) + const right: string = sUnwrapZod(s._def.right) + return `z.intersection(${left}, ${right})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodTuple: - const items = def.items.map(sUnwrapZod) - return `z.tuple([${items.join(', ')}])${_addMetadata(def)}`.trim() + case 'ZodTuple': + const items = s._def.items.map(sUnwrapZod) + return `z.tuple([${items.join(', ')}])${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodRecord: - const keyType = sUnwrapZod(def.keyType) - const valueType = sUnwrapZod(def.valueType) - return `z.record(${keyType}, ${valueType})${_addMetadata(def)}`.trim() + case 'ZodRecord': + const keyType = sUnwrapZod(s._def.keyType) + const valueType = sUnwrapZod(s._def.valueType) + return `z.record(${keyType}, ${valueType})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodMap: - const mapKeyType = sUnwrapZod(def.keyType) - const mapValueType = sUnwrapZod(def.valueType) - return `z.map(${mapKeyType}, ${mapValueType})${_addMetadata(def)}`.trim() + case 'ZodMap': + const mapKeyType = sUnwrapZod(s._def.keyType) + const mapValueType = sUnwrapZod(s._def.valueType) + return `z.map(${mapKeyType}, ${mapValueType})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodSet: - return `z.set(${sUnwrapZod(def.valueType)})${generateSetChecks(def)}${_addMetadata(def)}`.trim() + case 'ZodSet': + return `z.set(${sUnwrapZod(s._def.valueType)})${generateSetChecks(s._def)}${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodFunction: - const args = def.args.items.map(sUnwrapZod) + case 'ZodFunction': + const args = s._def.args.items.map(sUnwrapZod) const argsString = args.length ? `.args(${args.join(', ')})` : '' - const returns = sUnwrapZod(def.returns) - return `z.function()${argsString}.returns(${returns})${_addMetadata(def)}`.trim() + const returns = sUnwrapZod(s._def.returns) + return `z.function()${argsString}.returns(${returns})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodLazy: - return `z.lazy(() => ${sUnwrapZod(def.getter())})${_addMetadata(def)}`.trim() + case 'ZodLazy': + return `z.lazy(() => ${sUnwrapZod(s._def.getter())})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodLiteral: - const value = primitiveToTypescriptValue(def.value) - return `z.literal(${value})${_addMetadata(def)}`.trim() + case 'ZodLiteral': + const value = primitiveToTypescriptValue(s._def.value) + return `z.literal(${value})${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodEnum: - const values = def.values.map(primitiveToTypescriptValue) - return `z.enum([${values.join(', ')}])${_addMetadata(def)}`.trim() + case 'ZodEnum': + const values = s._def.values.map(primitiveToTypescriptValue) + return `z.enum([${values.join(', ')}])${_addMetadata(s._def)}`.trim() - case z.ZodFirstPartyTypeKind.ZodEffects: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodEffects) + case 'ZodEffects': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodEffects') - case z.ZodFirstPartyTypeKind.ZodNativeEnum: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodNativeEnum) + case 'ZodNativeEnum': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodNativeEnum') - case z.ZodFirstPartyTypeKind.ZodOptional: - return `z.optional(${sUnwrapZod(def.innerType)})${_addMetadata(def, def.innerType)}`.trim() + case 'ZodOptional': + return `z.optional(${sUnwrapZod(s._def.innerType)})${_addMetadata(s._def, s._def.innerType)}`.trim() - case z.ZodFirstPartyTypeKind.ZodNullable: - return `z.nullable(${sUnwrapZod(def.innerType)})${_addMetadata(def, def.innerType)}`.trim() + case 'ZodNullable': + return `z.nullable(${sUnwrapZod(s._def.innerType)})${_addMetadata(s._def, s._def.innerType)}`.trim() - case z.ZodFirstPartyTypeKind.ZodDefault: - const defaultValue = unknownToTypescriptValue(def.defaultValue()) + case 'ZodDefault': + const defaultValue = unknownToTypescriptValue(s._def.defaultValue()) // TODO: use z.default() notation - return `z.default(${sUnwrapZod(def.innerType)}, ${defaultValue})${_addMetadata(def, def.innerType)}`.trim() + return `z.default(${sUnwrapZod(s._def.innerType)}, ${defaultValue})${_addMetadata(s._def, s._def.innerType)}`.trim() - case z.ZodFirstPartyTypeKind.ZodCatch: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodCatch) + case 'ZodCatch': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodCatch') - case z.ZodFirstPartyTypeKind.ZodPromise: - return `z.promise(${sUnwrapZod(def.type)})${_addMetadata(def, def.type)}`.trim() + case 'ZodPromise': + return `z.promise(${sUnwrapZod(s._def.type)})${_addMetadata(s._def, s._def.type)}`.trim() - case z.ZodFirstPartyTypeKind.ZodBranded: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodBranded) + case 'ZodBranded': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodBranded') - case z.ZodFirstPartyTypeKind.ZodPipeline: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodPipeline) + case 'ZodPipeline': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodPipeline') - case z.ZodFirstPartyTypeKind.ZodSymbol: - throw new errors.UnsupportedZuiToTypescriptSchemaError(z.ZodFirstPartyTypeKind.ZodSymbol) + case 'ZodSymbol': + throw new errors.UnsupportedZuiToTypescriptSchemaError('ZodSymbol') - case z.ZodFirstPartyTypeKind.ZodReadonly: - return `z.readonly(${sUnwrapZod(def.innerType)})${_addMetadata(def, def.innerType)}`.trim() + case 'ZodReadonly': + return `z.readonly(${sUnwrapZod(s._def.innerType)})${_addMetadata(s._def, s._def.innerType)}`.trim() - case z.ZodFirstPartyTypeKind.ZodRef: - const uri = primitiveToTypescriptValue(def.uri) - return `z.ref(${uri})${_addMetadata(def)}`.trim() + case 'ZodRef': + const uri = primitiveToTypescriptValue(s._def.uri) + return `z.ref(${uri})${_addMetadata(s._def)}`.trim() default: - util.assertNever(def) + util.assertNever(s) } } diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index 087cf5e484b..0dc7fa14f46 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -131,7 +131,7 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n } if (optionalValue) { - let innerType = optionalValue._def.innerType as z.Schema + let innerType = optionalValue._def.innerType if (innerType instanceof z.Schema && !innerType.description && optionalValue.description) { innerType = innerType?.describe(optionalValue.description) } @@ -186,44 +186,43 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n return sUnwrapZod(schema.schema, newConfig) } - const schemaTyped = schema as z.ZodFirstPartySchemaTypes - const def = schemaTyped._def + const s = schema as z.ZodFirstPartySchemaTypes - switch (def.typeName) { - case z.ZodFirstPartyTypeKind.ZodString: - return `${getMultilineComment(schemaTyped.description)} string`.trim() + switch (s.typeName) { + case 'ZodString': + return `${getMultilineComment(s.description)} string`.trim() - case z.ZodFirstPartyTypeKind.ZodNumber: - case z.ZodFirstPartyTypeKind.ZodNaN: - case z.ZodFirstPartyTypeKind.ZodBigInt: - return `${getMultilineComment(schemaTyped.description)} number`.trim() + case 'ZodNumber': + case 'ZodNaN': + case 'ZodBigInt': + return `${getMultilineComment(s.description)} number`.trim() - case z.ZodFirstPartyTypeKind.ZodBoolean: - return `${getMultilineComment(schemaTyped.description)} boolean`.trim() + case 'ZodBoolean': + return `${getMultilineComment(s.description)} boolean`.trim() - case z.ZodFirstPartyTypeKind.ZodDate: - return `${getMultilineComment(schemaTyped.description)} Date`.trim() + case 'ZodDate': + return `${getMultilineComment(s.description)} Date`.trim() - case z.ZodFirstPartyTypeKind.ZodUndefined: - return `${getMultilineComment(schemaTyped.description)} undefined`.trim() + case 'ZodUndefined': + return `${getMultilineComment(s.description)} undefined`.trim() - case z.ZodFirstPartyTypeKind.ZodNull: - return `${getMultilineComment(schemaTyped.description)} null`.trim() + case 'ZodNull': + return `${getMultilineComment(s.description)} null`.trim() - case z.ZodFirstPartyTypeKind.ZodAny: - return `${getMultilineComment(schemaTyped.description)} any`.trim() + case 'ZodAny': + return `${getMultilineComment(s.description)} any`.trim() - case z.ZodFirstPartyTypeKind.ZodUnknown: - return `${getMultilineComment(schemaTyped.description)} unknown`.trim() + case 'ZodUnknown': + return `${getMultilineComment(s.description)} unknown`.trim() - case z.ZodFirstPartyTypeKind.ZodNever: - return `${getMultilineComment(schemaTyped.description)} never`.trim() + case 'ZodNever': + return `${getMultilineComment(s.description)} never`.trim() - case z.ZodFirstPartyTypeKind.ZodVoid: - return `${getMultilineComment(schemaTyped.description)} void`.trim() + case 'ZodVoid': + return `${getMultilineComment(s.description)} void`.trim() - case z.ZodFirstPartyTypeKind.ZodArray: - const item = sUnwrapZod(def.type, newConfig) + case 'ZodArray': + const item = sUnwrapZod(s._def.type, newConfig) if (isPrimitive(item)) { return `${item}[]` @@ -231,8 +230,8 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n return `Array<${item}>` - case z.ZodFirstPartyTypeKind.ZodObject: - const props = Object.entries(def.shape()).map(([key, value]) => { + case 'ZodObject': + const props = Object.entries(s._def.shape()).map(([key, value]) => { if (value instanceof z.Schema) { return sUnwrapZod(new KeyValue(toPropertyKey(key), value), newConfig) } @@ -241,106 +240,106 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n return `{ ${props.join('; ')} }` - case z.ZodFirstPartyTypeKind.ZodUnion: - const options = def.options.map((option) => { + case 'ZodUnion': + const options = s._def.options.map((option) => { return sUnwrapZod(option, newConfig) }) - return `${getMultilineComment(schemaTyped.description)} + return `${getMultilineComment(s.description)} ${options.join(' | ')}` - case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: - const opts = def.options.map((option) => { + case 'ZodDiscriminatedUnion': + const opts = s._def.options.map((option) => { return sUnwrapZod(option, newConfig) }) - return `${getMultilineComment(schemaTyped.description)} + return `${getMultilineComment(s.description)} ${opts.join(' | ')}` - case z.ZodFirstPartyTypeKind.ZodIntersection: - return `${sUnwrapZod(def.left, newConfig)} & ${sUnwrapZod(def.right, newConfig)}` + case 'ZodIntersection': + return `${sUnwrapZod(s._def.left, newConfig)} & ${sUnwrapZod(s._def.right, newConfig)}` - case z.ZodFirstPartyTypeKind.ZodTuple: - if (def.items.length === 0) { + case 'ZodTuple': + if (s._def.items.length === 0) { return '[]' } - const items = def.items.map((i: any) => sUnwrapZod(i, newConfig)) + const items = s._def.items.map((i: any) => sUnwrapZod(i, newConfig)) return `[${items.join(', ')}]` - case z.ZodFirstPartyTypeKind.ZodRecord: - const keyType = sUnwrapZod(def.keyType, newConfig) - const valueType = sUnwrapZod(def.valueType, newConfig) - return `${getMultilineComment(schemaTyped.description)} { [key: ${keyType}]: ${valueType} }` + case 'ZodRecord': + const keyType = sUnwrapZod(s._def.keyType, newConfig) + const valueType = sUnwrapZod(s._def.valueType, newConfig) + return `${getMultilineComment(s.description)} { [key: ${keyType}]: ${valueType} }` - case z.ZodFirstPartyTypeKind.ZodMap: - return `Map<${sUnwrapZod(def.keyType, newConfig)}, ${sUnwrapZod(def.valueType, newConfig)}>` + case 'ZodMap': + return `Map<${sUnwrapZod(s._def.keyType, newConfig)}, ${sUnwrapZod(s._def.valueType, newConfig)}>` - case z.ZodFirstPartyTypeKind.ZodSet: - return `Set<${sUnwrapZod(def.valueType, newConfig)}>` + case 'ZodSet': + return `Set<${sUnwrapZod(s._def.valueType, newConfig)}>` - case z.ZodFirstPartyTypeKind.ZodFunction: - const input = sUnwrapZod(new FnParameters(def.args), newConfig) - const output = sUnwrapZod(new FnReturn(def.returns), newConfig) + case 'ZodFunction': + const input = sUnwrapZod(new FnParameters(s._def.args), newConfig) + const output = sUnwrapZod(new FnReturn(s._def.returns), newConfig) const parentIsType = config?.parent instanceof Declaration && config?.parent.props.type === 'type' if (config?.declaration && !parentIsType) { - return `${getMultilineComment(schemaTyped.description)} + return `${getMultilineComment(s.description)} (${input}): ${output}` } - return `${getMultilineComment(schemaTyped.description)} + return `${getMultilineComment(s.description)} (${input}) => ${output}` - case z.ZodFirstPartyTypeKind.ZodLazy: - return sUnwrapZod(def.getter(), newConfig) + case 'ZodLazy': + return sUnwrapZod(s._def.getter(), newConfig) - case z.ZodFirstPartyTypeKind.ZodLiteral: - const value: string = primitiveToTypscriptLiteralType(def.value) - return `${getMultilineComment(schemaTyped.description)} + case 'ZodLiteral': + const value: string = primitiveToTypscriptLiteralType(s._def.value) + return `${getMultilineComment(s.description)} ${value}`.trim() - case z.ZodFirstPartyTypeKind.ZodEnum: - const values = def.values.map(primitiveToTypescriptValue) + case 'ZodEnum': + const values = s._def.values.map(primitiveToTypescriptValue) return values.join(' | ') - case z.ZodFirstPartyTypeKind.ZodEffects: - return sUnwrapZod(def.schema, newConfig) + case 'ZodEffects': + return sUnwrapZod(s._def.schema, newConfig) - case z.ZodFirstPartyTypeKind.ZodNativeEnum: - throw new errors.UnsupportedZuiToTypescriptTypeError(z.ZodFirstPartyTypeKind.ZodNativeEnum) + case 'ZodNativeEnum': + throw new errors.UnsupportedZuiToTypescriptTypeError('ZodNativeEnum') - case z.ZodFirstPartyTypeKind.ZodOptional: - return `${sUnwrapZod(def.innerType, newConfig)} | undefined` + case 'ZodOptional': + return `${sUnwrapZod(s._def.innerType, newConfig)} | undefined` - case z.ZodFirstPartyTypeKind.ZodNullable: - return `${sUnwrapZod(def.innerType, newConfig)} | null` + case 'ZodNullable': + return `${sUnwrapZod(s._def.innerType, newConfig)} | null` - case z.ZodFirstPartyTypeKind.ZodDefault: - const defaultInnerType = config.treatDefaultAsOptional ? def.innerType.optional() : def.innerType + case 'ZodDefault': + const defaultInnerType = config.treatDefaultAsOptional ? s._def.innerType.optional() : s._def.innerType return sUnwrapZod(defaultInnerType, newConfig) - case z.ZodFirstPartyTypeKind.ZodCatch: - return sUnwrapZod(def.innerType, newConfig) + case 'ZodCatch': + return sUnwrapZod(s._def.innerType, newConfig) - case z.ZodFirstPartyTypeKind.ZodPromise: - return `Promise<${sUnwrapZod(def.type, newConfig)}>` + case 'ZodPromise': + return `Promise<${sUnwrapZod(s._def.type, newConfig)}>` - case z.ZodFirstPartyTypeKind.ZodBranded: - return sUnwrapZod(def.type, newConfig) + case 'ZodBranded': + return sUnwrapZod(s._def.type, newConfig) - case z.ZodFirstPartyTypeKind.ZodPipeline: - return sUnwrapZod(def.in, newConfig) + case 'ZodPipeline': + return sUnwrapZod(s._def.in, newConfig) - case z.ZodFirstPartyTypeKind.ZodSymbol: - return `${getMultilineComment(schemaTyped.description)} symbol`.trim() + case 'ZodSymbol': + return `${getMultilineComment(s.description)} symbol`.trim() - case z.ZodFirstPartyTypeKind.ZodReadonly: - return `Readonly<${sUnwrapZod(def.innerType, newConfig)}>` + case 'ZodReadonly': + return `Readonly<${sUnwrapZod(s._def.innerType, newConfig)}>` - case z.ZodFirstPartyTypeKind.ZodRef: - return toTypeArgumentName(def.uri) + case 'ZodRef': + return toTypeArgumentName(s._def.uri) default: - util.assertNever(def) + util.assertNever(s) } } diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index a55d71b65c2..1c200e2e655 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -170,6 +170,10 @@ export abstract class ZodType /** deeply replace all references in the schema */ diff --git a/packages/zui/src/z/types/native.test.ts b/packages/zui/src/z/types/native.test.ts index 4f5d4eed67d..c25389686b2 100644 --- a/packages/zui/src/z/types/native.test.ts +++ b/packages/zui/src/z/types/native.test.ts @@ -4,86 +4,122 @@ import * as z from '../index' import { util } from './utils' test('first party switch', () => { - const myType = z.string() as z.ZodFirstPartySchemaTypes - const def = myType._def + const myType = z.string() as z.ZodNativeSchema - switch (def.typeName) { + switch (myType.typeName) { case z.ZodFirstPartyTypeKind.ZodString: + myType satisfies z.ZodString break case z.ZodFirstPartyTypeKind.ZodNumber: + myType satisfies z.ZodNumber break case z.ZodFirstPartyTypeKind.ZodNaN: + myType satisfies z.ZodNaN break case z.ZodFirstPartyTypeKind.ZodBigInt: + myType satisfies z.ZodBigInt break case z.ZodFirstPartyTypeKind.ZodBoolean: + myType satisfies z.ZodBoolean break case z.ZodFirstPartyTypeKind.ZodDate: + myType satisfies z.ZodDate break case z.ZodFirstPartyTypeKind.ZodUndefined: + myType satisfies z.ZodUndefined break case z.ZodFirstPartyTypeKind.ZodNull: + myType satisfies z.ZodNull break case z.ZodFirstPartyTypeKind.ZodAny: + myType satisfies z.ZodAny break case z.ZodFirstPartyTypeKind.ZodUnknown: + myType satisfies z.ZodUnknown break case z.ZodFirstPartyTypeKind.ZodNever: + myType satisfies z.ZodNever break case z.ZodFirstPartyTypeKind.ZodVoid: + myType satisfies z.ZodVoid break case z.ZodFirstPartyTypeKind.ZodArray: + myType satisfies z.ZodArray break case z.ZodFirstPartyTypeKind.ZodObject: + myType satisfies z.ZodObject break case z.ZodFirstPartyTypeKind.ZodUnion: + myType satisfies z.ZodUnion break case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: + myType satisfies z.ZodDiscriminatedUnion break case z.ZodFirstPartyTypeKind.ZodIntersection: + myType satisfies z.ZodIntersection break case z.ZodFirstPartyTypeKind.ZodTuple: + myType satisfies z.ZodTuple break case z.ZodFirstPartyTypeKind.ZodRecord: + myType satisfies z.ZodRecord break case z.ZodFirstPartyTypeKind.ZodRef: + myType satisfies z.ZodRef break case z.ZodFirstPartyTypeKind.ZodMap: + myType satisfies z.ZodMap break case z.ZodFirstPartyTypeKind.ZodSet: + myType satisfies z.ZodSet break case z.ZodFirstPartyTypeKind.ZodFunction: + myType satisfies z.ZodFunction break case z.ZodFirstPartyTypeKind.ZodLazy: + myType satisfies z.ZodLazy break case z.ZodFirstPartyTypeKind.ZodLiteral: + myType satisfies z.ZodLiteral break case z.ZodFirstPartyTypeKind.ZodEnum: + myType satisfies z.ZodEnum break case z.ZodFirstPartyTypeKind.ZodEffects: + myType satisfies z.ZodEffects break case z.ZodFirstPartyTypeKind.ZodNativeEnum: + myType satisfies z.ZodNativeEnum break case z.ZodFirstPartyTypeKind.ZodOptional: + myType satisfies z.ZodOptional break case z.ZodFirstPartyTypeKind.ZodNullable: + myType satisfies z.ZodNullable break case z.ZodFirstPartyTypeKind.ZodDefault: + myType satisfies z.ZodDefault break case z.ZodFirstPartyTypeKind.ZodCatch: + myType satisfies z.ZodCatch break case z.ZodFirstPartyTypeKind.ZodPromise: + myType satisfies z.ZodPromise break case z.ZodFirstPartyTypeKind.ZodBranded: + myType satisfies z.ZodBranded break case z.ZodFirstPartyTypeKind.ZodPipeline: + myType satisfies z.ZodPipeline break case z.ZodFirstPartyTypeKind.ZodSymbol: + myType satisfies z.ZodSymbol break case z.ZodFirstPartyTypeKind.ZodReadonly: + myType satisfies z.ZodReadonly break default: - util.assertNever(def) + util.assertNever(myType) } }) From 677a7514d111aec7f43f77d0082aa6f6b1121c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 14:56:00 -0500 Subject: [PATCH 03/50] chore(zui): rm internal usage of ZodTypeAny (#14949) --- .../zui-from-json-schema-legacy/index.ts | 12 +++---- .../json-schema-to-zui.test.ts | 4 +-- .../zui-from-json-schema/iterables/array.ts | 8 ++--- .../src/transforms/zui-from-object/index.ts | 4 +-- .../parsers/array.ts | 4 +-- .../parsers/default.ts | 4 +-- .../parsers/effects.ts | 4 +-- .../parsers/intersection.ts | 6 ++-- .../zui-to-json-schema-legacy/parsers/map.ts | 6 ++-- .../parsers/nullable.ts | 12 +++---- .../parsers/object.ts | 10 +++--- .../parsers/optional.ts | 6 ++-- .../parsers/promise.ts | 4 +-- .../parsers/record.ts | 29 ++++++++--------- .../zui-to-json-schema-legacy/parsers/set.ts | 4 +-- .../parsers/tuple.ts | 13 +++----- .../zui-extension.ts | 2 +- .../type-processors/array.ts | 2 +- .../zui-to-json-schema/type-processors/set.ts | 2 +- .../type-processors/tuple.ts | 2 +- .../zui-to-typescript-schema/index.ts | 2 +- packages/zui/src/ui/types.ts | 24 +++++++------- packages/zui/src/z/__tests__/generics.test.ts | 4 +-- packages/zui/src/z/deref.test.ts | 2 +- packages/zui/src/z/types/array/index.ts | 13 ++++---- packages/zui/src/z/types/basetype/index.ts | 18 ++++------- packages/zui/src/z/types/branded/index.ts | 12 +++---- packages/zui/src/z/types/catch/index.ts | 11 +++---- packages/zui/src/z/types/default/index.ts | 11 +++---- .../src/z/types/discriminatedUnion/index.ts | 7 ++-- packages/zui/src/z/types/function/index.ts | 25 +++++++-------- .../zui/src/z/types/intersection/index.ts | 9 +++--- packages/zui/src/z/types/lazy/index.ts | 11 +++---- packages/zui/src/z/types/map/index.ts | 9 +++--- packages/zui/src/z/types/nullable/index.ts | 13 ++++---- .../zui/src/z/types/nullable/nullable.test.ts | 2 +- packages/zui/src/z/types/object/index.ts | 27 ++++++++-------- packages/zui/src/z/types/optional/index.ts | 13 ++++---- .../zui/src/z/types/optional/optional.test.ts | 2 +- packages/zui/src/z/types/pipeline/index.ts | 10 +++--- packages/zui/src/z/types/promise/index.ts | 11 +++---- packages/zui/src/z/types/readonly/index.ts | 11 +++---- packages/zui/src/z/types/record/index.ts | 11 +++---- packages/zui/src/z/types/ref/index.ts | 13 ++------ packages/zui/src/z/types/set/index.ts | 12 +++---- packages/zui/src/z/types/transformer/index.ts | 11 +++---- packages/zui/src/z/types/tuple/index.ts | 32 ++++++++----------- packages/zui/src/z/types/union/index.ts | 17 ++++------ packages/zui/src/z/types/utils/partialUtil.ts | 6 ++-- packages/zui/src/z/z.ts | 5 +++ packages/zui/src/zui.test.ts | 2 +- 51 files changed, 225 insertions(+), 269 deletions(-) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts index e59506901f2..a66de1dd15d 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts @@ -149,7 +149,7 @@ export const traverseZodDefinitions = ( ) => { switch (def.typeName) { case ZodFirstPartyTypeKind.ZodObject: - const shape = def.shape() + const shape = def.shape() as Record cb(ZodFirstPartyTypeKind.ZodObject, def, path) Object.entries(shape).forEach(([key, field]) => { traverseZodDefinitions(field._def, cb, [...path, key]) @@ -158,18 +158,18 @@ export const traverseZodDefinitions = ( case ZodFirstPartyTypeKind.ZodArray: cb(ZodFirstPartyTypeKind.ZodArray, def, path) - traverseZodDefinitions(def.type._def, cb, [...path, '0']) + traverseZodDefinitions((def.type as ZodTypeAny)._def, cb, [...path, '0']) break case ZodFirstPartyTypeKind.ZodLazy: cb(ZodFirstPartyTypeKind.ZodLazy, def, path) - traverseZodDefinitions(def.getter()._def, cb, path) + traverseZodDefinitions((def.getter() as ZodTypeAny)._def, cb, path) break case ZodFirstPartyTypeKind.ZodUnion: cb(ZodFirstPartyTypeKind.ZodUnion, def, path) def.options.forEach((option) => { - traverseZodDefinitions(option._def, cb, path) + traverseZodDefinitions((option as ZodTypeAny)._def, cb, path) }) break @@ -212,11 +212,11 @@ export const traverseZodDefinitions = ( case ZodFirstPartyTypeKind.ZodNullable: cb(ZodFirstPartyTypeKind.ZodNullable, def, path) - traverseZodDefinitions(def.innerType._def, cb, path) + traverseZodDefinitions((def.innerType as ZodTypeAny)._def, cb, path) break case ZodFirstPartyTypeKind.ZodOptional: cb(ZodFirstPartyTypeKind.ZodOptional, def, path) - traverseZodDefinitions(def.innerType._def, cb, path) + traverseZodDefinitions((def.innerType as ZodTypeAny)._def, cb, path) break case ZodFirstPartyTypeKind.ZodNumber: diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts index 80d5900c459..1fcc97fa71d 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts @@ -1,12 +1,12 @@ import { describe, expect, test, it } from 'vitest' -import { ZodTypeAny, z } from '../../z/index' +import { ZodType, z } from '../../z/index' import { zuiKey } from '../../ui/constants' import { jsonSchemaToZodStr, fromJSONSchemaLegacy, traverseZodDefinitions } from '.' import { toJSONSchemaLegacy } from '../zui-to-json-schema-legacy/zui-extension' import { JSONSchema7 } from 'json-schema' import { assert } from '../../assertions.utils.test' -const testZuiConversion = (zuiObject: ZodTypeAny) => { +const testZuiConversion = (zuiObject: ZodType) => { const jsonSchema = toJSONSchemaLegacy(zuiObject) const asZui = fromJSONSchemaLegacy(jsonSchema) const convertedJsonSchema = toJSONSchemaLegacy(asZui) diff --git a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts index 22613cc4d9d..1b369752228 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts @@ -4,7 +4,7 @@ import { ArraySchema, SetSchema, TupleSchema } from '../../common/json-schema' export const arrayJSONSchemaToZuiArray = ( schema: ArraySchema | SetSchema | TupleSchema, - toZui: (x: JSONSchema7Definition) => z.ZodTypeAny + toZui: (x: JSONSchema7Definition) => z.ZodType ): z.ZodArray | z.ZodSet | z.ZodTuple => _isTuple(schema) ? _handleTuple(schema, toZui) @@ -19,7 +19,7 @@ const _isSet = (schema: ArraySchema | SetSchema | TupleSchema): schema is SetSch const _handleTuple = ( { items, additionalItems }: TupleSchema, - toZui: (x: JSONSchema7Definition) => z.ZodTypeAny + toZui: (x: JSONSchema7Definition) => z.ZodType ): z.ZodTuple => { const itemSchemas = items.map(toZui) as [] | [z.ZodType, ...z.ZodType[]] let zodTuple: z.ZodTuple = z.tuple(itemSchemas) @@ -33,7 +33,7 @@ const _handleTuple = ( const _handleSet = ( { items, minItems, maxItems }: SetSchema, - toZui: (x: JSONSchema7Definition) => z.ZodTypeAny + toZui: (x: JSONSchema7Definition) => z.ZodType ): z.ZodSet => { let zodSet = z.set(toZui(items)) @@ -50,7 +50,7 @@ const _handleSet = ( const _handleArray = ( { minItems, maxItems, items }: ArraySchema, - toZui: (x: JSONSchema7Definition) => z.ZodTypeAny + toZui: (x: JSONSchema7Definition) => z.ZodType ): z.ZodArray | z.ZodSet | z.ZodTuple => { let zodArray = z.array(toZui(items)) diff --git a/packages/zui/src/transforms/zui-from-object/index.ts b/packages/zui/src/transforms/zui-from-object/index.ts index 75bbf6a0393..9be97182f73 100644 --- a/packages/zui/src/transforms/zui-from-object/index.ts +++ b/packages/zui/src/transforms/zui-from-object/index.ts @@ -1,4 +1,4 @@ -import { z, SomeZodObject, ZodTypeAny } from '../../z/index' +import { z, SomeZodObject, ZodType } from '../../z/index' import * as errors from '../common/errors' // Using a basic regex do determine if it's a date or not to avoid using another lib for that @@ -14,7 +14,7 @@ export type ObjectToZuiOptions = { optional?: boolean; nullable?: boolean; passt * @param opts - Options to customize the Zod schema: * @returns A Zod schema representing the object. */ -export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true): ZodTypeAny => { +export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true): ZodType => { if (typeof obj !== 'object') { throw new errors.ObjectToZuiError('Input must be an object') } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts index 4877f2e8df1..4fd739dc66f 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodArrayDef, ZodFirstPartyTypeKind } from '../../../z/index' +import { ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z/index' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' @@ -20,7 +20,7 @@ export function parseArrayDef(def: ZodArrayDef, refs: Refs) { } if (def.type?._def?.typeName !== ZodFirstPartyTypeKind.ZodAny) { - res.items = parseDef(def.type._def, { + res.items = parseDef((def.type as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'items'], }) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts index e362f684250..c7bd69eb875 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts @@ -1,10 +1,10 @@ -import { ZodDefaultDef } from '../../../z/index' +import { ZodDefaultDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' export function parseDefaultDef(_def: ZodDefaultDef, refs: Refs): JsonSchema7Type & { default: any } { return { - ...parseDef(_def.innerType._def, refs), + ...parseDef((_def.innerType as ZodTypeAny)._def, refs), default: _def.defaultValue(), } } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts index ef497aba77b..00e6f8c4c0b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts @@ -1,7 +1,7 @@ -import { ZodEffectsDef } from '../../../z/index' +import { ZodEffectsDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' export function parseEffectsDef(_def: ZodEffectsDef, refs: Refs): JsonSchema7Type | undefined { - return refs.effectStrategy === 'input' ? parseDef(_def.schema._def, refs) : {} + return refs.effectStrategy === 'input' ? parseDef((_def.schema as ZodTypeAny)._def, refs) : {} } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts index a33c50c1793..9216e5e346a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodIntersectionDef } from '../../../z/index' +import { ZodIntersectionDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7StringType } from './string' @@ -21,11 +21,11 @@ export function parseIntersectionDef( refs: Refs ): JsonSchema7AllOfType | JsonSchema7Type | undefined { const allOf = [ - parseDef(def.left._def, { + parseDef((def.left as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'allOf', '0'], }), - parseDef(def.right._def, { + parseDef((def.right as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'allOf', '1'], }), diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts index f49d363dccd..2309809e33e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodMapDef } from '../../../z/index' +import { ZodMapDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7RecordType, parseRecordDef } from './record' @@ -23,12 +23,12 @@ export function parseMapDef(def: ZodMapDef, refs: Refs): JsonSchema7MapType | Js } const keys = - parseDef(def.keyType._def, { + parseDef((def.keyType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'items', 'items', '0'], }) || {} const values = - parseDef(def.valueType._def, { + parseDef((def.valueType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'items', 'items', '1'], }) || {} diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts index a11c6af401a..f0c6e499d7d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNullableDef } from '../../../z/index' +import { ZodNullableDef, ZodTypeAny } from '../../../z/index' import { addMeta, JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7NullType } from './null' @@ -17,11 +17,11 @@ export type JsonSchema7NullableType = } export function parseNullableDef(def: ZodNullableDef, refs: Refs): JsonSchema7NullableType | undefined { + const inner = def.innerType as ZodTypeAny if ( - ['ZodString', 'ZodNumber', 'ZodBigInt', 'ZodBoolean', 'ZodNull'].includes(def.innerType._def.typeName) && - (!def.innerType._def.checks || !def.innerType._def.checks.length) + ['ZodString', 'ZodNumber', 'ZodBigInt', 'ZodBoolean', 'ZodNull'].includes(inner._def.typeName) && + (!inner._def.checks || !inner._def.checks.length) ) { - const inner = def.innerType if (refs.target === 'openApi3') { const schema = { type: primitiveMappings[inner._def.typeName as keyof typeof primitiveMappings], @@ -37,7 +37,7 @@ export function parseNullableDef(def: ZodNullableDef, refs: Refs): JsonSchema7Nu } if (refs.target === 'openApi3') { - const base = parseDef(def.innerType._def, { + const base = parseDef(inner._def, { ...refs, currentPath: [...refs.currentPath], }) @@ -45,7 +45,7 @@ export function parseNullableDef(def: ZodNullableDef, refs: Refs): JsonSchema7Nu return base && ({ ...base, nullable: true } as any) } - const base = parseDef(def.innerType._def, { + const base = parseDef(inner._def, { ...refs, currentPath: [...refs.currentPath, 'anyOf', '0'], }) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts index 65d3955b62e..3c3968f8701 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodObjectDef, ZodType } from '../../../z/index' +import { ZodObjectDef, ZodType, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' @@ -15,7 +15,7 @@ export type JsonSchema7ObjectType = { const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonSchema7Type => { if (def.unknownKeys instanceof ZodType) { return ( - parseDef(def.unknownKeys._def, { + parseDef((def.unknownKeys as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'additionalProperties'], }) ?? true @@ -30,7 +30,7 @@ const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonS export function parseObjectDefX(def: ZodObjectDef, refs: Refs) { Object.keys(def.shape()).reduce( (schema: JsonSchema7ObjectType, key) => { - let prop = def.shape()[key] + let prop = def.shape()[key] as ZodTypeAny if (typeof prop === 'undefined' || typeof prop._def === 'undefined') { return schema } @@ -76,7 +76,7 @@ export function parseObjectDefX(def: ZodObjectDef, refs: Refs) { properties: Record required: string[] }, - [propName, propDef] + [propName, propDef]: [string, ZodTypeAny] ) => { if (propDef === undefined || propDef._def === undefined) return acc const parsedDef = parseDef(propDef._def, { @@ -107,7 +107,7 @@ export function parseObjectDef(def: ZodObjectDef, refs: Refs) { properties: Record required: string[] }, - [propName, propDef] + [propName, propDef]: [string, ZodTypeAny] ) => { if (propDef === undefined || propDef._def === undefined) return acc const parsedDef = parseDef(propDef._def, { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts index 6485ac2e21c..e5832358049 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts @@ -1,13 +1,13 @@ -import { ZodOptionalDef } from '../../../z/index' +import { ZodOptionalDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' export const parseOptionalDef = (def: ZodOptionalDef, refs: Refs): JsonSchema7Type | undefined => { if (refs.currentPath.toString() === refs.propertyPath?.toString()) { - return parseDef(def.innerType._def, refs) + return parseDef((def.innerType as ZodTypeAny)._def, refs) } - const innerSchema = parseDef(def.innerType._def, { + const innerSchema = parseDef((def.innerType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'anyOf', '1'], }) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts index 95cc43d0605..289f8d307f3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts @@ -1,7 +1,7 @@ -import { ZodPromiseDef } from '../../../z/index' +import { ZodPromiseDef, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' export function parsePromiseDef(def: ZodPromiseDef, refs: Refs): JsonSchema7Type | undefined { - return parseDef(def.type._def, refs) + return parseDef((def.type as ZodTypeAny)._def, refs) } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts index 98b73669f67..8a3c21e4b2d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodTypeAny } from '../../../z/index' +import { ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodType, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7EnumType } from './enum' @@ -16,19 +16,16 @@ export type JsonSchema7RecordType = { [zuiKey]?: ZuiExtensionObject } -export function parseRecordDef( - def: ZodRecordDef | ZodMapDef, - refs: Refs -): JsonSchema7RecordType { +export function parseRecordDef(def: ZodRecordDef | ZodMapDef, refs: Refs): JsonSchema7RecordType { if (refs.target === 'openApi3' && def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) { return { type: 'object', - required: def.keyType._def.values, - properties: def.keyType._def.values.reduce( + required: (def.keyType as ZodTypeAny)._def.values, + properties: (def.keyType as ZodTypeAny)._def.values.reduce( (acc: Record, key: string) => ({ ...acc, [key]: - parseDef(def.valueType._def, { + parseDef((def.valueType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'properties', key], }) ?? {}, @@ -42,7 +39,7 @@ export function parseRecordDef( const schema: JsonSchema7RecordType = { type: 'object', additionalProperties: - parseDef(def.valueType._def, { + parseDef((def.valueType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'additionalProperties'], }) ?? {}, @@ -52,11 +49,13 @@ export function parseRecordDef( return schema } - if (def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodString && def.keyType._def.checks?.length) { - const keyType: JsonSchema7RecordPropertyNamesType = Object.entries(parseStringDef(def.keyType._def, refs)).reduce( - (acc, [key, value]) => (key === 'type' ? acc : { ...acc, [key]: value }), - {} - ) + if ( + def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodString && + (def.keyType as ZodTypeAny)._def.checks?.length + ) { + const keyType: JsonSchema7RecordPropertyNamesType = Object.entries( + parseStringDef((def.keyType as ZodTypeAny)._def, refs) + ).reduce((acc, [key, value]) => (key === 'type' ? acc : { ...acc, [key]: value }), {}) return { ...schema, @@ -66,7 +65,7 @@ export function parseRecordDef( return { ...schema, propertyNames: { - enum: def.keyType._def.values, + enum: (def.keyType as ZodTypeAny)._def.values, }, } } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts index cacad63077b..da2f464df88 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodSetDef } from '../../../z/index' +import { ZodSetDef, ZodTypeAny } from '../../../z/index' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' @@ -16,7 +16,7 @@ export type JsonSchema7SetType = { } export function parseSetDef(def: ZodSetDef, refs: Refs): JsonSchema7SetType { - const items = parseDef(def.valueType._def, { + const items = parseDef((def.valueType as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'items'], }) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts index ce3ac2e2b68..721973c9cf0 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodTupleDef, ZodTupleItems, ZodTypeAny } from '../../../z/index' +import { ZodTupleDef, ZodTupleItems, ZodType, ZodTypeAny } from '../../../z/index' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' @@ -18,23 +18,20 @@ export type JsonSchema7TupleType = { } ) -export function parseTupleDef( - def: ZodTupleDef, - refs: Refs -): JsonSchema7TupleType { +export function parseTupleDef(def: ZodTupleDef, refs: Refs): JsonSchema7TupleType { if (def.rest) { return { type: 'array', minItems: def.items.length, items: def.items - .map((x, i) => + .map((x: ZodTypeAny, i) => parseDef(x._def, { ...refs, currentPath: [...refs.currentPath, 'items', `${i}`], }) ) .reduce((acc: JsonSchema7Type[], x) => (x === undefined ? acc : [...acc, x]), []), - additionalItems: parseDef(def.rest._def, { + additionalItems: parseDef((def.rest as ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'additionalItems'], }), @@ -45,7 +42,7 @@ export function parseTupleDef( minItems: def.items.length, maxItems: def.items.length, items: def.items - .map((x, i) => + .map((x: ZodTypeAny, i) => parseDef(x._def, { ...refs, currentPath: [...refs.currentPath, 'items', `${i}`], diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts index beb7e02dfdf..98b174e86fb 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts @@ -23,7 +23,7 @@ export type ZuiSchemaOptions = { * @deprecated Use the new toJSONSchema function instead. */ export const toJSONSchemaLegacy = ( - zuiType: z.ZodTypeAny, + zuiType: z.ZodType, opts: ZuiSchemaOptions = { target: 'openApi3' } ): JSONSchema7 => { const jsonSchema = zodToJsonSchema(zuiType as z.ZodType, opts) diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts index 47f211fbc55..00837d45836 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts @@ -4,7 +4,7 @@ import * as json from '../../common/json-schema' export const zodArrayToJsonArray = ( zodArray: z.ZodArray, - toSchema: (x: z.ZodTypeAny) => json.Schema + toSchema: (x: z.ZodType) => json.Schema ): json.ArraySchema => { const schema: json.ArraySchema = { type: 'array', diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts index 5eef084d3f9..7c8610af569 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts @@ -2,7 +2,7 @@ import { zuiKey } from '../../../ui/constants' import z from '../../../z' import * as json from '../../common/json-schema' -export const zodSetToJsonSet = (zodSet: z.ZodSet, toSchema: (x: z.ZodTypeAny) => json.Schema): json.SetSchema => { +export const zodSetToJsonSet = (zodSet: z.ZodSet, toSchema: (x: z.ZodType) => json.Schema): json.SetSchema => { const schema: json.SetSchema = { type: 'array', description: zodSet.description, diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts index 09c82b1654e..31c2d49bf0f 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts @@ -4,7 +4,7 @@ import * as json from '../../common/json-schema' export const zodTupleToJsonTuple = ( zodTuple: z.ZodTuple, - toSchema: (x: z.ZodTypeAny) => json.Schema + toSchema: (x: z.ZodType) => json.Schema ): json.TupleSchema => { const schema: json.TupleSchema = { type: 'array', diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts index 988e10ad93f..7a691c993d8 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts @@ -175,7 +175,7 @@ function sUnwrapZod(schema: z.Schema): string { } } -const _addMetadata = (def: z.ZodTypeDef, inner?: z.ZodTypeAny) => { +const _addMetadata = (def: z.ZodTypeDef, inner?: z.ZodType) => { const innerDef = inner?._def return `${_addZuiExtensions(def, innerDef)}${_maybeDescribe(def, innerDef)}` } diff --git a/packages/zui/src/ui/types.ts b/packages/zui/src/ui/types.ts index 1977edf113d..b49766c2e08 100644 --- a/packages/zui/src/ui/types.ts +++ b/packages/zui/src/ui/types.ts @@ -1,4 +1,5 @@ -import { ZodEnumDef, ZodNativeSchemaDef, z } from '../z' +import { ZodTypeDef, ZodType, TypeOf } from '../z/types/basetype' +import { ZodObject } from '../z/types/object' export type ZuiMetadata = string | number | boolean | null | undefined | ZuiMetadata[] | { [key: string]: ZuiMetadata } @@ -23,12 +24,12 @@ export type UIComponentDefinitions = { [T in BaseType]: { [K: string]: { id: string - params: z.ZodObject + params: ZodObject } } } -export type ZodKindToBaseType = T extends infer U +export type ZodKindToBaseType = T extends infer U ? U extends { typeName: 'ZodString' } ? 'string' : U extends { typeName: 'ZodNumber' } @@ -41,27 +42,24 @@ export type ZodKindToBaseType = T extends infer U ? 'object' : U extends { typeName: 'ZodTuple' } ? never - : U extends ZodEnumDef + : U extends { typeName: 'ZodEnum' } ? 'string' - : U extends { typeName: 'ZodDefault'; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodDefault'; innerType: ZodType } ? ZodKindToBaseType - : U extends { typeName: 'ZodOptional'; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodOptional'; innerType: ZodType } ? ZodKindToBaseType - : U extends { typeName: 'ZodNullable'; innerType: z.ZodTypeAny } + : U extends { typeName: 'ZodNullable'; innerType: ZodType } ? ZodKindToBaseType - : U extends { - typeName: 'ZodDiscriminatedUnion' - options: z.ZodDiscriminatedUnionOption[] - } + : U extends { typeName: 'ZodDiscriminatedUnion' } ? 'discriminatedUnion' : never : never export type ParseSchema = I extends infer U - ? U extends { id: string; params: z.AnyZodObject } + ? U extends { id: string; params: ZodObject } ? { id: U['id'] - params: z.infer + params: TypeOf } : object : never diff --git a/packages/zui/src/z/__tests__/generics.test.ts b/packages/zui/src/z/__tests__/generics.test.ts index 979c99ca7ff..572a1e9fb99 100644 --- a/packages/zui/src/z/__tests__/generics.test.ts +++ b/packages/zui/src/z/__tests__/generics.test.ts @@ -3,10 +3,10 @@ import z from '../index' import { util } from '../types/utils' test('generics', () => { - async function stripOuter(schema: TData, data: unknown) { + async function stripOuter(schema: TData, data: unknown) { return z .object({ - nested: schema, // as z.ZodTypeAny, + nested: schema, }) .transform((data) => { return data.nested! diff --git a/packages/zui/src/z/deref.test.ts b/packages/zui/src/z/deref.test.ts index c5d88c208b5..c9ea4f31210 100644 --- a/packages/zui/src/z/deref.test.ts +++ b/packages/zui/src/z/deref.test.ts @@ -11,7 +11,7 @@ const deref = { baz: z.boolean(), } -const intersect = (...schemas: z.ZodTypeAny[]) => { +const intersect = (...schemas: z.ZodType[]) => { if (schemas.length === 0) { throw new Error('Intersection expects at least one schema') } diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index 575a0c985a2..701abbf29e4 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -4,7 +4,6 @@ import { ParseInputLazyPath, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, @@ -16,7 +15,7 @@ import { ParseStatus, } from '../index' -export type ZodArrayDef = { +export type ZodArrayDef = { type: T typeName: 'ZodArray' exactLength: { value: number; message?: string } | null @@ -26,16 +25,16 @@ export type ZodArrayDef = { export type ArrayCardinality = 'many' | 'atleastone' export type arrayOutputType< - T extends ZodTypeAny, + T extends ZodType, Cardinality extends ArrayCardinality = 'many', > = Cardinality extends 'atleastone' ? [T['_output'], ...T['_output'][]] : T['_output'][] -export class ZodArray extends ZodType< +export class ZodArray extends ZodType< arrayOutputType, ZodArrayDef, Cardinality extends 'atleastone' ? [T['_input'], ...T['_input'][]] : T['_input'][] > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodArray({ ...this._def, type: this._def.type.dereference(defs), @@ -171,7 +170,7 @@ export class ZodArray } - static create = (schema: T, params?: RawCreateParams): ZodArray => { + static create = (schema: T, params?: RawCreateParams): ZodArray => { return new ZodArray({ type: schema, minLength: null, @@ -183,4 +182,4 @@ export class ZodArray = ZodArray +export type ZodNonEmptyArray = ZodArray diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 1c200e2e655..32468b8204d 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -38,7 +38,6 @@ import { ZodErrorMap, ZodIntersection, ZodIssueCode, - ZodNativeSchemaDef, ZodNullable, ZodOptional, ZodPipeline, @@ -61,14 +60,11 @@ type __ZodType = { readonly _input: Input } -type Cast = A extends B ? A : B - export type RefinementCtx = { addIssue: (arg: IssueData) => void path: (string | number)[] } -export type ZodRawShape = { [k: string]: ZodTypeAny } -export type ZodTypeAny = ZodType +export type ZodRawShape = { [k: string]: ZodType } export type TypeOf = T['_output'] export type OfType = T extends __ZodType ? T : never export type input = T['_input'] @@ -177,7 +173,7 @@ export abstract class ZodType /** deeply replace all references in the schema */ - dereference(_defs: Record): ZodTypeAny { + dereference(_defs: Record): ZodType { return this } @@ -448,11 +444,11 @@ export abstract class ZodType(option: T): ZodUnion<[this, T]> { + or(option: T): ZodUnion<[this, T]> { return ZodUnion.create([this, option], this._def) } - and(incoming: T): ZodIntersection { + and(incoming: T): ZodIntersection { return ZodIntersection.create(this, incoming, this._def) } @@ -506,7 +502,7 @@ export abstract class ZodType(target: T): ZodPipeline { + pipe(target: T): ZodPipeline { return ZodPipeline.create(this, target) } @@ -571,7 +567,7 @@ export abstract class ZodType>, + Type extends BaseType = ZodKindToBaseType, >(options: ParseSchema): this { return this.metadata({ displayAs: [options.id, options.params] }) } @@ -656,7 +652,7 @@ export abstract class ZodType = { +export type ZodBrandedDef = { type: T typeName: 'ZodBranded' } & ZodTypeDef @@ -14,12 +14,12 @@ export type BRAND = { } } -export class ZodBranded extends ZodType< +export class ZodBranded extends ZodType< T['_output'] & BRAND, ZodBrandedDef, T['_input'] > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodBranded({ ...this._def, type: this._def.type.dereference(defs), @@ -56,11 +56,11 @@ export class ZodBranded return this._def.type.isEqual(schema._def.type) } - naked(): ZodTypeAny { + naked(): ZodType { return this._def.type.naked() } - mandatory(): ZodBranded { + mandatory(): ZodBranded { return new ZodBranded({ ...this._def, type: this._def.type.mandatory(), diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index f8ca3b666df..f9d1356b52a 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -2,7 +2,6 @@ import { ZodError, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, isAsync, @@ -13,13 +12,13 @@ import { } from '../index' export type CatchFn = (ctx: { error: ZodError; input: unknown }) => Y -export type ZodCatchDef = { +export type ZodCatchDef = { innerType: T catchValue: CatchFn typeName: 'ZodCatch' } & ZodTypeDef -export class ZodCatch extends ZodType< +export class ZodCatch extends ZodType< T['_output'], ZodCatchDef, unknown // any input will pass validation // T["_input"] @@ -79,7 +78,7 @@ export class ZodCatch extends ZodType< return this._def.innerType } - static create = ( + static create = ( type: T, params: RawCreateParams & { catch: T['_output'] | CatchFn @@ -101,7 +100,7 @@ export class ZodCatch extends ZodType< ) } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodCatch({ ...this._def, innerType: this._def.innerType.dereference(defs), @@ -123,7 +122,7 @@ export class ZodCatch extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodCatch { + mandatory(): ZodCatch { return new ZodCatch({ ...this._def, innerType: this._def.innerType.mandatory(), diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 2927ba5e8d2..8a2abba7cb2 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -3,7 +3,6 @@ import { isEqual } from 'lodash-es' import { RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, util, @@ -12,13 +11,13 @@ import { ParseReturnType, } from '../index' -export type ZodDefaultDef = { +export type ZodDefaultDef = { innerType: T defaultValue: () => util.noUndefined typeName: 'ZodDefault' } & ZodTypeDef -export class ZodDefault extends ZodType< +export class ZodDefault extends ZodType< util.noUndefined, ZodDefaultDef, T['_input'] | undefined @@ -40,7 +39,7 @@ export class ZodDefault extends ZodType< return this._def.innerType } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodDefault({ ...this._def, innerType: this._def.innerType.dereference(defs), @@ -58,7 +57,7 @@ export class ZodDefault extends ZodType< }) as ZodDefault } - static create = ( + static create = ( type: T, value: T['_input'] | (() => util.noUndefined), params?: RawCreateParams @@ -87,7 +86,7 @@ export class ZodDefault extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodDefault { + mandatory(): ZodDefault { return new ZodDefault({ ...this._def, innerType: this._def.innerType.mandatory(), diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index 0d8cd3e8d4f..255a357dd2d 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -10,7 +10,6 @@ import { RawCreateParams, ZodRawShape, ZodType, - ZodTypeAny, ZodTypeDef, ZodLazy, ZodLiteral, @@ -34,7 +33,7 @@ import { } from '../index' import { CustomSet } from '../utils/custom-set' -const getDiscriminator = (type: T): Primitive[] => { +const getDiscriminator = (type: T): Primitive[] => { if (type instanceof ZodLazy) { return getDiscriminator(type.schema) } else if (type instanceof ZodEffects) { @@ -68,7 +67,7 @@ const getDiscriminator = (type: T): Primitive[] => { export type ZodDiscriminatedUnionOption = ZodObject< { - [key in Discriminator]: ZodTypeAny + [key in Discriminator]: ZodType } & ZodRawShape, UnknownKeysParam > @@ -87,7 +86,7 @@ export class ZodDiscriminatedUnion< Discriminator extends string = string, Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], > extends ZodType, ZodDiscriminatedUnionDef, input> { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { const options = this.options.map((option) => option.dereference(defs)) as [ ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[], diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 9dc8dd42c56..8d5098cea41 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -8,7 +8,6 @@ import { ZodIssueCode, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, ZodPromise, AnyZodTuple, @@ -24,27 +23,24 @@ import { ParseReturnType, } from '../index' -export type ZodFunctionDef = ZodTuple, Returns extends ZodTypeAny = ZodTypeAny> = { +export type ZodFunctionDef = ZodTuple, Returns extends ZodType = ZodType> = { args: Args returns: Returns typeName: 'ZodFunction' } & ZodTypeDef -export type OuterTypeOfFunction, Returns extends ZodTypeAny> = +export type OuterTypeOfFunction, Returns extends ZodType> = Args['_input'] extends Array ? (...args: Args['_input']) => Returns['_output'] : never -export type InnerTypeOfFunction, Returns extends ZodTypeAny> = +export type InnerTypeOfFunction, Returns extends ZodType> = Args['_output'] extends Array ? (...args: Args['_output']) => Returns['_input'] : never -export class ZodFunction< - Args extends ZodTuple = ZodTuple, - Returns extends ZodTypeAny = ZodTypeAny, -> extends ZodType< +export class ZodFunction = ZodTuple, Returns extends ZodType = ZodType> extends ZodType< OuterTypeOfFunction, ZodFunctionDef, InnerTypeOfFunction > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { const args = this._def.args.dereference(defs) as ZodTuple<[], ZodUnknown> const returns = this._def.returns.dereference(defs) return new ZodFunction({ @@ -120,9 +116,10 @@ export class ZodFunction< throw error }) const result = await Reflect.apply(fn, this, parsedArgs) - const parsedReturns = await (me._def.returns as unknown as ZodPromise)._def.type + const parsedReturns = await (me._def.returns as unknown as ZodPromise)._def.type .parseAsync(result, params) - .catch((e) => { + .catch((e: any) => { + // TODO: type e properly error.addIssue(makeReturnsIssue(result, e)) throw error }) @@ -190,13 +187,13 @@ export class ZodFunction< static create(): ZodFunction, ZodUnknown> static create>(args: T): ZodFunction - static create(args: T, returns: U): ZodFunction - static create, U extends ZodTypeAny = ZodUnknown>( + static create(args: T, returns: U): ZodFunction + static create, U extends ZodType = ZodUnknown>( args: T, returns: U, params?: RawCreateParams ): ZodFunction - static create(args?: AnyZodTuple, returns?: ZodTypeAny, params?: RawCreateParams) { + static create(args?: AnyZodTuple, returns?: ZodType, params?: RawCreateParams) { return new ZodFunction({ args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()), returns: returns || ZodUnknown.create(), diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 404ebf26a47..e842057c773 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -3,7 +3,6 @@ import { ZodIssueCode, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, getParsedType, processCreateParams, @@ -19,7 +18,7 @@ import { } from '../index' import { CustomSet } from '../utils/custom-set' -export type ZodIntersectionDef = { +export type ZodIntersectionDef = { left: T right: U typeName: 'ZodIntersection' @@ -71,12 +70,12 @@ function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: fals } } -export class ZodIntersection extends ZodType< +export class ZodIntersection extends ZodType< T['_output'] & U['_output'], ZodIntersectionDef, T['_input'] & U['_input'] > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodIntersection({ ...this._def, left: this._def.left.dereference(defs), @@ -151,7 +150,7 @@ export class ZodIntersection( + static create = ( left: T, right: U, params?: RawCreateParams diff --git a/packages/zui/src/z/types/lazy/index.ts b/packages/zui/src/z/types/lazy/index.ts index 0fc70754bb4..4bbb881f91c 100644 --- a/packages/zui/src/z/types/lazy/index.ts +++ b/packages/zui/src/z/types/lazy/index.ts @@ -5,22 +5,21 @@ import { processCreateParams, ParseInput, ParseReturnType, - ZodTypeAny, output, input, } from '../index' -export type ZodLazyDef = { +export type ZodLazyDef = { getter: () => T typeName: 'ZodLazy' } & ZodTypeDef -export class ZodLazy extends ZodType, ZodLazyDef, input> { +export class ZodLazy extends ZodType, ZodLazyDef, input> { get schema(): T { return this._def.getter() } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodLazy({ ...this._def, getter: () => this._def.getter().dereference(defs), @@ -44,7 +43,7 @@ export class ZodLazy extends ZodType(getter: () => T, params?: RawCreateParams): ZodLazy => { + static create = (getter: () => T, params?: RawCreateParams): ZodLazy => { return new ZodLazy({ getter, typeName: 'ZodLazy', @@ -61,7 +60,7 @@ export class ZodLazy extends ZodType { + mandatory(): ZodLazy { return new ZodLazy({ ...this._def, getter: () => this._def.getter().mandatory(), diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index e6fece73477..c6f31ac5c13 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -4,7 +4,6 @@ import { ParseInputLazyPath, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, @@ -15,13 +14,13 @@ import { SyncParseReturnType, } from '../index' -export type ZodMapDef = { +export type ZodMapDef = { valueType: Value keyType: Key typeName: 'ZodMap' } & ZodTypeDef -export class ZodMap extends ZodType< +export class ZodMap extends ZodType< Map, ZodMapDef, Map @@ -33,7 +32,7 @@ export class ZodMap): ZodTypeAny { + dereference(defs: Record): ZodType { const keyType = this._def.keyType.dereference(defs) const valueType = this._def.valueType.dereference(defs) return new ZodMap({ @@ -110,7 +109,7 @@ export class ZodMap( + static create = ( keyType: Key, valueType: Value, params?: RawCreateParams diff --git a/packages/zui/src/z/types/nullable/index.ts b/packages/zui/src/z/types/nullable/index.ts index 72b092b5e63..e2b69d20648 100644 --- a/packages/zui/src/z/types/nullable/index.ts +++ b/packages/zui/src/z/types/nullable/index.ts @@ -4,25 +4,24 @@ import { ParseReturnType, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, } from '../index' -export type ZodNullableDef = { +export type ZodNullableDef = { innerType: T typeName: 'ZodNullable' } & ZodTypeDef -export type ZodNullableType = ZodNullable +export type ZodNullableType = ZodNullable -export class ZodNullable extends ZodType< +export class ZodNullable extends ZodType< T['_output'] | null, ZodNullableDef, T['_input'] | null > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodNullable({ ...this._def, innerType: this._def.innerType.dereference(defs), @@ -52,7 +51,7 @@ export class ZodNullable extends ZodType< return this._def.innerType } - static create = (type: T, params?: RawCreateParams): ZodNullable => { + static create = (type: T, params?: RawCreateParams): ZodNullable => { return new ZodNullable({ innerType: type, typeName: 'ZodNullable', @@ -69,7 +68,7 @@ export class ZodNullable extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodNullable { + mandatory(): ZodNullable { return new ZodNullable({ ...this._def, innerType: this._def.innerType.mandatory(), diff --git a/packages/zui/src/z/types/nullable/nullable.test.ts b/packages/zui/src/z/types/nullable/nullable.test.ts index 22f5ddb3986..bf0f7fbc57f 100644 --- a/packages/zui/src/z/types/nullable/nullable.test.ts +++ b/packages/zui/src/z/types/nullable/nullable.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import * as z from '../../index' -function checkErrors(a: z.ZodTypeAny, bad: any) { +function checkErrors(a: z.ZodType, bad: any) { let expected try { a.parse(bad) diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index d84db29e225..c2b9cd764aa 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -18,7 +18,6 @@ import { RawCreateParams, ZodRawShape, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, enumUtil, @@ -30,7 +29,7 @@ import { } from '../index' import { CustomSet } from '../utils/custom-set' -export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodTypeAny +export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodType export type ZodObjectDef< T extends ZodRawShape = ZodRawShape, @@ -63,19 +62,19 @@ export type baseObjectInputType = objectUtil.addQuest [k in keyof Shape]: Shape[k]['_input'] }> -export type UnknownKeysInputType = T extends ZodTypeAny +export type UnknownKeysInputType = T extends ZodType ? { [k: string]: T['_input'] | unknown } // extra properties cannot contradict the main properties : T extends 'passthrough' ? { [k: string]: unknown } : {} -export type UnknownKeysOutputType = T extends ZodTypeAny +export type UnknownKeysOutputType = T extends ZodType ? { [k: string]: T['_output'] | unknown } // extra properties cannot contradict the main properties : T extends 'passthrough' ? { [k: string]: unknown } : {} -export type AdditionalProperties = T extends ZodTypeAny +export type AdditionalProperties = T extends ZodType ? T : T extends 'passthrough' ? ZodAny @@ -83,7 +82,7 @@ export type AdditionalProperties = T extends ZodType ? ZodNever : undefined -export type deoptional = +export type deoptional = T extends ZodOptional ? deoptional : T extends ZodNullable ? ZodNullable> : T export type SomeZodObject = ZodObject @@ -91,7 +90,7 @@ export type SomeZodObject = ZodObject export type noUnrecognized = { [k in keyof Obj]: k extends keyof Shape ? Obj[k] : never } -function deepPartialify(schema: ZodTypeAny): any { +function deepPartialify(schema: ZodType): any { if (schema instanceof ZodObject) { const newShape: any = {} @@ -134,9 +133,9 @@ export class ZodObject< return (this._cached = { shape, keys }) } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { const currentShape = this._def.shape() - const shape: Record = {} + const shape: Record = {} for (const key in currentShape) { shape[key] = currentShape[key]!.dereference(defs) } @@ -156,7 +155,7 @@ export class ZodObject< } clone(): ZodObject { - const newShape: Record = {} + const newShape: Record = {} const currentShape = this._def.shape() for (const [key, value] of Object.entries(currentShape)) { newShape[key] = value.clone() @@ -442,7 +441,7 @@ export class ZodObject< // }); // return merged; // } - setKey( + setKey( key: Key, schema: Schema ): ZodObject< @@ -479,7 +478,7 @@ export class ZodObject< // }); // return merged; // } - catchall(index: Index): ZodObject { + catchall(index: Index): ZodObject { return new ZodObject({ ...this._def, unknownKeys: index, @@ -550,7 +549,7 @@ export class ZodObject< UnknownKeys > partial(mask?: any) { - const newShape: Record = {} + const newShape: Record = {} util.objectKeys(this.shape).forEach((key) => { const fieldSchema = this.shape[key] @@ -621,7 +620,7 @@ export class ZodObject< const thisShape = this._def.shape() const thatShape = schema._def.shape() - type Property = [string, ZodTypeAny] + type Property = [string, ZodType] const compare = (a: Property, b: Property) => a[0] === b[0] && a[1].isEqual(b[1]) const thisProps = new CustomSet(Object.entries(thisShape), { compare }) const thatProps = new CustomSet(Object.entries(thatShape), { compare }) diff --git a/packages/zui/src/z/types/optional/index.ts b/packages/zui/src/z/types/optional/index.ts index 155d6c1c758..1ba859b042c 100644 --- a/packages/zui/src/z/types/optional/index.ts +++ b/packages/zui/src/z/types/optional/index.ts @@ -3,26 +3,25 @@ import { ZodParsedType, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, OK, ParseInput, ParseReturnType, } from '../index' -export type ZodOptionalDef = { +export type ZodOptionalDef = { innerType: T typeName: 'ZodOptional' } & ZodTypeDef -export type ZodOptionalType = ZodOptional +export type ZodOptionalType = ZodOptional -export class ZodOptional extends ZodType< +export class ZodOptional extends ZodType< T['_output'] | undefined, ZodOptionalDef, T['_input'] | undefined > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodOptional({ ...this._def, innerType: this._def.innerType.dereference(defs), @@ -52,7 +51,7 @@ export class ZodOptional extends ZodType< return this._def.innerType } - static create = (type: T, params?: RawCreateParams): ZodOptional => { + static create = (type: T, params?: RawCreateParams): ZodOptional => { return new ZodOptional({ innerType: type, typeName: 'ZodOptional', @@ -69,7 +68,7 @@ export class ZodOptional extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodTypeAny { + mandatory(): ZodType { return this._def.innerType.mandatory() } } diff --git a/packages/zui/src/z/types/optional/optional.test.ts b/packages/zui/src/z/types/optional/optional.test.ts index 647a99f2d4c..b44c40eef86 100644 --- a/packages/zui/src/z/types/optional/optional.test.ts +++ b/packages/zui/src/z/types/optional/optional.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import * as z from '../../index' -function checkErrors(a: z.ZodTypeAny, bad: any) { +function checkErrors(a: z.ZodType, bad: any) { let expected try { a.parse(bad) diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index 95ea4377f4d..22043b405de 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,18 +1,18 @@ import { unique } from '../../utils' -import { ZodType, ZodTypeAny, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../index' +import { ZodType, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../index' -export type ZodPipelineDef = { +export type ZodPipelineDef = { in: A out: B typeName: 'ZodPipeline' } & ZodTypeDef -export class ZodPipeline extends ZodType< +export class ZodPipeline extends ZodType< B['_output'], ZodPipelineDef, A['_input'] > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodPipeline({ ...this._def, in: this._def.in.dereference(defs), @@ -77,7 +77,7 @@ export class ZodPipeline(a: A, b: B): ZodPipeline { + static create(a: A, b: B): ZodPipeline { return new ZodPipeline({ in: a, out: b, diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index d81149710d3..741e42e19cc 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -2,7 +2,6 @@ import { ZodIssueCode, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, @@ -13,12 +12,12 @@ import { ParseReturnType, } from '../index' -export type ZodPromiseDef = { +export type ZodPromiseDef = { type: T typeName: 'ZodPromise' } & ZodTypeDef -export class ZodPromise extends ZodType< +export class ZodPromise extends ZodType< Promise, ZodPromiseDef, Promise @@ -27,7 +26,7 @@ export class ZodPromise extends ZodType< return this._def.type } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodPromise({ ...this._def, type: this._def.type.dereference(defs), @@ -68,7 +67,7 @@ export class ZodPromise extends ZodType< ) } - static create = (schema: T, params?: RawCreateParams): ZodPromise => { + static create = (schema: T, params?: RawCreateParams): ZodPromise => { return new ZodPromise({ type: schema, typeName: 'ZodPromise', @@ -76,7 +75,7 @@ export class ZodPromise extends ZodType< }) } - isEqual(schema: ZodTypeAny): boolean { + isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodPromise)) return false return this._def.type.isEqual(schema._def.type) } diff --git a/packages/zui/src/z/types/readonly/index.ts b/packages/zui/src/z/types/readonly/index.ts index 450bcdabf10..d92682938cb 100644 --- a/packages/zui/src/z/types/readonly/index.ts +++ b/packages/zui/src/z/types/readonly/index.ts @@ -2,7 +2,6 @@ import { processCreateParams, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, isValid, ParseInput, @@ -31,17 +30,17 @@ type MakeReadonly = ? T : Readonly -export type ZodReadonlyDef = { +export type ZodReadonlyDef = { innerType: T typeName: 'ZodReadonly' } & ZodTypeDef -export class ZodReadonly extends ZodType< +export class ZodReadonly extends ZodType< MakeReadonly, ZodReadonlyDef, MakeReadonly > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodReadonly({ ...this._def, innerType: this._def.innerType.dereference(defs), @@ -67,7 +66,7 @@ export class ZodReadonly extends ZodType< return result } - static create = (type: T, params?: RawCreateParams): ZodReadonly => { + static create = (type: T, params?: RawCreateParams): ZodReadonly => { return new ZodReadonly({ innerType: type, typeName: 'ZodReadonly', @@ -88,7 +87,7 @@ export class ZodReadonly extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodReadonly { + mandatory(): ZodReadonly { return new ZodReadonly({ ...this._def, innerType: this._def.innerType.mandatory(), diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index fc1815f32e5..69f36e6e4d6 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -5,7 +5,6 @@ import { ParseInputLazyPath, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, ZodString, processCreateParams, @@ -17,7 +16,7 @@ import { ParseStatus, } from '../index' -export type ZodRecordDef = { +export type ZodRecordDef = { valueType: Value keyType: Key typeName: 'ZodRecord' @@ -35,7 +34,7 @@ export type RecordType = [string] extends ? Record : Partial> -export class ZodRecord extends ZodType< +export class ZodRecord extends ZodType< RecordType, ZodRecordDef, RecordType @@ -47,7 +46,7 @@ export class ZodRecord): ZodTypeAny { + dereference(defs: Record): ZodType { const keyType = this._def.keyType.dereference(defs) const valueType = this._def.valueType.dereference(defs) return new ZodRecord({ @@ -106,8 +105,8 @@ export class ZodRecord(valueType: Value, params?: RawCreateParams): ZodRecord - static create( + static create(valueType: Value, params?: RawCreateParams): ZodRecord + static create( keySchema: Keys, valueType: Value, params?: RawCreateParams diff --git a/packages/zui/src/z/types/ref/index.ts b/packages/zui/src/z/types/ref/index.ts index 7d60a0fca66..8dd31f2ece7 100644 --- a/packages/zui/src/z/types/ref/index.ts +++ b/packages/zui/src/z/types/ref/index.ts @@ -1,13 +1,4 @@ -import { - ZodType, - ZodTypeDef, - INVALID, - ParseInput, - ParseReturnType, - ZodTypeAny, - addIssueToContext, - ZodIssueCode, -} from '../index' +import { ZodType, ZodTypeDef, INVALID, ParseInput, ParseReturnType, addIssueToContext, ZodIssueCode } from '../index' export type ZodRefDef = { typeName: 'ZodRef' @@ -17,7 +8,7 @@ export type ZodRefDef = { type ZodRefOutput = NonNullable export class ZodRef extends ZodType { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { const def = defs[this._def.uri] if (!def) { return this diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 6f9686327c4..1618b8c4392 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -3,7 +3,6 @@ import { ParseInputLazyPath, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, @@ -15,19 +14,19 @@ import { SyncParseReturnType, } from '../index' -export type ZodSetDef = { +export type ZodSetDef = { valueType: Value typeName: 'ZodSet' minSize: { value: number; message?: string } | null maxSize: { value: number; message?: string } | null } & ZodTypeDef -export class ZodSet extends ZodType< +export class ZodSet extends ZodType< Set, ZodSetDef, Set > { - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodSet({ ...this._def, valueType: this._def.valueType.dereference(defs), @@ -131,10 +130,7 @@ export class ZodSet extends ZodType< return this.min(1, message) as this } - static create = ( - valueType: Value, - params?: RawCreateParams - ): ZodSet => { + static create = (valueType: Value, params?: RawCreateParams): ZodSet => { return new ZodSet({ valueType, minSize: null, diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 686d1f047fb..a086e7d9cad 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -5,7 +5,6 @@ import { RawCreateParams, RefinementCtx, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, util, @@ -34,13 +33,13 @@ export type PreprocessEffect = { } export type Effect = RefinementEffect | TransformEffect | PreprocessEffect -export type ZodEffectsDef = { +export type ZodEffectsDef = { schema: T typeName: 'ZodEffects' effect: Effect } & ZodTypeDef -export class ZodEffects, Input = input> extends ZodType< +export class ZodEffects, Input = input> extends ZodType< Output, ZodEffectsDef, Input @@ -58,7 +57,7 @@ export class ZodEffects, I : (this._def.schema as T) } - dereference(defs: Record): ZodTypeAny { + dereference(defs: Record): ZodType { return new ZodEffects({ ...this._def, schema: this._def.schema.dereference(defs), @@ -209,7 +208,7 @@ export class ZodEffects, I }) } - static createWithPreprocess = ( + static createWithPreprocess = ( preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, schema: I, params?: RawCreateParams @@ -249,7 +248,7 @@ export class ZodEffects, I return this._def.schema.naked() } - mandatory(): ZodEffects { + mandatory(): ZodEffects { return new ZodEffects({ ...this._def, schema: this._def.schema.mandatory(), diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 43164d5ac04..eb112961378 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -4,7 +4,6 @@ import { ParseInputLazyPath, RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, processCreateParams, ZodParsedType, @@ -17,37 +16,37 @@ import { } from '../index' import { CustomSet } from '../utils/custom-set' -export type ZodTupleItems = [ZodTypeAny, ...ZodTypeAny[]] +export type ZodTupleItems = [ZodType, ...ZodType[]] export type AssertArray = T extends any[] ? T : never export type OutputTypeOfTuple = AssertArray<{ [k in keyof T]: T[k] extends ZodType ? T[k]['_output'] : never }> export type OutputTypeOfTupleWithRest< T extends ZodTupleItems | [], - Rest extends ZodTypeAny | null = null, -> = Rest extends ZodTypeAny ? [...OutputTypeOfTuple, ...Rest['_output'][]] : OutputTypeOfTuple + Rest extends ZodType | null = null, +> = Rest extends ZodType ? [...OutputTypeOfTuple, ...Rest['_output'][]] : OutputTypeOfTuple export type InputTypeOfTuple = AssertArray<{ [k in keyof T]: T[k] extends ZodType ? T[k]['_input'] : never }> export type InputTypeOfTupleWithRest< T extends ZodTupleItems | [], - Rest extends ZodTypeAny | null = null, -> = Rest extends ZodTypeAny ? [...InputTypeOfTuple, ...Rest['_input'][]] : InputTypeOfTuple + Rest extends ZodType | null = null, +> = Rest extends ZodType ? [...InputTypeOfTuple, ...Rest['_input'][]] : InputTypeOfTuple -export type ZodTupleDef = { +export type ZodTupleDef = { items: T rest: Rest typeName: 'ZodTuple' } & ZodTypeDef -export type AnyZodTuple = ZodTuple<[ZodTypeAny, ...ZodTypeAny[]] | [], ZodTypeAny | null> +export type AnyZodTuple = ZodTuple<[ZodType, ...ZodType[]] | [], ZodType | null> export class ZodTuple< - T extends [ZodTypeAny, ...ZodTypeAny[]] | [] = [ZodTypeAny, ...ZodTypeAny[]], - Rest extends ZodTypeAny | null = null, + T extends [ZodType, ...ZodType[]] | [] = [ZodType, ...ZodType[]], + Rest extends ZodType | null = null, > extends ZodType, ZodTupleDef, InputTypeOfTupleWithRest> { - dereference(defs: Record): ZodTypeAny { - const items = this._def.items.map((item) => item.dereference(defs)) as [ZodTypeAny, ...ZodTypeAny[]] + dereference(defs: Record): ZodType { + const items = this._def.items.map((item) => item.dereference(defs)) as [ZodType, ...ZodType[]] const rest = this._def.rest ? this._def.rest.dereference(defs) : null return new ZodTuple({ ...this._def, @@ -64,7 +63,7 @@ export class ZodTuple< } clone(): ZodTuple { - const items = this._def.items.map((item) => item.clone()) as [ZodTypeAny, ...ZodTypeAny[]] + const items = this._def.items.map((item) => item.clone()) as [ZodType, ...ZodType[]] const rest = this._def.rest ? this._def.rest.clone() : null return new ZodTuple({ ...this._def, @@ -130,17 +129,14 @@ export class ZodTuple< return this._def.items } - rest(rest: Rest): ZodTuple { + rest(rest: Rest): ZodTuple { return new ZodTuple({ ...this._def, rest, }) } - static create = ( - schemas: T, - params?: RawCreateParams - ): ZodTuple => { + static create = (schemas: T, params?: RawCreateParams): ZodTuple => { if (!Array.isArray(schemas)) { throw new Error('You must pass an array of schemas to z.tuple([ ... ])') } diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index e481b2db2c4..78451c1a1ed 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -2,7 +2,6 @@ import { unique } from '../../utils' import { RawCreateParams, ZodType, - ZodTypeAny, ZodTypeDef, ZodError, ZodIssue, @@ -20,8 +19,8 @@ import { } from '../index' import { CustomSet } from '../utils/custom-set' -type DefaultZodUnionOptions = Readonly<[ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]> -export type ZodUnionOptions = Readonly<[ZodTypeAny, ...ZodTypeAny[]]> +type DefaultZodUnionOptions = Readonly<[ZodType, ZodType, ...ZodType[]]> +export type ZodUnionOptions = Readonly<[ZodType, ...ZodType[]]> export type ZodUnionDef = { options: T typeName: 'ZodUnion' @@ -32,12 +31,8 @@ export class ZodUnion extend ZodUnionDef, T[number]['_input'] > { - dereference(defs: Record): ZodTypeAny { - const options = this._def.options.map((option) => option.dereference(defs)) as [ - ZodTypeAny, - ZodTypeAny, - ...ZodTypeAny[], - ] + dereference(defs: Record): ZodType { + const options = this._def.options.map((option) => option.dereference(defs)) as [ZodType, ZodType, ...ZodType[]] return new ZodUnion({ ...this._def, options, @@ -53,7 +48,7 @@ export class ZodUnion extend } clone(): ZodUnion { - const options = this._def.options.map((option) => option.clone()) as [ZodTypeAny, ...ZodTypeAny[]] + const options = this._def.options.map((option) => option.clone()) as [ZodType, ...ZodType[]] return new ZodUnion({ ...this._def, options, @@ -159,7 +154,7 @@ export class ZodUnion extend return this._def.options } - static create = >( + static create = >( types: T, params?: RawCreateParams ): ZodUnion => { diff --git a/packages/zui/src/z/types/utils/partialUtil.ts b/packages/zui/src/z/types/utils/partialUtil.ts index d6fc0e4f2a4..320c7d5f4e8 100644 --- a/packages/zui/src/z/types/utils/partialUtil.ts +++ b/packages/zui/src/z/types/utils/partialUtil.ts @@ -6,10 +6,10 @@ import type { ZodTuple, ZodTupleItems, ZodRawShape, - ZodTypeAny, + ZodType, } from '../index' export namespace partialUtil { - export type DeepPartial = + export type DeepPartial = T extends ZodObject ? ZodObject<{ [k in keyof T['shape']]: ZodOptional> }, T['_def']['unknownKeys']> : T extends ZodArray @@ -20,7 +20,7 @@ export namespace partialUtil { ? ZodNullable> : T extends ZodTuple ? { - [k in keyof Items]: Items[k] extends ZodTypeAny ? DeepPartial : never + [k in keyof Items]: Items[k] extends ZodType ? DeepPartial : never } extends infer PI ? PI extends ZodTupleItems ? ZodTuple diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index d1ec30e25af..f28a3714003 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -164,3 +164,8 @@ export * from './types/utils' export * from './types/utils/parseUtil' export * from './types/utils/typeAliases' export * from './extensions' + +/** + * @deprecated - use ZodType instead + */ +export type ZodTypeAny = ZodType diff --git a/packages/zui/src/zui.test.ts b/packages/zui/src/zui.test.ts index 95dd523b56b..f5c7fc814ac 100644 --- a/packages/zui/src/zui.test.ts +++ b/packages/zui/src/zui.test.ts @@ -94,7 +94,7 @@ test('Discriminated Unions', () => { }) test('ZuiTypeAny', () => { - const func = (type: zui.ZodTypeAny) => { + const func = (type: zui.ZodType) => { return type } From 9ab406b85ab1b4436d91db640ffdd852c2bcdb1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 15:13:58 -0500 Subject: [PATCH 04/50] chore(zui): rm internal usage of ZodFirstPartyTypeKind (#14950) --- packages/zui/src/transforms/common/errors.ts | 12 +-- .../transforms/zui-from-json-schema/guards.ts | 12 +-- .../zui-from-json-schema/index.test.ts | 2 +- .../zui-to-json-schema/index.test.ts | 2 +- .../type-processors/string.ts | 2 +- packages/zui/src/z/types/native.test.ts | 93 ++++++++----------- 6 files changed, 52 insertions(+), 71 deletions(-) diff --git a/packages/zui/src/transforms/common/errors.ts b/packages/zui/src/transforms/common/errors.ts index cd13b13f0dc..45ae0fa361e 100644 --- a/packages/zui/src/transforms/common/errors.ts +++ b/packages/zui/src/transforms/common/errors.ts @@ -1,5 +1,5 @@ import { JSONSchema7 } from 'json-schema' -import { ZodFirstPartyTypeKind } from '../../z' +import { ZodNativeSchemaType } from '../../z' type Transform = | 'json-schema-to-zui' @@ -38,7 +38,7 @@ export class ZuiToJSONSchemaError extends ZuiTransformError { } } export class UnsupportedZuiToJSONSchemaError extends ZuiToJSONSchemaError { - public constructor(type: ZodFirstPartyTypeKind, { suggestedAlternative }: { suggestedAlternative?: string } = {}) { + public constructor(type: ZodNativeSchemaType, { suggestedAlternative }: { suggestedAlternative?: string } = {}) { super( `Zod type ${type} cannot be transformed to JSON Schema.` + (suggestedAlternative ? ` Suggested alternative: ${suggestedAlternative}` : '') @@ -46,7 +46,7 @@ export class UnsupportedZuiToJSONSchemaError extends ZuiToJSONSchemaError { } } export class UnsupportedZuiCheckToJSONSchemaError extends ZuiToJSONSchemaError { - public constructor({ zodType, checkKind }: { zodType: ZodFirstPartyTypeKind; checkKind: string }) { + public constructor({ zodType, checkKind }: { zodType: ZodNativeSchemaType; checkKind: string }) { super(`Zod check .${checkKind}() of type ${zodType} cannot be transformed to JSON Schema.`) } } @@ -64,7 +64,7 @@ export class ZuiToTypescriptSchemaError extends ZuiTransformError { } } export class UnsupportedZuiToTypescriptSchemaError extends ZuiToTypescriptSchemaError { - public constructor(type: ZodFirstPartyTypeKind) { + public constructor(type: ZodNativeSchemaType) { super(`Zod type ${type} cannot be transformed to TypeScript schema.`) } } @@ -76,7 +76,7 @@ export class ZuiToTypescriptTypeError extends ZuiTransformError { } } export class UnsupportedZuiToTypescriptTypeError extends ZuiToTypescriptTypeError { - public constructor(type: ZodFirstPartyTypeKind) { + public constructor(type: ZodNativeSchemaType) { super(`Zod type ${type} cannot be transformed to TypeScript type.`) } } @@ -89,6 +89,6 @@ export class UntitledDeclarationError extends ZuiToTypescriptTypeError { export class UnrepresentableGenericError extends ZuiToTypescriptTypeError { public constructor() { - super(`${ZodFirstPartyTypeKind.ZodRef} can only be transformed to a TypeScript type with a "type" declaration.`) + super('ZodRef can only be transformed to a TypeScript type with a "type" declaration.') } } diff --git a/packages/zui/src/transforms/zui-from-json-schema/guards.ts b/packages/zui/src/transforms/zui-from-json-schema/guards.ts index 885bbb45e34..ede9241afbc 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/guards.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/guards.ts @@ -1,25 +1,23 @@ import { JSONSchema7 } from 'json-schema' -import z from '../../z' import * as json from '../common/json-schema' export const isOptionalSchema = (s: JSONSchema7): s is json.OptionalSchema => s.anyOf !== undefined && s.anyOf.length === 2 && s.anyOf.some((s) => typeof s !== 'boolean' && isUndefinedSchema(s)) && - (s as json.OptionalSchema)['x-zui']?.def?.typeName === z.ZodFirstPartyTypeKind.ZodOptional + (s as json.OptionalSchema)['x-zui']?.def?.typeName === 'ZodOptional' export const isNullableSchema = (s: JSONSchema7): s is json.NullableSchema => s.anyOf !== undefined && s.anyOf.length === 2 && s.anyOf.some((s) => typeof s !== 'boolean' && s.type === 'null') && - (s as json.NullableSchema)['x-zui']?.def?.typeName === z.ZodFirstPartyTypeKind.ZodNullable + (s as json.NullableSchema)['x-zui']?.def?.typeName === 'ZodNullable' export const isUndefinedSchema = (s: JSONSchema7): s is json.UndefinedSchema => - s.not === true && (s as json.UndefinedSchema)['x-zui']?.def?.typeName === z.ZodFirstPartyTypeKind.ZodUndefined + s.not === true && (s as json.UndefinedSchema)['x-zui']?.def?.typeName === 'ZodUndefined' export const isUnknownSchema = (s: JSONSchema7): s is json.UnknownSchema => - !s.not && (s as json.UnknownSchema)['x-zui']?.def?.typeName === z.ZodFirstPartyTypeKind.ZodUnknown + !s.not && (s as json.UnknownSchema)['x-zui']?.def?.typeName === 'ZodUnknown' export const isDiscriminatedUnionSchema = (s: JSONSchema7): s is json.DiscriminatedUnionSchema => - s.anyOf !== undefined && - (s as json.DiscriminatedUnionSchema)['x-zui']?.def?.typeName === z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion + s.anyOf !== undefined && (s as json.DiscriminatedUnionSchema)['x-zui']?.def?.typeName === 'ZodDiscriminatedUnion' diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts index b1cf8629ba5..c36e4fde572 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts @@ -12,7 +12,7 @@ const buildSchema = (s: JSONSchema7, xZui: ZuiJSONSchema['x-zui'] = undefined): } const undefinedSchema = (xZui?: ZuiJSONSchema['x-zui']): JSONSchema7 => - buildSchema({ not: true }, { ...xZui, def: { typeName: z.ZodFirstPartyTypeKind.ZodUndefined } }) + buildSchema({ not: true }, { ...xZui, def: { typeName: 'ZodUndefined' } }) const nullSchema = (xZui?: ZuiJSONSchema['x-zui']): JSONSchema7 => buildSchema({ type: 'null' }, xZui) diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.test.ts b/packages/zui/src/transforms/zui-to-json-schema/index.test.ts index 162bc6e387d..79112e4890b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.test.ts @@ -192,7 +192,7 @@ describe('zuiToJSONSchemaNext', () => { }, ], 'x-zui': { - def: { typeName: z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion, discriminator: 'type' }, + def: { typeName: 'ZodDiscriminatedUnion', discriminator: 'type' }, }, }) }) diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts index e4826c488da..99af891bbd4 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts @@ -84,7 +84,7 @@ export const zodStringToJsonString = (zodString: z.ZodString): json.StringSchema break default: throw new errors.UnsupportedZuiCheckToJSONSchemaError({ - zodType: z.ZodFirstPartyTypeKind.ZodString, + zodType: 'ZodString', checkKind: check.kind, }) } diff --git a/packages/zui/src/z/types/native.test.ts b/packages/zui/src/z/types/native.test.ts index c25389686b2..85fe4f4172a 100644 --- a/packages/zui/src/z/types/native.test.ts +++ b/packages/zui/src/z/types/native.test.ts @@ -1,140 +1,123 @@ import { test } from 'vitest' -import { ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind } from './native' import * as z from '../index' import { util } from './utils' test('first party switch', () => { - const myType = z.string() as z.ZodNativeSchema + const myType = z.ZodString.create() as z.ZodNativeSchema switch (myType.typeName) { - case z.ZodFirstPartyTypeKind.ZodString: + case 'ZodString': myType satisfies z.ZodString break - case z.ZodFirstPartyTypeKind.ZodNumber: + case 'ZodNumber': myType satisfies z.ZodNumber break - case z.ZodFirstPartyTypeKind.ZodNaN: + case 'ZodNaN': myType satisfies z.ZodNaN break - case z.ZodFirstPartyTypeKind.ZodBigInt: + case 'ZodBigInt': myType satisfies z.ZodBigInt break - case z.ZodFirstPartyTypeKind.ZodBoolean: + case 'ZodBoolean': myType satisfies z.ZodBoolean break - case z.ZodFirstPartyTypeKind.ZodDate: + case 'ZodDate': myType satisfies z.ZodDate break - case z.ZodFirstPartyTypeKind.ZodUndefined: + case 'ZodUndefined': myType satisfies z.ZodUndefined break - case z.ZodFirstPartyTypeKind.ZodNull: + case 'ZodNull': myType satisfies z.ZodNull break - case z.ZodFirstPartyTypeKind.ZodAny: + case 'ZodAny': myType satisfies z.ZodAny break - case z.ZodFirstPartyTypeKind.ZodUnknown: + case 'ZodUnknown': myType satisfies z.ZodUnknown break - case z.ZodFirstPartyTypeKind.ZodNever: + case 'ZodNever': myType satisfies z.ZodNever break - case z.ZodFirstPartyTypeKind.ZodVoid: + case 'ZodVoid': myType satisfies z.ZodVoid break - case z.ZodFirstPartyTypeKind.ZodArray: + case 'ZodArray': myType satisfies z.ZodArray break - case z.ZodFirstPartyTypeKind.ZodObject: + case 'ZodObject': myType satisfies z.ZodObject break - case z.ZodFirstPartyTypeKind.ZodUnion: + case 'ZodUnion': myType satisfies z.ZodUnion break - case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: + case 'ZodDiscriminatedUnion': myType satisfies z.ZodDiscriminatedUnion break - case z.ZodFirstPartyTypeKind.ZodIntersection: + case 'ZodIntersection': myType satisfies z.ZodIntersection break - case z.ZodFirstPartyTypeKind.ZodTuple: + case 'ZodTuple': myType satisfies z.ZodTuple break - case z.ZodFirstPartyTypeKind.ZodRecord: + case 'ZodRecord': myType satisfies z.ZodRecord break - case z.ZodFirstPartyTypeKind.ZodRef: + case 'ZodRef': myType satisfies z.ZodRef break - case z.ZodFirstPartyTypeKind.ZodMap: + case 'ZodMap': myType satisfies z.ZodMap break - case z.ZodFirstPartyTypeKind.ZodSet: + case 'ZodSet': myType satisfies z.ZodSet break - case z.ZodFirstPartyTypeKind.ZodFunction: + case 'ZodFunction': myType satisfies z.ZodFunction break - case z.ZodFirstPartyTypeKind.ZodLazy: + case 'ZodLazy': myType satisfies z.ZodLazy break - case z.ZodFirstPartyTypeKind.ZodLiteral: + case 'ZodLiteral': myType satisfies z.ZodLiteral break - case z.ZodFirstPartyTypeKind.ZodEnum: + case 'ZodEnum': myType satisfies z.ZodEnum break - case z.ZodFirstPartyTypeKind.ZodEffects: + case 'ZodEffects': myType satisfies z.ZodEffects break - case z.ZodFirstPartyTypeKind.ZodNativeEnum: + case 'ZodNativeEnum': myType satisfies z.ZodNativeEnum break - case z.ZodFirstPartyTypeKind.ZodOptional: + case 'ZodOptional': myType satisfies z.ZodOptional break - case z.ZodFirstPartyTypeKind.ZodNullable: + case 'ZodNullable': myType satisfies z.ZodNullable break - case z.ZodFirstPartyTypeKind.ZodDefault: + case 'ZodDefault': myType satisfies z.ZodDefault break - case z.ZodFirstPartyTypeKind.ZodCatch: + case 'ZodCatch': myType satisfies z.ZodCatch break - case z.ZodFirstPartyTypeKind.ZodPromise: + case 'ZodPromise': myType satisfies z.ZodPromise break - case z.ZodFirstPartyTypeKind.ZodBranded: + case 'ZodBranded': myType satisfies z.ZodBranded break - case z.ZodFirstPartyTypeKind.ZodPipeline: + case 'ZodPipeline': myType satisfies z.ZodPipeline break - case z.ZodFirstPartyTypeKind.ZodSymbol: + case 'ZodSymbol': myType satisfies z.ZodSymbol break - case z.ZodFirstPartyTypeKind.ZodReadonly: + case 'ZodReadonly': myType satisfies z.ZodReadonly break default: util.assertNever(myType) } }) - -test('Identify missing [ZodFirstPartySchemaTypes]', () => { - type ZodFirstPartySchemaForType = ZodFirstPartySchemaTypes extends infer Schema - ? Schema extends { _def: { typeName: T } } - ? Schema - : never - : never - type ZodMappedTypes = { - [key in ZodFirstPartyTypeKind]: ZodFirstPartySchemaForType - } - type ZodFirstPartySchemaTypesMissingFromUnion = keyof { - [key in keyof ZodMappedTypes as ZodMappedTypes[key] extends { _def: never } ? key : never]: unknown - } - - util.assertEqual(true) -}) From 61ed8d798020d9989eab96768368a8c8f055fb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 20:18:30 -0500 Subject: [PATCH 05/50] chore(zui): rm unused stuff (#14952) --- .gitignore | 1 + .../zui/src/z/__tests__/primitive.test.ts | 6 -- packages/zui/src/z/extensions.ts | 64 ------------------- packages/zui/src/z/types/utils/parseUtil.ts | 3 + packages/zui/src/z/z.ts | 10 --- packages/zui/src/zui.test.ts | 31 --------- 6 files changed, 4 insertions(+), 111 deletions(-) delete mode 100644 packages/zui/src/z/extensions.ts diff --git a/.gitignore b/.gitignore index af9df9e35f9..6ee4ea0f5a5 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tilt_config.json hubspot.config.yml AGENTS.md CLAUDE.md +.claude diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index 820fbf7e608..6b9d7282edd 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -430,9 +430,3 @@ test('primitive inference', () => { test('get literal value', () => { expect(literalStringSchema.value).toEqual('asdf') }) - -test('optional convenience method', () => { - z.ostring().parse(undefined) - z.onumber().parse(undefined) - z.oboolean().parse(undefined) -}) diff --git a/packages/zui/src/z/extensions.ts b/packages/zui/src/z/extensions.ts deleted file mode 100644 index f453b1d9a52..00000000000 --- a/packages/zui/src/z/extensions.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { TypeOf, ZodEnum, ZodString } from './types' - -const AI_MODELS = [ - 'gpt-3.5-turbo', - 'gpt-3.5-turbo-16k', - 'gpt-4', - 'gpt-4-1106-preview', - 'gpt-4-vision-preview', - 'gpt-4-0125-preview', - 'gpt-4-turbo-preview', - 'gpt-4-turbo', - 'gpt-4o', - 'gpt-3.5-turbo-0125', - 'gpt-3.5-turbo-1106', -] as const - -const variableType = ZodEnum.create([ - 'any', - 'string', - 'number', - 'boolean', - 'object', - 'pattern', - 'date', - 'array', - 'target', - 'time', - 'enum', -]) - -export const variable = (opts?: { type?: TypeOf; params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'variable', params: { type: opts?.type || 'any', ...opts?.params } }) - -export const conversation = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'conversation', params: { ...opts?.params } }) - -export const user = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'user', params: { ...opts?.params } }) - -export const message = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'message', params: { ...opts?.params } }) - -export const agent = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'agent', params: { ...opts?.params } }) - -export const event = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'event', params: { ...opts?.params } }) - -export const table = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'table', params: { ...opts?.params } }) - -export const tablerow = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'tablerow', params: { ...opts?.params } }) - -export const intent = (opts?: { params?: { horizontal?: boolean } }) => - ZodString.create().displayAs({ id: 'intent', params: { ...opts?.params } }) - -export const aimodel = () => ZodEnum.create(AI_MODELS).displayAs({ id: 'dropdown', params: {} }) - -export const datasource = (opts?: { horizontal?: boolean }) => - ZodString.create().displayAs({ id: 'datasource', params: { ...opts } }) - -export const knowledgebase = (opts?: { horizontal?: boolean }) => - ZodString.create().displayAs({ id: 'knowledgebase', params: { ...opts } }) diff --git a/packages/zui/src/z/types/utils/parseUtil.ts b/packages/zui/src/z/types/utils/parseUtil.ts index 155fe051983..8619b0d622d 100644 --- a/packages/zui/src/z/types/utils/parseUtil.ts +++ b/packages/zui/src/z/types/utils/parseUtil.ts @@ -146,6 +146,9 @@ export const INVALID: INVALID = Object.freeze({ status: 'aborted', }) +export type NEVER = never +export const NEVER = INVALID as never + export type DIRTY = { status: 'dirty'; value: T } export const DIRTY = (value: T): DIRTY => ({ status: 'dirty', value }) diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index f28a3714003..73549eaba86 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -1,7 +1,6 @@ import { custom, CustomParams, - INVALID, ZodAny, ZodArray, ZodBigInt, @@ -95,9 +94,6 @@ const nullableType = ZodNullable.create const defaultType = ZodDefault.create const preprocessType = ZodEffects.createWithPreprocess const pipelineType = ZodPipeline.create -const ostring = () => stringType().optional() -const onumber = () => numberType().optional() -const oboolean = () => booleanType().optional() export const coerce = { string: ((arg) => ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)['create'], @@ -134,10 +130,7 @@ export { nullableType as nullable, numberType as number, objectType as object, - oboolean, - onumber, optionalType as optional, - ostring, pipelineType as pipeline, preprocessType as preprocess, promiseType as promise, @@ -156,14 +149,11 @@ export { voidType as void, } -export const NEVER = INVALID as never - export * from './types' export * from './types/error' export * from './types/utils' export * from './types/utils/parseUtil' export * from './types/utils/typeAliases' -export * from './extensions' /** * @deprecated - use ZodType instead diff --git a/packages/zui/src/zui.test.ts b/packages/zui/src/zui.test.ts index f5c7fc814ac..403c3d53d67 100644 --- a/packages/zui/src/zui.test.ts +++ b/packages/zui/src/zui.test.ts @@ -170,34 +170,3 @@ test('array', () => { }, ] satisfies zui.infer) }) - -describe('custom types', () => { - const schema = zui.object({ - agent: zui.agent(), - conversation: zui.conversation(), - user: zui.user(), - message: zui.message(), - event: zui.event(), - table: zui.table(), - tablerow: zui.tablerow(), - intent: zui.intent(), - aimodel: zui.aimodel().default('gpt-3.5-turbo'), - datasource: zui.datasource(), - }) - - it('should parse', () => { - const parse = schema.safeParse({ - agent: 'hello', - conversation: 'hello', - user: 'hello', - message: 'hello', - event: 'hello', - table: 'hello', - tablerow: 'hello', - intent: 'hello', - aimodel: 'gpt-3.5-turbo', - datasource: 'hello', - }) - expect(parse.success).toBe(true) - }) -}) From 14667f86c25cba2c728abb7016509407e9092579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 16 Feb 2026 20:46:46 -0500 Subject: [PATCH 06/50] chore(zui): move builder functions in dedicated file (#14953) --- packages/zui/src/z/builders.ts | 178 ++++++++++++++++++ packages/zui/src/z/index.ts | 1 - .../zui/src/z/types/custom/custom.test.ts | 16 -- packages/zui/src/z/types/custom/index.ts | 32 ---- packages/zui/src/z/types/index.ts | 1 - packages/zui/src/z/z.ts | 150 +-------------- 6 files changed, 181 insertions(+), 197 deletions(-) create mode 100644 packages/zui/src/z/builders.ts delete mode 100644 packages/zui/src/z/types/custom/custom.test.ts delete mode 100644 packages/zui/src/z/types/custom/index.ts diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts new file mode 100644 index 00000000000..c0541533073 --- /dev/null +++ b/packages/zui/src/z/builders.ts @@ -0,0 +1,178 @@ +import { + CustomErrorParams, + ZodAny, + ZodArray, + ZodBigInt, + ZodBoolean, + ZodDate, + ZodDefault, + ZodDiscriminatedUnion, + ZodEffects, + ZodEnum, + ZodFunction, + ZodIntersection, + ZodLazy, + ZodLiteral, + ZodMap, + ZodNaN, + ZodNativeEnum, + ZodNever, + ZodNull, + ZodNullable, + ZodNumber, + ZodObject, + ZodOptional, + ZodPipeline, + ZodPromise, + ZodReadonly, + ZodRecord, + ZodRef, + ZodSet, + ZodString, + ZodSymbol, + ZodTuple, + ZodType, + ZodUndefined, + ZodUnion, + ZodUnknown, + ZodVoid, +} from './types' + +type CustomParams = CustomErrorParams & { fatal?: boolean } +const customType = ( + check?: (data: unknown) => any, + params: string | CustomParams | ((input: any) => CustomParams) = {}, + /** + * @deprecated + * + * Pass `fatal` into the params object instead: + * + * ```ts + * z.string().custom((val) => val.length > 5, { fatal: false }) + * ``` + * + */ + fatal?: boolean +): ZodType => { + if (check) { + return ZodAny.create().superRefine((data, ctx) => { + if (!check(data)) { + const p = + typeof params === 'function' ? params(data) : typeof params === 'string' ? { message: params } : params + const _fatal = p.fatal ?? fatal ?? true + const p2 = typeof p === 'string' ? { message: p } : p + ctx.addIssue({ code: 'custom', ...p2, fatal: _fatal }) + } + }) + } + return ZodAny.create() +} + +abstract class Cls { + constructor(..._: any[]) {} +} + +const instanceOfType = ( + // const instanceOfType = any>( + cls: T, + params: CustomParams = { + message: `Input not instance of ${cls.name}`, + } +) => customType>((data) => data instanceof cls, params) + +const stringType = ZodString.create +const numberType = ZodNumber.create +const nanType = ZodNaN.create +const bigIntType = ZodBigInt.create +const booleanType = ZodBoolean.create +const dateType = ZodDate.create +const symbolType = ZodSymbol.create +const undefinedType = ZodUndefined.create +const nullType = ZodNull.create +const anyType = ZodAny.create +const unknownType = ZodUnknown.create +const neverType = ZodNever.create +const voidType = ZodVoid.create +const arrayType = ZodArray.create +const objectType = ZodObject.create +const strictObjectType = ZodObject.strictCreate +const unionType = ZodUnion.create +const discriminatedUnionType = ZodDiscriminatedUnion.create +const intersectionType = ZodIntersection.create +const tupleType = ZodTuple.create +const recordType = ZodRecord.create +const refType = ZodRef.create +const readonlyType = ZodReadonly.create +const mapType = ZodMap.create +const setType = ZodSet.create +const functionType = ZodFunction.create +const lazyType = ZodLazy.create +const literalType = ZodLiteral.create +const enumType = ZodEnum.create +const nativeEnumType = ZodNativeEnum.create +const promiseType = ZodPromise.create +const effectsType = ZodEffects.create +const optionalType = ZodOptional.create +const nullableType = ZodNullable.create +const defaultType = ZodDefault.create +const preprocessType = ZodEffects.createWithPreprocess +const pipelineType = ZodPipeline.create + +export const late = { + object: ZodObject.lazycreate, +} + +export const coerce = { + string: ((arg) => ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)['create'], + number: ((arg) => ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)['create'], + boolean: ((arg) => + ZodBoolean.create({ + ...arg, + coerce: true, + })) as (typeof ZodBoolean)['create'], + bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)['create'], + date: ((arg) => ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)['create'], +} + +export { + anyType as any, + arrayType as array, + bigIntType as bigint, + booleanType as boolean, + customType as custom, + dateType as date, + defaultType as default, + discriminatedUnionType as discriminatedUnion, + effectsType as effects, + enumType as enum, + functionType as function, + instanceOfType as instanceof, + intersectionType as intersection, + lazyType as lazy, + literalType as literal, + mapType as map, + nanType as nan, + nativeEnumType as nativeEnum, + neverType as never, + nullType as null, + nullableType as nullable, + numberType as number, + objectType as object, + optionalType as optional, + pipelineType as pipeline, + preprocessType as preprocess, + promiseType as promise, + recordType as record, + refType as ref, + readonlyType as readonly, + setType as set, + strictObjectType as strictObject, + stringType as string, + symbolType as symbol, + effectsType as transformer, + tupleType as tuple, + undefinedType as undefined, + unionType as union, + unknownType as unknown, + voidType as void, +} diff --git a/packages/zui/src/z/index.ts b/packages/zui/src/z/index.ts index 9ccc376992f..f38dd7595e9 100644 --- a/packages/zui/src/z/index.ts +++ b/packages/zui/src/z/index.ts @@ -1,5 +1,4 @@ import * as z from './z' export * from './z' export { z } - export default z diff --git a/packages/zui/src/z/types/custom/custom.test.ts b/packages/zui/src/z/types/custom/custom.test.ts deleted file mode 100644 index 1180624f866..00000000000 --- a/packages/zui/src/z/types/custom/custom.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { test, expect } from 'vitest' -import * as z from '../../index' - -test('passing validations', () => { - const example1 = z.custom((x) => typeof x === 'number') - example1.parse(1234) - expect(() => example1.parse({})).toThrow() -}) - -test('string params', () => { - const example1 = z.custom((x) => typeof x !== 'number', 'customerr') - const result = example1.safeParse(1234) - expect(result.success).toEqual(false) - // @ts-ignore - expect(JSON.stringify(result.error).includes('customerr')).toEqual(true) -}) diff --git a/packages/zui/src/z/types/custom/index.ts b/packages/zui/src/z/types/custom/index.ts deleted file mode 100644 index baab35ab6bd..00000000000 --- a/packages/zui/src/z/types/custom/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ZodAny, CustomErrorParams, ZodType } from '../index' - -export type CustomParams = CustomErrorParams & { fatal?: boolean } - -export const custom = ( - check?: (data: unknown) => any, - params: string | CustomParams | ((input: any) => CustomParams) = {}, - /** - * @deprecated - * - * Pass `fatal` into the params object instead: - * - * ```ts - * z.string().custom((val) => val.length > 5, { fatal: false }) - * ``` - * - */ - fatal?: boolean -): ZodType => { - if (check) { - return ZodAny.create().superRefine((data, ctx) => { - if (!check(data)) { - const p = - typeof params === 'function' ? params(data) : typeof params === 'string' ? { message: params } : params - const _fatal = p.fatal ?? fatal ?? true - const p2 = typeof p === 'string' ? { message: p } : p - ctx.addIssue({ code: 'custom', ...p2, fatal: _fatal }) - } - }) - } - return ZodAny.create() -} diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index 288033bc624..841ee12591a 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -18,7 +18,6 @@ export * from './bigint' export * from './boolean' export * from './branded' export * from './catch' -export * from './custom' export * from './date' export * from './default' export * from './discriminatedUnion' diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 73549eaba86..4921fa9ae77 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -1,153 +1,9 @@ -import { - custom, - CustomParams, - ZodAny, - ZodArray, - ZodBigInt, - ZodBoolean, - ZodDate, - ZodDefault, - ZodDiscriminatedUnion, - ZodEffects, - ZodEnum, - ZodFunction, - ZodIntersection, - ZodLazy, - ZodLiteral, - ZodMap, - ZodNaN, - ZodNativeEnum, - ZodNever, - ZodNull, - ZodNullable, - ZodNumber, - ZodObject, - ZodOptional, - ZodPipeline, - ZodPromise, - ZodReadonly, - ZodRecord, - ZodRef, - ZodSet, - ZodString, - ZodSymbol, - ZodTuple, - ZodType, - ZodUndefined, - ZodUnion, - ZodUnknown, - ZodVoid, -} from './types' +import { ZodType } from './types' export { ZodType as Schema, ZodType as ZodSchema } -export const late = { - object: ZodObject.lazycreate, -} - -// requires TS 4.4+ -abstract class Class { - constructor(..._: any[]) {} -} -const instanceOfType = ( - // const instanceOfType = any>( - cls: T, - params: CustomParams = { - message: `Input not instance of ${cls.name}`, - } -) => custom>((data) => data instanceof cls, params) - -const stringType = ZodString.create -const numberType = ZodNumber.create -const nanType = ZodNaN.create -const bigIntType = ZodBigInt.create -const booleanType = ZodBoolean.create -const dateType = ZodDate.create -const symbolType = ZodSymbol.create -const undefinedType = ZodUndefined.create -const nullType = ZodNull.create -const anyType = ZodAny.create -const unknownType = ZodUnknown.create -const neverType = ZodNever.create -const voidType = ZodVoid.create -const arrayType = ZodArray.create -const objectType = ZodObject.create -const strictObjectType = ZodObject.strictCreate -const unionType = ZodUnion.create -const discriminatedUnionType = ZodDiscriminatedUnion.create -const intersectionType = ZodIntersection.create -const tupleType = ZodTuple.create -const recordType = ZodRecord.create -const refType = ZodRef.create -const readonlyType = ZodReadonly.create -const mapType = ZodMap.create -const setType = ZodSet.create -const functionType = ZodFunction.create -const lazyType = ZodLazy.create -const literalType = ZodLiteral.create -const enumType = ZodEnum.create -const nativeEnumType = ZodNativeEnum.create -const promiseType = ZodPromise.create -const effectsType = ZodEffects.create -const optionalType = ZodOptional.create -const nullableType = ZodNullable.create -const defaultType = ZodDefault.create -const preprocessType = ZodEffects.createWithPreprocess -const pipelineType = ZodPipeline.create - -export const coerce = { - string: ((arg) => ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)['create'], - number: ((arg) => ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)['create'], - boolean: ((arg) => - ZodBoolean.create({ - ...arg, - coerce: true, - })) as (typeof ZodBoolean)['create'], - bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)['create'], - date: ((arg) => ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)['create'], -} - -export { - anyType as any, - arrayType as array, - bigIntType as bigint, - booleanType as boolean, - dateType as date, - defaultType as default, - discriminatedUnionType as discriminatedUnion, - effectsType as effect, - enumType as enum, - functionType as function, - instanceOfType as instanceof, - intersectionType as intersection, - lazyType as lazy, - literalType as literal, - mapType as map, - nanType as nan, - nativeEnumType as nativeEnum, - neverType as never, - nullType as null, - nullableType as nullable, - numberType as number, - objectType as object, - optionalType as optional, - pipelineType as pipeline, - preprocessType as preprocess, - promiseType as promise, - recordType as record, - refType as ref, - readonlyType as readonly, - setType as set, - strictObjectType as strictObject, - stringType as string, - symbolType as symbol, - effectsType as transformer, - tupleType as tuple, - undefinedType as undefined, - unionType as union, - unknownType as unknown, - voidType as void, -} +export * from './builders' +export { default } from './builders' // Re-export 'default' explicitly since export * doesn't handle it export * from './types' export * from './types/error' From 19b005b3809219326d9df52e57f73cdc9aa665bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Tue, 17 Feb 2026 18:43:45 -0500 Subject: [PATCH 07/50] chore(zui): extract zod error logic out of types (#14955) --- packages/zui/src/z/__tests__/refine.test.ts | 2 +- packages/zui/src/z/builders.ts | 1 - .../zui/src/z/{types => }/error/error.test.ts | 32 +--- packages/zui/src/z/{types => }/error/index.ts | 35 +--- .../zui/src/z/{types => }/error/locales/en.ts | 0 packages/zui/src/z/types/array/index.ts | 2 +- packages/zui/src/z/types/basetype/index.ts | 6 +- packages/zui/src/z/types/bigint/index.ts | 2 +- packages/zui/src/z/types/boolean/index.ts | 2 +- packages/zui/src/z/types/catch/index.ts | 2 +- packages/zui/src/z/types/date/index.ts | 2 +- .../src/z/types/discriminatedUnion/index.ts | 2 +- packages/zui/src/z/types/enum/index.ts | 2 +- .../zui/src/z/types/error/all-errors.test.ts | 155 ------------------ packages/zui/src/z/types/function/index.ts | 7 +- packages/zui/src/z/types/index.ts | 4 - .../zui/src/z/types/intersection/index.ts | 2 +- packages/zui/src/z/types/literal/index.ts | 2 +- packages/zui/src/z/types/map/index.ts | 2 +- packages/zui/src/z/types/nan/index.ts | 2 +- packages/zui/src/z/types/nativeEnum/index.ts | 2 +- packages/zui/src/z/types/never/index.ts | 2 +- packages/zui/src/z/types/null/index.ts | 2 +- .../zui/src/z/types/nullable/nullable.test.ts | 4 +- packages/zui/src/z/types/number/index.ts | 2 +- packages/zui/src/z/types/object/index.ts | 2 +- .../zui/src/z/types/optional/optional.test.ts | 4 +- packages/zui/src/z/types/promise/index.ts | 2 +- packages/zui/src/z/types/record/index.ts | 2 +- packages/zui/src/z/types/ref/index.ts | 3 +- packages/zui/src/z/types/set/index.ts | 2 +- packages/zui/src/z/types/string/index.ts | 3 +- packages/zui/src/z/types/symbol/index.ts | 2 +- packages/zui/src/z/types/transformer/index.ts | 2 +- packages/zui/src/z/types/tuple/index.ts | 2 +- packages/zui/src/z/types/tuple/tuple.test.ts | 2 +- packages/zui/src/z/types/undefined/index.ts | 2 +- packages/zui/src/z/types/union/index.ts | 4 +- packages/zui/src/z/types/utils/index.ts | 2 +- packages/zui/src/z/types/utils/parseUtil.ts | 2 +- packages/zui/src/z/types/void/index.ts | 2 +- packages/zui/src/z/z.ts | 2 +- 42 files changed, 46 insertions(+), 270 deletions(-) rename packages/zui/src/z/{types => }/error/error.test.ts (92%) rename packages/zui/src/z/{types => }/error/index.ts (87%) rename packages/zui/src/z/{types => }/error/locales/en.ts (100%) delete mode 100644 packages/zui/src/z/types/error/all-errors.test.ts diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index aa465c74f99..84d39d04c3b 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import { util } from '../types/utils' import z from '../index' -import { ZodIssueCode } from '../types/error' +import { ZodIssueCode } from '../error' test('refinement', () => { const obj1 = z.object({ diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index c0541533073..26bc03a3024 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -73,7 +73,6 @@ abstract class Cls { } const instanceOfType = ( - // const instanceOfType = any>( cls: T, params: CustomParams = { message: `Input not instance of ${cls.name}`, diff --git a/packages/zui/src/z/types/error/error.test.ts b/packages/zui/src/z/error/error.test.ts similarity index 92% rename from packages/zui/src/z/types/error/error.test.ts rename to packages/zui/src/z/error/error.test.ts index 455f59f01fe..f60b19a88ae 100644 --- a/packages/zui/src/z/types/error/error.test.ts +++ b/packages/zui/src/z/error/error.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' -import * as z from '../../index' -import { ZodParsedType } from '../../index' +import * as z from '../index' +import { ZodParsedType } from '../index' import { ZodError, ZodIssueCode } from '.' test('error creation', () => { @@ -130,25 +130,6 @@ test('array minimum', () => { } }) -// implement test for semi-smart union logic that checks for type error on either left or right -// test("union smart errors", () => { -// // expect.assertions(2); - -// const p1 = z -// .union([z.string(), z.number().refine((x) => x > 0)]) -// .safeParse(-3.2); - -// if (p1.success === true) throw new Error(); -// expect(p1.success).toBe(false); -// expect(p1.error.issues[0]?.code).toEqual(ZodIssueCode.custom); - -// const p2 = z.union([z.string(), z.number()]).safeParse(false); -// // .catch(err => expect(err.issues[0].code).toEqual(ZodIssueCode.invalid_union)); -// if (p2.success === true) throw new Error(); -// expect(p2.success).toBe(false); -// expect(p2.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_union); -// }); - test('custom path in custom error map', () => { const schema = z.object({ items: z.array(z.string()).refine((data) => data.length > 3, { @@ -291,8 +272,7 @@ test('formatting', () => { expect(error.inner?.name?.[1]).toEqual(undefined) } if (!result2.success) { - type FormattedError = z.inferFormattedError - const error: FormattedError = result2.error.format() + const error = result2.error.format() expect(error._errors).toEqual([]) expect(error.inner?._errors).toEqual([]) expect(error.inner?.name?._errors).toEqual(['Invalid input']) @@ -303,8 +283,7 @@ test('formatting', () => { // test custom mapper if (!result2.success) { - type FormattedError = z.inferFormattedError - const error: FormattedError = result2.error.format(() => 5) + const error = result2.error.format(() => 5) expect(error._errors).toEqual([]) expect(error.inner?._errors).toEqual([]) expect(error.inner?.name?._errors).toEqual([5]) @@ -332,8 +311,7 @@ test('formatting with nullable and optional fields', () => { const result = schema.safeParse(invalidItem) expect(result.success).toEqual(false) if (!result.success) { - type FormattedError = z.inferFormattedError - const error: FormattedError = result.error.format() + const error = result.error.format() expect(error._errors).toEqual([]) expect(error.nullableObject?._errors).toEqual([]) expect(error.nullableObject?.name?._errors).toEqual(['Invalid input']) diff --git a/packages/zui/src/z/types/error/index.ts b/packages/zui/src/z/error/index.ts similarity index 87% rename from packages/zui/src/z/types/error/index.ts rename to packages/zui/src/z/error/index.ts index 1fe8384a243..79be55b987e 100644 --- a/packages/zui/src/z/types/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -1,16 +1,7 @@ -import { TypeOf, ZodType, ZodParsedType, util, Primitive } from '../index' +import { util, ZodParsedType } from '../types/utils' +import { Primitive } from '../types/utils/typeAliases' import { errorMap as defaultErrorMap } from './locales/en' -type allKeys = T extends any ? keyof T : never - -export type inferFlattenedErrors, U = string> = typeToFlattenedError, U> -export type typeToFlattenedError = { - formErrors: U[] - fieldErrors: { - [P in allKeys]?: U[] - } -} - export const ZodIssueCode = util.arrayToEnum([ 'invalid_type', 'invalid_literal', @@ -186,8 +177,6 @@ export type ZodFormattedError = { _errors: U[] } & recursiveZodFormattedError> -export type inferFormattedError, U = string> = ZodFormattedError, U> - export class ZodError extends Error { issues: ZodIssue[] = [] @@ -288,26 +277,6 @@ export class ZodError extends Error { addIssues = (subs: ZodIssue[] = []) => { this.issues = [...this.issues, ...subs] } - - flatten(): typeToFlattenedError - flatten(mapper?: (issue: ZodIssue) => U): typeToFlattenedError - flatten(mapper: (issue: ZodIssue) => U = (issue: ZodIssue) => issue.message as U): any { - const fieldErrors: any = {} - const formErrors: U[] = [] - for (const sub of this.issues) { - if (sub.path.length > 0) { - fieldErrors[sub.path[0]!] = fieldErrors[sub.path[0]!] || [] - fieldErrors[sub.path[0]!].push(mapper(sub)) - } else { - formErrors.push(mapper(sub)) - } - } - return { formErrors, fieldErrors } - } - - get formErrors() { - return this.flatten() - } } type stripPath = T extends any ? util.OmitKeys : never diff --git a/packages/zui/src/z/types/error/locales/en.ts b/packages/zui/src/z/error/locales/en.ts similarity index 100% rename from packages/zui/src/z/types/error/locales/en.ts rename to packages/zui/src/z/error/locales/en.ts diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index 701abbf29e4..437be614780 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, ParseInputLazyPath, RawCreateParams, ZodType, diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 32468b8204d..8d8c33a09a4 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -11,12 +11,12 @@ import type { ZuiExtensionObject, ZuiMetadata, } from '../../../ui/types' +import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap, ZodIssueCode } from '../../error' import { CatchFn } from '../catch' import { AsyncParseReturnType, getParsedType, isAsync, - IssueData, isValid, ParseContext, ParseInput, @@ -31,13 +31,9 @@ import { ZodArray, ZodBranded, ZodCatch, - ZodCustomIssue, ZodDefault, ZodEffects, - ZodError, - ZodErrorMap, ZodIntersection, - ZodIssueCode, ZodNullable, ZodOptional, ZodPipeline, diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 187215e4331..8d8ebf3fe9c 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -1,3 +1,4 @@ +import { ZodIssueCode } from '../../error' import { addIssueToContext, INVALID, @@ -5,7 +6,6 @@ import { ParseInput, ParseReturnType, ParseStatus, - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index bb644eeff1b..6f3d93d7fd0 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index f9d1356b52a..696ec3c5c5e 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -1,5 +1,5 @@ +import { ZodError } from '../../error' import { - ZodError, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index 3e28979d0db..e6fccb836f6 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, processCreateParams, util, ZodParsedType, diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index 255a357dd2d..bb0937d530c 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,10 +1,10 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { ZodBranded, ZodCatch, ZodDefault, ZodEnum, - ZodIssueCode, input, output, RawCreateParams, diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index 5dfd69a96e7..79954ec1785 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/error/all-errors.test.ts b/packages/zui/src/z/types/error/all-errors.test.ts deleted file mode 100644 index 3ad12b1afe7..00000000000 --- a/packages/zui/src/z/types/error/all-errors.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { test, expect } from 'vitest' -import * as z from '../../index' -import { util } from '../utils' - -const Test = z.object({ - f1: z.number(), - f2: z.string().optional(), - f3: z.string().nullable(), - f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })), -}) -type TestFlattenedErrors = z.inferFlattenedErrors -type TestFormErrors = z.inferFlattenedErrors - -test('default flattened errors type inference', () => { - type TestTypeErrors = { - formErrors: string[] - fieldErrors: { [P in keyof z.TypeOf]?: string[] | undefined } - } - - util.assertEqual, TestTypeErrors>(true) - util.assertEqual, TestTypeErrors>(false) -}) - -test('custom flattened errors type inference', () => { - type ErrorType = { message: string; code: number } - type TestTypeErrors = { - formErrors: ErrorType[] - fieldErrors: { - [P in keyof z.TypeOf]?: ErrorType[] | undefined - } - } - - util.assertEqual, TestTypeErrors>(false) - util.assertEqual, TestTypeErrors>(true) - util.assertEqual, TestTypeErrors>(false) -}) - -test('form errors type inference', () => { - type TestTypeErrors = { - formErrors: string[] - fieldErrors: { [P in keyof z.TypeOf]?: string[] | undefined } - } - - util.assertEqual, TestTypeErrors>(true) -}) - -test('.flatten() type assertion', () => { - const parsed = Test.safeParse({}) as z.SafeParseError - const validFlattenedErrors: TestFlattenedErrors = parsed.error.flatten(() => ({ message: '', code: 0 })) - // @ts-expect-error should fail assertion between `TestFlattenedErrors` and unmapped `flatten()`. - const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.flatten() - const validFormErrors: TestFormErrors = parsed.error.flatten() - // @ts-expect-error should fail assertion between `TestFormErrors` and mapped `flatten()`. - const invalidFormErrors: TestFormErrors = parsed.error.flatten(() => ({ - message: 'string', - code: 0, - })) - - ;[validFlattenedErrors, invalidFlattenedErrors, validFormErrors, invalidFormErrors] -}) - -test('.formErrors type assertion', () => { - const parsed = Test.safeParse({}) as z.SafeParseError - const validFormErrors: TestFormErrors = parsed.error.formErrors - // @ts-expect-error should fail assertion between `TestFlattenedErrors` and `.formErrors`. - const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.formErrors - - ;[validFormErrors, invalidFlattenedErrors] -}) - -test('all errors', () => { - const propertySchema = z.string() - const schema = z - .object({ - a: propertySchema, - b: propertySchema, - }) - .refine( - (val) => { - return val.a === val.b - }, - { message: 'Must be equal' } - ) - - try { - schema.parse({ - a: 'asdf', - b: 'qwer', - }) - } catch (error) { - if (error instanceof z.ZodError) { - expect(error.flatten()).toEqual({ - formErrors: ['Must be equal'], - fieldErrors: {}, - }) - } - } - - try { - schema.parse({ - a: null, - b: null, - }) - } catch (_error) { - const error = _error as z.ZodError - expect(error.flatten()).toEqual({ - formErrors: [], - fieldErrors: { - a: ['Expected string, received null'], - b: ['Expected string, received null'], - }, - }) - - expect(error.flatten((iss) => iss.message.toUpperCase())).toEqual({ - formErrors: [], - fieldErrors: { - a: ['EXPECTED STRING, RECEIVED NULL'], - b: ['EXPECTED STRING, RECEIVED NULL'], - }, - }) - // Test identity - - expect(error.flatten((i: z.ZodIssue) => i)).toEqual({ - formErrors: [], - fieldErrors: { - a: [ - { - code: 'invalid_type', - expected: 'string', - message: 'Expected string, received null', - path: ['a'], - received: 'null', - }, - ], - b: [ - { - code: 'invalid_type', - expected: 'string', - message: 'Expected string, received null', - path: ['b'], - received: 'null', - }, - ], - }, - }) - // Test mapping - expect(error.flatten((i: z.ZodIssue) => i.message.length)).toEqual({ - formErrors: [], - fieldErrors: { - a: ['Expected string, received null'.length], - b: ['Expected string, received null'.length], - }, - }) - } -}) diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 8d5098cea41..dabd560b807 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,11 +1,6 @@ +import { defaultErrorMap, getErrorMap, ZodError, ZodErrorMap, ZodIssue, ZodIssueCode } from '../../error' import { unique } from '../../utils' import { - defaultErrorMap, - getErrorMap, - ZodError, - ZodErrorMap, - ZodIssue, - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index 841ee12591a..c8479559a2a 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -22,7 +22,6 @@ export * from './date' export * from './default' export * from './discriminatedUnion' export * from './enum' -export * from './error' export * from './function' export * from './index' export * from './intersection' @@ -51,6 +50,3 @@ export * from './undefined' export * from './union' export * from './unknown' export * from './void' - -import defaultErrorMap from './error/locales/en' -export { defaultErrorMap } diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index e842057c773..a7d552805f0 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -1,6 +1,6 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index da8df95a4a7..378c0556595 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,7 +1,7 @@ import { isEqual } from 'lodash-es' +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index c6f31ac5c13..dc7709130ed 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -1,6 +1,6 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { - ZodIssueCode, ParseInputLazyPath, RawCreateParams, ZodType, diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index 30b4adaec6c..912fd375fa6 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index 3b3942c5d9e..d77a9214e63 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,7 +1,7 @@ import { isEqual } from 'lodash-es' +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/never/index.ts b/packages/zui/src/z/types/never/index.ts index 3d150cb51c8..2ec7ab89a0c 100644 --- a/packages/zui/src/z/types/never/index.ts +++ b/packages/zui/src/z/types/never/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index ae2e7b53feb..0446d9d9cca 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/nullable/nullable.test.ts b/packages/zui/src/z/types/nullable/nullable.test.ts index bf0f7fbc57f..d81de983055 100644 --- a/packages/zui/src/z/types/nullable/nullable.test.ts +++ b/packages/zui/src/z/types/nullable/nullable.test.ts @@ -6,12 +6,12 @@ function checkErrors(a: z.ZodType, bad: any) { try { a.parse(bad) } catch (error) { - expected = (error as z.ZodError).formErrors + expected = error as z.ZodError } try { a.nullable().parse(bad) } catch (error) { - expect((error as z.ZodError).formErrors).toEqual(expected) + expect(error as z.ZodError).toEqual(expected) } } diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index c4c505bc137..604235c0637 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index c2b9cd764aa..90041558a52 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,3 +1,4 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { ZodArray, @@ -12,7 +13,6 @@ import { ParseReturnType, ParseStatus, util, - ZodIssueCode, ZodParsedType, ParseInputLazyPath, RawCreateParams, diff --git a/packages/zui/src/z/types/optional/optional.test.ts b/packages/zui/src/z/types/optional/optional.test.ts index b44c40eef86..d81ec727711 100644 --- a/packages/zui/src/z/types/optional/optional.test.ts +++ b/packages/zui/src/z/types/optional/optional.test.ts @@ -6,12 +6,12 @@ function checkErrors(a: z.ZodType, bad: any) { try { a.parse(bad) } catch (error) { - expected = (error as z.ZodError).formErrors + expected = error as z.ZodError } try { a.optional().parse(bad) } catch (error) { - expect((error as z.ZodError).formErrors).toEqual(expected) + expect(error as z.ZodError).toEqual(expected) } } diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index 741e42e19cc..c74072a21c7 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 69f36e6e4d6..2157a790896 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,7 +1,7 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { BRAND, - ZodIssueCode, ParseInputLazyPath, RawCreateParams, ZodType, diff --git a/packages/zui/src/z/types/ref/index.ts b/packages/zui/src/z/types/ref/index.ts index 8dd31f2ece7..9e4c0fcd7b4 100644 --- a/packages/zui/src/z/types/ref/index.ts +++ b/packages/zui/src/z/types/ref/index.ts @@ -1,4 +1,5 @@ -import { ZodType, ZodTypeDef, INVALID, ParseInput, ParseReturnType, addIssueToContext, ZodIssueCode } from '../index' +import { ZodIssueCode } from '../../error' +import { ZodType, ZodTypeDef, INVALID, ParseInput, ParseReturnType, addIssueToContext } from '../index' export type ZodRefDef = { typeName: 'ZodRef' diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 1618b8c4392..b0a3422e8ae 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, ParseInputLazyPath, RawCreateParams, ZodType, diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 5887234f7ff..c7548ae494a 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,7 +1,6 @@ import { zuiKey } from '../../../ui/constants' +import { StringValidation, ZodIssueCode } from '../../error' import { - StringValidation, - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index 07f0c83ff3d..cf021645c61 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index a086e7d9cad..73598b9aa60 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -1,5 +1,5 @@ +import { IssueData } from '../../error' import { - IssueData, input, output, RawCreateParams, diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index eb112961378..06a02aa8327 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -1,6 +1,6 @@ +import { ZodIssueCode } from '../../error' import { unique } from '../../utils' import { - ZodIssueCode, ParseInputLazyPath, RawCreateParams, ZodType, diff --git a/packages/zui/src/z/types/tuple/tuple.test.ts b/packages/zui/src/z/types/tuple/tuple.test.ts index 111b4955a3b..61beba1584c 100644 --- a/packages/zui/src/z/types/tuple/tuple.test.ts +++ b/packages/zui/src/z/types/tuple/tuple.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import { util } from '../utils' import * as z from '../../index' -import { ZodError } from '../error' +import { ZodError } from '../../error' const testTuple = z.tuple([z.string(), z.object({ name: z.literal('Rudy') }), z.array(z.literal('blue'))]) const testData = ['asdf', { name: 'Rudy' }, ['blue']] diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index cdb3a3fb7c8..f3a1c437c37 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index 78451c1a1ed..af9e847812d 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,11 +1,9 @@ +import { ZodError, ZodIssue, ZodIssueCode } from '../../error' import { unique } from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, - ZodError, - ZodIssue, - ZodIssueCode, processCreateParams, addIssueToContext, DIRTY, diff --git a/packages/zui/src/z/types/utils/index.ts b/packages/zui/src/z/types/utils/index.ts index 67756f61930..1186d943634 100644 --- a/packages/zui/src/z/types/utils/index.ts +++ b/packages/zui/src/z/types/utils/index.ts @@ -1,5 +1,5 @@ import { zuiKey } from '../../../ui/constants' -import type { ZodErrorMap } from '../error' +import type { ZodErrorMap } from '../../error' import type { ProcessedCreateParams, RawCreateParams } from '../index' export namespace util { diff --git a/packages/zui/src/z/types/utils/parseUtil.ts b/packages/zui/src/z/types/utils/parseUtil.ts index 8619b0d622d..b97466607a4 100644 --- a/packages/zui/src/z/types/utils/parseUtil.ts +++ b/packages/zui/src/z/types/utils/parseUtil.ts @@ -1,4 +1,4 @@ -import { IssueData, ZodErrorMap, ZodIssue, defaultErrorMap, getErrorMap } from '../error' +import { IssueData, ZodErrorMap, ZodIssue, defaultErrorMap, getErrorMap } from '../../error' import type { ZodParsedType } from '.' export const makeIssue = (params: { diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index e876ef545de..89c20c9bdcb 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,5 +1,5 @@ +import { ZodIssueCode } from '../../error' import { - ZodIssueCode, RawCreateParams, ZodType, ZodTypeDef, diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 4921fa9ae77..5831064fb84 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -6,7 +6,7 @@ export * from './builders' export { default } from './builders' // Re-export 'default' explicitly since export * doesn't handle it export * from './types' -export * from './types/error' +export * from './error' export * from './types/utils' export * from './types/utils/parseUtil' export * from './types/utils/typeAliases' From 4c7e5fb158fc11e39cb909c429ccb6b3965418ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Tue, 17 Feb 2026 18:53:33 -0500 Subject: [PATCH 08/50] chore(zui): rm unused benchmarks (#14956) --- packages/zui/package.json | 2 - .../src/z/benchmarks/discriminatedUnion.ts | 80 ----------- packages/zui/src/z/benchmarks/index.ts | 45 ------ packages/zui/src/z/benchmarks/object.ts | 69 ---------- packages/zui/src/z/benchmarks/primitives.ts | 128 ------------------ packages/zui/src/z/benchmarks/realworld.ts | 63 --------- packages/zui/src/z/benchmarks/string.ts | 55 -------- packages/zui/src/z/benchmarks/union.ts | 80 ----------- pnpm-lock.yaml | 24 ---- 9 files changed, 546 deletions(-) delete mode 100644 packages/zui/src/z/benchmarks/discriminatedUnion.ts delete mode 100644 packages/zui/src/z/benchmarks/index.ts delete mode 100644 packages/zui/src/z/benchmarks/object.ts delete mode 100644 packages/zui/src/z/benchmarks/primitives.ts delete mode 100644 packages/zui/src/z/benchmarks/realworld.ts delete mode 100644 packages/zui/src/z/benchmarks/string.ts delete mode 100644 packages/zui/src/z/benchmarks/union.ts diff --git a/packages/zui/package.json b/packages/zui/package.json index 13cf4e57bec..e577dbb781d 100644 --- a/packages/zui/package.json +++ b/packages/zui/package.json @@ -18,13 +18,11 @@ "test": "vitest --run" }, "devDependencies": { - "@types/benchmark": "^2.1.5", "@types/json-schema": "^7.0.12", "@types/lodash-es": "^4.17.12", "@types/node": "^22.16.4", "ajv": "^8.12.0", "ajv-formats": "^3.0.1", - "benchmark": "^2.1.4", "local-ref-resolver": "^0.2.0", "lodash-es": "^4.17.21", "tsup": "^8.0.2" diff --git a/packages/zui/src/z/benchmarks/discriminatedUnion.ts b/packages/zui/src/z/benchmarks/discriminatedUnion.ts deleted file mode 100644 index e3cb7350712..00000000000 --- a/packages/zui/src/z/benchmarks/discriminatedUnion.ts +++ /dev/null @@ -1,80 +0,0 @@ -import Benchmark from 'benchmark' - -import { z } from '../index' - -const doubleSuite = new Benchmark.Suite('z.discriminatedUnion: double') -const manySuite = new Benchmark.Suite('z.discriminatedUnion: many') - -const aSchema = z.object({ - type: z.literal('a'), -}) -const objA = { - type: 'a', -} - -const bSchema = z.object({ - type: z.literal('b'), -}) -const objB = { - type: 'b', -} - -const cSchema = z.object({ - type: z.literal('c'), -}) -const objC = { - type: 'c', -} - -const dSchema = z.object({ - type: z.literal('d'), -}) - -const double = z.discriminatedUnion('type', [aSchema, bSchema]) -const many = z.discriminatedUnion('type', [aSchema, bSchema, cSchema, dSchema]) - -doubleSuite - .add('valid: a', () => { - double.parse(objA) - }) - .add('valid: b', () => { - double.parse(objB) - }) - .add('invalid: null', () => { - try { - double.parse(null) - } catch {} - }) - .add('invalid: wrong shape', () => { - try { - double.parse(objC) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${doubleSuite.name}: ${e.target}`) - }) - -manySuite - .add('valid: a', () => { - many.parse(objA) - }) - .add('valid: c', () => { - many.parse(objC) - }) - .add('invalid: null', () => { - try { - many.parse(null) - } catch {} - }) - .add('invalid: wrong shape', () => { - try { - many.parse({ type: 'unknown' }) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${manySuite.name}: ${e.target}`) - }) - -export default { - suites: [doubleSuite, manySuite], -} diff --git a/packages/zui/src/z/benchmarks/index.ts b/packages/zui/src/z/benchmarks/index.ts deleted file mode 100644 index 25e1ed9dfa2..00000000000 --- a/packages/zui/src/z/benchmarks/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import Benchmark from 'benchmark' - -import discriminatedUnionBenchmarks from './discriminatedUnion' -import objectBenchmarks from './object' -import primitiveBenchmarks from './primitives' -import realworld from './realworld' -import stringBenchmarks from './string' -import unionBenchmarks from './union' - -const argv = process.argv.slice(2) -let suites: Benchmark.Suite[] = [] - -if (!argv.length) { - suites = [ - ...realworld.suites, - ...primitiveBenchmarks.suites, - ...stringBenchmarks.suites, - ...objectBenchmarks.suites, - ...unionBenchmarks.suites, - ...discriminatedUnionBenchmarks.suites, - ] -} else { - if (argv.includes('--realworld')) { - suites.push(...realworld.suites) - } - if (argv.includes('--primitives')) { - suites.push(...primitiveBenchmarks.suites) - } - if (argv.includes('--string')) { - suites.push(...stringBenchmarks.suites) - } - if (argv.includes('--object')) { - suites.push(...objectBenchmarks.suites) - } - if (argv.includes('--union')) { - suites.push(...unionBenchmarks.suites) - } - if (argv.includes('--discriminatedUnion')) { - suites.push(...discriminatedUnionBenchmarks.suites) - } -} - -for (const suite of suites) { - suite.run() -} diff --git a/packages/zui/src/z/benchmarks/object.ts b/packages/zui/src/z/benchmarks/object.ts deleted file mode 100644 index a4bd78489e5..00000000000 --- a/packages/zui/src/z/benchmarks/object.ts +++ /dev/null @@ -1,69 +0,0 @@ -import Benchmark from 'benchmark' - -import { z } from '../index' - -const emptySuite = new Benchmark.Suite('z.object: empty') -const shortSuite = new Benchmark.Suite('z.object: short') -const longSuite = new Benchmark.Suite('z.object: long') - -const empty = z.object({}) -const short = z.object({ - string: z.string(), -}) -const long = z.object({ - string: z.string(), - number: z.number(), - boolean: z.boolean(), -}) - -emptySuite - .add('valid', () => { - empty.parse({}) - }) - .add('valid: extra keys', () => { - empty.parse({ string: 'string' }) - }) - .add('invalid: null', () => { - try { - empty.parse(null) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${emptySuite.name}: ${e.target}`) - }) - -shortSuite - .add('valid', () => { - short.parse({ string: 'string' }) - }) - .add('valid: extra keys', () => { - short.parse({ string: 'string', number: 42 }) - }) - .add('invalid: null', () => { - try { - short.parse(null) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${shortSuite.name}: ${e.target}`) - }) - -longSuite - .add('valid', () => { - long.parse({ string: 'string', number: 42, boolean: true }) - }) - .add('valid: extra keys', () => { - long.parse({ string: 'string', number: 42, boolean: true, list: [] }) - }) - .add('invalid: null', () => { - try { - long.parse(null) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${longSuite.name}: ${e.target}`) - }) - -export default { - suites: [emptySuite, shortSuite, longSuite], -} diff --git a/packages/zui/src/z/benchmarks/primitives.ts b/packages/zui/src/z/benchmarks/primitives.ts deleted file mode 100644 index c1333d2f59f..00000000000 --- a/packages/zui/src/z/benchmarks/primitives.ts +++ /dev/null @@ -1,128 +0,0 @@ -import Benchmark from 'benchmark' - -import { Mocker } from '../__tests__/Mocker' -import { z } from '../index' - -const val = new Mocker() - -const enumSuite = new Benchmark.Suite('z.enum') -const enumSchema = z.enum(['a', 'b', 'c']) - -enumSuite - .add('valid', () => { - enumSchema.parse('a') - }) - .add('invalid', () => { - try { - enumSchema.parse('x') - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.enum: ${e.target}`) - }) - -const undefinedSuite = new Benchmark.Suite('z.undefined') -const undefinedSchema = z.undefined() - -undefinedSuite - .add('valid', () => { - undefinedSchema.parse(undefined) - }) - .add('invalid', () => { - try { - undefinedSchema.parse(1) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.undefined: ${e.target}`) - }) - -const literalSuite = new Benchmark.Suite('z.literal') -const short = 'short' -const bad = 'bad' -const literalSchema = z.literal('short') - -literalSuite - .add('valid', () => { - literalSchema.parse(short) - }) - .add('invalid', () => { - try { - literalSchema.parse(bad) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.literal: ${e.target}`) - }) - -const numberSuite = new Benchmark.Suite('z.number') -const numberSchema = z.number().int() - -numberSuite - .add('valid', () => { - numberSchema.parse(1) - }) - .add('invalid type', () => { - try { - numberSchema.parse('bad') - } catch {} - }) - .add('invalid number', () => { - try { - numberSchema.parse(0.5) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.number: ${e.target}`) - }) - -const dateSuite = new Benchmark.Suite('z.date') - -const plainDate = z.date() -const minMaxDate = z.date().min(new Date('2021-01-01')).max(new Date('2030-01-01')) - -dateSuite - .add('valid', () => { - plainDate.parse(new Date()) - }) - .add('invalid', () => { - try { - plainDate.parse(1) - } catch {} - }) - .add('valid min and max', () => { - minMaxDate.parse(new Date('2023-01-01')) - }) - .add('invalid min', () => { - try { - minMaxDate.parse(new Date('2019-01-01')) - } catch {} - }) - .add('invalid max', () => { - try { - minMaxDate.parse(new Date('2031-01-01')) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.date: ${e.target}`) - }) - -const symbolSuite = new Benchmark.Suite('z.symbol') -const symbolSchema = z.symbol() - -symbolSuite - .add('valid', () => { - symbolSchema.parse(val.symbol) - }) - .add('invalid', () => { - try { - symbolSchema.parse(1) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`z.symbol: ${e.target}`) - }) - -export default { - suites: [enumSuite, undefinedSuite, literalSuite, numberSuite, dateSuite, symbolSuite], -} diff --git a/packages/zui/src/z/benchmarks/realworld.ts b/packages/zui/src/z/benchmarks/realworld.ts deleted file mode 100644 index fcc41c67252..00000000000 --- a/packages/zui/src/z/benchmarks/realworld.ts +++ /dev/null @@ -1,63 +0,0 @@ -import Benchmark from 'benchmark' - -import { z } from '../index' - -const shortSuite = new Benchmark.Suite('realworld') - -const People = z.array( - z.object({ - type: z.literal('person'), - hair: z.enum(['blue', 'brown']), - active: z.boolean(), - name: z.string(), - age: z.number().int(), - hobbies: z.array(z.string()), - address: z.object({ - street: z.string(), - zip: z.string(), - country: z.string(), - }), - }) -) - -let i = 0 - -function num() { - return ++i -} - -function str() { - return (++i % 100).toString(16) -} - -function array(fn: () => T): T[] { - return Array.from({ length: ++i % 10 }, () => fn()) -} - -const people = Array.from({ length: 100 }, () => { - return { - type: 'person', - hair: i % 2 ? 'blue' : 'brown', - active: !!(i % 2), - name: str(), - age: num(), - hobbies: array(str), - address: { - street: str(), - zip: str(), - country: str(), - }, - } -}) - -shortSuite - .add('valid', () => { - People.parse(people) - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${shortSuite.name}: ${e.target}`) - }) - -export default { - suites: [shortSuite], -} diff --git a/packages/zui/src/z/benchmarks/string.ts b/packages/zui/src/z/benchmarks/string.ts deleted file mode 100644 index a9c0fc052b3..00000000000 --- a/packages/zui/src/z/benchmarks/string.ts +++ /dev/null @@ -1,55 +0,0 @@ -import Benchmark from 'benchmark' - -import { z } from '../index' - -const SUITE_NAME = 'z.string' -const suite = new Benchmark.Suite(SUITE_NAME) - -const empty = '' -const short = 'short' -const long = 'long'.repeat(256) -const manual = (str: unknown) => { - if (typeof str !== 'string') { - throw new Error('Not a string') - } - - return str -} -const stringSchema = z.string() -const optionalStringSchema = z.string().optional() -const optionalNullableStringSchema = z.string().optional().nullable() - -suite - .add('empty string', () => { - stringSchema.parse(empty) - }) - .add('short string', () => { - stringSchema.parse(short) - }) - .add('long string', () => { - stringSchema.parse(long) - }) - .add('optional string', () => { - optionalStringSchema.parse(long) - }) - .add('nullable string', () => { - optionalNullableStringSchema.parse(long) - }) - .add('nullable (null) string', () => { - optionalNullableStringSchema.parse(null) - }) - .add('invalid: null', () => { - try { - stringSchema.parse(null) - } catch {} - }) - .add('manual parser: long', () => { - manual(long) - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${SUITE_NAME}: ${e.target}`) - }) - -export default { - suites: [suite], -} diff --git a/packages/zui/src/z/benchmarks/union.ts b/packages/zui/src/z/benchmarks/union.ts deleted file mode 100644 index 6312ef8a929..00000000000 --- a/packages/zui/src/z/benchmarks/union.ts +++ /dev/null @@ -1,80 +0,0 @@ -import Benchmark from 'benchmark' - -import { z } from '../index' - -const doubleSuite = new Benchmark.Suite('z.union: double') -const manySuite = new Benchmark.Suite('z.union: many') - -const aSchema = z.object({ - type: z.literal('a'), -}) -const objA = { - type: 'a', -} - -const bSchema = z.object({ - type: z.literal('b'), -}) -const objB = { - type: 'b', -} - -const cSchema = z.object({ - type: z.literal('c'), -}) -const objC = { - type: 'c', -} - -const dSchema = z.object({ - type: z.literal('d'), -}) - -const double = z.union([aSchema, bSchema]) -const many = z.union([aSchema, bSchema, cSchema, dSchema]) - -doubleSuite - .add('valid: a', () => { - double.parse(objA) - }) - .add('valid: b', () => { - double.parse(objB) - }) - .add('invalid: null', () => { - try { - double.parse(null) - } catch {} - }) - .add('invalid: wrong shape', () => { - try { - double.parse(objC) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${doubleSuite.name}: ${e.target}`) - }) - -manySuite - .add('valid: a', () => { - many.parse(objA) - }) - .add('valid: c', () => { - many.parse(objC) - }) - .add('invalid: null', () => { - try { - many.parse(null) - } catch {} - }) - .add('invalid: wrong shape', () => { - try { - many.parse({ type: 'unknown' }) - } catch {} - }) - .on('cycle', (e: Benchmark.Event) => { - console.info(`${manySuite.name}: ${e.target}`) - }) - -export default { - suites: [doubleSuite, manySuite], -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22e9f604a26..4a1c6f0a864 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3096,9 +3096,6 @@ importers: packages/zui: devDependencies: - '@types/benchmark': - specifier: ^2.1.5 - version: 2.1.5 '@types/json-schema': specifier: ^7.0.12 version: 7.0.15 @@ -3114,9 +3111,6 @@ importers: ajv-formats: specifier: ^3.0.1 version: 3.0.1(ajv@8.17.1) - benchmark: - specifier: ^2.1.4 - version: 2.1.4 local-ref-resolver: specifier: ^0.2.0 version: 0.2.0 @@ -6084,9 +6078,6 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/benchmark@2.1.5': - resolution: {integrity: sha512-cKio2eFB3v7qmKcvIHLUMw/dIx/8bhWPuzpzRT4unCPRTD8VdA9Zb0afxpcxOqR4PixRS7yT42FqGS8BYL8g1w==} - '@types/bluebird@3.5.38': resolution: {integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==} @@ -6810,9 +6801,6 @@ packages: before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - benchmark@2.1.4: - resolution: {integrity: sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==} - big-integer@1.6.52: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} @@ -10129,9 +10117,6 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - platform@1.3.6: - resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} - pony-cause@1.1.1: resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} engines: {node: '>=12.0.0'} @@ -15525,8 +15510,6 @@ snapshots: dependencies: '@babel/types': 7.26.9 - '@types/benchmark@2.1.5': {} - '@types/bluebird@3.5.38': {} '@types/body-parser@1.19.2': @@ -16463,11 +16446,6 @@ snapshots: before-after-hook@2.2.3: {} - benchmark@2.1.4: - dependencies: - lodash: 4.17.21 - platform: 1.3.6 - big-integer@1.6.52: {} bignumber.js@9.1.1: {} @@ -20685,8 +20663,6 @@ snapshots: dependencies: find-up: 4.1.0 - platform@1.3.6: {} - pony-cause@1.1.1: {} possible-typed-array-names@1.0.0: {} From 76564fd086e70d9216800e45b87c154d565b9925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Tue, 17 Feb 2026 22:16:26 -0500 Subject: [PATCH 09/50] chore(zui): move most utils outside types (#14957) --- .../zui/src/transforms/common/json-schema.ts | 56 ++--- packages/zui/src/transforms/common/utils.ts | 2 +- .../transforms/zui-from-json-schema/index.ts | 3 +- .../transforms/zui-to-json-schema/index.ts | 5 +- .../zui-to-typescript-schema/bigint-checks.ts | 4 +- .../zui-to-typescript-schema/date-checks.ts | 4 +- .../zui-to-typescript-schema/index.ts | 5 +- .../zui-to-typescript-schema/number-checks.ts | 4 +- .../zui-to-typescript-schema/string-checks.ts | 4 +- .../zui-to-typescript-type/index.test.ts | 5 +- .../zui-to-typescript-type/index.ts | 5 +- packages/zui/src/z/__tests__/base.test.ts | 4 +- packages/zui/src/z/__tests__/generics.test.ts | 4 +- .../zui/src/z/__tests__/instanceof.test.ts | 4 +- packages/zui/src/z/__tests__/partials.test.ts | 10 +- packages/zui/src/z/__tests__/pickomit.test.ts | 8 +- .../zui/src/z/__tests__/preprocess.test.ts | 6 +- .../zui/src/z/__tests__/primitive.test.ts | 54 ++--- packages/zui/src/z/__tests__/refine.test.ts | 18 +- packages/zui/src/z/__tests__/set.test.ts | 4 +- packages/zui/src/z/error/index.ts | 69 ++++-- packages/zui/src/z/error/locales/en.ts | 16 +- .../zui/src/z/types/any/anyunknown.test.ts | 6 +- packages/zui/src/z/types/array/array.test.ts | 6 +- packages/zui/src/z/types/array/index.ts | 16 +- packages/zui/src/z/types/basetype/index.ts | 18 +- packages/zui/src/z/types/bigint/index.ts | 48 ++-- .../zui/src/z/types/branded/branded.test.ts | 16 +- packages/zui/src/z/types/catch/catch.test.ts | 20 +- packages/zui/src/z/types/catch/index.ts | 4 +- packages/zui/src/z/types/date/index.ts | 18 +- .../zui/src/z/types/default/default.test.ts | 20 +- packages/zui/src/z/types/default/index.ts | 8 +- .../discriminatedUnion.test.ts | 3 +- .../src/z/types/discriminatedUnion/index.ts | 19 +- packages/zui/src/z/types/enum/enum.test.ts | 14 +- packages/zui/src/z/types/enum/index.ts | 9 +- .../zui/src/z/types/function/function.test.ts | 16 +- packages/zui/src/z/types/function/index.ts | 4 +- packages/zui/src/z/types/index.ts | 3 +- .../zui/src/z/types/intersection/index.ts | 14 +- packages/zui/src/z/types/literal/index.ts | 9 +- packages/zui/src/z/types/map/index.ts | 4 +- packages/zui/src/z/types/map/map.test.ts | 4 +- packages/zui/src/z/types/native.test.ts | 4 +- packages/zui/src/z/types/native.ts | 2 +- packages/zui/src/z/types/nativeEnum/index.ts | 20 +- .../src/z/types/nativeEnum/nativeEnum.test.ts | 8 +- packages/zui/src/z/types/number/index.ts | 68 +++--- packages/zui/src/z/types/object/index.ts | 29 +-- .../zui/src/z/types/object/object.test.ts | 40 ++-- packages/zui/src/z/types/pipeline/index.ts | 4 +- .../zui/src/z/types/promise/promise.test.ts | 4 +- .../zui/src/z/types/readonly/readonly.test.ts | 93 ++++---- packages/zui/src/z/types/record/index.ts | 4 +- .../zui/src/z/types/record/record.test.ts | 8 +- packages/zui/src/z/types/ref/ref.test.ts | 4 +- packages/zui/src/z/types/set/index.ts | 14 +- packages/zui/src/z/types/string/index.ts | 76 +++--- packages/zui/src/z/types/transformer/index.ts | 12 +- .../z/types/transformer/transformer.test.ts | 8 +- packages/zui/src/z/types/tuple/index.ts | 9 +- packages/zui/src/z/types/tuple/tuple.test.ts | 10 +- packages/zui/src/z/types/union/index.ts | 9 +- packages/zui/src/z/types/utils/errorUtil.ts | 6 - packages/zui/src/z/types/utils/index.ts | 223 ++++-------------- packages/zui/src/z/types/utils/objectUtil.ts | 39 +++ packages/zui/src/z/types/utils/partialUtil.ts | 1 + packages/zui/src/z/types/utils/typeAliases.ts | 2 - packages/zui/src/z/types/void/void.test.ts | 4 +- packages/zui/src/z/utils.ts | 5 - packages/zui/src/z/utils/assert-utils.ts | 10 + .../ds-utils.test.ts} | 2 +- .../utils/custom-set.ts => utils/ds-utils.ts} | 2 +- packages/zui/src/z/utils/error-utils.ts | 4 + .../fn-utils.test.ts} | 2 +- .../utils/is-equal.ts => utils/fn-utils.ts} | 4 + packages/zui/src/z/utils/index.ts | 6 + packages/zui/src/z/utils/other-utils.ts | 21 ++ packages/zui/src/z/utils/type-utils.ts | 22 ++ packages/zui/src/z/z.ts | 2 - 81 files changed, 665 insertions(+), 689 deletions(-) delete mode 100644 packages/zui/src/z/types/utils/errorUtil.ts create mode 100644 packages/zui/src/z/types/utils/objectUtil.ts delete mode 100644 packages/zui/src/z/types/utils/typeAliases.ts delete mode 100644 packages/zui/src/z/utils.ts create mode 100644 packages/zui/src/z/utils/assert-utils.ts rename packages/zui/src/z/{types/utils/custom-set.test.ts => utils/ds-utils.test.ts} (99%) rename packages/zui/src/z/{types/utils/custom-set.ts => utils/ds-utils.ts} (96%) create mode 100644 packages/zui/src/z/utils/error-utils.ts rename packages/zui/src/z/{types/utils/is-equal.test.ts => utils/fn-utils.test.ts} (99%) rename packages/zui/src/z/{types/utils/is-equal.ts => utils/fn-utils.ts} (93%) create mode 100644 packages/zui/src/z/utils/index.ts create mode 100644 packages/zui/src/z/utils/other-utils.ts create mode 100644 packages/zui/src/z/utils/type-utils.ts diff --git a/packages/zui/src/transforms/common/json-schema.ts b/packages/zui/src/transforms/common/json-schema.ts index 834cf79ad4c..7062a788b61 100644 --- a/packages/zui/src/transforms/common/json-schema.ts +++ b/packages/zui/src/transforms/common/json-schema.ts @@ -1,7 +1,7 @@ import { JSONSchema7 } from 'json-schema' import { ZuiExtensionObject } from '../../ui/types' import z from '../../z' -import { util } from '../../z/types/utils' +import * as utils from '../../z/utils/type-utils' /** * Definitions: @@ -9,11 +9,11 @@ import { util } from '../../z/types/utils' * Mutiple zui schemas map to the same JSON schema; undefined/never, any/unknown, union/discriminated-union * Adding some ZodDef to the ZuiExtension allows us to differentiate between them */ -type NullableDef = util.Satisfies<{ typeName: 'ZodNullable' }, Partial> -type OptionalDef = util.Satisfies<{ typeName: 'ZodOptional' }, Partial> -type UndefinedDef = util.Satisfies<{ typeName: 'ZodUndefined' }, Partial> -type UnknownDef = util.Satisfies<{ typeName: 'ZodUnknown' }, Partial> -type DiscriminatedUnionDef = util.Satisfies< +type NullableDef = utils.Satisfies<{ typeName: 'ZodNullable' }, Partial> +type OptionalDef = utils.Satisfies<{ typeName: 'ZodOptional' }, Partial> +type UndefinedDef = utils.Satisfies<{ typeName: 'ZodUndefined' }, Partial> +type UnknownDef = utils.Satisfies<{ typeName: 'ZodUnknown' }, Partial> +type DiscriminatedUnionDef = utils.Satisfies< { typeName: 'ZodDiscriminatedUnion'; discriminator?: string }, Partial > @@ -26,7 +26,7 @@ type DiscriminatedUnionDef = util.Satisfies< type ZuiExtension = {}> = { def?: Def } & ZuiExtensionObject type JsonData = string | number | boolean | null | JsonData[] | { [key: string]: JsonData } -type BaseZuiJSONSchema = {}> = util.Satisfies< +type BaseZuiJSONSchema = {}> = utils.Satisfies< { description?: string readOnly?: boolean @@ -39,7 +39,7 @@ type BaseZuiJSONSchema = {}> = util.Satisfies< // From the JSON Schema spec: "Format is not limited to a specific set of valid values or types. Users may define their own custom keywords" type _ZodSpecificStringFormat = 'cuid' | 'cuid2' | 'emoji' | 'ulid' type _JSONSchemaStringFormat = 'date-time' | 'email' | 'ipv4' | 'ipv6' | 'uri' | 'uuid' -type _StringSchema = util.Satisfies< +type _StringSchema = utils.Satisfies< { type: 'string' pattern?: string @@ -50,7 +50,7 @@ type _StringSchema = util.Satisfies< JSONSchema7 > type _ZodSpecificNumberFormat = 'finite' -type _NumberSchema = util.Satisfies< +type _NumberSchema = utils.Satisfies< { type: 'number' | 'integer' minimum?: number @@ -62,21 +62,21 @@ type _NumberSchema = util.Satisfies< }, JSONSchema7 > -type _BooleanSchema = util.Satisfies<{ type: 'boolean' }, JSONSchema7> -type _NullSchema = util.Satisfies<{ type: 'null' }, JSONSchema7> -type _UndefinedSchema = util.Satisfies<{ not: true }, JSONSchema7> -type _NeverSchema = util.Satisfies<{ not: true }, JSONSchema7> -type _ArraySchema = util.Satisfies<{ type: 'array'; items: Schema; minItems?: number; maxItems?: number }, JSONSchema7> -type _UnionSchema = util.Satisfies<{ anyOf: Schema[] }, JSONSchema7> -type _DiscriminatedUnionSchema = util.Satisfies<{ anyOf: Schema[] }, JSONSchema7> -type _IntersectionSchema = util.Satisfies<{ allOf: Schema[] }, JSONSchema7> -type _SetSchema = util.Satisfies< +type _BooleanSchema = utils.Satisfies<{ type: 'boolean' }, JSONSchema7> +type _NullSchema = utils.Satisfies<{ type: 'null' }, JSONSchema7> +type _UndefinedSchema = utils.Satisfies<{ not: true }, JSONSchema7> +type _NeverSchema = utils.Satisfies<{ not: true }, JSONSchema7> +type _ArraySchema = utils.Satisfies<{ type: 'array'; items: Schema; minItems?: number; maxItems?: number }, JSONSchema7> +type _UnionSchema = utils.Satisfies<{ anyOf: Schema[] }, JSONSchema7> +type _DiscriminatedUnionSchema = utils.Satisfies<{ anyOf: Schema[] }, JSONSchema7> +type _IntersectionSchema = utils.Satisfies<{ allOf: Schema[] }, JSONSchema7> +type _SetSchema = utils.Satisfies< { type: 'array'; items: Schema; uniqueItems: true; minItems?: number; maxItems?: number }, JSONSchema7 > -type _EnumSchema = util.Satisfies<{ type: 'string'; enum: string[] }, JSONSchema7> -type _RefSchema = util.Satisfies<{ $ref: string }, JSONSchema7> -type _ObjectSchema = util.Satisfies< +type _EnumSchema = utils.Satisfies<{ type: 'string'; enum: string[] }, JSONSchema7> +type _RefSchema = utils.Satisfies<{ $ref: string }, JSONSchema7> +type _ObjectSchema = utils.Satisfies< { type: 'object' properties: { [key: string]: Schema } @@ -85,13 +85,13 @@ type _ObjectSchema = util.Satisfies< }, JSONSchema7 > -type _TupleSchema = util.Satisfies<{ type: 'array'; items: Schema[]; additionalItems?: Schema }, JSONSchema7> -type _RecordSchema = util.Satisfies<{ type: 'object'; additionalProperties: Schema }, JSONSchema7> -type _LiteralStringSchema = util.Satisfies<{ type: 'string'; const: string }, JSONSchema7> -type _LiteralNumberSchema = util.Satisfies<{ type: 'number'; const: number }, JSONSchema7> -type _LiteralBooleanSchema = util.Satisfies<{ type: 'boolean'; const: boolean }, JSONSchema7> -type _OptionalSchema = util.Satisfies<{ anyOf: [Schema, UndefinedSchema] }, JSONSchema7> -type _NullableSchema = util.Satisfies<{ anyOf: [Schema, NullSchema] }, JSONSchema7> +type _TupleSchema = utils.Satisfies<{ type: 'array'; items: Schema[]; additionalItems?: Schema }, JSONSchema7> +type _RecordSchema = utils.Satisfies<{ type: 'object'; additionalProperties: Schema }, JSONSchema7> +type _LiteralStringSchema = utils.Satisfies<{ type: 'string'; const: string }, JSONSchema7> +type _LiteralNumberSchema = utils.Satisfies<{ type: 'number'; const: number }, JSONSchema7> +type _LiteralBooleanSchema = utils.Satisfies<{ type: 'boolean'; const: boolean }, JSONSchema7> +type _OptionalSchema = utils.Satisfies<{ anyOf: [Schema, UndefinedSchema] }, JSONSchema7> +type _NullableSchema = utils.Satisfies<{ anyOf: [Schema, NullSchema] }, JSONSchema7> export type StringSchema = _StringSchema & BaseZuiJSONSchema export type NumberSchema = _NumberSchema & BaseZuiJSONSchema diff --git a/packages/zui/src/transforms/common/utils.ts b/packages/zui/src/transforms/common/utils.ts index e121ed0b6c2..09eb7f47175 100644 --- a/packages/zui/src/transforms/common/utils.ts +++ b/packages/zui/src/transforms/common/utils.ts @@ -1,4 +1,4 @@ -import { Primitive } from '../../z' +import { Primitive } from '../../z/utils/type-utils' /** * @returns a valid typescript literal type usable in `type MyType = ${x}` diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index 7693456ba18..f2b1a647b81 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -1,5 +1,6 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema' import z from '../../z' +import * as utils from '../../z/utils' import * as errors from '../common/errors' import { ArraySchema, SetSchema, TupleSchema } from '../common/json-schema' import * as guards from './guards' @@ -197,7 +198,7 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { return z.intersection(zLeft, zRight) } - type _expectUndefined = z.util.AssertTrue> + type _expectUndefined = utils.assert.AssertTrue> if (guards.isUnknownSchema(schema)) { return z.unknown() diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index 9f1489595b8..96c30372936 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -1,4 +1,5 @@ import z from '../../z' +import * as utils from '../../z/utils' import * as err from '../common/errors' import * as json from '../common/json-schema' import { zodArrayToJsonArray } from './type-processors/array' @@ -190,7 +191,7 @@ export function toJSONSchema(schema: z.Schema): json.Schema { } else if (s.value === undefined) { return undefinedSchema(s._def) } else { - z.util.assertEqual(true) + utils.assert.assertEqual(true) const unsupportedLiteral = typeof s.value throw new err.ZuiToJSONSchemaError(`Unsupported literal type: "${unsupportedLiteral}"`) } @@ -266,7 +267,7 @@ export function toJSONSchema(schema: z.Schema): json.Schema { } default: - z.util.assertNever(s) + utils.assert.assertNever(s) } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts index bc719b76bb2..212c8ccd74d 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts @@ -1,5 +1,5 @@ -import { util } from '../../z' import { ZodBigIntCheck, ZodBigIntDef } from '../../z/types/bigint' +import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateBigIntChecks = (def: ZodBigIntDef): string => { @@ -19,7 +19,7 @@ const _generateBigIntCheck = (check: ZodBigIntCheck): string => { case 'multipleOf': return `.multipleOf(${toTs(check.value)}, ${toTs(check.message)})` default: - type _assertion = util.AssertNever + type _assertion = utils.assert.AssertNever return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts index d136a80259c..38a3e29d309 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts @@ -1,5 +1,5 @@ -import { util } from '../../z' import { ZodDateCheck, ZodDateDef } from '../../z/types/date' +import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateDateChecks = (def: ZodDateDef): string => { @@ -19,7 +19,7 @@ const _generateDateCheck = (check: ZodDateCheck): string => { const maxDate = dateTs(check.value) return `.max(${maxDate}, ${toTs(check.message)})` default: - type _assertion = util.AssertNever + type _assertion = utils.assert.AssertNever return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts index 7a691c993d8..2a66952c412 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts @@ -1,7 +1,8 @@ import { mapValues, isEqual } from 'lodash-es' import { zuiKey } from '../../ui/constants' -import z, { util } from '../../z' +import z from '../../z' +import * as utils from '../../z/utils' import * as errors from '../common/errors' import { primitiveToTypescriptValue, @@ -171,7 +172,7 @@ function sUnwrapZod(schema: z.Schema): string { return `z.ref(${uri})${_addMetadata(s._def)}`.trim() default: - util.assertNever(s) + utils.assert.assertNever(s) } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts index e0e52477b3e..03a79563991 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts @@ -1,5 +1,5 @@ -import { util } from '../../z' import { ZodNumberCheck, ZodNumberDef } from '../../z/types/number' +import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateNumberChecks = (def: ZodNumberDef): string => { @@ -23,7 +23,7 @@ const _generateNumberCheck = (check: ZodNumberCheck): string => { case 'finite': return `.finite(${toTs(check.message)})` default: - type _assertion = util.AssertNever + type _assertion = utils.assert.AssertNever return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts index f4414bef1aa..48bdd25d4e7 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts @@ -1,5 +1,5 @@ -import { util } from '../../z' import { ZodStringCheck, ZodStringDef } from '../../z/types/string' +import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs, unknownToTypescriptValue } from '../common/utils' export const generateStringChecks = (def: ZodStringDef): string => { @@ -60,7 +60,7 @@ const _generateStringCheck = (check: ZodStringCheck): string => { const ipOptions = unknownToTypescriptValue({ message: check.message, version: check.version }) return `.ip(${ipOptions})` default: - type _assertion = util.AssertNever + type _assertion = utils.assert.AssertNever return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts index 19a21c74b68..f7894ea4ce2 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts @@ -1,6 +1,7 @@ import { describe, it, expect } from 'vitest' import { toTypescriptType as toTs } from '.' -import z, { util, ZodType } from '../../z' +import * as utils from '../../z/utils' +import z, { ZodType } from '../../z' import * as errors from '../common/errors' import { assert } from '../../assertions.utils.test' @@ -894,7 +895,7 @@ describe.concurrent('objects', () => { await assert(actual).toMatchWithoutFormatting(expected) type S = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) it('should treat an optional any key as optional with a single question mark', async () => { diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index 0dc7fa14f46..03766901e4a 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -1,4 +1,5 @@ -import z, { util } from '../../z' +import z from '../../z' +import * as utils from '../../z/utils' import * as errors from '../common/errors' import { primitiveToTypescriptValue, @@ -339,7 +340,7 @@ ${value}`.trim() return toTypeArgumentName(s._def.uri) default: - util.assertNever(s) + utils.assert.assertNever(s) } } diff --git a/packages/zui/src/z/__tests__/base.test.ts b/packages/zui/src/z/__tests__/base.test.ts index 1dca9645373..c208db0d2ac 100644 --- a/packages/zui/src/z/__tests__/base.test.ts +++ b/packages/zui/src/z/__tests__/base.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import { util } from '../types/utils' +import * as utils from '../../z/utils' test('type guard', () => { const stringToNumber = z.string().transform((arg) => arg.length) @@ -13,7 +13,7 @@ test('type guard', () => { const data = { stringToNumber: 'asdf' } const parsed = s1.safeParse(data) if (parsed.success) { - util.assertEqual(true) + utils.assert.assertEqual(true) } }) diff --git a/packages/zui/src/z/__tests__/generics.test.ts b/packages/zui/src/z/__tests__/generics.test.ts index 572a1e9fb99..b8be5705500 100644 --- a/packages/zui/src/z/__tests__/generics.test.ts +++ b/packages/zui/src/z/__tests__/generics.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import z from '../index' -import { util } from '../types/utils' +import * as utils from '../../z/utils' test('generics', () => { async function stripOuter(schema: TData, data: unknown) { @@ -15,7 +15,7 @@ test('generics', () => { } const result = stripOuter(z.object({ a: z.string() }), { a: 'asdf' }) - util.assertEqual>(true) + utils.assert.assertEqual>(true) }) test('assignability', () => { diff --git a/packages/zui/src/z/__tests__/instanceof.test.ts b/packages/zui/src/z/__tests__/instanceof.test.ts index 39cd8cedba5..b0d23fe5a15 100644 --- a/packages/zui/src/z/__tests__/instanceof.test.ts +++ b/packages/zui/src/z/__tests__/instanceof.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import z from '../index' test('instanceof', async () => { @@ -25,7 +25,7 @@ test('instanceof', async () => { await expect(() => SubtestSchema.parse(new Test())).toThrow(/Input not instance of Subtest/) await expect(() => TestSchema.parse(12)).toThrow(/Input not instance of Test/) - util.assertEqual>(true) + utils.assert.assertEqual>(true) }) test('instanceof fatal', () => { diff --git a/packages/zui/src/z/__tests__/partials.test.ts b/packages/zui/src/z/__tests__/partials.test.ts index fc41615724e..08eb35d9cd9 100644 --- a/packages/zui/src/z/__tests__/partials.test.ts +++ b/packages/zui/src/z/__tests__/partials.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import z, { ZodNullable, ZodOptional } from '../index' const nested = z.object({ @@ -20,7 +20,7 @@ test('shallow inference', () => { outer?: { inner: string } | undefined array?: { asdf: string }[] } - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('shallow partial parse', () => { @@ -44,7 +44,7 @@ test('deep partial inference', () => { outer?: { inner?: string | undefined } | undefined } - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('deep partial parse', () => { @@ -117,7 +117,7 @@ test('deep partial inference', () => { | undefined tuple?: [{ value?: string }] | undefined } - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('required', () => { @@ -156,7 +156,7 @@ test('required inference', () => { nullableField: number | null nullishField: string | null } - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('required with mask', () => { diff --git a/packages/zui/src/z/__tests__/pickomit.test.ts b/packages/zui/src/z/__tests__/pickomit.test.ts index 10ce87a33c7..081301ac3ac 100644 --- a/packages/zui/src/z/__tests__/pickomit.test.ts +++ b/packages/zui/src/z/__tests__/pickomit.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import z from '../index' const fish = z.object({ @@ -11,7 +11,7 @@ const fish = z.object({ test('pick type inference', () => { const nameonlyFish = fish.pick({ name: true }) type nameonlyFish = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('pick parse - success', () => { @@ -46,7 +46,7 @@ test('pick parse - fail', () => { test('omit type inference', () => { const nonameFish = fish.omit({ name: true }) type nonameFish = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('omit parse - success', () => { @@ -77,7 +77,7 @@ test('omit parse - fail', () => { test('nonstrict inference', () => { const laxfish = fish.pick({ name: true }).catchall(z.any()) type laxfish = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('nonstrict parsing - pass', () => { diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 2235374d90d..19eb71785c0 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import z from '../index' test('preprocess', () => { @@ -7,7 +7,7 @@ test('preprocess', () => { const value = schema.parse('asdf') expect(value).toEqual(['asdf']) - util.assertEqual<(typeof schema)['_input'], unknown>(true) + utils.assert.assertEqual<(typeof schema)['_input'], unknown>(true) }) test('async preprocess', async () => { @@ -132,7 +132,7 @@ test('z.NEVER in preprocess', () => { }, z.number()) type foo = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) const arg = foo.safeParse(undefined) if (!arg.success) { expect(arg.error.issues[0]?.message).toEqual('bad') diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index 6b9d7282edd..039cbca1219 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import { Mocker } from './Mocker' const literalStringSchema = z.literal('asdf') @@ -135,7 +135,7 @@ test('literal bigint object', () => { }) test('literal symbol', () => { - util.assertEqual, typeof MySymbol>(true) + utils.assert.assertEqual, typeof MySymbol>(true) literalSymbolSchema.parse(MySymbol) expect(() => literalSymbolSchema.parse(Symbol('asdf'))).toThrow() }) @@ -371,31 +371,31 @@ test('parse nullSchema null', () => { }) test('primitive inference', () => { - util.assertEqual, 'asdf'>(true) - util.assertEqual, 12>(true) - util.assertEqual, true>(true) - util.assertEqual, bigint>(true) - util.assertEqual, string>(true) - util.assertEqual, number>(true) - util.assertEqual, bigint>(true) - util.assertEqual, boolean>(true) - util.assertEqual, Date>(true) - util.assertEqual, symbol>(true) - - util.assertEqual, null>(true) - util.assertEqual, undefined>(true) - util.assertEqual, string | undefined>(true) - util.assertEqual, string | null>(true) - util.assertEqual, number | undefined>(true) - util.assertEqual, number | null>(true) - util.assertEqual, bigint | undefined>(true) - util.assertEqual, bigint | null>(true) - util.assertEqual, boolean | undefined>(true) - util.assertEqual, boolean | null>(true) - util.assertEqual, Date | undefined>(true) - util.assertEqual, Date | null>(true) - util.assertEqual, symbol | undefined>(true) - util.assertEqual, symbol | null>(true) + utils.assert.assertEqual, 'asdf'>(true) + utils.assert.assertEqual, 12>(true) + utils.assert.assertEqual, true>(true) + utils.assert.assertEqual, bigint>(true) + utils.assert.assertEqual, string>(true) + utils.assert.assertEqual, number>(true) + utils.assert.assertEqual, bigint>(true) + utils.assert.assertEqual, boolean>(true) + utils.assert.assertEqual, Date>(true) + utils.assert.assertEqual, symbol>(true) + + utils.assert.assertEqual, null>(true) + utils.assert.assertEqual, undefined>(true) + utils.assert.assertEqual, string | undefined>(true) + utils.assert.assertEqual, string | null>(true) + utils.assert.assertEqual, number | undefined>(true) + utils.assert.assertEqual, number | null>(true) + utils.assert.assertEqual, bigint | undefined>(true) + utils.assert.assertEqual, bigint | null>(true) + utils.assert.assertEqual, boolean | undefined>(true) + utils.assert.assertEqual, boolean | null>(true) + utils.assert.assertEqual, Date | undefined>(true) + utils.assert.assertEqual, Date | null>(true) + utils.assert.assertEqual, symbol | undefined>(true) + utils.assert.assertEqual, symbol | null>(true) // [ // literalStringSchemaTest, diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index 84d39d04c3b..89270282187 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import z from '../index' import { ZodIssueCode } from '../error' @@ -48,11 +48,11 @@ test('refinement type guard', () => { type Input = z.input type Schema = z.infer - util.assertEqual<'a', Input['a']>(false) - util.assertEqual(true) + utils.assert.assertEqual<'a', Input['a']>(false) + utils.assert.assertEqual(true) - util.assertEqual<'a', Schema['a']>(true) - util.assertEqual(false) + utils.assert.assertEqual<'a', Schema['a']>(true) + utils.assert.assertEqual(false) }) test('refinement Promise', async () => { @@ -194,7 +194,7 @@ test('superRefine - type narrowing', () => { return true }) - util.assertEqual, NarrowType>(true) + utils.assert.assertEqual, NarrowType>(true) expect(schema.safeParse({ type: 'test', age: 0 }).success).toEqual(true) expect(schema.safeParse(null).success).toEqual(false) @@ -213,7 +213,7 @@ test('chained mixed refining types', () => { .nullable() .refine((arg): arg is firstRefinement => !!arg?.third) .superRefine((arg, ctx): arg is secondRefinement => { - util.assertEqual(true) + utils.assert.assertEqual(true) if (arg.first !== 'bob') { ctx.addIssue({ code: z.ZodIssueCode.custom, @@ -224,11 +224,11 @@ test('chained mixed refining types', () => { return true }) .refine((arg): arg is thirdRefinement => { - util.assertEqual(true) + utils.assert.assertEqual(true) return arg.second === 33 }) - util.assertEqual, thirdRefinement>(true) + utils.assert.assertEqual, thirdRefinement>(true) }) test('get inner type', () => { diff --git a/packages/zui/src/z/__tests__/set.test.ts b/packages/zui/src/z/__tests__/set.test.ts index e3a695f21e7..84936879f3a 100644 --- a/packages/zui/src/z/__tests__/set.test.ts +++ b/packages/zui/src/z/__tests__/set.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../types/utils' +import * as utils from '../../z/utils' import * as z from '../index' import { ZodIssueCode } from '../index' @@ -13,7 +13,7 @@ const nonEmpty = z.set(z.string()).nonempty() const nonEmptyMax = z.set(z.string()).nonempty().max(2) test('type inference', () => { - util.assertEqual>(true) + utils.assert.assertEqual>(true) }) test('valid parse', () => { diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index 79be55b987e..bd9cb788fe9 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -1,28 +1,45 @@ -import { util, ZodParsedType } from '../types/utils' -import { Primitive } from '../types/utils/typeAliases' +import { ZodParsedType } from '../types/utils' +import * as utils from '../utils' import { errorMap as defaultErrorMap } from './locales/en' -export const ZodIssueCode = util.arrayToEnum([ - 'invalid_type', - 'invalid_literal', - 'custom', - 'invalid_union', - 'invalid_union_discriminator', - 'invalid_enum_value', - 'unrecognized_keys', - 'invalid_arguments', - 'invalid_return_type', - 'invalid_date', - 'invalid_string', - 'too_small', - 'too_big', - 'invalid_intersection_types', - 'not_multiple_of', - 'not_finite', - 'unresolved_reference', -]) - -export type ZodIssueCode = keyof typeof ZodIssueCode +export type ZodIssueCode = + | 'invalid_type' + | 'invalid_literal' + | 'custom' + | 'invalid_union' + | 'invalid_union_discriminator' + | 'invalid_enum_value' + | 'unrecognized_keys' + | 'invalid_arguments' + | 'invalid_return_type' + | 'invalid_date' + | 'invalid_string' + | 'too_small' + | 'too_big' + | 'invalid_intersection_types' + | 'not_multiple_of' + | 'not_finite' + | 'unresolved_reference' + +export const ZodIssueCode = { + invalid_type: 'invalid_type', + invalid_literal: 'invalid_literal', + custom: 'custom', + invalid_union: 'invalid_union', + invalid_union_discriminator: 'invalid_union_discriminator', + invalid_enum_value: 'invalid_enum_value', + unrecognized_keys: 'unrecognized_keys', + invalid_arguments: 'invalid_arguments', + invalid_return_type: 'invalid_return_type', + invalid_date: 'invalid_date', + invalid_string: 'invalid_string', + too_small: 'too_small', + too_big: 'too_big', + invalid_intersection_types: 'invalid_intersection_types', + not_multiple_of: 'not_multiple_of', + not_finite: 'not_finite', + unresolved_reference: 'unresolved_reference', +} as const satisfies { [k in ZodIssueCode]: k } export type ZodIssueBase = { path: (string | number)[] @@ -53,7 +70,7 @@ export type ZodInvalidUnionIssue = { export type ZodInvalidUnionDiscriminatorIssue = { code: typeof ZodIssueCode.invalid_union_discriminator - options: Primitive[] + options: utils.types.Primitive[] } & ZodIssueBase export type ZodInvalidEnumValueIssue = { @@ -263,7 +280,7 @@ export class ZodError extends Error { return this.message } get message() { - return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2) + return JSON.stringify(this.issues, utils.others.jsonStringifyReplacer, 2) } get isEmpty(): boolean { @@ -279,7 +296,7 @@ export class ZodError extends Error { } } -type stripPath = T extends any ? util.OmitKeys : never +type stripPath = T extends any ? Omit : never export type IssueData = stripPath & { path?: (string | number)[] diff --git a/packages/zui/src/z/error/locales/en.ts b/packages/zui/src/z/error/locales/en.ts index 8e21597aad6..b3f966b3da6 100644 --- a/packages/zui/src/z/error/locales/en.ts +++ b/packages/zui/src/z/error/locales/en.ts @@ -1,4 +1,6 @@ -import { type ZodErrorMap, util, ZodIssueCode, ZodParsedType } from '../../index' +import { ZodParsedType } from '../../types' +import * as utils from '../../utils' +import { type ZodErrorMap, ZodIssueCode } from '../index' export const errorMap: ZodErrorMap = (issue, _ctx) => { let message: string @@ -11,19 +13,19 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { } break case ZodIssueCode.invalid_literal: - message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}` + message = `Invalid literal value, expected ${JSON.stringify(issue.expected, utils.others.jsonStringifyReplacer)}` break case ZodIssueCode.unrecognized_keys: - message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ', ')}` + message = `Unrecognized key(s) in object: ${utils.others.joinValues(issue.keys, ', ')}` break case ZodIssueCode.invalid_union: message = 'Invalid input' break case ZodIssueCode.invalid_union_discriminator: - message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}` + message = `Invalid discriminator value. Expected ${utils.others.joinValues(issue.options)}` break case ZodIssueCode.invalid_enum_value: - message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'` + message = `Invalid enum value. Expected ${utils.others.joinValues(issue.options)}, received '${issue.received}'` break case ZodIssueCode.invalid_arguments: message = 'Invalid function arguments' @@ -47,7 +49,7 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { } else if ('endsWith' in issue.validation) { message = `Invalid input: must end with "${issue.validation.endsWith}"` } else { - util.assertNever(issue.validation) + utils.assert.assertNever(issue.validation) } } else if (issue.validation !== 'regex') { message = `Invalid ${issue.validation}` @@ -114,7 +116,7 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { break default: message = _ctx.defaultError - util.assertNever(issue) + utils.assert.assertNever(issue) } return { message } } diff --git a/packages/zui/src/z/types/any/anyunknown.test.ts b/packages/zui/src/z/types/any/anyunknown.test.ts index f6d2bbc1606..d3b7fd6ee3d 100644 --- a/packages/zui/src/z/types/any/anyunknown.test.ts +++ b/packages/zui/src/z/types/any/anyunknown.test.ts @@ -1,13 +1,13 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' test('check any inference', () => { const t1 = z.any() t1.optional() t1.nullable() type t1 = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('check unknown inference', () => { @@ -15,7 +15,7 @@ test('check unknown inference', () => { t1.optional() t1.nullable() type t1 = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('check never inference', () => { diff --git a/packages/zui/src/z/types/array/array.test.ts b/packages/zui/src/z/types/array/array.test.ts index f1db27a17a7..987ac658c85 100644 --- a/packages/zui/src/z/types/array/array.test.ts +++ b/packages/zui/src/z/types/array/array.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' const minTwo = z.string().array().min(2) const maxTwo = z.string().array().max(2) @@ -9,10 +9,10 @@ const intNum = z.string().array().nonempty() const nonEmptyMax = z.string().array().nonempty().max(2) type t1 = z.infer -util.assertEqual<[string, ...string[]], t1>(true) +utils.assert.assertEqual<[string, ...string[]], t1>(true) type t2 = z.infer -util.assertEqual(true) +utils.assert.assertEqual(true) test('passing validations', () => { minTwo.parse(['a', 'a']) diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index 437be614780..bdaea19e728 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -1,5 +1,6 @@ import { isEqual } from 'lodash-es' import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { ParseInputLazyPath, RawCreateParams, @@ -7,7 +8,6 @@ import { ZodTypeDef, processCreateParams, ZodParsedType, - errorUtil, addIssueToContext, INVALID, ParseInput, @@ -145,28 +145,28 @@ export class ZodArray { + nonempty(message?: utils.errors.ErrMessage): ZodArray { return this.min(1, message) as ZodArray } diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 8d8c33a09a4..94375181e86 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -12,6 +12,7 @@ import type { ZuiMetadata, } from '../../../ui/types' import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap, ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { CatchFn } from '../catch' import { AsyncParseReturnType, @@ -27,7 +28,6 @@ import { processCreateParams, RefinementEffect, SyncParseReturnType, - util, ZodArray, ZodBranded, ZodCatch, @@ -56,6 +56,10 @@ type __ZodType = { readonly _input: Input } +type _DeepPartialBoolean = { + [K in keyof T]?: T[K] extends object ? _DeepPartialBoolean | boolean : boolean +} + export type RefinementCtx = { addIssue: (arg: IssueData) => void path: (string | number)[] @@ -66,8 +70,8 @@ export type OfType = T extends __ZodType ? T : never export type input = T['_input'] export type output = T['_output'] export type { TypeOf as infer } -export type Maskable = boolean | ((shape: T | null) => util.DeepPartialBoolean | boolean) -export type CustomErrorParams = Partial> +export type Maskable = boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) +export type CustomErrorParams = Partial> export type ZodTypeDef = { typeName: string errorMap?: ZodErrorMap @@ -459,8 +463,8 @@ export abstract class ZodType): ZodDefault - default(def: () => util.noUndefined): ZodDefault + default(def: utils.types.NoUndefined): ZodDefault + default(def: () => utils.types.NoUndefined): ZodDefault default(def: any) { const defaultValueFunc = typeof def === 'function' ? def : () => def @@ -580,7 +584,7 @@ export abstract class ZodType( - value?: boolean | ((shape: T | null) => util.DeepPartialBoolean | boolean) + value?: boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) ): this { let data: ZuiMetadata if (value === undefined) { @@ -598,7 +602,7 @@ export abstract class ZodType( - value?: boolean | ((shape: T | null) => util.DeepPartialBoolean | boolean) + value?: boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) ): this { let data: ZuiMetadata if (value === undefined) { diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 8d8ebf3fe9c..120174c3c26 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -1,4 +1,5 @@ import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { addIssueToContext, INVALID, @@ -10,11 +11,8 @@ import { ZodType, ZodTypeDef, processCreateParams, - util, ZodParsedType, - errorUtil, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ZodBigIntCheck = | { kind: 'min'; value: bigint; inclusive: boolean; message?: string } @@ -84,7 +82,7 @@ export class ZodBigInt extends ZodType { status.dirty() } } else { - util.assertNever(check) + utils.assert.assertNever(check) } } @@ -106,28 +104,28 @@ export class ZodBigInt extends ZodType { } if (this._def.coerce !== schema._def.coerce) return false - const thisChecks = new CustomSet(this._def.checks) - const thatChecks = new CustomSet(schema._def.checks) + const thisChecks = new utils.ds.CustomSet(this._def.checks) + const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) } - gte(value: bigint, message?: errorUtil.ErrMessage) { - return this.setLimit('min', value, true, errorUtil.toString(message)) + gte(value: bigint, message?: utils.errors.ErrMessage) { + return this.setLimit('min', value, true, utils.errors.toString(message)) } min = this.gte - gt(value: bigint, message?: errorUtil.ErrMessage) { - return this.setLimit('min', value, false, errorUtil.toString(message)) + gt(value: bigint, message?: utils.errors.ErrMessage) { + return this.setLimit('min', value, false, utils.errors.toString(message)) } - lte(value: bigint, message?: errorUtil.ErrMessage) { - return this.setLimit('max', value, true, errorUtil.toString(message)) + lte(value: bigint, message?: utils.errors.ErrMessage) { + return this.setLimit('max', value, true, utils.errors.toString(message)) } max = this.lte - lt(value: bigint, message?: errorUtil.ErrMessage) { - return this.setLimit('max', value, false, errorUtil.toString(message)) + lt(value: bigint, message?: utils.errors.ErrMessage) { + return this.setLimit('max', value, false, utils.errors.toString(message)) } protected setLimit(kind: 'min' | 'max', value: bigint, inclusive: boolean, message?: string) { @@ -139,7 +137,7 @@ export class ZodBigInt extends ZodType { kind, value, inclusive, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }, ], }) @@ -152,47 +150,47 @@ export class ZodBigInt extends ZodType { }) } - positive(message?: errorUtil.ErrMessage) { + positive(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: BigInt(0), inclusive: false, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - negative(message?: errorUtil.ErrMessage) { + negative(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: BigInt(0), inclusive: false, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - nonpositive(message?: errorUtil.ErrMessage) { + nonpositive(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: BigInt(0), inclusive: true, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - nonnegative(message?: errorUtil.ErrMessage) { + nonnegative(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: BigInt(0), inclusive: true, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - multipleOf(value: bigint, message?: errorUtil.ErrMessage) { + multipleOf(value: bigint, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'multipleOf', value, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } diff --git a/packages/zui/src/z/types/branded/branded.test.ts b/packages/zui/src/z/types/branded/branded.test.ts index ff13bd38144..048e05ff088 100644 --- a/packages/zui/src/z/types/branded/branded.test.ts +++ b/packages/zui/src/z/types/branded/branded.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' test('branded types', () => { const mySchema = z @@ -11,7 +11,7 @@ test('branded types', () => { // simple branding type MySchema = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) const doStuff = (arg: MySchema) => arg doStuff(mySchema.parse({ name: 'hello there' })) @@ -19,14 +19,14 @@ test('branded types', () => { // inheritance const extendedSchema = mySchema.brand<'subschema'>() type ExtendedSchema = z.infer - util.assertEqual & z.BRAND<'subschema'>>(true) + utils.assert.assertEqual & z.BRAND<'subschema'>>(true) doStuff(extendedSchema.parse({ name: 'hello again' })) // number branding const numberSchema = z.number().brand<42>() type NumberSchema = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) // symbol branding const MyBrand: unique symbol = Symbol('hello') @@ -34,7 +34,7 @@ test('branded types', () => { const symbolBrand = z.number().brand<'sup'>().brand() type SymbolBrand = z.infer // number & { [z.BRAND]: { sup: true, [MyBrand]: true } } - util.assertEqual & z.BRAND>(true) + utils.assert.assertEqual & z.BRAND>(true) // keeping brands out of input types const age = z.number().brand<'age'>() @@ -42,9 +42,9 @@ test('branded types', () => { type Age = z.infer type AgeInput = z.input - util.assertEqual(false) - util.assertEqual(true) - util.assertEqual, Age>(true) + utils.assert.assertEqual(false) + utils.assert.assertEqual(true) + utils.assert.assertEqual, Age>(true) // @ts-expect-error doStuff({ name: 'hello there!' }) diff --git a/packages/zui/src/z/types/catch/catch.test.ts b/packages/zui/src/z/types/catch/catch.test.ts index 4675c4442c3..f5e8d6b9a98 100644 --- a/packages/zui/src/z/types/catch/catch.test.ts +++ b/packages/zui/src/z/types/catch/catch.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import { z } from '../..' -import { util } from '../utils' +import * as utils from '../../utils' test('basic catch', () => { expect(z.string().catch('default').parse(undefined)).toBe('default') @@ -43,9 +43,9 @@ test('catch with transform', () => { expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema) type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('catch on existing optional', () => { @@ -57,18 +57,18 @@ test('catch on existing optional', () => { expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString) type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('optional on catch', () => { const stringWithDefault = z.string().catch('asdf').optional() type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('complex chain example', () => { @@ -91,7 +91,7 @@ test('removeCatch', () => { const stringWithRemovedDefault = z.string().catch('asdf').removeCatch() type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('nested', () => { @@ -100,9 +100,9 @@ test('nested', () => { inner: 'asdf', }) type input = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) expect(outer.parse(undefined)).toEqual({ inner: 'asdf' }) expect(outer.parse({})).toEqual({ inner: 'asdf' }) expect(outer.parse({ inner: undefined })).toEqual({ inner: 'asdf' }) diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index 696ec3c5c5e..bd2b7681d55 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -1,4 +1,5 @@ import { ZodError } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, @@ -8,7 +9,6 @@ import { ParseContext, ParseInput, ParseReturnType, - util, } from '../index' export type CatchFn = (ctx: { error: ZodError; input: unknown }) => Y @@ -96,7 +96,7 @@ export class ZodCatch extends ZodType< if (!(schema instanceof ZodCatch)) return false return ( this._def.innerType.isEqual(schema._def.innerType) && - util.compareFunctions(this._def.catchValue, schema._def.catchValue) + utils.others.compareFunctions(this._def.catchValue, schema._def.catchValue) ) } diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index e6fccb836f6..458ceac583d 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,9 +1,8 @@ import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { processCreateParams, - util, ZodParsedType, - errorUtil, ZodTypeDef, addIssueToContext, INVALID, @@ -14,7 +13,6 @@ import { ZodType, RawCreateParams, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ZodDateCheck = | { kind: 'min'; value: number; message?: string } @@ -81,7 +79,7 @@ export class ZodDate extends ZodType { status.dirty() } } else { - util.assertNever(check) + utils.assert.assertNever(check) } } @@ -98,19 +96,19 @@ export class ZodDate extends ZodType { }) } - min(minDate: Date, message?: errorUtil.ErrMessage) { + min(minDate: Date, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: minDate.getTime(), - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - max(maxDate: Date, message?: errorUtil.ErrMessage) { + max(maxDate: Date, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: maxDate.getTime(), - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } @@ -147,8 +145,8 @@ export class ZodDate extends ZodType { isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodDate)) return false - const thisChecks = new CustomSet(this._def.checks) - const thatChecks = new CustomSet(schema._def.checks) + const thisChecks = new utils.ds.CustomSet(this._def.checks) + const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) && this._def.coerce === schema._def.coerce } } diff --git a/packages/zui/src/z/types/default/default.test.ts b/packages/zui/src/z/types/default/default.test.ts index 1e375f815f0..972b36081b9 100644 --- a/packages/zui/src/z/types/default/default.test.ts +++ b/packages/zui/src/z/types/default/default.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import { z } from '../..' -import { util } from '../utils' +import * as utils from '../../utils' test('basic defaults', () => { expect(z.string().default('default').parse(undefined)).toBe('default') @@ -17,9 +17,9 @@ test('default with transform', () => { expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema) type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('default on existing optional', () => { @@ -30,18 +30,18 @@ test('default on existing optional', () => { expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString) type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('optional on default', () => { const stringWithDefault = z.string().default('asdf').optional() type inp = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('complex chain example', () => { @@ -61,7 +61,7 @@ test('removeDefault', () => { const stringWithRemovedDefault = z.string().default('asdf').removeDefault() type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('nested', () => { @@ -70,9 +70,9 @@ test('nested', () => { inner: undefined, }) type input = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type out = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) expect(outer.parse(undefined)).toEqual({ inner: 'asdf' }) expect(outer.parse({})).toEqual({ inner: 'asdf' }) expect(outer.parse({ inner: undefined })).toEqual({ inner: 'asdf' }) diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 8a2abba7cb2..f5af0d10243 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -1,11 +1,11 @@ import { isEqual } from 'lodash-es' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - util, ZodParsedType, ParseInput, ParseReturnType, @@ -13,12 +13,12 @@ import { export type ZodDefaultDef = { innerType: T - defaultValue: () => util.noUndefined + defaultValue: () => utils.types.NoUndefined typeName: 'ZodDefault' } & ZodTypeDef export class ZodDefault extends ZodType< - util.noUndefined, + utils.types.NoUndefined, ZodDefaultDef, T['_input'] | undefined > { @@ -59,7 +59,7 @@ export class ZodDefault extends ZodType< static create = ( type: T, - value: T['_input'] | (() => util.noUndefined), + value: T['_input'] | (() => utils.types.NoUndefined), params?: RawCreateParams ): ZodDefault => { return new ZodDefault({ diff --git a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts index 36b0207c31b..7034e72bce2 100644 --- a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts +++ b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts @@ -1,5 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' +import * as utils from '../../utils' test('valid', () => { expect( @@ -281,7 +282,7 @@ test('optional and nullable', () => { ]) type schema = z.infer - z.util.assertEqual(true) + utils.assert.assertEqual(true) schema.parse({ key: 'a', a: true }) schema.parse({ key: undefined, a: true }) diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index bb0937d530c..ec8dc2dfcc4 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,5 +1,5 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { ZodBranded, ZodCatch, @@ -23,17 +23,14 @@ import { ZodEffects, ZodUndefined, processCreateParams, - util, ZodParsedType, addIssueToContext, INVALID, ParseInput, ParseReturnType, - Primitive, } from '../index' -import { CustomSet } from '../utils/custom-set' -const getDiscriminator = (type: T): Primitive[] => { +const getDiscriminator = (type: T): utils.types.Primitive[] => { if (type instanceof ZodLazy) { return getDiscriminator(type.schema) } else if (type instanceof ZodEffects) { @@ -43,7 +40,7 @@ const getDiscriminator = (type: T): Primitive[] => { } else if (type instanceof ZodEnum) { return type.options } else if (type instanceof ZodNativeEnum) { - return util.objectValues(type.enum) + return Object.values(type.enum) } else if (type instanceof ZodDefault) { return getDiscriminator(type._def.innerType) } else if (type instanceof ZodUndefined) { @@ -78,7 +75,7 @@ export type ZodDiscriminatedUnionDef< > = { discriminator: Discriminator options: Options - optionsMap: Map> + optionsMap: Map> typeName: 'ZodDiscriminatedUnion' } & ZodTypeDef @@ -102,7 +99,7 @@ export class ZodDiscriminatedUnion< } getReferences(): string[] { - return unique(this.options.flatMap((option) => option.getReferences())) + return utils.fn.unique(this.options.flatMap((option) => option.getReferences())) } clone(): ZodDiscriminatedUnion { @@ -204,7 +201,7 @@ export class ZodDiscriminatedUnion< Types extends [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], >(discriminator: Discriminator, options: Types) { // Get all the valid discriminator values - const optionsMap: Map = new Map() + const optionsMap: Map = new Map() // try { for (const type of options) { @@ -231,8 +228,8 @@ export class ZodDiscriminatedUnion< if (this._def.discriminator !== schema._def.discriminator) return false const compare = (a: ZodObject, b: ZodObject) => a.isEqual(b) - const thisOptions = new CustomSet(this._def.options, { compare }) - const thatOptions = new CustomSet(schema._def.options, { compare }) + const thisOptions = new utils.ds.CustomSet(this._def.options, { compare }) + const thatOptions = new utils.ds.CustomSet(schema._def.options, { compare }) // no need to compare optionsMap, as it is derived from discriminator + options diff --git a/packages/zui/src/z/types/enum/enum.test.ts b/packages/zui/src/z/types/enum/enum.test.ts index 97795ec8979..121fa5119b3 100644 --- a/packages/zui/src/z/types/enum/enum.test.ts +++ b/packages/zui/src/z/types/enum/enum.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' test('create enum', () => { @@ -12,7 +12,7 @@ test('create enum', () => { test('infer enum', () => { const MyEnum = z.enum(['Red', 'Green', 'Blue']) type MyEnum = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('get options', () => { @@ -23,7 +23,7 @@ test('readonly enum', () => { const HTTP_SUCCESS = ['200', '201'] as const const arg = z.enum(HTTP_SUCCESS) type arg = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) arg.parse('201') expect(() => arg.parse('202')).toThrow() @@ -44,11 +44,11 @@ test('extract/exclude', () => { const UnhealthyEnum = FoodEnum.exclude(['Salad']) const EmptyFoodEnum = FoodEnum.exclude(foods) - util.assertEqual, 'Pasta' | 'Pizza'>(true) - util.assertEqual, 'Pasta' | 'Pizza' | 'Tacos' | 'Burgers'>(true) + utils.assert.assertEqual, 'Pasta' | 'Pizza'>(true) + utils.assert.assertEqual, 'Pasta' | 'Pizza' | 'Tacos' | 'Burgers'>(true) // @ts-expect-error TS2344 - util.assertEqual>(true) - util.assertEqual, never>(true) + utils.assert.assertEqual>(true) + utils.assert.assertEqual, never>(true) }) test('error map in extract/exclude', () => { diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index 79954ec1785..c8acaaf65ff 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,17 +1,16 @@ import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - util, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ArrayKeys = keyof any[] export type Indices = Exclude @@ -63,7 +62,7 @@ export class ZodEnum ex const ctx = this._getOrReturnCtx(input) const expectedValues = this._def.values addIssueToContext(ctx, { - expected: util.joinValues(expectedValues) as 'string', + expected: utils.others.joinValues(expectedValues) as 'string', received: ctx.parsedType, code: ZodIssueCode.invalid_type, }) @@ -136,8 +135,8 @@ export class ZodEnum ex isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodEnum)) return false - const thisValues = new CustomSet(this._def.values) - const thatValues = new CustomSet(schema._def.values) + const thisValues = new utils.ds.CustomSet(this._def.values) + const thatValues = new utils.ds.CustomSet(schema._def.values) return thisValues.isEqual(thatValues) } } diff --git a/packages/zui/src/z/types/function/function.test.ts b/packages/zui/src/z/types/function/function.test.ts index b343be8fe02..9e6215692d9 100644 --- a/packages/zui/src/z/types/function/function.test.ts +++ b/packages/zui/src/z/types/function/function.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' const args1 = z.tuple([z.string()]) const returns1 = z.number() @@ -23,7 +23,7 @@ test('parsed function fail 2', () => { test('function inference 1', () => { type func1 = z.TypeOf - util.assertEqual number>(true) + utils.assert.assertEqual number>(true) }) test('method parsing', () => { @@ -59,15 +59,15 @@ test('async method parsing', async () => { test('args method', () => { const t1 = z.function() type t1 = z.infer - util.assertEqual unknown>(true) + utils.assert.assertEqual unknown>(true) const t2 = t1.args(z.string()) type t2 = z.infer - util.assertEqual unknown>(true) + utils.assert.assertEqual unknown>(true) const t3 = t2.returns(z.boolean()) type t3 = z.infer - util.assertEqual boolean>(true) + utils.assert.assertEqual boolean>(true) }) const args2 = z.tuple([ @@ -83,7 +83,7 @@ const func2 = z.function(args2, returns2) test('function inference 2', () => { type func2 = z.TypeOf - util.assertEqual< + utils.assert.assertEqual< func2, (arg: { f1: number; f2: string | null; f3?: (boolean | undefined)[] | undefined }) => string | number >(true) @@ -234,7 +234,7 @@ test('inference with transforms', () => { }) myFunc('asdf') - util.assertEqual { val: number; extra: string }>(true) + utils.assert.assertEqual { val: number; extra: string }>(true) }) test('fallback to OuterTypeOfFunction', () => { @@ -247,5 +247,5 @@ test('fallback to OuterTypeOfFunction', () => { return { arg: val, arg2: false } }) - util.assertEqual number>(true) + utils.assert.assertEqual number>(true) }) diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index dabd560b807..b4f63cf1ade 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,5 +1,5 @@ import { defaultErrorMap, getErrorMap, ZodError, ZodErrorMap, ZodIssue, ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { RawCreateParams, ZodType, @@ -46,7 +46,7 @@ export class ZodFunction = ZodTuple, Returns ext } getReferences(): string[] { - return unique([...this._def.args.getReferences(), ...this._def.returns.getReferences()]) + return utils.fn.unique([...this._def.args.getReferences(), ...this._def.returns.getReferences()]) } clone(): ZodFunction { diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index c8479559a2a..b2762b9b307 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -9,9 +9,8 @@ export * from './native' export * from './utils' export * from './utils/parseUtil' export * from './utils/enumUtil' -export * from './utils/errorUtil' export * from './utils/partialUtil' -export * from './utils/typeAliases' +export * from './utils/objectUtil' export * from './any' export * from './array' export * from './bigint' diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index a7d552805f0..430ed3b4143 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -1,12 +1,11 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, getParsedType, processCreateParams, - util, ZodParsedType, addIssueToContext, INVALID, @@ -16,7 +15,6 @@ import { ParseReturnType, SyncParseReturnType, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ZodIntersectionDef = { left: T @@ -31,8 +29,8 @@ function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: fals if (a === b) { return { valid: true, data: a } } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { - const bKeys = util.objectKeys(b) - const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1) + const bKeys = Object.keys(b) + const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1) const newObj: any = { ...a, ...b } for (const key of sharedKeys) { @@ -84,7 +82,7 @@ export class ZodIntersection { @@ -167,8 +165,8 @@ export class ZodIntersection a.isEqual(b) - const thisItems = new CustomSet([this._def.left, this._def.right], { compare }) - const thatItems = new CustomSet([schema._def.left, schema._def.right], { compare }) + const thisItems = new utils.ds.CustomSet([this._def.left, this._def.right], { compare }) + const thatItems = new utils.ds.CustomSet([schema._def.left, schema._def.right], { compare }) return thisItems.isEqual(thatItems) } } diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index 378c0556595..958ffc788b0 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' - import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, @@ -10,15 +10,14 @@ import { INVALID, ParseInput, ParseReturnType, - Primitive, } from '../index' -export type ZodLiteralDef = { +export type ZodLiteralDef = { value: T typeName: 'ZodLiteral' } & ZodTypeDef -export class ZodLiteral extends ZodType> { +export class ZodLiteral extends ZodType> { _parse(input: ParseInput): ParseReturnType { if (input.data !== this._def.value) { const ctx = this._getOrReturnCtx(input) @@ -36,7 +35,7 @@ export class ZodLiteral extends ZodType(value: T, params?: RawCreateParams): ZodLiteral => { + static create = (value: T, params?: RawCreateParams): ZodLiteral => { return new ZodLiteral({ value, typeName: 'ZodLiteral', diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index dc7709130ed..d4f6869d880 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -1,5 +1,5 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { ParseInputLazyPath, RawCreateParams, @@ -43,7 +43,7 @@ export class ZodMap { diff --git a/packages/zui/src/z/types/map/map.test.ts b/packages/zui/src/z/types/map/map.test.ts index a7cafc4b997..f73043fb6c1 100644 --- a/packages/zui/src/z/types/map/map.test.ts +++ b/packages/zui/src/z/types/map/map.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' import { ZodIssueCode } from '../../index' @@ -7,7 +7,7 @@ const stringMap = z.map(z.string(), z.string()) type stringMap = z.infer test('type inference', () => { - util.assertEqual>(true) + utils.assert.assertEqual>(true) }) test('valid parse', () => { diff --git a/packages/zui/src/z/types/native.test.ts b/packages/zui/src/z/types/native.test.ts index 85fe4f4172a..58338e778dd 100644 --- a/packages/zui/src/z/types/native.test.ts +++ b/packages/zui/src/z/types/native.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import * as z from '../index' -import { util } from './utils' +import * as utils from '../utils' test('first party switch', () => { const myType = z.ZodString.create() as z.ZodNativeSchema @@ -118,6 +118,6 @@ test('first party switch', () => { myType satisfies z.ZodReadonly break default: - util.assertNever(myType) + utils.assert.assertNever(myType) } }) diff --git a/packages/zui/src/z/types/native.ts b/packages/zui/src/z/types/native.ts index 77eb1bbcd2b..033848829df 100644 --- a/packages/zui/src/z/types/native.ts +++ b/packages/zui/src/z/types/native.ts @@ -36,7 +36,7 @@ import { ZodUnion, ZodUnknown, ZodVoid, -} from '.' +} from './index' /** * @deprecated - use ZodNativeSchema instead diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index d77a9214e63..66138bad1ef 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,12 +1,11 @@ import { isEqual } from 'lodash-es' - import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - util, ZodParsedType, addIssueToContext, INVALID, @@ -24,13 +23,13 @@ export type EnumLike = { [k: string]: string | number; [nu: number]: string } export class ZodNativeEnum extends ZodType> { _parse(input: ParseInput): ParseReturnType { - const nativeEnumValues = util.getValidEnumValues(this._def.values) + const nativeEnumValues = this._getValidEnumValues(this._def.values) const ctx = this._getOrReturnCtx(input) if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) { - const expectedValues = util.objectValues(nativeEnumValues) + const expectedValues = Object.values(nativeEnumValues) addIssueToContext(ctx, { - expected: util.joinValues(expectedValues) as 'string', + expected: utils.others.joinValues(expectedValues) as 'string', received: ctx.parsedType, code: ZodIssueCode.invalid_type, }) @@ -38,7 +37,7 @@ export class ZodNativeEnum extends ZodType extends ZodType { + const validKeys = Object.keys(obj).filter((k: any) => typeof obj[obj[k]!] !== 'number') + const filtered: EnumLike = {} + for (const k of validKeys) { + filtered[k] = obj[k]! + } + return Object.values(filtered) + } } diff --git a/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts b/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts index 16eb029699d..bb5faab695d 100644 --- a/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts +++ b/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' test('nativeEnum test with consts', () => { @@ -13,7 +13,7 @@ test('nativeEnum test with consts', () => { fruitEnum.parse('banana') fruitEnum.parse(Fruits.Apple) fruitEnum.parse(Fruits.Banana) - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('nativeEnum test with real enum', () => { @@ -28,7 +28,7 @@ test('nativeEnum test with real enum', () => { fruitEnum.parse('banana') fruitEnum.parse(Fruits.Apple) fruitEnum.parse(Fruits.Banana) - util.assertIs(true) + utils.assert.assertIs(true) }) test('nativeEnum test with const with numeric keys', () => { @@ -43,7 +43,7 @@ test('nativeEnum test with const with numeric keys', () => { fruitEnum.parse(20) fruitEnum.parse(FruitValues.Apple) fruitEnum.parse(FruitValues.Banana) - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('from enum', () => { diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 604235c0637..0ae27b3c951 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,12 +1,11 @@ import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - util, ZodParsedType, - errorUtil, addIssueToContext, INVALID, ParseContext, @@ -14,7 +13,6 @@ import { ParseReturnType, ParseStatus, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ZodNumberCheck = | { kind: 'min'; value: number; inclusive: boolean; message?: string } @@ -59,7 +57,7 @@ export class ZodNumber extends ZodType { for (const check of this._def.checks) { if (check.kind === 'int') { - if (!util.isInteger(input.data)) { + if (!Number.isInteger(input.data)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, @@ -117,7 +115,7 @@ export class ZodNumber extends ZodType { status.dirty() } } else { - util.assertNever(check) + utils.assert.assertNever(check) } } @@ -133,22 +131,22 @@ export class ZodNumber extends ZodType { }) } - gte(value: number, message?: errorUtil.ErrMessage) { - return this.setLimit('min', value, true, errorUtil.toString(message)) + gte(value: number, message?: utils.errors.ErrMessage) { + return this.setLimit('min', value, true, utils.errors.toString(message)) } min = this.gte - gt(value: number, message?: errorUtil.ErrMessage) { - return this.setLimit('min', value, false, errorUtil.toString(message)) + gt(value: number, message?: utils.errors.ErrMessage) { + return this.setLimit('min', value, false, utils.errors.toString(message)) } - lte(value: number, message?: errorUtil.ErrMessage) { - return this.setLimit('max', value, true, errorUtil.toString(message)) + lte(value: number, message?: utils.errors.ErrMessage) { + return this.setLimit('max', value, true, utils.errors.toString(message)) } max = this.lte - lt(value: number, message?: errorUtil.ErrMessage) { - return this.setLimit('max', value, false, errorUtil.toString(message)) + lt(value: number, message?: utils.errors.ErrMessage) { + return this.setLimit('max', value, false, utils.errors.toString(message)) } protected setLimit(kind: 'min' | 'max', value: number, inclusive: boolean, message?: string) { @@ -160,7 +158,7 @@ export class ZodNumber extends ZodType { kind, value, inclusive, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }, ], }) @@ -173,76 +171,76 @@ export class ZodNumber extends ZodType { }) } - int(message?: errorUtil.ErrMessage) { + int(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'int', - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - positive(message?: errorUtil.ErrMessage) { + positive(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: 0, inclusive: false, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - negative(message?: errorUtil.ErrMessage) { + negative(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: 0, inclusive: false, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - nonpositive(message?: errorUtil.ErrMessage) { + nonpositive(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: 0, inclusive: true, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - nonnegative(message?: errorUtil.ErrMessage) { + nonnegative(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: 0, inclusive: true, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - multipleOf(value: number, message?: errorUtil.ErrMessage) { + multipleOf(value: number, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'multipleOf', value, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } step = this.multipleOf - finite(message?: errorUtil.ErrMessage) { + finite(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'finite', - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } - safe(message?: errorUtil.ErrMessage) { + safe(message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', inclusive: true, value: Number.MIN_SAFE_INTEGER, - message: errorUtil.toString(message), + message: utils.errors.toString(message), })._addCheck({ kind: 'max', inclusive: true, value: Number.MAX_SAFE_INTEGER, - message: errorUtil.toString(message), + message: utils.errors.toString(message), }) } @@ -267,7 +265,9 @@ export class ZodNumber extends ZodType { } get isInt() { - return !!this._def.checks.find((ch) => ch.kind === 'int' || (ch.kind === 'multipleOf' && util.isInteger(ch.value))) + return !!this._def.checks.find( + (ch) => ch.kind === 'int' || (ch.kind === 'multipleOf' && Number.isInteger(ch.value)) + ) } get isFinite() { @@ -287,8 +287,8 @@ export class ZodNumber extends ZodType { isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodNumber)) return false - const thisChecks = new CustomSet(this._def.checks) - const thatChecks = new CustomSet(schema._def.checks) + const thisChecks = new utils.ds.CustomSet(this._def.checks) + const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) } } diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 90041558a52..5ba020667f7 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,5 +1,5 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { ZodArray, ZodEnum, @@ -12,7 +12,6 @@ import { ParseInput, ParseReturnType, ParseStatus, - util, ZodParsedType, ParseInputLazyPath, RawCreateParams, @@ -21,13 +20,11 @@ import { ZodTypeDef, processCreateParams, enumUtil, - errorUtil, partialUtil, createZodEnum, ZodNever, ZodAny, } from '../index' -import { CustomSet } from '../utils/custom-set' export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodType @@ -129,7 +126,7 @@ export class ZodObject< _getCached(): { shape: T; keys: string[] } { if (this._cached !== null) return this._cached const shape = this._def.shape() - const keys = util.objectKeys(shape) + const keys = Object.keys(shape) return (this._cached = { shape, keys }) } @@ -151,7 +148,7 @@ export class ZodObject< for (const key in shape) { refs.push(...shape[key]!.getReferences()) } - return unique(refs) + return utils.fn.unique(refs) } clone(): ZodObject { @@ -263,8 +260,8 @@ export class ZodObject< return this._def.shape() } - strict(message?: errorUtil.ErrMessage): ZodObject { - errorUtil.errToObj + strict(message?: utils.errors.ErrMessage): ZodObject { + utils.errors.errToObj return new ZodObject({ ...this._def, unknownKeys: 'strict', @@ -274,7 +271,7 @@ export class ZodObject< const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError if (issue.code === 'unrecognized_keys') { return { - message: errorUtil.errToObj(message).message ?? defaultError, + message: utils.errors.errToObj(message).message ?? defaultError, } } return { @@ -492,7 +489,7 @@ export class ZodObject< >(mask: Mask): ZodObject>, UnknownKeys> { const shape: any = {} - util.objectKeys(mask).forEach((key) => { + Object.keys(mask).forEach((key) => { if (mask[key] && this.shape[key]) { shape[key] = this.shape[key] } @@ -511,7 +508,7 @@ export class ZodObject< >(mask: Mask): ZodObject, UnknownKeys> { const shape: any = {} - util.objectKeys(this.shape).forEach((key) => { + Object.keys(this.shape).forEach((key) => { if (!mask[key]) { shape[key] = this.shape[key] } @@ -551,7 +548,7 @@ export class ZodObject< partial(mask?: any) { const newShape: Record = {} - util.objectKeys(this.shape).forEach((key) => { + Object.keys(this.shape).forEach((key) => { const fieldSchema = this.shape[key] if (mask && !mask[key]) { @@ -588,7 +585,7 @@ export class ZodObject< required(mask?: any) { const newShape: any = {} - util.objectKeys(this.shape).forEach((key) => { + Object.keys(this.shape).forEach((key) => { if (mask && !mask[key]) { newShape[key] = this.shape[key] } else { @@ -610,7 +607,7 @@ export class ZodObject< } keyof(): ZodEnum> { - return createZodEnum(util.objectKeys(this.shape) as [string, ...string[]]) as any + return createZodEnum(Object.keys(this.shape) as [string, ...string[]]) as any } isEqual(schema: ZodType): boolean { @@ -622,8 +619,8 @@ export class ZodObject< type Property = [string, ZodType] const compare = (a: Property, b: Property) => a[0] === b[0] && a[1].isEqual(b[1]) - const thisProps = new CustomSet(Object.entries(thisShape), { compare }) - const thatProps = new CustomSet(Object.entries(thatShape), { compare }) + const thisProps = new utils.ds.CustomSet(Object.entries(thisShape), { compare }) + const thatProps = new utils.ds.CustomSet(Object.entries(thatShape), { compare }) return thisProps.isEqual(thatProps) } diff --git a/packages/zui/src/z/types/object/object.test.ts b/packages/zui/src/z/types/object/object.test.ts index 7b876e65a66..736ab17e806 100644 --- a/packages/zui/src/z/types/object/object.test.ts +++ b/packages/zui/src/z/types/object/object.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' const Test = z.object({ @@ -18,7 +18,7 @@ test('object type inference', () => { f4: { t: string | boolean }[] } - util.assertEqual, TestType>(true) + utils.assert.assertEqual, TestType>(true) }) test('unknown throw', () => { @@ -124,8 +124,8 @@ test('catchall inference', () => { const prop1 = d1.first const prop2 = d1.num - util.assertEqual(true) - util.assertEqual(true) + utils.assert.assertEqual(true) + utils.assert.assertEqual(true) }) test('catchall overrides strict', () => { @@ -213,7 +213,7 @@ test('test async union', async () => { test('test inferred merged type', async () => { const asdf = z.object({ a: z.string() }).merge(z.object({ a: z.number() })) type asdf = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('inferred merged object type with optional properties', async () => { @@ -221,9 +221,9 @@ test('inferred merged object type with optional properties', async () => { .object({ a: z.string(), b: z.string().optional() }) .merge(z.object({ a: z.string().optional(), b: z.string() })) type Merged = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) // todo - // util.assertEqual(true); + // utils.assert.assertEqual(true); }) test('inferred unioned object type with optional properties', async () => { @@ -232,7 +232,7 @@ test('inferred unioned object type with optional properties', async () => { z.object({ a: z.string().optional(), b: z.string() }), ]) type Unioned = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('inferred enum type', async () => { @@ -248,19 +248,19 @@ test('inferred enum type', async () => { }) expect(Enum._def.values).toEqual(['a', 'b']) type Enum = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('inferred partial object type with optional properties', async () => { const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial() type Partial = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('inferred picked object type with optional properties', async () => { const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true }) type Picked = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('inferred type for unknown/any keys', () => { @@ -271,7 +271,7 @@ test('inferred type for unknown/any keys', () => { unknownRequired: z.unknown(), }) type myType = z.infer - util.assertEqual< + utils.assert.assertEqual< myType, { anyOptional?: any @@ -287,7 +287,7 @@ test('setKey', () => { const withNewKey = base.setKey('age', z.number()) type withNewKey = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) withNewKey.parse({ name: 'asdf', age: 1234 }) }) @@ -347,7 +347,7 @@ test('constructor key', () => { }) type Example = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('unknownkeys merging', () => { @@ -368,7 +368,7 @@ test('unknownkeys merging', () => { const mergedSchema = schemaA.merge(schemaB) type mergedSchema = typeof mergedSchema - util.assertEqual(true) + utils.assert.assertEqual(true) expect(mergedSchema._def.unknownKeys instanceof z.ZodString).toEqual(true) }) @@ -385,8 +385,8 @@ test('extend() should return schema with new key', () => { const actual = PersonWithNickname.parse(expected) expect(actual).toEqual(expected) - util.assertEqual(true) - util.assertEqual(true) + utils.assert.assertEqual(true) + utils.assert.assertEqual(true) }) test('extend() should have power to override existing key', () => { @@ -399,16 +399,16 @@ test('extend() should have power to override existing key', () => { const actual = PersonWithNumberAsLastName.parse(expected) expect(actual).toEqual(expected) - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('passthrough index signature', () => { const a = z.object({ a: z.string() }) type a = z.infer - util.assertEqual<{ a: string }, a>(true) + utils.assert.assertEqual<{ a: string }, a>(true) const b = a.passthrough() type b = z.infer - util.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true) + utils.assert.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true) }) test('xor', () => { diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index 22043b405de..e7c0fa34246 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,4 +1,4 @@ -import { unique } from '../../utils' +import * as utils from '../../utils' import { ZodType, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../index' export type ZodPipelineDef = { @@ -21,7 +21,7 @@ export class ZodPipeline { diff --git a/packages/zui/src/z/types/promise/promise.test.ts b/packages/zui/src/z/types/promise/promise.test.ts index 843d498920c..90779818f10 100644 --- a/packages/zui/src/z/types/promise/promise.test.ts +++ b/packages/zui/src/z/types/promise/promise.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' const promSchema = z.promise( @@ -11,7 +11,7 @@ const promSchema = z.promise( test('promise inference', () => { type promSchemaType = z.infer - util.assertEqual>(true) + utils.assert.assertEqual>(true) }) test('promise parsing success', async () => { diff --git a/packages/zui/src/z/types/readonly/readonly.test.ts b/packages/zui/src/z/types/readonly/readonly.test.ts index 61293008f00..3b0700c1b75 100644 --- a/packages/zui/src/z/types/readonly/readonly.test.ts +++ b/packages/zui/src/z/types/readonly/readonly.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' enum testEnum { @@ -33,89 +33,90 @@ const schemas = [ ] as const test('flat inference', () => { - util.assertEqual, string>(true) - util.assertEqual, number>(true) - util.assertEqual, number>(true) - util.assertEqual, bigint>(true) - util.assertEqual, boolean>(true) - util.assertEqual, Date>(true) - util.assertEqual, undefined>(true) - util.assertEqual, null>(true) - util.assertEqual, any>(true) - util.assertEqual, Readonly>(true) - util.assertEqual, void>(true) - util.assertEqual, (args_0: string, args_1: number, ...args_2: unknown[]) => unknown>( - true - ) - util.assertEqual, readonly string[]>(true) + utils.assert.assertEqual, string>(true) + utils.assert.assertEqual, number>(true) + utils.assert.assertEqual, number>(true) + utils.assert.assertEqual, bigint>(true) + utils.assert.assertEqual, boolean>(true) + utils.assert.assertEqual, Date>(true) + utils.assert.assertEqual, undefined>(true) + utils.assert.assertEqual, null>(true) + utils.assert.assertEqual, any>(true) + utils.assert.assertEqual, Readonly>(true) + utils.assert.assertEqual, void>(true) + utils.assert.assertEqual< + z.infer<(typeof schemas)[11]>, + (args_0: string, args_1: number, ...args_2: unknown[]) => unknown + >(true) + utils.assert.assertEqual, readonly string[]>(true) - util.assertEqual, readonly [string, number]>(true) - util.assertEqual, ReadonlyMap>(true) - util.assertEqual, ReadonlySet>>(true) - util.assertEqual, Readonly>>(true) - util.assertEqual, Readonly>>(true) - util.assertEqual, { readonly a: string; readonly 1: number }>(true) - util.assertEqual, Readonly>(true) - util.assertEqual, Promise>(true) + utils.assert.assertEqual, readonly [string, number]>(true) + utils.assert.assertEqual, ReadonlyMap>(true) + utils.assert.assertEqual, ReadonlySet>>(true) + utils.assert.assertEqual, Readonly>>(true) + utils.assert.assertEqual, Readonly>>(true) + utils.assert.assertEqual, { readonly a: string; readonly 1: number }>(true) + utils.assert.assertEqual, Readonly>(true) + utils.assert.assertEqual, Promise>(true) }) // test("deep inference", () => { -// util.assertEqual, string>(true); -// util.assertEqual, number>(true); -// util.assertEqual, number>(true); -// util.assertEqual, bigint>(true); -// util.assertEqual, boolean>(true); -// util.assertEqual, Date>(true); -// util.assertEqual, undefined>(true); -// util.assertEqual, null>(true); -// util.assertEqual, any>(true); -// util.assertEqual< +// utils.assert.assertEqual, string>(true); +// utils.assert.assertEqual, number>(true); +// utils.assert.assertEqual, number>(true); +// utils.assert.assertEqual, bigint>(true); +// utils.assert.assertEqual, boolean>(true); +// utils.assert.assertEqual, Date>(true); +// utils.assert.assertEqual, undefined>(true); +// utils.assert.assertEqual, null>(true); +// utils.assert.assertEqual, any>(true); +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[9]>, // Readonly // >(true); -// util.assertEqual, void>(true); -// util.assertEqual< +// utils.assert.assertEqual, void>(true); +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[11]>, // (args_0: string, args_1: number, ...args_2: unknown[]) => unknown // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[12]>, // readonly string[] // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[13]>, // readonly [string, number] // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[14]>, // ReadonlyMap // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[15]>, // ReadonlySet> // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[16]>, // Readonly> // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[17]>, // Readonly> // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[18]>, // { readonly a: string; readonly 1: number } // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[19]>, // Readonly // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[20]>, // Promise // >(true); -// util.assertEqual< +// utils.assert.assertEqual< // z.infer, // ReadonlyMap< // ReadonlySet, diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 2157a790896..e6cb98cde09 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,5 +1,5 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { BRAND, ParseInputLazyPath, @@ -57,7 +57,7 @@ export class ZodRecord { diff --git a/packages/zui/src/z/types/record/record.test.ts b/packages/zui/src/z/types/record/record.test.ts index 956ee78a5e9..059522a8afa 100644 --- a/packages/zui/src/z/types/record/record.test.ts +++ b/packages/zui/src/z/types/record/record.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' const booleanRecord = z.record(z.boolean()) @@ -12,11 +12,11 @@ const recordWithLiteralKeys = z.record(z.union([z.literal('Tuna'), z.literal('Sa type recordWithLiteralKeys = z.infer test('type inference', () => { - util.assertEqual>(true) + utils.assert.assertEqual>(true) - util.assertEqual>>(true) + utils.assert.assertEqual>>(true) - util.assertEqual>>(true) + utils.assert.assertEqual>>(true) }) test('methods', () => { diff --git a/packages/zui/src/z/types/ref/ref.test.ts b/packages/zui/src/z/types/ref/ref.test.ts index b4511ffd1f2..cda16de61e4 100644 --- a/packages/zui/src/z/types/ref/ref.test.ts +++ b/packages/zui/src/z/types/ref/ref.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' const T = z.ref('T') @@ -20,5 +20,5 @@ test('type inference', () => { data: NonNullable } type Actual = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index b0a3422e8ae..24084d1f0be 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,4 +1,5 @@ import { ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { ParseInputLazyPath, RawCreateParams, @@ -6,7 +7,6 @@ import { ZodTypeDef, processCreateParams, ZodParsedType, - errorUtil, addIssueToContext, INVALID, ParseInput, @@ -108,25 +108,25 @@ export class ZodSet extends ZodType< } } - min(minSize: number, message?: errorUtil.ErrMessage): this { + min(minSize: number, message?: utils.errors.ErrMessage): this { return new ZodSet({ ...this._def, - minSize: { value: minSize, message: errorUtil.toString(message) }, + minSize: { value: minSize, message: utils.errors.toString(message) }, }) as this } - max(maxSize: number, message?: errorUtil.ErrMessage): this { + max(maxSize: number, message?: utils.errors.ErrMessage): this { return new ZodSet({ ...this._def, - maxSize: { value: maxSize, message: errorUtil.toString(message) }, + maxSize: { value: maxSize, message: utils.errors.toString(message) }, }) as this } - size(size: number, message?: errorUtil.ErrMessage): this { + size(size: number, message?: utils.errors.ErrMessage): this { return this.min(size, message).max(size, message) as this } - nonempty(message?: errorUtil.ErrMessage): ZodSet { + nonempty(message?: utils.errors.ErrMessage): ZodSet { return this.min(1, message) as this } diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index c7548ae494a..3d9ba38f784 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,13 +1,12 @@ import { zuiKey } from '../../../ui/constants' import { StringValidation, ZodIssueCode } from '../../error' +import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - util, ZodParsedType, - errorUtil, addIssueToContext, INVALID, ParseContext, @@ -15,7 +14,6 @@ import { ParseReturnType, ParseStatus, } from '../index' -import { CustomSet } from '../utils/custom-set' import { generateDatetimeRegex } from './datetime' export type IpVersion = 'v4' | 'v6' @@ -304,18 +302,18 @@ export class ZodString extends ZodType { status.dirty() } } else { - util.assertNever(check) + utils.assert.assertNever(check) } } return { status: status.value, value: input.data } } - protected _regex(regex: RegExp, validation: StringValidation, message?: errorUtil.ErrMessage) { + protected _regex(regex: RegExp, validation: StringValidation, message?: utils.errors.ErrMessage) { return this.refinement((data) => regex.test(data), { validation, code: ZodIssueCode.invalid_string, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } @@ -326,30 +324,30 @@ export class ZodString extends ZodType { }) } - email(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'email', ...errorUtil.errToObj(message) }) + email(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'email', ...utils.errors.errToObj(message) }) } - url(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'url', ...errorUtil.errToObj(message) }) + url(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'url', ...utils.errors.errToObj(message) }) } - emoji(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'emoji', ...errorUtil.errToObj(message) }) + emoji(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'emoji', ...utils.errors.errToObj(message) }) } - uuid(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'uuid', ...errorUtil.errToObj(message) }) + uuid(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'uuid', ...utils.errors.errToObj(message) }) } - cuid(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'cuid', ...errorUtil.errToObj(message) }) + cuid(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'cuid', ...utils.errors.errToObj(message) }) } - cuid2(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'cuid2', ...errorUtil.errToObj(message) }) + cuid2(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'cuid2', ...utils.errors.errToObj(message) }) } - ulid(message?: errorUtil.ErrMessage) { - return this._addCheck({ kind: 'ulid', ...errorUtil.errToObj(message) }) + ulid(message?: utils.errors.ErrMessage) { + return this._addCheck({ kind: 'ulid', ...utils.errors.errToObj(message) }) } ip(options?: string | { version?: 'v4' | 'v6'; message?: string }) { - return this._addCheck({ kind: 'ip', ...errorUtil.errToObj(options) }) + return this._addCheck({ kind: 'ip', ...utils.errors.errToObj(options) }) } datetime( @@ -373,15 +371,15 @@ export class ZodString extends ZodType { kind: 'datetime', precision: typeof options?.precision === 'undefined' ? null : options?.precision, offset: options?.offset ?? false, - ...errorUtil.errToObj(options?.message), + ...utils.errors.errToObj(options?.message), }) } - regex(regex: RegExp, message?: errorUtil.ErrMessage) { + regex(regex: RegExp, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'regex', regex, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } @@ -390,47 +388,47 @@ export class ZodString extends ZodType { kind: 'includes', value, position: options?.position, - ...errorUtil.errToObj(options?.message), + ...utils.errors.errToObj(options?.message), }) } - startsWith(value: string, message?: errorUtil.ErrMessage) { + startsWith(value: string, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'startsWith', value, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } - endsWith(value: string, message?: errorUtil.ErrMessage) { + endsWith(value: string, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'endsWith', value, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } - min(minLength: number, message?: errorUtil.ErrMessage) { + min(minLength: number, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'min', value: minLength, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } - max(maxLength: number, message?: errorUtil.ErrMessage) { + max(maxLength: number, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'max', value: maxLength, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } - length(len: number, message?: errorUtil.ErrMessage) { + length(len: number, message?: utils.errors.ErrMessage) { return this._addCheck({ kind: 'length', value: len, - ...errorUtil.errToObj(message), + ...utils.errors.errToObj(message), }) } @@ -438,8 +436,8 @@ export class ZodString extends ZodType { * @deprecated Use z.string().min(1) instead. * @see {@link ZodString.min} */ - nonempty(message?: errorUtil.ErrMessage) { - return this.min(1, errorUtil.errToObj(message)) + nonempty(message?: utils.errors.ErrMessage) { + return this.min(1, utils.errors.errToObj(message)) } trim() { @@ -527,8 +525,8 @@ export class ZodString extends ZodType { isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodString)) return false - const thisChecks = new CustomSet(this._def.checks) - const thatChecks = new CustomSet(schema._def.checks) + const thisChecks = new utils.ds.CustomSet(this._def.checks) + const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) } } diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 73598b9aa60..9da70b9e4f9 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -1,4 +1,5 @@ import { IssueData } from '../../error' +import * as utils from '../../utils' import { input, output, @@ -7,7 +8,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - util, addIssueToContext, DIRTY, INVALID, @@ -192,7 +192,7 @@ export class ZodEffects, Input = } } - util.assertNever(effect) + utils.assert.assertNever(effect) } static create = ( @@ -227,20 +227,20 @@ export class ZodEffects, Input = if (this._def.effect.type === 'refinement') { if (schema._def.effect.type !== 'refinement') return false - return util.compareFunctions(this._def.effect.refinement, schema._def.effect.refinement) + return utils.others.compareFunctions(this._def.effect.refinement, schema._def.effect.refinement) } if (this._def.effect.type === 'transform') { if (schema._def.effect.type !== 'transform') return false - return util.compareFunctions(this._def.effect.transform, schema._def.effect.transform) + return utils.others.compareFunctions(this._def.effect.transform, schema._def.effect.transform) } if (this._def.effect.type === 'preprocess') { if (schema._def.effect.type !== 'preprocess') return false - return util.compareFunctions(this._def.effect.transform, schema._def.effect.transform) + return utils.others.compareFunctions(this._def.effect.transform, schema._def.effect.transform) } - type _assertion = util.AssertNever + type _assertion = utils.assert.AssertNever return false } diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index a354737b1fb..c4d9fa0f1d0 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' const stringToNumber = z.string().transform((arg) => parseFloat(arg)) @@ -83,7 +83,7 @@ test('z.NEVER in transform', () => { return val }) type foo = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) const arg = foo.safeParse(undefined) if (!arg.success) { expect(arg.error.issues[0]?.message).toEqual('bad') @@ -175,8 +175,8 @@ test('object typing', () => { type t1 = z.input type t2 = z.output - util.assertEqual(true) - util.assertEqual(true) + utils.assert.assertEqual(true) + utils.assert.assertEqual(true) }) test('transform method overloads', () => { diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 06a02aa8327..86562e4882e 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -1,5 +1,5 @@ import { ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { ParseInputLazyPath, RawCreateParams, @@ -14,7 +14,6 @@ import { ParseStatus, SyncParseReturnType, } from '../index' -import { CustomSet } from '../utils/custom-set' export type ZodTupleItems = [ZodType, ...ZodType[]] export type AssertArray = T extends any[] ? T : never @@ -56,7 +55,7 @@ export class ZodTuple< } getReferences(): string[] { - return unique([ + return utils.fn.unique([ ...this._def.items.flatMap((item) => item.getReferences()), ...(this._def.rest ? this._def.rest.getReferences() : []), ]) @@ -153,8 +152,8 @@ export class ZodTuple< if (!this._restEquals(schema)) return false const compare = (a: ZodType, b: ZodType) => a.isEqual(b) - const thisItems = new CustomSet(this._def.items, { compare }) - const schemaItems = new CustomSet(schema._def.items, { compare }) + const thisItems = new utils.ds.CustomSet(this._def.items, { compare }) + const schemaItems = new utils.ds.CustomSet(schema._def.items, { compare }) return thisItems.isEqual(schemaItems) } diff --git a/packages/zui/src/z/types/tuple/tuple.test.ts b/packages/zui/src/z/types/tuple/tuple.test.ts index 61beba1584c..f2fdc5e0432 100644 --- a/packages/zui/src/z/types/tuple/tuple.test.ts +++ b/packages/zui/src/z/types/tuple/tuple.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { util } from '../utils' +import * as utils from '../../utils' import * as z from '../../index' import { ZodError } from '../../error' @@ -12,7 +12,7 @@ test('tuple inference', () => { const returns1 = z.number() const func1 = z.function(args1, returns1) type func1 = z.TypeOf - util.assertEqual number>(true) + utils.assert.assertEqual number>(true) }) test('successful validation', () => { @@ -58,9 +58,9 @@ test('tuple with transformers', () => { const val = z.tuple([stringToNumber]) type t1 = z.input - util.assertEqual(true) + utils.assert.assertEqual(true) type t2 = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) expect(val.parse(['1234'])).toEqual([4]) }) @@ -73,7 +73,7 @@ test('tuple with rest schema', () => { expect(() => myTuple.parse(['asdf', 1234, 'asdf'])).toThrow() type t1 = z.output - util.assertEqual(true) + utils.assert.assertEqual(true) }) test('parse should fail given sparse array as tuple', () => { diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index af9e847812d..f91727a7674 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,5 +1,5 @@ import { ZodError, ZodIssue, ZodIssueCode } from '../../error' -import { unique } from '../../utils' +import * as utils from '../../utils' import { RawCreateParams, ZodType, @@ -15,7 +15,6 @@ import { ZodUndefined, ZodNever, } from '../index' -import { CustomSet } from '../utils/custom-set' type DefaultZodUnionOptions = Readonly<[ZodType, ZodType, ...ZodType[]]> export type ZodUnionOptions = Readonly<[ZodType, ...ZodType[]]> @@ -38,7 +37,7 @@ export class ZodUnion extend } getReferences(): string[] { - return unique( + return utils.fn.unique( this._def.options.reduce((acc, option) => { return [...acc, ...option.getReferences()] }, []) @@ -167,8 +166,8 @@ export class ZodUnion extend if (!(schema instanceof ZodUnion)) return false const compare = (a: ZodType, b: ZodType) => a.isEqual(b) - const thisOptions = new CustomSet([...this._def.options], { compare }) - const thatOptions = new CustomSet([...schema._def.options], { compare }) + const thisOptions = new utils.ds.CustomSet([...this._def.options], { compare }) + const thatOptions = new utils.ds.CustomSet([...schema._def.options], { compare }) return thisOptions.isEqual(thatOptions) } diff --git a/packages/zui/src/z/types/utils/errorUtil.ts b/packages/zui/src/z/types/utils/errorUtil.ts deleted file mode 100644 index bf74e54891a..00000000000 --- a/packages/zui/src/z/types/utils/errorUtil.ts +++ /dev/null @@ -1,6 +0,0 @@ -export namespace errorUtil { - export type ErrMessage = string | { message?: string } - export const errToObj = (message?: ErrMessage) => (typeof message === 'string' ? { message } : message || {}) - export const toString = (message?: ErrMessage): string | undefined => - typeof message === 'string' ? message : message?.message -} diff --git a/packages/zui/src/z/types/utils/index.ts b/packages/zui/src/z/types/utils/index.ts index 1186d943634..f9ec33c3b1a 100644 --- a/packages/zui/src/z/types/utils/index.ts +++ b/packages/zui/src/z/types/utils/index.ts @@ -2,185 +2,50 @@ import { zuiKey } from '../../../ui/constants' import type { ZodErrorMap } from '../../error' import type { ProcessedCreateParams, RawCreateParams } from '../index' -export namespace util { - export type IsEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false - - export type isAny = 0 extends 1 & T ? true : false - export const assertEqual = (val: IsEqual) => val - export function assertIs(_arg: T): void {} - export function assertNever(_x: never): never { - throw new Error('assertNever called') - } - - export type AssertNever<_T extends never> = true - export type AssertTrue<_T extends true> = true - - export type Omit = Pick> - export type OmitKeys = Pick> - export type MakePartial = Omit & Partial> - export type DeepPartialBoolean = { - [K in keyof T]?: T[K] extends object ? DeepPartialBoolean | boolean : boolean - } - - export const arrayToEnum = (items: U): { [k in U[number]]: k } => { - const obj: { [k in U[number]]?: k } = {} - for (const item of items) { - obj[item] = item - } - return obj as { [k in U[number]]: k } - } - - export const getValidEnumValues = (obj: any) => { - const validKeys = objectKeys(obj).filter((k: any) => typeof obj[obj[k]] !== 'number') - const filtered: any = {} - for (const k of validKeys) { - filtered[k] = obj[k] - } - return objectValues(filtered) - } - - export const objectValues = (obj: any) => { - return objectKeys(obj).map(function (e) { - return obj[e] - }) - } - - export const objectKeys: ObjectConstructor['keys'] = - typeof Object.keys === 'function' - ? (obj: any) => Object.keys(obj) - : (object: any) => { - const keys = [] - for (const key in object) { - if (Object.prototype.hasOwnProperty.call(object, key)) { - keys.push(key) - } - } - return keys - } - - export const find = (arr: T[], checker: (arg: T) => any): T | undefined => { - for (const item of arr) { - if (checker(item)) return item - } - return undefined - } - - export type identity = objectUtil.identity - export type flatten = objectUtil.flatten - - export type noUndefined = T extends undefined ? never : T - - export const isInteger: NumberConstructor['isInteger'] = - typeof Number.isInteger === 'function' - ? (val) => Number.isInteger(val) - : (val) => typeof val === 'number' && isFinite(val) && Math.floor(val) === val - - export function joinValues(array: T, separator = ' | '): string { - return array.map((val) => (typeof val === 'string' ? `'${val}'` : val)).join(separator) - } - - export const jsonStringifyReplacer = (_: string, value: any): any => { - if (typeof value === 'bigint') { - return value.toString() - } - return value - } - - export const compareFunctions = (a: Function, b: Function) => { - /** - * The only proper way to deeply compare functions would be to ensure they return the same value for the same input. - * This is impossible to do unless the domain of the function is known and the function is pure. - * - * Comparing source code is not ideal since 2 function could be equivalent but have different source code, - * but that's our best option. - */ - return a.toString() === b.toString() - } - - export const mock = (): T => ({}) as T - - export type Satisfies = X - - type NormalizeObject = T extends infer O ? { [K in keyof O]: Normalize } : never - export type Normalize = T extends (...args: infer A) => infer R - ? (...args: Normalize) => Normalize - : T extends Array - ? Array> - : T extends ReadonlyArray - ? ReadonlyArray> - : T extends Promise - ? Promise> - : T extends Buffer - ? Buffer - : T extends object - ? NormalizeObject - : T -} - -export namespace objectUtil { - export type MergeShapes = { - [k in Exclude]: U[k] - } & V - - type optionalKeys = { - [k in keyof T]: undefined extends T[k] ? k : never - }[keyof T] - - type requiredKeys = { - [k in keyof T]: undefined extends T[k] ? never : k - }[keyof T] - - export type addQuestionMarks< - T extends object, - R extends keyof T = requiredKeys, - O extends keyof T = optionalKeys, - > = Pick & Partial> & { [k in keyof T]?: unknown } - - export type identity = T - export type flatten = identity<{ [k in keyof T]: T[k] }> - - export type noNeverKeys = { - [k in keyof T]: [T[k]] extends [never] ? never : k - }[keyof T] - - export type noNever = identity<{ - [k in noNeverKeys]: k extends keyof T ? T[k] : never - }> - - export const mergeShapes = (first: U, second: T): T & U => { - return { - ...first, - ...second, // second overwrites first - } - } - - export type extendShape = flatten & B> -} - -export const ZodParsedType = util.arrayToEnum([ - 'string', - 'nan', - 'number', - 'integer', - 'float', - 'boolean', - 'date', - 'bigint', - 'symbol', - 'function', - 'undefined', - 'null', - 'array', - 'object', - 'unknown', - 'promise', - 'void', - 'never', - 'map', - 'set', -]) - -export type ZodParsedType = keyof typeof ZodParsedType +export type ZodParsedType = + | 'string' + | 'nan' + | 'number' + | 'integer' + | 'float' + | 'boolean' + | 'date' + | 'bigint' + | 'symbol' + | 'function' + | 'undefined' + | 'null' + | 'array' + | 'object' + | 'unknown' + | 'promise' + | 'void' + | 'never' + | 'map' + | 'set' + +export const ZodParsedType = { + string: 'string', + nan: 'nan', + number: 'number', + integer: 'integer', + float: 'float', + boolean: 'boolean', + date: 'date', + bigint: 'bigint', + symbol: 'symbol', + function: 'function', + undefined: 'undefined', + null: 'null', + array: 'array', + object: 'object', + unknown: 'unknown', + promise: 'promise', + void: 'void', + never: 'never', + map: 'map', + set: 'set', +} as const satisfies { [k in ZodParsedType]: k } export const getParsedType = (data: any): ZodParsedType => { const t = typeof data diff --git a/packages/zui/src/z/types/utils/objectUtil.ts b/packages/zui/src/z/types/utils/objectUtil.ts new file mode 100644 index 00000000000..a99a0c7b0c3 --- /dev/null +++ b/packages/zui/src/z/types/utils/objectUtil.ts @@ -0,0 +1,39 @@ +export namespace objectUtil { + export type MergeShapes = { + [k in Exclude]: U[k] + } & V + + type optionalKeys = { + [k in keyof T]: undefined extends T[k] ? k : never + }[keyof T] + + type requiredKeys = { + [k in keyof T]: undefined extends T[k] ? never : k + }[keyof T] + + export type addQuestionMarks< + T extends object, + R extends keyof T = requiredKeys, + O extends keyof T = optionalKeys, + > = Pick & Partial> & { [k in keyof T]?: unknown } + + export type identity = T + export type flatten = identity<{ [k in keyof T]: T[k] }> + + export type noNeverKeys = { + [k in keyof T]: [T[k]] extends [never] ? never : k + }[keyof T] + + export type noNever = identity<{ + [k in noNeverKeys]: k extends keyof T ? T[k] : never + }> + + export const mergeShapes = (first: U, second: T): T & U => { + return { + ...first, + ...second, // second overwrites first + } + } + + export type extendShape = flatten & B> +} diff --git a/packages/zui/src/z/types/utils/partialUtil.ts b/packages/zui/src/z/types/utils/partialUtil.ts index 320c7d5f4e8..034f2ded6b7 100644 --- a/packages/zui/src/z/types/utils/partialUtil.ts +++ b/packages/zui/src/z/types/utils/partialUtil.ts @@ -8,6 +8,7 @@ import type { ZodRawShape, ZodType, } from '../index' + export namespace partialUtil { export type DeepPartial = T extends ZodObject diff --git a/packages/zui/src/z/types/utils/typeAliases.ts b/packages/zui/src/z/types/utils/typeAliases.ts deleted file mode 100644 index 1b4dda268a2..00000000000 --- a/packages/zui/src/z/types/utils/typeAliases.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type Primitive = string | number | symbol | bigint | boolean | null | undefined -export type Scalars = Primitive | Primitive[] diff --git a/packages/zui/src/z/types/void/void.test.ts b/packages/zui/src/z/types/void/void.test.ts index 9769f203c9d..1fe884fc0f3 100644 --- a/packages/zui/src/z/types/void/void.test.ts +++ b/packages/zui/src/z/types/void/void.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import { util } from '../utils' +import * as utils from '../../utils' test('void', () => { const v = z.void() @@ -10,5 +10,5 @@ test('void', () => { expect(() => v.parse('')).toThrow() type v = z.infer - util.assertEqual(true) + utils.assert.assertEqual(true) }) diff --git a/packages/zui/src/z/utils.ts b/packages/zui/src/z/utils.ts deleted file mode 100644 index 6765396e448..00000000000 --- a/packages/zui/src/z/utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type ValueOf = T[keyof T] - -export const unique = (arr: T[]): T[] => { - return Array.from(new Set(arr)) -} diff --git a/packages/zui/src/z/utils/assert-utils.ts b/packages/zui/src/z/utils/assert-utils.ts new file mode 100644 index 00000000000..433f45b82b9 --- /dev/null +++ b/packages/zui/src/z/utils/assert-utils.ts @@ -0,0 +1,10 @@ +import { IsEqual } from './type-utils' + +export type AssertNever<_T extends never> = true +export type AssertTrue<_T extends true> = true + +export const assertEqual = (val: IsEqual) => val +export function assertIs(_arg: T): void {} +export function assertNever(_x: never): never { + throw new Error('assertNever called') +} diff --git a/packages/zui/src/z/types/utils/custom-set.test.ts b/packages/zui/src/z/utils/ds-utils.test.ts similarity index 99% rename from packages/zui/src/z/types/utils/custom-set.test.ts rename to packages/zui/src/z/utils/ds-utils.test.ts index 16489fe016c..45821a19796 100644 --- a/packages/zui/src/z/types/utils/custom-set.test.ts +++ b/packages/zui/src/z/utils/ds-utils.test.ts @@ -1,5 +1,5 @@ import { it, expect, describe } from 'vitest' -import { CustomSet } from './custom-set' +import { CustomSet } from './ds-utils' describe.concurrent('CustomSet', () => { describe.concurrent('sets of primitives', () => { diff --git a/packages/zui/src/z/types/utils/custom-set.ts b/packages/zui/src/z/utils/ds-utils.ts similarity index 96% rename from packages/zui/src/z/types/utils/custom-set.ts rename to packages/zui/src/z/utils/ds-utils.ts index 769be1d3a02..040e72541e0 100644 --- a/packages/zui/src/z/types/utils/custom-set.ts +++ b/packages/zui/src/z/utils/ds-utils.ts @@ -1,4 +1,4 @@ -import { isEqual } from './is-equal' +import { isEqual } from './fn-utils' export type CustomSetOptions = { compare: (a: T, b: T) => boolean diff --git a/packages/zui/src/z/utils/error-utils.ts b/packages/zui/src/z/utils/error-utils.ts new file mode 100644 index 00000000000..d1ea3d04e9b --- /dev/null +++ b/packages/zui/src/z/utils/error-utils.ts @@ -0,0 +1,4 @@ +export type ErrMessage = string | { message?: string } +export const errToObj = (message?: ErrMessage) => (typeof message === 'string' ? { message } : message || {}) +export const toString = (message?: ErrMessage): string | undefined => + typeof message === 'string' ? message : message?.message diff --git a/packages/zui/src/z/types/utils/is-equal.test.ts b/packages/zui/src/z/utils/fn-utils.test.ts similarity index 99% rename from packages/zui/src/z/types/utils/is-equal.test.ts rename to packages/zui/src/z/utils/fn-utils.test.ts index 56781af54d1..d06343a52ae 100644 --- a/packages/zui/src/z/types/utils/is-equal.test.ts +++ b/packages/zui/src/z/utils/fn-utils.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import { isEqual } from './is-equal' +import { isEqual } from './fn-utils' import * as lodash from 'lodash-es' describe.concurrent('custom isEqual', () => { diff --git a/packages/zui/src/z/types/utils/is-equal.ts b/packages/zui/src/z/utils/fn-utils.ts similarity index 93% rename from packages/zui/src/z/types/utils/is-equal.ts rename to packages/zui/src/z/utils/fn-utils.ts index 1c5786a41bf..294c64566a7 100644 --- a/packages/zui/src/z/types/utils/is-equal.ts +++ b/packages/zui/src/z/utils/fn-utils.ts @@ -32,3 +32,7 @@ const _customizerWithVisitedTracking = return undefined // Offload to default lodash isEqual comparison } + +export const unique = (arr: T[]): T[] => { + return Array.from(new Set(arr)) +} diff --git a/packages/zui/src/z/utils/index.ts b/packages/zui/src/z/utils/index.ts new file mode 100644 index 00000000000..79ff08327ce --- /dev/null +++ b/packages/zui/src/z/utils/index.ts @@ -0,0 +1,6 @@ +export * as ds from './ds-utils' +export * as errors from './error-utils' +export * as fn from './fn-utils' +export * as types from './type-utils' +export * as assert from './assert-utils' +export * as others from './other-utils' diff --git a/packages/zui/src/z/utils/other-utils.ts b/packages/zui/src/z/utils/other-utils.ts new file mode 100644 index 00000000000..b6824a672a3 --- /dev/null +++ b/packages/zui/src/z/utils/other-utils.ts @@ -0,0 +1,21 @@ +export function joinValues(array: T, separator = ' | '): string { + return array.map((val) => (typeof val === 'string' ? `'${val}'` : val)).join(separator) +} + +export const jsonStringifyReplacer = (_: string, value: any): any => { + if (typeof value === 'bigint') { + return value.toString() + } + return value +} + +export const compareFunctions = (a: Function, b: Function) => { + /** + * The only proper way to deeply compare functions would be to ensure they return the same value for the same input. + * This is impossible to do unless the domain of the function is known and the function is pure. + * + * Comparing source code is not ideal since 2 function could be equivalent but have different source code, + * but that's our best option. + */ + return a.toString() === b.toString() +} diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts new file mode 100644 index 00000000000..ed5573d995f --- /dev/null +++ b/packages/zui/src/z/utils/type-utils.ts @@ -0,0 +1,22 @@ +export type ValueOf = T[keyof T] +export type IsEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false +export type IsAny = 0 extends 1 & T ? true : false +export type NoUndefined = T extends undefined ? never : T +export type Satisfies = X +export type SafeOmit = Omit +export type Primitive = string | number | bigint | boolean | symbol | null | undefined + +type NormalizeObject = T extends infer O ? { [K in keyof O]: Normalize } : never +export type Normalize = T extends (...args: infer A) => infer R + ? (...args: Normalize) => Normalize + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends Promise + ? Promise> + : T extends Buffer + ? Buffer + : T extends object + ? NormalizeObject + : T diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 5831064fb84..69c66b94fb2 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -9,8 +9,6 @@ export * from './types' export * from './error' export * from './types/utils' export * from './types/utils/parseUtil' -export * from './types/utils/typeAliases' - /** * @deprecated - use ZodType instead */ From a46903dad9e2e4f29c6fa6f51408a5358f10119d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 10:06:42 -0500 Subject: [PATCH 10/50] chore(zui): rm enumUtils (#14958) --- packages/zui/src/z/types/index.ts | 1 - packages/zui/src/z/types/object/index.ts | 15 +++++++++++++-- packages/zui/src/z/types/utils/enumUtil.ts | 17 ----------------- packages/zui/src/z/utils/type-utils.ts | 13 +++++++++++++ 4 files changed, 26 insertions(+), 20 deletions(-) delete mode 100644 packages/zui/src/z/types/utils/enumUtil.ts diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index b2762b9b307..02dc55a7868 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -8,7 +8,6 @@ export * from './basetype' export * from './native' export * from './utils' export * from './utils/parseUtil' -export * from './utils/enumUtil' export * from './utils/partialUtil' export * from './utils/objectUtil' export * from './any' diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 5ba020667f7..95ae8872042 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -19,7 +19,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - enumUtil, partialUtil, createZodEnum, ZodNever, @@ -82,11 +81,20 @@ export type AdditionalProperties = T extends ZodType export type deoptional = T extends ZodOptional ? deoptional : T extends ZodNullable ? ZodNullable> : T +/** + * @deprecated use ZodObject instead + */ export type SomeZodObject = ZodObject export type noUnrecognized = { [k in keyof Obj]: k extends keyof Shape ? Obj[k] : never } + +export type KeyOfObject = utils.types.Cast< + utils.types.UnionToTuple, + [string, ...string[]] +> + function deepPartialify(schema: ZodType): any { if (schema instanceof ZodObject) { const newShape: any = {} @@ -606,7 +614,7 @@ export class ZodObject< }) } - keyof(): ZodEnum> { + keyof(): ZodEnum> { return createZodEnum(Object.keys(this.shape) as [string, ...string[]]) as any } @@ -662,4 +670,7 @@ export class ZodObject< } } +/** + * @deprecated use ZodObject instead + */ export type AnyZodObject = ZodObject diff --git a/packages/zui/src/z/types/utils/enumUtil.ts b/packages/zui/src/z/types/utils/enumUtil.ts deleted file mode 100644 index d8a900c5e46..00000000000 --- a/packages/zui/src/z/types/utils/enumUtil.ts +++ /dev/null @@ -1,17 +0,0 @@ -export namespace enumUtil { - type UnionToIntersectionFn = (T extends unknown ? (k: () => T) => void : never) extends ( - k: infer Intersection - ) => void - ? Intersection - : never - - type GetUnionLast = UnionToIntersectionFn extends () => infer Last ? Last : never - - type UnionToTuple = [T] extends [never] - ? Tuple - : UnionToTuple>, [GetUnionLast, ...Tuple]> - - type CastToStringTuple = T extends [string, ...string[]] ? T : never - - export type UnionToTupleString = CastToStringTuple> -} diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts index ed5573d995f..b6ff98457eb 100644 --- a/packages/zui/src/z/utils/type-utils.ts +++ b/packages/zui/src/z/utils/type-utils.ts @@ -5,6 +5,7 @@ export type NoUndefined = T extends undefined ? never : T export type Satisfies = X export type SafeOmit = Omit export type Primitive = string | number | bigint | boolean | symbol | null | undefined +export type Cast = A extends B ? A : B type NormalizeObject = T extends infer O ? { [K in keyof O]: Normalize } : never export type Normalize = T extends (...args: infer A) => infer R @@ -20,3 +21,15 @@ export type Normalize = T extends (...args: infer A) => infer R : T extends object ? NormalizeObject : T + +type _UnionToIntersectionFn = (T extends unknown ? (k: () => T) => void : never) extends ( + k: infer Intersection +) => void + ? Intersection + : never + +type _GetUnionLast = _UnionToIntersectionFn extends () => infer Last ? Last : never + +export type UnionToTuple = [T] extends [never] + ? Tuple + : UnionToTuple>, [_GetUnionLast, ...Tuple]> From 94120b12b1b2ee66f00ebc98d96b89a5566a0404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 10:22:15 -0500 Subject: [PATCH 11/50] chore(zui): rm objectUtils (#14959) --- packages/zui/src/z/types/index.ts | 1 - packages/zui/src/z/types/object/index.ts | 21 +++++------ packages/zui/src/z/types/utils/objectUtil.ts | 39 -------------------- packages/zui/src/z/utils/type-utils.ts | 27 ++++++++++++++ 4 files changed, 37 insertions(+), 51 deletions(-) delete mode 100644 packages/zui/src/z/types/utils/objectUtil.ts diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index 02dc55a7868..d6e970d4c70 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -9,7 +9,6 @@ export * from './native' export * from './utils' export * from './utils/parseUtil' export * from './utils/partialUtil' -export * from './utils/objectUtil' export * from './any' export * from './array' export * from './bigint' diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 95ae8872042..fa481858938 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -8,7 +8,6 @@ import { ZodTuple, addIssueToContext, INVALID, - objectUtil, ParseInput, ParseReturnType, ParseStatus, @@ -43,7 +42,7 @@ export type mergeTypes = { export type objectOutputType< Shape extends ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = UnknownKeysOutputType & objectUtil.flatten>> +> = UnknownKeysOutputType & utils.types.Flatten>> export type baseObjectOutputType = { [k in keyof Shape]: Shape[k]['_output'] @@ -52,9 +51,9 @@ export type baseObjectOutputType = { export type objectInputType< Shape extends ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = objectUtil.flatten> & UnknownKeysInputType +> = utils.types.Flatten> & UnknownKeysInputType -export type baseObjectInputType = objectUtil.addQuestionMarks<{ +export type baseObjectInputType = utils.types.AddQuestionMarks<{ [k in keyof Shape]: Shape[k]['_input'] }> @@ -346,7 +345,7 @@ export class ZodObject< // }; extend( augmentation: Augmentation - ): ZodObject, UnknownKeys> { + ): ZodObject, UnknownKeys> { return new ZodObject({ ...this._def, shape: () => ({ @@ -400,7 +399,7 @@ export class ZodObject< */ merge( merging: Incoming - ): ZodObject, Incoming['_def']['unknownKeys']> { + ): ZodObject, Incoming['_def']['unknownKeys']> { const merged: any = new ZodObject({ unknownKeys: merging._def.unknownKeys, shape: () => ({ @@ -441,7 +440,7 @@ export class ZodObject< // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => - // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // utils.types.mergeShapes(this._def.shape(), merging._def.shape()), // typeName: 'ZodObject', // }); // return merged; @@ -470,7 +469,7 @@ export class ZodObject< // Incoming["_def"]["unknownKeys"], // Incoming["_def"]["catchall"] // > { - // // const mergedShape = objectUtil.mergeShapes( + // // const mergedShape = utils.types.mergeShapes( // // this._def.shape(), // // merging._def.shape() // // ); @@ -478,7 +477,7 @@ export class ZodObject< // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => - // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), + // utils.types.mergeShapes(this._def.shape(), merging._def.shape()), // typeName: 'ZodObject', // }); // return merged; @@ -548,7 +547,7 @@ export class ZodObject< >( mask: Mask ): ZodObject< - objectUtil.noNever<{ + utils.types.NoNever<{ [k in keyof T]: k extends keyof Mask ? ZodOptional : T[k] }>, UnknownKeys @@ -585,7 +584,7 @@ export class ZodObject< >( mask: Mask ): ZodObject< - objectUtil.noNever<{ + utils.types.NoNever<{ [k in keyof T]: k extends keyof Mask ? deoptional : T[k] }>, UnknownKeys diff --git a/packages/zui/src/z/types/utils/objectUtil.ts b/packages/zui/src/z/types/utils/objectUtil.ts deleted file mode 100644 index a99a0c7b0c3..00000000000 --- a/packages/zui/src/z/types/utils/objectUtil.ts +++ /dev/null @@ -1,39 +0,0 @@ -export namespace objectUtil { - export type MergeShapes = { - [k in Exclude]: U[k] - } & V - - type optionalKeys = { - [k in keyof T]: undefined extends T[k] ? k : never - }[keyof T] - - type requiredKeys = { - [k in keyof T]: undefined extends T[k] ? never : k - }[keyof T] - - export type addQuestionMarks< - T extends object, - R extends keyof T = requiredKeys, - O extends keyof T = optionalKeys, - > = Pick & Partial> & { [k in keyof T]?: unknown } - - export type identity = T - export type flatten = identity<{ [k in keyof T]: T[k] }> - - export type noNeverKeys = { - [k in keyof T]: [T[k]] extends [never] ? never : k - }[keyof T] - - export type noNever = identity<{ - [k in noNeverKeys]: k extends keyof T ? T[k] : never - }> - - export const mergeShapes = (first: U, second: T): T & U => { - return { - ...first, - ...second, // second overwrites first - } - } - - export type extendShape = flatten & B> -} diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts index b6ff98457eb..df16f6482a0 100644 --- a/packages/zui/src/z/utils/type-utils.ts +++ b/packages/zui/src/z/utils/type-utils.ts @@ -33,3 +33,30 @@ type _GetUnionLast = _UnionToIntersectionFn extends () => infer Last ? Las export type UnionToTuple = [T] extends [never] ? Tuple : UnionToTuple>, [_GetUnionLast, ...Tuple]> + +type _OptionalKeys = { + [k in keyof T]: undefined extends T[k] ? k : never +}[keyof T] + +type _RequiredKeys = { + [k in keyof T]: undefined extends T[k] ? never : k +}[keyof T] + +export type AddQuestionMarks< + T extends object, + R extends keyof T = _RequiredKeys, + O extends keyof T = _OptionalKeys, +> = Pick & Partial> & { [k in keyof T]?: unknown } + +export type Identity = T +export type Flatten = Identity<{ [k in keyof T]: T[k] }> + +type _NoNeverKeys = { + [k in keyof T]: [T[k]] extends [never] ? never : k +}[keyof T] + +export type NoNever = Identity<{ + [k in _NoNeverKeys]: k extends keyof T ? T[k] : never +}> + +export type ExtendShape = Flatten & B> From 6c4ebded79352cd8e1638b7b0f266afa2a886d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 10:34:19 -0500 Subject: [PATCH 12/50] chore(zui): rm partialUtils (#14960) --- packages/zui/src/z/types/index.ts | 1 - packages/zui/src/z/types/object/index.ts | 22 +++++++++++-- packages/zui/src/z/types/utils/partialUtil.ts | 31 ------------------- 3 files changed, 20 insertions(+), 34 deletions(-) delete mode 100644 packages/zui/src/z/types/utils/partialUtil.ts diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index d6e970d4c70..91746f1d8aa 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -8,7 +8,6 @@ export * from './basetype' export * from './native' export * from './utils' export * from './utils/parseUtil' -export * from './utils/partialUtil' export * from './any' export * from './array' export * from './bigint' diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index fa481858938..13d0279512d 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -18,10 +18,10 @@ import { ZodType, ZodTypeDef, processCreateParams, - partialUtil, createZodEnum, ZodNever, ZodAny, + ZodTupleItems, } from '../index' export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodType @@ -94,6 +94,24 @@ export type KeyOfObject = utils.types.Cast< [string, ...string[]] > +export type DeepPartial = T extends ZodObject + ? ZodObject<{ [k in keyof T['shape']]: ZodOptional> }, T['_def']['unknownKeys']> + : T extends ZodArray + ? ZodArray, Card> + : T extends ZodOptional + ? ZodOptional> + : T extends ZodNullable + ? ZodNullable> + : T extends ZodTuple + ? { + [k in keyof Items]: Items[k] extends ZodType ? DeepPartial : never + } extends infer PI + ? PI extends ZodTupleItems + ? ZodTuple + : never + : never + : T + function deepPartialify(schema: ZodType): any { if (schema instanceof ZodObject) { const newShape: any = {} @@ -530,7 +548,7 @@ export class ZodObject< /** * @deprecated */ - deepPartial(): partialUtil.DeepPartial { + deepPartial(): DeepPartial { return deepPartialify(this) } diff --git a/packages/zui/src/z/types/utils/partialUtil.ts b/packages/zui/src/z/types/utils/partialUtil.ts deleted file mode 100644 index 034f2ded6b7..00000000000 --- a/packages/zui/src/z/types/utils/partialUtil.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { - ZodArray, - ZodNullable, - ZodObject, - ZodOptional, - ZodTuple, - ZodTupleItems, - ZodRawShape, - ZodType, -} from '../index' - -export namespace partialUtil { - export type DeepPartial = - T extends ZodObject - ? ZodObject<{ [k in keyof T['shape']]: ZodOptional> }, T['_def']['unknownKeys']> - : T extends ZodArray - ? ZodArray, Card> - : T extends ZodOptional - ? ZodOptional> - : T extends ZodNullable - ? ZodNullable> - : T extends ZodTuple - ? { - [k in keyof Items]: Items[k] extends ZodType ? DeepPartial : never - } extends infer PI - ? PI extends ZodTupleItems - ? ZodTuple - : never - : never - : T -} From 463b0cbef9171e203a0ee592adfc8713939edc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 11:10:16 -0500 Subject: [PATCH 13/50] chore(zui): replace enums by unions of string literals (#14961) --- .../zui/src/z/__tests__/preprocess.test.ts | 6 +- .../zui/src/z/__tests__/primitive.test.ts | 2 +- packages/zui/src/z/__tests__/refine.test.ts | 18 ++--- packages/zui/src/z/__tests__/set.test.ts | 14 ++-- packages/zui/src/z/error/error.test.ts | 19 +++-- packages/zui/src/z/error/index.ts | 74 +++++-------------- packages/zui/src/z/error/locales/en.ts | 39 +++++----- packages/zui/src/z/types/array/index.ts | 14 ++-- packages/zui/src/z/types/basetype/index.ts | 4 +- packages/zui/src/z/types/bigint/index.ts | 14 ++-- packages/zui/src/z/types/boolean/index.ts | 8 +- packages/zui/src/z/types/date/index.ts | 14 ++-- packages/zui/src/z/types/default/index.ts | 4 +- .../discriminatedUnion.test.ts | 14 ++-- .../src/z/types/discriminatedUnion/index.ts | 10 +-- packages/zui/src/z/types/enum/index.ts | 5 +- .../zui/src/z/types/function/function.test.ts | 6 +- packages/zui/src/z/types/function/index.ts | 13 ++-- .../zui/src/z/types/intersection/index.ts | 10 +-- .../z/types/intersection/intersection.test.ts | 8 +- packages/zui/src/z/types/literal/index.ts | 3 +- packages/zui/src/z/types/map/index.ts | 8 +- packages/zui/src/z/types/map/map.test.ts | 14 ++-- packages/zui/src/z/types/nan/index.ts | 8 +- packages/zui/src/z/types/nativeEnum/index.ts | 8 +- packages/zui/src/z/types/never/index.ts | 6 +- packages/zui/src/z/types/null/index.ts | 8 +- packages/zui/src/z/types/nullable/index.ts | 4 +- packages/zui/src/z/types/number/index.ts | 18 ++--- packages/zui/src/z/types/object/index.ts | 10 +-- packages/zui/src/z/types/optional/index.ts | 4 +- packages/zui/src/z/types/promise/index.ts | 10 +-- packages/zui/src/z/types/record/index.ts | 8 +- packages/zui/src/z/types/ref/index.ts | 13 +++- packages/zui/src/z/types/set/index.ts | 12 ++- packages/zui/src/z/types/string/index.ts | 45 ++++++----- packages/zui/src/z/types/symbol/index.ts | 8 +- .../z/types/transformer/transformer.test.ts | 10 +-- packages/zui/src/z/types/tuple/index.ts | 12 ++- packages/zui/src/z/types/undefined/index.ts | 8 +- packages/zui/src/z/types/union/index.ts | 6 +- packages/zui/src/z/types/utils/index.ts | 53 ++++--------- packages/zui/src/z/types/void/index.ts | 8 +- 43 files changed, 239 insertions(+), 341 deletions(-) diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 19eb71785c0..28634750382 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -125,7 +125,7 @@ test('preprocess ctx.addIssue with parseAsync', async () => { test('z.NEVER in preprocess', () => { const foo = z.preprocess((val, ctx) => { if (!val) { - ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'bad' }) + ctx.addIssue({ code: 'custom', message: 'bad' }) return z.NEVER } return val @@ -150,8 +150,8 @@ test('preprocess as the second property of object', () => { expect(result.success).toEqual(false) if (!result.success) { expect(result.error.issues.length).toEqual(2) - expect(result.error.issues[0]?.code).toEqual(z.ZodIssueCode.too_small) - expect(result.error.issues[1]?.code).toEqual(z.ZodIssueCode.too_small) + expect(result.error.issues[0]?.code).toEqual('too_small') + expect(result.error.issues[1]?.code).toEqual('too_small') } }) diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index 039cbca1219..c38d03045c9 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -281,7 +281,7 @@ test('parse dateSchema invalid date', async () => { try { await dateSchema.parseAsync(new Date('invalid')) } catch (err) { - expect((err as z.ZodError).issues[0]?.code).toEqual(z.ZodIssueCode.invalid_date) + expect((err as z.ZodError).issues[0]?.code).toEqual('invalid_date') } }) // ============== diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index 89270282187..8da4b53c20a 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -92,7 +92,7 @@ test('use path in refinement context', async () => { const noNested = z.string()._refinement((_val, ctx) => { if (ctx.path.length > 0) { ctx.addIssue({ - code: ZodIssueCode.custom, + code: 'custom', message: `schema cannot be nested. path: ${ctx.path.join('.')}`, }) return false @@ -119,7 +119,7 @@ test('superRefine', () => { const Strings = z.array(z.string()).superRefine((val, ctx) => { if (val.length > 3) { ctx.addIssue({ - code: z.ZodIssueCode.too_big, + code: 'too_big', maximum: 3, type: 'array', inclusive: true, @@ -130,7 +130,7 @@ test('superRefine', () => { if (val.length !== new Set(val).size) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: `No duplicates allowed.`, }) } @@ -148,7 +148,7 @@ test('superRefine async', async () => { const Strings = z.array(z.string()).superRefine(async (val, ctx) => { if (val.length > 3) { ctx.addIssue({ - code: z.ZodIssueCode.too_big, + code: 'too_big', maximum: 3, type: 'array', inclusive: true, @@ -159,7 +159,7 @@ test('superRefine async', async () => { if (val.length !== new Set(val).size) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: `No duplicates allowed.`, }) } @@ -185,7 +185,7 @@ test('superRefine - type narrowing', () => { if (!arg) { // still need to make a call to ctx.addIssue ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: 'cannot be null', fatal: true, }) @@ -216,7 +216,7 @@ test('chained mixed refining types', () => { utils.assert.assertEqual(true) if (arg.first !== 'bob') { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: '`first` property must be `bob`', }) return false @@ -273,7 +273,7 @@ test('fatal superRefine', () => { .superRefine((val, ctx) => { if (val === '') { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: 'foo', fatal: true, }) @@ -282,7 +282,7 @@ test('fatal superRefine', () => { .superRefine((val, ctx) => { if (val !== ' ') { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: 'custom', message: 'bar', }) } diff --git a/packages/zui/src/z/__tests__/set.test.ts b/packages/zui/src/z/__tests__/set.test.ts index 84936879f3a..422733a033d 100644 --- a/packages/zui/src/z/__tests__/set.test.ts +++ b/packages/zui/src/z/__tests__/set.test.ts @@ -78,7 +78,7 @@ test('failing when parsing empty set in nonempty ', () => { if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.too_small) + expect(result.error.issues[0]?.code).toEqual('too_small') } }) @@ -88,7 +88,7 @@ test('failing when set is smaller than min() ', () => { if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.too_small) + expect(result.error.issues[0]?.code).toEqual('too_small') } }) @@ -98,7 +98,7 @@ test('failing when set is bigger than max() ', () => { if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.too_big) + expect(result.error.issues[0]?.code).toEqual('too_big') } }) @@ -112,7 +112,7 @@ test('throws when a Map is given', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') } }) @@ -121,7 +121,7 @@ test('throws when the given set has invalid input', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') expect(result.error.issues[0]?.path).toEqual([0]) } }) @@ -132,9 +132,9 @@ test('throws when the given set has multiple invalid entries', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(2) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') expect(result.error.issues[0]?.path).toEqual([0]) - expect(result.error.issues[1]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[1]?.code).toEqual('invalid_type') expect(result.error.issues[1]?.path).toEqual([1]) } }) diff --git a/packages/zui/src/z/error/error.test.ts b/packages/zui/src/z/error/error.test.ts index f60b19a88ae..7b1be77ff19 100644 --- a/packages/zui/src/z/error/error.test.ts +++ b/packages/zui/src/z/error/error.test.ts @@ -1,14 +1,13 @@ import { test, expect } from 'vitest' import * as z from '../index' -import { ZodParsedType } from '../index' import { ZodError, ZodIssueCode } from '.' test('error creation', () => { const err1 = ZodError.create([]) err1.addIssue({ - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.object, - received: ZodParsedType.string, + code: 'invalid_type', + expected: 'object', + received: 'string', path: [], message: '', fatal: true, @@ -25,12 +24,12 @@ test('error creation', () => { }) const errorMap: z.ZodErrorMap = (error, ctx) => { - if (error.code === ZodIssueCode.invalid_type) { + if (error.code === 'invalid_type') { if (error.expected === 'string') { return { message: 'bad type!' } } } - if (error.code === ZodIssueCode.custom) { + if (error.code === 'custom') { return { message: `less-than-${(error.params || {}).minimum}` } } return { message: ctx.defaultError } @@ -42,7 +41,7 @@ test('type error with custom error map', () => { } catch (err) { const zerr = err as z.ZodError - expect(zerr.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_type) + expect(zerr.issues[0]?.code).toEqual('invalid_type') expect(zerr.issues[0]?.message).toEqual(`bad type!`) } }) @@ -56,7 +55,7 @@ test('refinement fail with params', () => { .parse(2, { errorMap }) } catch (err) { const zerr = err as z.ZodError - expect(zerr.issues[0]?.code).toEqual(z.ZodIssueCode.custom) + expect(zerr.issues[0]?.code).toEqual('custom') expect(zerr.issues[0]?.message).toEqual(`less-than-3`) } }) @@ -118,14 +117,14 @@ test('array minimum', () => { z.array(z.string()).min(3, 'tooshort').parse(['asdf', 'qwer']) } catch (err) { const zerr = err as ZodError - expect(zerr.issues[0]?.code).toEqual(ZodIssueCode.too_small) + expect(zerr.issues[0]?.code).toEqual('too_small') expect(zerr.issues[0]?.message).toEqual('tooshort') } try { z.array(z.string()).min(3).parse(['asdf', 'qwer']) } catch (err) { const zerr = err as ZodError - expect(zerr.issues[0]?.code).toEqual(ZodIssueCode.too_small) + expect(zerr.issues[0]?.code).toEqual('too_small') expect(zerr.issues[0]?.message).toEqual(`Array must contain at least 3 element(s)`) } }) diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index bd9cb788fe9..74fb78bdc5a 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -2,95 +2,56 @@ import { ZodParsedType } from '../types/utils' import * as utils from '../utils' import { errorMap as defaultErrorMap } from './locales/en' -export type ZodIssueCode = - | 'invalid_type' - | 'invalid_literal' - | 'custom' - | 'invalid_union' - | 'invalid_union_discriminator' - | 'invalid_enum_value' - | 'unrecognized_keys' - | 'invalid_arguments' - | 'invalid_return_type' - | 'invalid_date' - | 'invalid_string' - | 'too_small' - | 'too_big' - | 'invalid_intersection_types' - | 'not_multiple_of' - | 'not_finite' - | 'unresolved_reference' - -export const ZodIssueCode = { - invalid_type: 'invalid_type', - invalid_literal: 'invalid_literal', - custom: 'custom', - invalid_union: 'invalid_union', - invalid_union_discriminator: 'invalid_union_discriminator', - invalid_enum_value: 'invalid_enum_value', - unrecognized_keys: 'unrecognized_keys', - invalid_arguments: 'invalid_arguments', - invalid_return_type: 'invalid_return_type', - invalid_date: 'invalid_date', - invalid_string: 'invalid_string', - too_small: 'too_small', - too_big: 'too_big', - invalid_intersection_types: 'invalid_intersection_types', - not_multiple_of: 'not_multiple_of', - not_finite: 'not_finite', - unresolved_reference: 'unresolved_reference', -} as const satisfies { [k in ZodIssueCode]: k } - export type ZodIssueBase = { path: (string | number)[] message?: string } export type ZodInvalidTypeIssue = { - code: typeof ZodIssueCode.invalid_type + code: 'invalid_type' expected: ZodParsedType received: ZodParsedType } & ZodIssueBase export type ZodInvalidLiteralIssue = { - code: typeof ZodIssueCode.invalid_literal + code: 'invalid_literal' expected: unknown received: unknown } & ZodIssueBase export type ZodUnrecognizedKeysIssue = { - code: typeof ZodIssueCode.unrecognized_keys + code: 'unrecognized_keys' keys: string[] } & ZodIssueBase export type ZodInvalidUnionIssue = { - code: typeof ZodIssueCode.invalid_union + code: 'invalid_union' unionErrors: ZodError[] } & ZodIssueBase export type ZodInvalidUnionDiscriminatorIssue = { - code: typeof ZodIssueCode.invalid_union_discriminator + code: 'invalid_union_discriminator' options: utils.types.Primitive[] } & ZodIssueBase export type ZodInvalidEnumValueIssue = { received: string | number - code: typeof ZodIssueCode.invalid_enum_value + code: 'invalid_enum_value' options: (string | number)[] } & ZodIssueBase export type ZodInvalidArgumentsIssue = { - code: typeof ZodIssueCode.invalid_arguments + code: 'invalid_arguments' argumentsError: ZodError } & ZodIssueBase export type ZodInvalidReturnTypeIssue = { - code: typeof ZodIssueCode.invalid_return_type + code: 'invalid_return_type' returnTypeError: ZodError } & ZodIssueBase export type ZodInvalidDateIssue = { - code: typeof ZodIssueCode.invalid_date + code: 'invalid_date' } & ZodIssueBase export type StringValidation = @@ -109,12 +70,12 @@ export type StringValidation = | { endsWith: string } export type ZodInvalidStringIssue = { - code: typeof ZodIssueCode.invalid_string + code: 'invalid_string' validation: StringValidation } & ZodIssueBase export type ZodTooSmallIssue = { - code: typeof ZodIssueCode.too_small + code: 'too_small' minimum: number | bigint inclusive: boolean exact?: boolean @@ -122,7 +83,7 @@ export type ZodTooSmallIssue = { } & ZodIssueBase export type ZodTooBigIssue = { - code: typeof ZodIssueCode.too_big + code: 'too_big' maximum: number | bigint inclusive: boolean exact?: boolean @@ -130,29 +91,30 @@ export type ZodTooBigIssue = { } & ZodIssueBase export type ZodInvalidIntersectionTypesIssue = { - code: typeof ZodIssueCode.invalid_intersection_types + code: 'invalid_intersection_types' } & ZodIssueBase export type ZodNotMultipleOfIssue = { - code: typeof ZodIssueCode.not_multiple_of + code: 'not_multiple_of' multipleOf: number | bigint } & ZodIssueBase export type ZodNotFiniteIssue = { - code: typeof ZodIssueCode.not_finite + code: 'not_finite' } & ZodIssueBase export type ZodUnresolvedReferenceIssue = { - code: typeof ZodIssueCode.unresolved_reference + code: 'unresolved_reference' } & ZodIssueBase export type ZodCustomIssue = { - code: typeof ZodIssueCode.custom + code: 'custom' params?: { [k: string]: any } } & ZodIssueBase export type DenormalizedError = { [k: string]: DenormalizedError | string[] } +export type ZodIssueCode = ZodIssueOptionalMessage['code'] export type ZodIssueOptionalMessage = | ZodInvalidTypeIssue | ZodInvalidLiteralIssue diff --git a/packages/zui/src/z/error/locales/en.ts b/packages/zui/src/z/error/locales/en.ts index b3f966b3da6..a5259934b9f 100644 --- a/packages/zui/src/z/error/locales/en.ts +++ b/packages/zui/src/z/error/locales/en.ts @@ -1,42 +1,41 @@ -import { ZodParsedType } from '../../types' import * as utils from '../../utils' -import { type ZodErrorMap, ZodIssueCode } from '../index' +import { type ZodErrorMap } from '../index' export const errorMap: ZodErrorMap = (issue, _ctx) => { let message: string switch (issue.code) { - case ZodIssueCode.invalid_type: - if (issue.received === ZodParsedType.undefined) { + case 'invalid_type': + if (issue.received === 'undefined') { message = 'Required' } else { message = `Expected ${issue.expected}, received ${issue.received}` } break - case ZodIssueCode.invalid_literal: + case 'invalid_literal': message = `Invalid literal value, expected ${JSON.stringify(issue.expected, utils.others.jsonStringifyReplacer)}` break - case ZodIssueCode.unrecognized_keys: + case 'unrecognized_keys': message = `Unrecognized key(s) in object: ${utils.others.joinValues(issue.keys, ', ')}` break - case ZodIssueCode.invalid_union: + case 'invalid_union': message = 'Invalid input' break - case ZodIssueCode.invalid_union_discriminator: + case 'invalid_union_discriminator': message = `Invalid discriminator value. Expected ${utils.others.joinValues(issue.options)}` break - case ZodIssueCode.invalid_enum_value: + case 'invalid_enum_value': message = `Invalid enum value. Expected ${utils.others.joinValues(issue.options)}, received '${issue.received}'` break - case ZodIssueCode.invalid_arguments: + case 'invalid_arguments': message = 'Invalid function arguments' break - case ZodIssueCode.invalid_return_type: + case 'invalid_return_type': message = 'Invalid function return type' break - case ZodIssueCode.invalid_date: + case 'invalid_date': message = 'Invalid date' break - case ZodIssueCode.invalid_string: + case 'invalid_string': if (typeof issue.validation === 'object') { if ('includes' in issue.validation) { message = `Invalid input: must include "${issue.validation.includes}"` @@ -57,7 +56,7 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { message = 'Invalid' } break - case ZodIssueCode.too_small: + case 'too_small': if (issue.type === 'array') { message = `Array must contain ${ issue.exact ? 'exactly' : issue.inclusive ? 'at least' : 'more than' @@ -76,7 +75,7 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { }${new Date(Number(issue.minimum))}` } else message = 'Invalid input' break - case ZodIssueCode.too_big: + case 'too_big': if (issue.type === 'array') { message = `Array must contain ${ issue.exact ? 'exactly' : issue.inclusive ? 'at most' : 'less than' @@ -99,19 +98,19 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { } ${new Date(Number(issue.maximum))}` } else message = 'Invalid input' break - case ZodIssueCode.custom: + case 'custom': message = 'Invalid input' break - case ZodIssueCode.invalid_intersection_types: + case 'invalid_intersection_types': message = 'Intersection results could not be merged' break - case ZodIssueCode.not_multiple_of: + case 'not_multiple_of': message = `Number must be a multiple of ${issue.multipleOf}` break - case ZodIssueCode.not_finite: + case 'not_finite': message = 'Number must be finite' break - case ZodIssueCode.unresolved_reference: + case 'unresolved_reference': message = 'Unresolved reference' break default: diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index bdaea19e728..a98ae670bbc 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -1,5 +1,4 @@ import { isEqual } from 'lodash-es' -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ParseInputLazyPath, @@ -7,7 +6,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -70,10 +68,10 @@ export class ZodArray def.maxLength.value) { addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: def.maxLength.value, type: 'array', inclusive: true, diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 94375181e86..de752e0298f 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -11,7 +11,7 @@ import type { ZuiExtensionObject, ZuiMetadata, } from '../../../ui/types' -import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap, ZodIssueCode } from '../../error' +import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap } from '../../error' import * as utils from '../../utils' import { CatchFn } from '../catch' import { @@ -320,7 +320,7 @@ export abstract class ZodType ctx.addIssue({ - code: ZodIssueCode.custom, + code: 'custom', ...getIssueProperties(val), }) if (typeof Promise !== 'undefined' && result instanceof Promise) { diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 120174c3c26..a94ee56b59d 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { addIssueToContext, @@ -11,7 +10,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, } from '../index' export type ZodBigIntCheck = @@ -31,11 +29,11 @@ export class ZodBigInt extends ZodType { input.data = BigInt(input.data) } const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.bigint) { + if (parsedType !== 'bigint') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.bigint, + code: 'invalid_type', + expected: 'bigint', received: ctx.parsedType, }) return INVALID @@ -50,7 +48,7 @@ export class ZodBigInt extends ZodType { if (tooSmall) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', type: 'bigint', minimum: check.value, inclusive: check.inclusive, @@ -63,7 +61,7 @@ export class ZodBigInt extends ZodType { if (tooBig) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', type: 'bigint', maximum: check.value, inclusive: check.inclusive, @@ -75,7 +73,7 @@ export class ZodBigInt extends ZodType { if (input.data % check.value !== BigInt(0)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.not_multiple_of, + code: 'not_multiple_of', multipleOf: check.value, message: check.message, }) diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index 6f3d93d7fd0..6fa7d54f3f2 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -24,11 +22,11 @@ export class ZodBoolean extends ZodType { } const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.boolean) { + if (parsedType !== 'boolean') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.boolean, + code: 'invalid_type', + expected: 'boolean', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index 458ceac583d..77a49e6e494 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,8 +1,6 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { processCreateParams, - ZodParsedType, ZodTypeDef, addIssueToContext, INVALID, @@ -30,11 +28,11 @@ export class ZodDate extends ZodType { } const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.date) { + if (parsedType !== 'date') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.date, + code: 'invalid_type', + expected: 'date', received: ctx.parsedType, }) return INVALID @@ -43,7 +41,7 @@ export class ZodDate extends ZodType { if (isNaN(input.data.getTime())) { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_date, + code: 'invalid_date', }) return INVALID } @@ -56,7 +54,7 @@ export class ZodDate extends ZodType { if (input.data.getTime() < check.value) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', message: check.message, inclusive: true, exact: false, @@ -69,7 +67,7 @@ export class ZodDate extends ZodType { if (input.data.getTime() > check.value) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', message: check.message, inclusive: true, exact: false, diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index f5af0d10243..3ccdc4c0853 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -2,11 +2,11 @@ import { isEqual } from 'lodash-es' import * as utils from '../../utils' import { + // RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, ParseInput, ParseReturnType, } from '../index' @@ -25,7 +25,7 @@ export class ZodDefault extends ZodType< _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) let data = ctx.data - if (ctx.parsedType === ZodParsedType.undefined) { + if (ctx.parsedType === 'undefined') { data = this._def.defaultValue() } return this._def.innerType._parse({ diff --git a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts index 7034e72bce2..3e28524e9c1 100644 --- a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts +++ b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts @@ -71,10 +71,10 @@ test('invalid - null', () => { } catch (e: any) { expect(JSON.parse(e.message)).toEqual([ { - code: z.ZodIssueCode.invalid_type, - expected: z.ZodParsedType.object, + code: 'invalid_type', + expected: 'object', message: 'Expected object, received null', - received: z.ZodParsedType.null, + received: 'null', path: [], }, ]) @@ -91,7 +91,7 @@ test('invalid discriminator value', () => { } catch (e: any) { expect(JSON.parse(e.message)).toEqual([ { - code: z.ZodIssueCode.invalid_union_discriminator, + code: 'invalid_union_discriminator', options: ['a', 'b'], message: "Invalid discriminator value. Expected 'a' | 'b'", path: ['type'], @@ -110,11 +110,11 @@ test('valid discriminator value, invalid data', () => { } catch (e: any) { expect(JSON.parse(e.message)).toEqual([ { - code: z.ZodIssueCode.invalid_type, - expected: z.ZodParsedType.string, + code: 'invalid_type', + expected: 'string', message: 'Required', path: ['a'], - received: z.ZodParsedType.undefined, + received: 'undefined', }, ]) } diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index ec8dc2dfcc4..97509f81c7d 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ZodBranded, @@ -23,7 +22,6 @@ import { ZodEffects, ZodUndefined, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -115,10 +113,10 @@ export class ZodDiscriminatedUnion< _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.object) { + if (ctx.parsedType !== 'object') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.object, + code: 'invalid_type', + expected: 'object', received: ctx.parsedType, }) return INVALID @@ -132,7 +130,7 @@ export class ZodDiscriminatedUnion< if (!option) { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_union_discriminator, + code: 'invalid_union_discriminator', options: Array.from(this.optionsMap.keys()), path: [discriminator], }) diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index c8acaaf65ff..b1af8f4e1eb 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { RawCreateParams, @@ -64,7 +63,7 @@ export class ZodEnum ex addIssueToContext(ctx, { expected: utils.others.joinValues(expectedValues) as 'string', received: ctx.parsedType, - code: ZodIssueCode.invalid_type, + code: 'invalid_type', }) return INVALID } @@ -75,7 +74,7 @@ export class ZodEnum ex addIssueToContext(ctx, { received: ctx.data, - code: ZodIssueCode.invalid_enum_value, + code: 'invalid_enum_value', options: expectedValues, }) return INVALID diff --git a/packages/zui/src/z/types/function/function.test.ts b/packages/zui/src/z/types/function/function.test.ts index 9e6215692d9..a5168785ed7 100644 --- a/packages/zui/src/z/types/function/function.test.ts +++ b/packages/zui/src/z/types/function/function.test.ts @@ -144,9 +144,7 @@ test('special function error codes', () => { } catch (err) { const zerr = err as z.ZodError const first = zerr.issues[0] - if (first?.code !== z.ZodIssueCode.invalid_return_type) throw new Error() - - expect(first?.returnTypeError).toBeInstanceOf(z.ZodError) + if (first?.code !== 'invalid_return_type') throw new Error() } try { @@ -154,7 +152,7 @@ test('special function error codes', () => { } catch (err) { const zerr = err as z.ZodError const first = zerr.issues[0] - if (first?.code !== z.ZodIssueCode.invalid_arguments) throw new Error() + if (first?.code !== 'invalid_arguments') throw new Error() expect(first?.argumentsError).toBeInstanceOf(z.ZodError) } }) diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index b4f63cf1ade..9ff07e152af 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,4 +1,4 @@ -import { defaultErrorMap, getErrorMap, ZodError, ZodErrorMap, ZodIssue, ZodIssueCode } from '../../error' +import { defaultErrorMap, getErrorMap, ZodError, ZodErrorMap, ZodIssue } from '../../error' import * as utils from '../../utils' import { RawCreateParams, @@ -9,7 +9,6 @@ import { ZodTuple, ZodUnknown, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, makeIssue, @@ -59,10 +58,10 @@ export class ZodFunction = ZodTuple, Returns ext _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.function) { + if (ctx.parsedType !== 'function') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.function, + code: 'invalid_type', + expected: 'function', received: ctx.parsedType, }) return INVALID @@ -76,7 +75,7 @@ export class ZodFunction = ZodTuple, Returns ext (x) => !!x ) as ZodErrorMap[], issueData: { - code: ZodIssueCode.invalid_arguments, + code: 'invalid_arguments', argumentsError: error, }, }) @@ -90,7 +89,7 @@ export class ZodFunction = ZodTuple, Returns ext (x) => !!x ) as ZodErrorMap[], issueData: { - code: ZodIssueCode.invalid_return_type, + code: 'invalid_return_type', returnTypeError: error, }, }) diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 430ed3b4143..7bce194368b 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { RawCreateParams, @@ -6,7 +5,6 @@ import { ZodTypeDef, getParsedType, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, isAborted, @@ -28,7 +26,7 @@ function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: fals if (a === b) { return { valid: true, data: a } - } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { + } else if (aType === 'object' && bType === 'object') { const bKeys = Object.keys(b) const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1) @@ -42,7 +40,7 @@ function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: fals } return { valid: true, data: newObj } - } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) { + } else if (aType === 'array' && bType === 'array') { if (a.length !== b.length) { return { valid: false } } @@ -61,7 +59,7 @@ function mergeValues(a: any, b: any): { valid: true; data: any } | { valid: fals } return { valid: true, data: newArray } - } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) { + } else if (aType === 'date' && bType === 'date' && +a === +b) { return { valid: true, data: a } } else { return { valid: false } @@ -107,7 +105,7 @@ export class ZodIntersection { const syncResult = numberIntersection.safeParse(1234) expect(syncResult.success).toEqual(false) if (!syncResult.success) { - expect(syncResult.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_intersection_types) + expect(syncResult.error.issues[0]?.code).toEqual('invalid_intersection_types') } const asyncResult = await numberIntersection.spa(1234) expect(asyncResult.success).toEqual(false) if (!asyncResult.success) { - expect(asyncResult.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_intersection_types) + expect(asyncResult.error.issues[0]?.code).toEqual('invalid_intersection_types') } }) @@ -97,12 +97,12 @@ test('invalid array merge', async () => { const syncResult = stringArrInt.safeParse(['asdf', 'qwer']) expect(syncResult.success).toEqual(false) if (!syncResult.success) { - expect(syncResult.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_intersection_types) + expect(syncResult.error.issues[0]?.code).toEqual('invalid_intersection_types') } const asyncResult = await stringArrInt.spa(['asdf', 'qwer']) expect(asyncResult.success).toEqual(false) if (!asyncResult.success) { - expect(asyncResult.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_intersection_types) + expect(asyncResult.error.issues[0]?.code).toEqual('invalid_intersection_types') } }) diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index 958ffc788b0..c92214b9e35 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,5 +1,4 @@ import { isEqual } from 'lodash-es' -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { RawCreateParams, @@ -23,7 +22,7 @@ export class ZodLiteral const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { received: ctx.data, - code: ZodIssueCode.invalid_literal, + code: 'invalid_literal', expected: this._def.value, }) return INVALID diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index d4f6869d880..06c61e09d01 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ParseInputLazyPath, @@ -6,7 +5,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -56,10 +54,10 @@ export class ZodMap { const { status, ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.map) { + if (ctx.parsedType !== 'map') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.map, + code: 'invalid_type', + expected: 'map', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/map/map.test.ts b/packages/zui/src/z/types/map/map.test.ts index f73043fb6c1..d588ccbdceb 100644 --- a/packages/zui/src/z/types/map/map.test.ts +++ b/packages/zui/src/z/types/map/map.test.ts @@ -47,7 +47,7 @@ test('throws when a Set is given', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(1) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') } }) @@ -56,9 +56,9 @@ test('throws when the given map has invalid key and invalid input', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(2) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') expect(result.error.issues[0]?.path).toEqual([0, 'key']) - expect(result.error.issues[1]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[1]?.code).toEqual('invalid_type') expect(result.error.issues[1]?.path).toEqual([0, 'value']) } }) @@ -77,9 +77,9 @@ test('throws when the given map has multiple invalid entries', () => { expect(result.success).toEqual(false) if (result.success === false) { expect(result.error.issues.length).toEqual(2) - expect(result.error.issues[0]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[0]?.code).toEqual('invalid_type') expect(result.error.issues[0]?.path).toEqual([0, 'key']) - expect(result.error.issues[1]?.code).toEqual(ZodIssueCode.invalid_type) + expect(result.error.issues[1]?.code).toEqual('invalid_type') expect(result.error.issues[1]?.path).toEqual([1, 'value']) } }) @@ -100,9 +100,9 @@ test('dirty', async () => { expect(result.success).toEqual(false) if (!result.success) { expect(result.error.issues.length).toEqual(2) - expect(result.error.issues[0]?.code).toEqual(z.ZodIssueCode.custom) + expect(result.error.issues[0]?.code).toEqual('custom') expect(result.error.issues[0]?.message).toEqual('Keys must be uppercase') - expect(result.error.issues[1]?.code).toEqual(z.ZodIssueCode.custom) + expect(result.error.issues[1]?.code).toEqual('custom') expect(result.error.issues[1]?.message).toEqual('Keys must be uppercase') } }) diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index 912fd375fa6..3fe6d8bfc54 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -18,11 +16,11 @@ export type ZodNaNDef = { export class ZodNaN extends ZodType { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.nan) { + if (parsedType !== 'nan') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.nan, + code: 'invalid_type', + expected: 'nan', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index 66138bad1ef..e10ca82436d 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,12 +1,10 @@ import { isEqual } from 'lodash-es' -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -26,12 +24,12 @@ export class ZodNativeEnum extends ZodType extends ZodType { _parse(input: ParseInput): ParseReturnType { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.never, + code: 'invalid_type', + expected: 'never', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index 0446d9d9cca..6c18cfcdaa7 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -19,11 +17,11 @@ export type ZodNullDef = { export class ZodNull extends ZodType { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.null) { + if (parsedType !== 'null') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.null, + code: 'invalid_type', + expected: 'null', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/nullable/index.ts b/packages/zui/src/z/types/nullable/index.ts index e2b69d20648..0758095a204 100644 --- a/packages/zui/src/z/types/nullable/index.ts +++ b/packages/zui/src/z/types/nullable/index.ts @@ -1,4 +1,5 @@ import { + // OK, ParseInput, ParseReturnType, @@ -6,7 +7,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, } from '../index' export type ZodNullableDef = { @@ -41,7 +41,7 @@ export class ZodNullable extends ZodType< _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType === ZodParsedType.null) { + if (parsedType === 'null') { return OK(null) } return this._def.innerType._parse(input) diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 0ae27b3c951..8a0c8c0b812 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,11 +1,9 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseContext, @@ -42,11 +40,11 @@ export class ZodNumber extends ZodType { input.data = Number(input.data) } const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.number) { + if (parsedType !== 'number') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.number, + code: 'invalid_type', + expected: 'number', received: ctx.parsedType, }) return INVALID @@ -60,7 +58,7 @@ export class ZodNumber extends ZodType { if (!Number.isInteger(input.data)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, + code: 'invalid_type', expected: 'integer', received: 'float', message: check.message, @@ -72,7 +70,7 @@ export class ZodNumber extends ZodType { if (tooSmall) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', minimum: check.value, type: 'number', inclusive: check.inclusive, @@ -86,7 +84,7 @@ export class ZodNumber extends ZodType { if (tooBig) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: check.value, type: 'number', inclusive: check.inclusive, @@ -99,7 +97,7 @@ export class ZodNumber extends ZodType { if (floatSafeRemainder(input.data, check.value) !== 0) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.not_multiple_of, + code: 'not_multiple_of', multipleOf: check.value, message: check.message, }) @@ -109,7 +107,7 @@ export class ZodNumber extends ZodType { if (!Number.isFinite(input.data)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.not_finite, + code: 'not_finite', message: check.message, }) status.dirty() diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 13d0279512d..9ab380635e0 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ZodArray, @@ -11,7 +10,6 @@ import { ParseInput, ParseReturnType, ParseStatus, - ZodParsedType, ParseInputLazyPath, RawCreateParams, ZodRawShape, @@ -190,11 +188,11 @@ export class ZodObject< _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.object) { + if (parsedType !== 'object') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.object, + code: 'invalid_type', + expected: 'object', received: ctx.parsedType, }) return INVALID @@ -239,7 +237,7 @@ export class ZodObject< } else if (unknownKeys === 'strict') { if (extraKeys.length > 0) { addIssueToContext(ctx, { - code: ZodIssueCode.unrecognized_keys, + code: 'unrecognized_keys', keys: extraKeys, }) status.dirty() diff --git a/packages/zui/src/z/types/optional/index.ts b/packages/zui/src/z/types/optional/index.ts index 1ba859b042c..b843d75904b 100644 --- a/packages/zui/src/z/types/optional/index.ts +++ b/packages/zui/src/z/types/optional/index.ts @@ -1,6 +1,6 @@ import { + // processCreateParams, - ZodParsedType, RawCreateParams, ZodType, ZodTypeDef, @@ -41,7 +41,7 @@ export class ZodOptional extends ZodType< _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType === ZodParsedType.undefined) { + if (parsedType === 'undefined') { return OK(undefined) } return this._def.innerType._parse(input) diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index c74072a21c7..5e2a7f4924c 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -46,16 +44,16 @@ export class ZodPromise extends ZodType< _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) { + if (ctx.parsedType !== 'promise' && ctx.common.async === false) { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.promise, + code: 'invalid_type', + expected: 'promise', received: ctx.parsedType, }) return INVALID } - const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data) + const promisified = ctx.parsedType === 'promise' ? ctx.data : Promise.resolve(ctx.data) return OK( promisified.then((data: any) => { diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index e6cb98cde09..405aaa13ae7 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { BRAND, @@ -8,7 +7,6 @@ import { ZodTypeDef, ZodString, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -70,10 +68,10 @@ export class ZodRecord { const { status, ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.object) { + if (ctx.parsedType !== 'object') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.object, + code: 'invalid_type', + expected: 'object', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/ref/index.ts b/packages/zui/src/z/types/ref/index.ts index 9e4c0fcd7b4..2b88f8f5476 100644 --- a/packages/zui/src/z/types/ref/index.ts +++ b/packages/zui/src/z/types/ref/index.ts @@ -1,5 +1,12 @@ -import { ZodIssueCode } from '../../error' -import { ZodType, ZodTypeDef, INVALID, ParseInput, ParseReturnType, addIssueToContext } from '../index' +import { + // + ZodType, + ZodTypeDef, + INVALID, + ParseInput, + ParseReturnType, + addIssueToContext, +} from '../index' export type ZodRefDef = { typeName: 'ZodRef' @@ -25,7 +32,7 @@ export class ZodRef extends ZodType { // a schema containing references should never be used to parse data const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.unresolved_reference, + code: 'unresolved_reference', }) return INVALID } diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 24084d1f0be..329e3d3b13a 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ParseInputLazyPath, @@ -6,7 +5,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -46,10 +44,10 @@ export class ZodSet extends ZodType< _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.set) { + if (ctx.parsedType !== 'set') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.set, + code: 'invalid_type', + expected: 'set', received: ctx.parsedType, }) return INVALID @@ -60,7 +58,7 @@ export class ZodSet extends ZodType< if (def.minSize !== null) { if (ctx.data.size < def.minSize.value) { addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', minimum: def.minSize.value, type: 'set', inclusive: true, @@ -74,7 +72,7 @@ export class ZodSet extends ZodType< if (def.maxSize !== null) { if (ctx.data.size > def.maxSize.value) { addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: def.maxSize.value, type: 'set', inclusive: true, diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 3d9ba38f784..3cf035f178f 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,12 +1,11 @@ import { zuiKey } from '../../../ui/constants' -import { StringValidation, ZodIssueCode } from '../../error' +import { StringValidation } from '../../error' import * as utils from '../../utils' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseContext, @@ -86,13 +85,13 @@ export class ZodString extends ZodType { } const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.string) { + if (parsedType !== 'string') { const ctx = this._getOrReturnCtx(input) addIssueToContext( ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.string, + code: 'invalid_type', + expected: 'string', received: ctx.parsedType, } // @@ -108,7 +107,7 @@ export class ZodString extends ZodType { if (input.data.length < check.value) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', minimum: check.value, type: 'string', inclusive: true, @@ -121,7 +120,7 @@ export class ZodString extends ZodType { if (input.data.length > check.value) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: check.value, type: 'string', inclusive: true, @@ -137,7 +136,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) if (tooBig) { addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: check.value, type: 'string', inclusive: true, @@ -146,7 +145,7 @@ export class ZodString extends ZodType { }) } else if (tooSmall) { addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', minimum: check.value, type: 'string', inclusive: true, @@ -161,7 +160,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'email', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -174,7 +173,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'emoji', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -184,7 +183,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'uuid', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -194,7 +193,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'cuid', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -204,7 +203,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'cuid2', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -214,7 +213,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'ulid', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -226,7 +225,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'url', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -238,7 +237,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'regex', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -249,7 +248,7 @@ export class ZodString extends ZodType { if (!(input.data as string).includes(check.value, check.position)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_string, + code: 'invalid_string', validation: { includes: check.value, position: check.position }, message: check.message, }) @@ -263,7 +262,7 @@ export class ZodString extends ZodType { if (!(input.data as string).startsWith(check.value)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_string, + code: 'invalid_string', validation: { startsWith: check.value }, message: check.message, }) @@ -273,7 +272,7 @@ export class ZodString extends ZodType { if (!(input.data as string).endsWith(check.value)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_string, + code: 'invalid_string', validation: { endsWith: check.value }, message: check.message, }) @@ -285,7 +284,7 @@ export class ZodString extends ZodType { if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_string, + code: 'invalid_string', validation: 'datetime', message: check.message, }) @@ -296,7 +295,7 @@ export class ZodString extends ZodType { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { validation: 'ip', - code: ZodIssueCode.invalid_string, + code: 'invalid_string', message: check.message, }) status.dirty() @@ -312,7 +311,7 @@ export class ZodString extends ZodType { protected _regex(regex: RegExp, validation: StringValidation, message?: utils.errors.ErrMessage) { return this.refinement((data) => regex.test(data), { validation, - code: ZodIssueCode.invalid_string, + code: 'invalid_string', ...utils.errors.errToObj(message), }) } diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index cf021645c61..de1e3c8e35c 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -19,11 +17,11 @@ export type ZodSymbolDef = { export class ZodSymbol extends ZodType { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.symbol) { + if (parsedType !== 'symbol') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.symbol, + code: 'invalid_type', + expected: 'symbol', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index c4d9fa0f1d0..32a070d794f 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -77,7 +77,7 @@ test('z.NEVER in transform', () => { .optional() .transform((val, ctx) => { if (!val) { - ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'bad' }) + ctx.addIssue({ code: 'custom', message: 'bad' }) return z.NEVER } return val @@ -202,13 +202,13 @@ test('short circuit on dirty', () => { const result = schema.safeParse('asdf') expect(result.success).toEqual(false) if (!result.success) { - expect(result.error.issues[0]?.code).toEqual(z.ZodIssueCode.custom) + expect(result.error.issues[0]?.code).toEqual('custom') } const result2 = schema.safeParse(1234) expect(result2.success).toEqual(false) if (!result2.success) { - expect(result2.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_type) + expect(result2.error.issues[0]?.code).toEqual('invalid_type') } }) @@ -220,12 +220,12 @@ test('async short circuit on dirty', async () => { const result = await schema.spa('asdf') expect(result.success).toEqual(false) if (!result.success) { - expect(result.error.issues[0]?.code).toEqual(z.ZodIssueCode.custom) + expect(result.error.issues[0]?.code).toEqual('custom') } const result2 = await schema.spa(1234) expect(result2.success).toEqual(false) if (!result2.success) { - expect(result2.error.issues[0]?.code).toEqual(z.ZodIssueCode.invalid_type) + expect(result2.error.issues[0]?.code).toEqual('invalid_type') } }) diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 86562e4882e..e25ac371c78 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -1,4 +1,3 @@ -import { ZodIssueCode } from '../../error' import * as utils from '../../utils' import { ParseInputLazyPath, @@ -6,7 +5,6 @@ import { ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, ParseInput, @@ -73,10 +71,10 @@ export class ZodTuple< _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) - if (ctx.parsedType !== ZodParsedType.array) { + if (ctx.parsedType !== 'array') { addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.array, + code: 'invalid_type', + expected: 'array', received: ctx.parsedType, }) return INVALID @@ -84,7 +82,7 @@ export class ZodTuple< if (ctx.data.length < this._def.items.length) { addIssueToContext(ctx, { - code: ZodIssueCode.too_small, + code: 'too_small', minimum: this._def.items.length, inclusive: true, exact: false, @@ -98,7 +96,7 @@ export class ZodTuple< if (!rest && ctx.data.length > this._def.items.length) { addIssueToContext(ctx, { - code: ZodIssueCode.too_big, + code: 'too_big', maximum: this._def.items.length, inclusive: true, exact: false, diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index f3a1c437c37..fb27685620b 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -20,11 +18,11 @@ export type ZodUndefinedDef = { export class ZodUndefined extends ZodType { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.undefined) { + if (parsedType !== 'undefined') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.undefined, + code: 'invalid_type', + expected: 'undefined', received: ctx.parsedType, }) return INVALID diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index f91727a7674..e069bd29569 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,4 +1,4 @@ -import { ZodError, ZodIssue, ZodIssueCode } from '../../error' +import { ZodError, ZodIssue } from '../../error' import * as utils from '../../utils' import { RawCreateParams, @@ -76,7 +76,7 @@ export class ZodUnion extend const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues)) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_union, + code: 'invalid_union', unionErrors, }) return INVALID @@ -139,7 +139,7 @@ export class ZodUnion extend const unionErrors = issues.map((issues) => new ZodError(issues)) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_union, + code: 'invalid_union', unionErrors, }) diff --git a/packages/zui/src/z/types/utils/index.ts b/packages/zui/src/z/types/utils/index.ts index f9ec33c3b1a..80d9c5c26de 100644 --- a/packages/zui/src/z/types/utils/index.ts +++ b/packages/zui/src/z/types/utils/index.ts @@ -24,77 +24,54 @@ export type ZodParsedType = | 'map' | 'set' -export const ZodParsedType = { - string: 'string', - nan: 'nan', - number: 'number', - integer: 'integer', - float: 'float', - boolean: 'boolean', - date: 'date', - bigint: 'bigint', - symbol: 'symbol', - function: 'function', - undefined: 'undefined', - null: 'null', - array: 'array', - object: 'object', - unknown: 'unknown', - promise: 'promise', - void: 'void', - never: 'never', - map: 'map', - set: 'set', -} as const satisfies { [k in ZodParsedType]: k } - export const getParsedType = (data: any): ZodParsedType => { const t = typeof data switch (t) { case 'undefined': - return ZodParsedType.undefined + return 'undefined' case 'string': - return ZodParsedType.string + return 'string' case 'number': - return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number + return isNaN(data) ? 'nan' : 'number' case 'boolean': - return ZodParsedType.boolean + return 'boolean' case 'function': - return ZodParsedType.function + return 'function' case 'bigint': - return ZodParsedType.bigint + return 'bigint' case 'symbol': - return ZodParsedType.symbol + return 'symbol' case 'object': if (Array.isArray(data)) { - return ZodParsedType.array + return 'array' } if (data === null) { - return ZodParsedType.null + return 'null' } if (data.then && typeof data.then === 'function' && data.catch && typeof data.catch === 'function') { - return ZodParsedType.promise + return 'promise' } if (typeof Map !== 'undefined' && data instanceof Map) { - return ZodParsedType.map + return 'map' } if (typeof Set !== 'undefined' && data instanceof Set) { - return ZodParsedType.set + return 'set' } if (typeof Date !== 'undefined' && data instanceof Date) { - return ZodParsedType.date + return 'date' } - return ZodParsedType.object + return 'object' default: - return ZodParsedType.unknown + return 'unknown' } } diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index 89c20c9bdcb..8afd0192cb8 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,10 +1,8 @@ -import { ZodIssueCode } from '../../error' import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, - ZodParsedType, addIssueToContext, INVALID, OK, @@ -19,11 +17,11 @@ export type ZodVoidDef = { export class ZodVoid extends ZodType { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) - if (parsedType !== ZodParsedType.undefined) { + if (parsedType !== 'undefined') { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { - code: ZodIssueCode.invalid_type, - expected: ZodParsedType.void, + code: 'invalid_type', + expected: 'void', received: ctx.parsedType, }) return INVALID From 1f8492e9509cc5eeb12476f5f7e3702b90fe0d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 13:02:33 -0500 Subject: [PATCH 14/50] chore(zui): move parsing utils to basetype (#14962) --- packages/zui/src/z/error/index.ts | 2 +- packages/zui/src/z/types/basetype/index.ts | 32 +++-- .../z/types/{utils => basetype}/parseUtil.ts | 114 +++++++++++++++++- packages/zui/src/z/types/index.ts | 2 - packages/zui/src/z/types/utils/index.ts | 112 ----------------- packages/zui/src/z/z.ts | 3 +- 6 files changed, 133 insertions(+), 132 deletions(-) rename packages/zui/src/z/types/{utils => basetype}/parseUtil.ts (63%) delete mode 100644 packages/zui/src/z/types/utils/index.ts diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index 74fb78bdc5a..9b1939bd4a3 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -1,4 +1,4 @@ -import { ZodParsedType } from '../types/utils' +import type { ZodParsedType } from '../types/basetype' import * as utils from '../utils' import { errorMap as defaultErrorMap } from './locales/en' diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index de752e0298f..152c2c1827a 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -14,20 +14,8 @@ import type { import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap } from '../../error' import * as utils from '../../utils' import { CatchFn } from '../catch' + import { - AsyncParseReturnType, - getParsedType, - isAsync, - isValid, - ParseContext, - ParseInput, - ParseParams, - ParsePath, - ParseReturnType, - ParseStatus, - processCreateParams, - RefinementEffect, - SyncParseReturnType, ZodArray, ZodBranded, ZodCatch, @@ -40,8 +28,26 @@ import { ZodPromise, ZodReadonly, ZodUnion, + RefinementEffect, } from '../index' +import { + AsyncParseReturnType, + getParsedType, + isAsync, + isValid, + ParseContext, + ParseInput, + ParseParams, + ParsePath, + ParseReturnType, + ParseStatus, + processCreateParams, + SyncParseReturnType, +} from './parseUtil' + +export * from './parseUtil' + /** * This type is not part of the original Zod library, it's been added in Zui to: * - Brand the type as a ZuiType and avoid conflicts with 'zod' types diff --git a/packages/zui/src/z/types/utils/parseUtil.ts b/packages/zui/src/z/types/basetype/parseUtil.ts similarity index 63% rename from packages/zui/src/z/types/utils/parseUtil.ts rename to packages/zui/src/z/types/basetype/parseUtil.ts index b97466607a4..7d262f9977d 100644 --- a/packages/zui/src/z/types/utils/parseUtil.ts +++ b/packages/zui/src/z/types/basetype/parseUtil.ts @@ -1,5 +1,6 @@ -import { IssueData, ZodErrorMap, ZodIssue, defaultErrorMap, getErrorMap } from '../../error' -import type { ZodParsedType } from '.' +import { zuiKey } from '../../../ui/constants' +import { type IssueData, type ZodIssue, type ZodErrorMap, defaultErrorMap, getErrorMap } from '../../error' +import type { ProcessedCreateParams, RawCreateParams } from '../index' export const makeIssue = (params: { data: any @@ -165,3 +166,112 @@ export const isDirty = (x: ParseReturnType): x is OK | DIRTY => export const isValid = (x: ParseReturnType): x is OK => (x as SyncParseReturnType).status === 'valid' export const isAsync = (x: ParseReturnType): x is AsyncParseReturnType => typeof Promise !== 'undefined' && x instanceof Promise + +export type ZodParsedType = + | 'string' + | 'nan' + | 'number' + | 'integer' + | 'float' + | 'boolean' + | 'date' + | 'bigint' + | 'symbol' + | 'function' + | 'undefined' + | 'null' + | 'array' + | 'object' + | 'unknown' + | 'promise' + | 'void' + | 'never' + | 'map' + | 'set' + +export const getParsedType = (data: any): ZodParsedType => { + const t = typeof data + + switch (t) { + case 'undefined': + return 'undefined' + + case 'string': + return 'string' + + case 'number': + return isNaN(data) ? 'nan' : 'number' + + case 'boolean': + return 'boolean' + + case 'function': + return 'function' + + case 'bigint': + return 'bigint' + + case 'symbol': + return 'symbol' + + case 'object': + if (Array.isArray(data)) { + return 'array' + } + if (data === null) { + return 'null' + } + if (data.then && typeof data.then === 'function' && data.catch && typeof data.catch === 'function') { + return 'promise' + } + if (typeof Map !== 'undefined' && data instanceof Map) { + return 'map' + } + if (typeof Set !== 'undefined' && data instanceof Set) { + return 'set' + } + if (typeof Date !== 'undefined' && data instanceof Date) { + return 'date' + } + return 'object' + + default: + return 'unknown' + } +} + +export function processCreateParams( + params: RawCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) +): ProcessedCreateParams { + if (!params) return {} + + const { + errorMap, + invalid_type_error, + required_error, + description, + supportsExtensions, + [zuiKey]: zuiExtensions, + } = params + + if (errorMap && (invalid_type_error || required_error)) { + throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.') + } + + const filteredZuiExtensions = zuiExtensions + ? Object.fromEntries( + Object.entries(zuiExtensions).filter(([key]) => key !== 'secret' || supportsExtensions?.includes('secret')) + ) + : undefined + + if (errorMap) return { errorMap, description, [zuiKey]: filteredZuiExtensions } + + const customMap: ZodErrorMap = (iss, ctx) => { + if (iss.code !== 'invalid_type') return { message: ctx.defaultError } + if (typeof ctx.data === 'undefined') { + return { message: required_error ?? ctx.defaultError } + } + return { message: invalid_type_error ?? ctx.defaultError } + } + return { errorMap: customMap, description, [zuiKey]: filteredZuiExtensions } +} diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index 91746f1d8aa..b2a17c16a3d 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -6,8 +6,6 @@ export * from './basetype' export * from './native' -export * from './utils' -export * from './utils/parseUtil' export * from './any' export * from './array' export * from './bigint' diff --git a/packages/zui/src/z/types/utils/index.ts b/packages/zui/src/z/types/utils/index.ts deleted file mode 100644 index 80d9c5c26de..00000000000 --- a/packages/zui/src/z/types/utils/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { zuiKey } from '../../../ui/constants' -import type { ZodErrorMap } from '../../error' -import type { ProcessedCreateParams, RawCreateParams } from '../index' - -export type ZodParsedType = - | 'string' - | 'nan' - | 'number' - | 'integer' - | 'float' - | 'boolean' - | 'date' - | 'bigint' - | 'symbol' - | 'function' - | 'undefined' - | 'null' - | 'array' - | 'object' - | 'unknown' - | 'promise' - | 'void' - | 'never' - | 'map' - | 'set' - -export const getParsedType = (data: any): ZodParsedType => { - const t = typeof data - - switch (t) { - case 'undefined': - return 'undefined' - - case 'string': - return 'string' - - case 'number': - return isNaN(data) ? 'nan' : 'number' - - case 'boolean': - return 'boolean' - - case 'function': - return 'function' - - case 'bigint': - return 'bigint' - - case 'symbol': - return 'symbol' - - case 'object': - if (Array.isArray(data)) { - return 'array' - } - if (data === null) { - return 'null' - } - if (data.then && typeof data.then === 'function' && data.catch && typeof data.catch === 'function') { - return 'promise' - } - if (typeof Map !== 'undefined' && data instanceof Map) { - return 'map' - } - if (typeof Set !== 'undefined' && data instanceof Set) { - return 'set' - } - if (typeof Date !== 'undefined' && data instanceof Date) { - return 'date' - } - return 'object' - - default: - return 'unknown' - } -} - -export function processCreateParams( - params: RawCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) -): ProcessedCreateParams { - if (!params) return {} - - const { - errorMap, - invalid_type_error, - required_error, - description, - supportsExtensions, - [zuiKey]: zuiExtensions, - } = params - - if (errorMap && (invalid_type_error || required_error)) { - throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.') - } - - const filteredZuiExtensions = zuiExtensions - ? Object.fromEntries( - Object.entries(zuiExtensions).filter(([key]) => key !== 'secret' || supportsExtensions?.includes('secret')) - ) - : undefined - - if (errorMap) return { errorMap, description, [zuiKey]: filteredZuiExtensions } - - const customMap: ZodErrorMap = (iss, ctx) => { - if (iss.code !== 'invalid_type') return { message: ctx.defaultError } - if (typeof ctx.data === 'undefined') { - return { message: required_error ?? ctx.defaultError } - } - return { message: invalid_type_error ?? ctx.defaultError } - } - return { errorMap: customMap, description, [zuiKey]: filteredZuiExtensions } -} diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 69c66b94fb2..e87229fce5e 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -7,8 +7,7 @@ export { default } from './builders' // Re-export 'default' explicitly since exp export * from './types' export * from './error' -export * from './types/utils' -export * from './types/utils/parseUtil' + /** * @deprecated - use ZodType instead */ From 78792e5f80f9a4cf5bdebf4a6f6ca960f8ae3551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 18 Feb 2026 14:06:37 -0500 Subject: [PATCH 15/50] chore(zui): rm unused import --- packages/zui/src/z/error/error.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/zui/src/z/error/error.test.ts b/packages/zui/src/z/error/error.test.ts index 7b1be77ff19..bd53546e150 100644 --- a/packages/zui/src/z/error/error.test.ts +++ b/packages/zui/src/z/error/error.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../index' -import { ZodError, ZodIssueCode } from '.' +import { ZodError } from './index' test('error creation', () => { const err1 = ZodError.create([]) From d5b0db418957a950deb8d722e79cc2da18336f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Fri, 20 Feb 2026 14:07:07 -0500 Subject: [PATCH 16/50] chore(zui): cleanup API (#14964) --- .../zui-from-json-schema-legacy/index.ts | 2 +- .../transforms/zui-from-json-schema/index.ts | 7 +- .../src/transforms/zui-from-object/index.ts | 4 +- .../zui-to-json-schema-legacy/Options.ts | 2 +- .../zui-to-json-schema-legacy/Refs.ts | 2 +- .../zui-to-json-schema-legacy/parseDef.ts | 2 +- .../parsers/array.ts | 2 +- .../parsers/bigint.ts | 2 +- .../parsers/branded.ts | 2 +- .../parsers/catch.ts | 2 +- .../zui-to-json-schema-legacy/parsers/date.ts | 2 +- .../parsers/default.ts | 2 +- .../parsers/effects.ts | 2 +- .../zui-to-json-schema-legacy/parsers/enum.ts | 2 +- .../parsers/intersection.ts | 2 +- .../parsers/literal.ts | 2 +- .../zui-to-json-schema-legacy/parsers/map.ts | 2 +- .../parsers/nativeEnum.ts | 2 +- .../parsers/nullable.ts | 2 +- .../parsers/number.ts | 2 +- .../parsers/object.ts | 2 +- .../parsers/optional.ts | 2 +- .../parsers/pipeline.ts | 2 +- .../parsers/promise.ts | 2 +- .../parsers/readonly.ts | 2 +- .../parsers/record.ts | 2 +- .../zui-to-json-schema-legacy/parsers/set.ts | 2 +- .../parsers/string.ts | 2 +- .../parsers/tuple.ts | 2 +- .../parsers/union.ts | 2 +- .../zodToJsonSchema.ts | 2 +- .../zui-extension.ts | 2 +- .../zui/src/z/__tests__/parseUtil.test.ts | 22 --- .../zui/src/z/__tests__/preprocess.test.ts | 3 +- packages/zui/src/z/builders.ts | 2 +- packages/zui/src/z/error/index.ts | 2 + packages/zui/src/z/types/any/index.ts | 2 +- packages/zui/src/z/types/array/index.ts | 13 +- packages/zui/src/z/types/basetype/index.ts | 113 +++++------- .../src/z/types/basetype/parseUtil.test.ts | 21 +++ .../zui/src/z/types/basetype/parseUtil.ts | 43 ++++- packages/zui/src/z/types/bigint/index.ts | 2 +- packages/zui/src/z/types/boolean/index.ts | 2 +- packages/zui/src/z/types/branded/index.ts | 2 +- packages/zui/src/z/types/catch/index.ts | 2 +- packages/zui/src/z/types/date/index.ts | 2 +- packages/zui/src/z/types/default/index.ts | 2 +- .../src/z/types/discriminatedUnion/index.ts | 34 ++-- packages/zui/src/z/types/enum/index.ts | 59 +++---- packages/zui/src/z/types/function/index.ts | 25 +-- packages/zui/src/z/types/index.ts | 9 +- .../zui/src/z/types/intersection/index.ts | 96 +++++------ packages/zui/src/z/types/lazy/index.ts | 2 +- packages/zui/src/z/types/literal/index.ts | 2 +- packages/zui/src/z/types/map/index.ts | 2 +- packages/zui/src/z/types/nan/index.ts | 2 +- packages/zui/src/z/types/native.ts | 76 ++++----- packages/zui/src/z/types/nativeEnum/index.ts | 2 +- packages/zui/src/z/types/never/index.ts | 2 +- packages/zui/src/z/types/null/index.ts | 2 +- packages/zui/src/z/types/nullable/index.ts | 4 +- packages/zui/src/z/types/number/index.ts | 21 +-- packages/zui/src/z/types/object/index.ts | 161 +++++++++--------- packages/zui/src/z/types/optional/index.ts | 4 +- packages/zui/src/z/types/pipeline/index.ts | 2 +- packages/zui/src/z/types/promise/index.ts | 2 +- packages/zui/src/z/types/readonly/index.ts | 12 +- packages/zui/src/z/types/record/index.ts | 22 +-- packages/zui/src/z/types/ref/index.ts | 6 +- packages/zui/src/z/types/set/index.ts | 2 +- packages/zui/src/z/types/string/datetime.ts | 20 +-- packages/zui/src/z/types/string/index.ts | 5 +- packages/zui/src/z/types/symbol/index.ts | 2 +- packages/zui/src/z/types/transformer/index.ts | 5 +- .../z/types/transformer/transformer.test.ts | 3 +- packages/zui/src/z/types/tuple/index.ts | 31 ++-- packages/zui/src/z/types/undefined/index.ts | 6 +- packages/zui/src/z/types/union/index.ts | 15 +- packages/zui/src/z/types/unknown/index.ts | 2 +- packages/zui/src/z/types/void/index.ts | 2 +- packages/zui/src/z/utils/index.ts | 1 + packages/zui/src/z/utils/type-utils.ts | 4 + packages/zui/src/z/z.ts | 10 -- 83 files changed, 473 insertions(+), 486 deletions(-) delete mode 100644 packages/zui/src/z/__tests__/parseUtil.test.ts create mode 100644 packages/zui/src/z/types/basetype/parseUtil.test.ts diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts index a66de1dd15d..d039fce1307 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts @@ -20,7 +20,7 @@ import { ZodEnumDef, ZodDefaultDef, z, -} from '../../z/index' +} from '../../z' import * as errors from '../common/errors' import { evalZuiString } from '../common/eval-zui-string' import { JsonSchema7Type } from '../zui-to-json-schema-legacy/parseDef' diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index f2b1a647b81..b8d775d6ed4 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -1,5 +1,6 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema' import z from '../../z' +import type { ZodDiscriminatedUnionOption } from '../../z/types/discriminatedUnion' import * as utils from '../../z/utils' import * as errors from '../common/errors' import { ArraySchema, SetSchema, TupleSchema } from '../common/json-schema' @@ -174,9 +175,9 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { if (guards.isDiscriminatedUnionSchema(schema) && schema['x-zui']?.def?.discriminator) { const { discriminator } = schema['x-zui'].def const options = schema.anyOf.map(_fromJSONSchema) as [ - z.ZodDiscriminatedUnionOption, - z.ZodDiscriminatedUnionOption, - ...z.ZodDiscriminatedUnionOption[], + ZodDiscriminatedUnionOption, + ZodDiscriminatedUnionOption, + ...ZodDiscriminatedUnionOption[], ] return z.discriminatedUnion(discriminator, options) } diff --git a/packages/zui/src/transforms/zui-from-object/index.ts b/packages/zui/src/transforms/zui-from-object/index.ts index 9be97182f73..fd44756f71f 100644 --- a/packages/zui/src/transforms/zui-from-object/index.ts +++ b/packages/zui/src/transforms/zui-from-object/index.ts @@ -1,4 +1,4 @@ -import { z, SomeZodObject, ZodType } from '../../z/index' +import { z, ZodObject, ZodType } from '../../z' import * as errors from '../common/errors' // Using a basic regex do determine if it's a date or not to avoid using another lib for that @@ -65,7 +65,7 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true } } return acc - }, {} as SomeZodObject) + }, {} as ZodObject) const hasProperties = Object.keys(schema).length > 0 if (opts?.passtrough || (!isRoot && !hasProperties)) { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts index e2677eac87c..f199f8c20b5 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts @@ -1,4 +1,4 @@ -import type { ZodSchema } from '../../z/index' +import type { ZodSchema } from '../../z' export type Targets = 'jsonSchema7' | 'jsonSchema2019-09' | 'openApi3' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/Refs.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/Refs.ts index 9a201314aa6..43590d86f1c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/Refs.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/Refs.ts @@ -1,4 +1,4 @@ -import type { ZodTypeDef } from '../../z/index' +import type { ZodTypeDef } from '../../z' import { getDefaultOptions, Options, Targets } from './Options' import { JsonSchema7Type } from './parseDef' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts index e141ffeaead..854a3f7276e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts @@ -1,5 +1,5 @@ import { zuiKey } from '../../ui/constants' -import { ZodFirstPartyTypeKind, ZodDef } from '../../z/index' +import { ZodFirstPartyTypeKind, ZodDef } from '../../z' import { JsonSchema7AnyType, parseAnyDef } from './parsers/any' import { JsonSchema7ArrayType, parseArrayDef } from './parsers/array' import { JsonSchema7BigintType, parseBigintDef } from './parsers/bigint' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts index 4fd739dc66f..b58dd5f7193 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z/index' +import { ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts index 154305190f6..087e678b7d4 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodBigIntDef } from '../../../z/index' +import { ZodBigIntDef } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/branded.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/branded.ts index 5c22c70ba2d..5f97e0237bc 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/branded.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/branded.ts @@ -1,4 +1,4 @@ -import { ZodBrandedDef } from '../../../z/index' +import { ZodBrandedDef } from '../../../z' import { parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/catch.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/catch.ts index 90dbd2f2d0e..76ed37866a8 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/catch.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/catch.ts @@ -1,4 +1,4 @@ -import { ZodCatchDef } from '../../../z/index' +import { ZodCatchDef } from '../../../z' import { parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts index fa187d9a0de..eeda4bed18e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodDateDef } from '../../../z/index' +import { ZodDateDef } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' import { JsonSchema7NumberType } from './number' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts index c7bd69eb875..0d25191d50a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/default.ts @@ -1,4 +1,4 @@ -import { ZodDefaultDef, ZodTypeAny } from '../../../z/index' +import { ZodDefaultDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts index 00e6f8c4c0b..eb270e71829 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/effects.ts @@ -1,4 +1,4 @@ -import { ZodEffectsDef, ZodTypeAny } from '../../../z/index' +import { ZodEffectsDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts index af6bad2ead4..346443f9c5e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodEnumDef } from '../../../z/index' +import { ZodEnumDef } from '../../../z' export type JsonSchema7EnumType = { type: 'string' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts index 9216e5e346a..8953e644cee 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodIntersectionDef, ZodTypeAny } from '../../../z/index' +import { ZodIntersectionDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7StringType } from './string' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts index 49692bb04e6..ead804e3dc0 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodLiteralDef } from '../../../z/index' +import { ZodLiteralDef } from '../../../z' import { Refs } from '../Refs' export type JsonSchema7LiteralType = diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts index 2309809e33e..c7c678f6871 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodMapDef, ZodTypeAny } from '../../../z/index' +import { ZodMapDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7RecordType, parseRecordDef } from './record' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts index 32acc3f1463..ce450232731 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNativeEnumDef } from '../../../z/index' +import { ZodNativeEnumDef } from '../../../z' export type JsonSchema7NativeEnumType = { type: 'string' | 'number' | ['string', 'number'] diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts index f0c6e499d7d..91ce8dd2851 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNullableDef, ZodTypeAny } from '../../../z/index' +import { ZodNullableDef, ZodTypeAny } from '../../../z' import { addMeta, JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7NullType } from './null' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts index e14f6c16851..46cbb3669d0 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNumberDef } from '../../../z/index' +import { ZodNumberDef } from '../../../z' import { addErrorMessage, ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts index 3c3968f8701..4262add5ec7 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodObjectDef, ZodType, ZodTypeAny } from '../../../z/index' +import { ZodObjectDef, ZodType, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts index e5832358049..817688a858e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/optional.ts @@ -1,4 +1,4 @@ -import { ZodOptionalDef, ZodTypeAny } from '../../../z/index' +import { ZodOptionalDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/pipeline.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/pipeline.ts index ebe6b756bde..dd50a4bc2df 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/pipeline.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/pipeline.ts @@ -1,4 +1,4 @@ -import { ZodPipelineDef } from '../../../z/index' +import { ZodPipelineDef } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7AllOfType } from './intersection' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts index 289f8d307f3..8a527be7ee4 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/promise.ts @@ -1,4 +1,4 @@ -import { ZodPromiseDef, ZodTypeAny } from '../../../z/index' +import { ZodPromiseDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/readonly.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/readonly.ts index 1c14ed746ea..6518c4fdefe 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/readonly.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/readonly.ts @@ -1,4 +1,4 @@ -import { ZodReadonlyDef } from '../../../z/index' +import { ZodReadonlyDef } from '../../../z' import { parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts index 8a3c21e4b2d..9ea2146c94d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodType, ZodTypeAny } from '../../../z/index' +import { ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodType, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7EnumType } from './enum' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts index da2f464df88..46cab43420f 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodSetDef, ZodTypeAny } from '../../../z/index' +import { ZodSetDef, ZodTypeAny } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts index 7529d9c9aeb..0343287ba31 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodStringDef } from '../../../z/index' +import { ZodStringDef } from '../../../z' import { regexUtils } from '../../common' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts index 721973c9cf0..4eb3491d24c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodTupleDef, ZodTupleItems, ZodType, ZodTypeAny } from '../../../z/index' +import { ZodTupleDef, ZodTupleItems, ZodType, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts index 2f1ddc88401..a0c23e2c0d9 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts @@ -1,6 +1,6 @@ import { zuiKey } from '../../../ui/constants' import { ZuiExtensionObject } from '../../../ui/types' -import { ZodDiscriminatedUnionDef, ZodLiteralDef, ZodTypeAny, ZodUnionDef } from '../../../z/index' +import { ZodDiscriminatedUnionDef, ZodLiteralDef, ZodTypeAny, ZodUnionDef } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts index 4a28b896cdc..8c2a57b6200 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts @@ -1,4 +1,4 @@ -import type { ZodDef, ZodSchema } from '../../z/index' +import type { ZodDef, ZodSchema } from '../../z' import { Options, Targets } from './Options' import { JsonSchema7Type, parseDef } from './parseDef' import { getRefs } from './Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts index 98b174e86fb..45223edaa3e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts @@ -1,5 +1,5 @@ import { JSONSchema7 } from 'json-schema' -import { z } from '../../z/index' +import { z } from '../../z' import { Options } from './Options' import { zodToJsonSchema } from './zodToJsonSchema' diff --git a/packages/zui/src/z/__tests__/parseUtil.test.ts b/packages/zui/src/z/__tests__/parseUtil.test.ts deleted file mode 100644 index 3649f3ab52b..00000000000 --- a/packages/zui/src/z/__tests__/parseUtil.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { test, expect } from 'vitest' -import z from '../index' -import type { SyncParseReturnType } from '../types' - -test('parseUtil isInvalid should use structural typing', () => { - // Test for issue #556: https://github.com/colinhacks/zod/issues/556 - const aborted: SyncParseReturnType = { status: 'aborted' } - const dirty: SyncParseReturnType = { status: 'dirty', value: 'whatever' } - const valid: SyncParseReturnType = { status: 'valid', value: 'whatever' } - - expect(z.isAborted(aborted)).toBe(true) - expect(z.isAborted(dirty)).toBe(false) - expect(z.isAborted(valid)).toBe(false) - - expect(z.isDirty(aborted)).toBe(false) - expect(z.isDirty(dirty)).toBe(true) - expect(z.isDirty(valid)).toBe(false) - - expect(z.isValid(aborted)).toBe(false) - expect(z.isValid(dirty)).toBe(false) - expect(z.isValid(valid)).toBe(true) -}) diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 28634750382..a28a246d7e0 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' import * as utils from '../../z/utils' import z from '../index' +import { NEVER } from '../types/basetype' test('preprocess', () => { const schema = z.preprocess((data) => [data], z.string().array()) @@ -126,7 +127,7 @@ test('z.NEVER in preprocess', () => { const foo = z.preprocess((val, ctx) => { if (!val) { ctx.addIssue({ code: 'custom', message: 'bad' }) - return z.NEVER + return NEVER } return val }, z.number()) diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index 26bc03a3024..d948d22dca9 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -1,5 +1,5 @@ +import type { CustomErrorParams } from './error' import { - CustomErrorParams, ZodAny, ZodArray, ZodBigInt, diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index 9b1939bd4a3..710c565d2d7 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -139,6 +139,8 @@ export type ZodIssue = ZodIssueOptionalMessage & { message: string } +export type CustomErrorParams = Partial> + export const quotelessJson = (obj: any) => { const json = JSON.stringify(obj, null, 2) return json.replace(/"([^"]+)":/g, '$1:') diff --git a/packages/zui/src/z/types/any/index.ts b/packages/zui/src/z/types/any/index.ts index 7e5176ad02a..e118c3f3123 100644 --- a/packages/zui/src/z/types/any/index.ts +++ b/packages/zui/src/z/types/any/index.ts @@ -1,4 +1,4 @@ -import { RawCreateParams, ZodType, ZodTypeDef, OK, ParseInput, ParseReturnType, processCreateParams } from '../index' +import { RawCreateParams, ZodType, ZodTypeDef, OK, ParseInput, ParseReturnType, processCreateParams } from '../basetype' export type ZodAnyDef = { typeName: 'ZodAny' diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index a98ae670bbc..15d05f755bd 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -11,7 +11,7 @@ import { ParseInput, ParseReturnType, ParseStatus, -} from '../index' +} from '../basetype' export type ZodArrayDef = { type: T @@ -21,14 +21,15 @@ export type ZodArrayDef = { maxLength: { value: number; message?: string } | null } & ZodTypeDef -export type ArrayCardinality = 'many' | 'atleastone' -export type arrayOutputType< +type _ArrayCardinality = 'many' | 'atleastone' + +type _ArrayOutputType< T extends ZodType, - Cardinality extends ArrayCardinality = 'many', + Cardinality extends _ArrayCardinality = 'many', > = Cardinality extends 'atleastone' ? [T['_output'], ...T['_output'][]] : T['_output'][] -export class ZodArray extends ZodType< - arrayOutputType, +export class ZodArray extends ZodType< + _ArrayOutputType, ZodArrayDef, Cardinality extends 'atleastone' ? [T['_input'], ...T['_input'][]] : T['_input'][] > { diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 152c2c1827a..495e316ddc7 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -11,24 +11,25 @@ import type { ZuiExtensionObject, ZuiMetadata, } from '../../../ui/types' -import { IssueData, ZodCustomIssue, ZodError, ZodErrorMap } from '../../error' +import { type CustomErrorParams, type IssueData, type ZodErrorMap, ZodError } from '../../error' import * as utils from '../../utils' -import { CatchFn } from '../catch' +// TODO(circle): these may potentially cause circular dependencies errors import { ZodArray, ZodBranded, ZodCatch, + type CatchFn, ZodDefault, - ZodEffects, ZodIntersection, ZodNullable, ZodOptional, ZodPipeline, ZodPromise, ZodReadonly, + ZodEffects, + type RefinementEffect, ZodUnion, - RefinementEffect, } from '../index' import { @@ -39,7 +40,6 @@ import { ParseContext, ParseInput, ParseParams, - ParsePath, ParseReturnType, ParseStatus, processCreateParams, @@ -70,14 +70,13 @@ export type RefinementCtx = { addIssue: (arg: IssueData) => void path: (string | number)[] } -export type ZodRawShape = { [k: string]: ZodType } + export type TypeOf = T['_output'] export type OfType = T extends __ZodType ? T : never export type input = T['_input'] export type output = T['_output'] export type { TypeOf as infer } -export type Maskable = boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) -export type CustomErrorParams = Partial> + export type ZodTypeDef = { typeName: string errorMap?: ZodErrorMap @@ -85,72 +84,12 @@ export type ZodTypeDef = { [zuiKey]?: ZuiExtensionObject } -export class ParseInputLazyPath implements ParseInput { - parent: ParseContext - data: any - _path: ParsePath - _key: string | number | (string | number)[] - _cachedPath: ParsePath = [] - constructor(parent: ParseContext, value: any, path: ParsePath, key: string | number | (string | number)[]) { - this.parent = parent - this.data = value - this._path = path - this._key = key - } - get path() { - if (!this._cachedPath.length) { - if (this._key instanceof Array) { - this._cachedPath.push(...this._path, ...this._key) - } else { - this._cachedPath.push(...this._path, this._key) - } - } - - return this._cachedPath - } -} -const handleResult = ( - ctx: ParseContext, - result: SyncParseReturnType -): { success: true; data: Output } | { success: false; error: ZodError } => { - if (isValid(result)) { - return { success: true, data: result.value } - } else { - if (!ctx.common.issues.length) { - throw new Error('Validation failed but no issues detected.') - } - - return { - success: false, - get error() { - if ((this as any)._error) return (this as any)._error as Error - const error = new ZodError(ctx.common.issues) - ;(this as any)._error = error - return (this as any)._error - }, - } - } -} - -export type RawCreateParams = - | { - errorMap?: ZodErrorMap - invalid_type_error?: string - required_error?: string - description?: string - [zuiKey]?: ZuiExtensionObject - } - | undefined -export type ProcessedCreateParams = { - errorMap?: ZodErrorMap - description?: string - [zuiKey]?: ZuiExtensionObject -} export type SafeParseSuccess = { success: true data: Output error?: never } + export type SafeParseError = { success: false error: ZodError @@ -159,6 +98,13 @@ export type SafeParseError = { export type SafeParseReturnType = SafeParseSuccess | SafeParseError +export { ZodType as Schema, ZodType as ZodSchema } + +/** + * @deprecated - use ZodType instead + */ +export type ZodTypeAny = ZodType + export abstract class ZodType implements __ZodType { @@ -270,7 +216,7 @@ export abstract class ZodType): Promise { @@ -295,7 +241,7 @@ export abstract class ZodType) { + catch(def: Output | CatchFn): ZodCatch { const catchValueFunc = typeof def === 'function' ? (def as CatchFn) : () => def return new ZodCatch({ @@ -661,4 +607,27 @@ export abstract class ZodType( + ctx: ParseContext, + result: SyncParseReturnType + ): { success: true; data: Output } | { success: false; error: ZodError } => { + if (isValid(result)) { + return { success: true, data: result.value } + } else { + if (!ctx.common.issues.length) { + throw new Error('Validation failed but no issues detected.') + } + + return { + success: false, + get error() { + if ((this as any)._error) return (this as any)._error as Error + const error = new ZodError(ctx.common.issues) + ;(this as any)._error = error + return (this as any)._error + }, + } + } + } } diff --git a/packages/zui/src/z/types/basetype/parseUtil.test.ts b/packages/zui/src/z/types/basetype/parseUtil.test.ts new file mode 100644 index 00000000000..9e6c65c57e9 --- /dev/null +++ b/packages/zui/src/z/types/basetype/parseUtil.test.ts @@ -0,0 +1,21 @@ +import { test, expect } from 'vitest' +import { isAborted, isDirty, isValid, SyncParseReturnType } from './parseUtil' + +test('parseUtil isInvalid should use structural typing', () => { + // Test for issue #556: https://github.com/colinhacks/zod/issues/556 + const aborted: SyncParseReturnType = { status: 'aborted' } + const dirty: SyncParseReturnType = { status: 'dirty', value: 'whatever' } + const valid: SyncParseReturnType = { status: 'valid', value: 'whatever' } + + expect(isAborted(aborted)).toBe(true) + expect(isAborted(dirty)).toBe(false) + expect(isAborted(valid)).toBe(false) + + expect(isDirty(aborted)).toBe(false) + expect(isDirty(dirty)).toBe(true) + expect(isDirty(valid)).toBe(false) + + expect(isValid(aborted)).toBe(false) + expect(isValid(dirty)).toBe(false) + expect(isValid(valid)).toBe(true) +}) diff --git a/packages/zui/src/z/types/basetype/parseUtil.ts b/packages/zui/src/z/types/basetype/parseUtil.ts index 7d262f9977d..b5c3565b4e8 100644 --- a/packages/zui/src/z/types/basetype/parseUtil.ts +++ b/packages/zui/src/z/types/basetype/parseUtil.ts @@ -1,6 +1,22 @@ import { zuiKey } from '../../../ui/constants' +import { ZuiExtensionObject } from '../../../ui/types' import { type IssueData, type ZodIssue, type ZodErrorMap, defaultErrorMap, getErrorMap } from '../../error' -import type { ProcessedCreateParams, RawCreateParams } from '../index' + +export type RawCreateParams = + | { + errorMap?: ZodErrorMap + invalid_type_error?: string + required_error?: string + description?: string + [zuiKey]?: ZuiExtensionObject + } + | undefined + +export type ProcessedCreateParams = { + errorMap?: ZodErrorMap + description?: string + [zuiKey]?: ZuiExtensionObject +} export const makeIssue = (params: { data: any @@ -275,3 +291,28 @@ export function processCreateParams( } return { errorMap: customMap, description, [zuiKey]: filteredZuiExtensions } } + +export class ParseInputLazyPath implements ParseInput { + parent: ParseContext + data: any + _path: ParsePath + _key: string | number | (string | number)[] + _cachedPath: ParsePath = [] + constructor(parent: ParseContext, value: any, path: ParsePath, key: string | number | (string | number)[]) { + this.parent = parent + this.data = value + this._path = path + this._key = key + } + get path() { + if (!this._cachedPath.length) { + if (this._key instanceof Array) { + this._cachedPath.push(...this._path, ...this._key) + } else { + this._cachedPath.push(...this._path, this._key) + } + } + + return this._cachedPath + } +} diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index a94ee56b59d..9a366382242 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -10,7 +10,7 @@ import { ZodType, ZodTypeDef, processCreateParams, -} from '../index' +} from '../basetype' export type ZodBigIntCheck = | { kind: 'min'; value: bigint; inclusive: boolean; message?: string } diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index 6fa7d54f3f2..00f65636da9 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -8,7 +8,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodBooleanDef = { typeName: 'ZodBoolean' diff --git a/packages/zui/src/z/types/branded/index.ts b/packages/zui/src/z/types/branded/index.ts index c0d86e0ec8f..0e9e83d6b43 100644 --- a/packages/zui/src/z/types/branded/index.ts +++ b/packages/zui/src/z/types/branded/index.ts @@ -1,4 +1,4 @@ -import { ZodType, ZodTypeDef, ParseInput, ParseReturnType } from '../index' +import { ZodType, ZodTypeDef, ParseInput, ParseReturnType } from '../basetype' type Key = string | number | symbol diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index bd2b7681d55..b50622d4fd5 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -9,7 +9,7 @@ import { ParseContext, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type CatchFn = (ctx: { error: ZodError; input: unknown }) => Y export type ZodCatchDef = { diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index 77a49e6e494..206649a4117 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -10,7 +10,7 @@ import { ParseStatus, ZodType, RawCreateParams, -} from '../index' +} from '../basetype' export type ZodDateCheck = | { kind: 'min'; value: number; message?: string } diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 3ccdc4c0853..02289eb6d3b 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -9,7 +9,7 @@ import { processCreateParams, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodDefaultDef = { innerType: T diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index 97509f81c7d..ee7604aba48 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,32 +1,32 @@ import * as utils from '../../utils' import { - ZodBranded, - ZodCatch, - ZodDefault, - ZodEnum, input, output, RawCreateParams, - ZodRawShape, ZodType, ZodTypeDef, - ZodLazy, - ZodLiteral, - ZodNativeEnum, - ZodNull, - ZodNullable, - UnknownKeysParam, - ZodObject, - ZodOptional, - ZodReadonly, - ZodEffects, - ZodUndefined, processCreateParams, addIssueToContext, INVALID, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' + +// TODO(circle): these may potentially cause circular dependencies errors +import { ZodBranded } from '../branded' +import { ZodCatch } from '../catch' +import { ZodDefault } from '../default' +import { ZodEnum } from '../enum' +import { ZodLazy } from '../lazy' +import { ZodLiteral } from '../literal' +import { ZodNativeEnum } from '../nativeEnum' +import { ZodNull } from '../null' +import { ZodNullable } from '../nullable' +import { ZodObject, type ZodRawShape, type UnknownKeysParam } from '../object' +import { ZodOptional } from '../optional' +import { ZodReadonly } from '../readonly' +import { ZodEffects } from '../transformer' +import { ZodUndefined } from '../undefined' const getDiscriminator = (type: T): utils.types.Primitive[] => { if (type instanceof ZodLazy) { diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index b1af8f4e1eb..204f2809594 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -9,14 +9,11 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' - -export type ArrayKeys = keyof any[] -export type Indices = Exclude +} from '../basetype' export type EnumValues = [string, ...string[]] -export type Values = { +export type EnumValuesMap = { [k in T[number]]: k } @@ -25,32 +22,15 @@ export type ZodEnumDef = { typeName: 'ZodEnum' } & ZodTypeDef -export type Writeable = { - -readonly [P in keyof T]: T[P] -} - -export type FilterEnum = Values extends [] +type _FilterEnum = Values extends [] ? [] : Values extends [infer Head, ...infer Rest] ? Head extends ToExclude - ? FilterEnum - : [Head, ...FilterEnum] + ? _FilterEnum + : [Head, ..._FilterEnum] : never -export type typecast = A extends T ? A : never - -export function createZodEnum>( - values: T, - params?: RawCreateParams -): ZodEnum> -export function createZodEnum(values: T, params?: RawCreateParams): ZodEnum -export function createZodEnum(values: [string, ...string[]], params?: RawCreateParams) { - return new ZodEnum({ - values, - typeName: 'ZodEnum', - ...processCreateParams(params), - }) -} +type _NeverCast = A extends T ? A : never export class ZodEnum extends ZodType< T[number], @@ -86,7 +66,7 @@ export class ZodEnum ex return this._def.values } - get enum(): Values { + get enum(): EnumValuesMap { const enumValues: any = {} for (const val of this._def.values) { enumValues[val] = val @@ -94,7 +74,7 @@ export class ZodEnum ex return enumValues } - get Values(): Values { + get Values(): EnumValuesMap { const enumValues: any = {} for (const val of this._def.values) { enumValues[val] = val @@ -102,7 +82,7 @@ export class ZodEnum ex return enumValues } - get Enum(): Values { + get Enum(): EnumValuesMap { const enumValues: any = {} for (const val of this._def.values) { enumValues[val] = val @@ -113,7 +93,7 @@ export class ZodEnum ex extract( values: ToExtract, newDef: RawCreateParams = this._def - ): ZodEnum> { + ): ZodEnum> { return ZodEnum.create(values, { ...this._def, ...newDef, @@ -123,14 +103,25 @@ export class ZodEnum ex exclude( values: ToExclude, newDef: RawCreateParams = this._def - ): ZodEnum>, [string, ...string[]]>> { - return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)) as FilterEnum, { + ): ZodEnum<_NeverCast>, [string, ...string[]]>> { + return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)) as _FilterEnum, { ...this._def, ...newDef, - }) as ZodEnum>, [string, ...string[]]>> + }) as ZodEnum<_NeverCast>, [string, ...string[]]>> } - static create = createZodEnum + static create>( + values: T, + params?: RawCreateParams + ): ZodEnum> + static create(values: T, params?: RawCreateParams): ZodEnum + static create(values: [string, ...string[]], params?: RawCreateParams) { + return new ZodEnum({ + values, + typeName: 'ZodEnum', + ...processCreateParams(params), + }) + } isEqual(schema: ZodType): boolean { if (!(schema instanceof ZodEnum)) return false diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 9ff07e152af..b86850eb9bf 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -4,10 +4,6 @@ import { RawCreateParams, ZodType, ZodTypeDef, - ZodPromise, - AnyZodTuple, - ZodTuple, - ZodUnknown, processCreateParams, addIssueToContext, INVALID, @@ -15,7 +11,12 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' + +// TODO(circle): these may potentially cause circular dependencies errors +import { ZodPromise } from '../promise' +import { ZodTuple, type AnyZodTuple } from '../tuple' +import { ZodUnknown } from '../unknown' export type ZodFunctionDef = ZodTuple, Returns extends ZodType = ZodType> = { args: Args @@ -23,16 +24,16 @@ export type ZodFunctionDef = ZodTuple, Returns e typeName: 'ZodFunction' } & ZodTypeDef -export type OuterTypeOfFunction, Returns extends ZodType> = +type _OuterTypeOfFunction, Returns extends ZodType> = Args['_input'] extends Array ? (...args: Args['_input']) => Returns['_output'] : never -export type InnerTypeOfFunction, Returns extends ZodType> = +type _InnerTypeOfFunction, Returns extends ZodType> = Args['_output'] extends Array ? (...args: Args['_output']) => Returns['_input'] : never export class ZodFunction = ZodTuple, Returns extends ZodType = ZodType> extends ZodType< - OuterTypeOfFunction, + _OuterTypeOfFunction, ZodFunctionDef, - InnerTypeOfFunction + _InnerTypeOfFunction > { dereference(defs: Record): ZodType { const args = this._def.args.dereference(defs) as ZodTuple<[], ZodUnknown> @@ -163,16 +164,16 @@ export class ZodFunction = ZodTuple, Returns ext }) } - implement>( + implement>( func: F ): ReturnType extends Returns['_output'] ? (...args: Args['_input']) => ReturnType - : OuterTypeOfFunction { + : _OuterTypeOfFunction { const validatedFunc = this.parse(func) return validatedFunc } - strictImplement(func: InnerTypeOfFunction): InnerTypeOfFunction { + strictImplement(func: _InnerTypeOfFunction): _InnerTypeOfFunction { const validatedFunc = this.parse(func) return validatedFunc } diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index b2a17c16a3d..68581b6785d 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -1,11 +1,4 @@ -/** - * DO NOT CHANGE IMPORT ORDER - * Internal pattern to get rid of circular dependencies - * @see https://medium.com/p/a04c987cf0de - */ - export * from './basetype' -export * from './native' export * from './any' export * from './array' export * from './bigint' @@ -17,7 +10,6 @@ export * from './default' export * from './discriminatedUnion' export * from './enum' export * from './function' -export * from './index' export * from './intersection' export * from './lazy' export * from './literal' @@ -44,3 +36,4 @@ export * from './undefined' export * from './union' export * from './unknown' export * from './void' +export * from './native' diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 7bce194368b..ae23f1a7940 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -12,7 +12,7 @@ import { ParseInput, ParseReturnType, SyncParseReturnType, -} from '../index' +} from '../basetype' export type ZodIntersectionDef = { left: T @@ -20,52 +20,6 @@ export type ZodIntersectionDef bKeys.indexOf(key) !== -1) - - const newObj: any = { ...a, ...b } - for (const key of sharedKeys) { - const sharedValue = mergeValues(a[key], b[key]) - if (!sharedValue.valid) { - return { valid: false } - } - newObj[key] = sharedValue.data - } - - return { valid: true, data: newObj } - } else if (aType === 'array' && bType === 'array') { - if (a.length !== b.length) { - return { valid: false } - } - - const newArray: unknown[] = [] - for (let index = 0; index < a.length; index++) { - const itemA = a[index] - const itemB = b[index] - const sharedValue = mergeValues(itemA, itemB) - - if (!sharedValue.valid) { - return { valid: false } - } - - newArray.push(sharedValue.data) - } - - return { valid: true, data: newArray } - } else if (aType === 'date' && bType === 'date' && +a === +b) { - return { valid: true, data: a } - } else { - return { valid: false } - } -} - export class ZodIntersection extends ZodType< T['_output'] & U['_output'], ZodIntersectionDef, @@ -101,7 +55,7 @@ export class ZodIntersection([schema._def.left, schema._def.right], { compare }) return thisItems.isEqual(thatItems) } + + private _mergeValues(a: any, b: any): { valid: true; data: any } | { valid: false } { + const aType = getParsedType(a) + const bType = getParsedType(b) + + if (a === b) { + return { valid: true, data: a } + } else if (aType === 'object' && bType === 'object') { + const bKeys = Object.keys(b) + const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1) + + const newObj: any = { ...a, ...b } + for (const key of sharedKeys) { + const sharedValue = this._mergeValues(a[key], b[key]) + if (!sharedValue.valid) { + return { valid: false } + } + newObj[key] = sharedValue.data + } + + return { valid: true, data: newObj } + } else if (aType === 'array' && bType === 'array') { + if (a.length !== b.length) { + return { valid: false } + } + + const newArray: unknown[] = [] + for (let index = 0; index < a.length; index++) { + const itemA = a[index] + const itemB = b[index] + const sharedValue = this._mergeValues(itemA, itemB) + + if (!sharedValue.valid) { + return { valid: false } + } + + newArray.push(sharedValue.data) + } + + return { valid: true, data: newArray } + } else if (aType === 'date' && bType === 'date' && +a === +b) { + return { valid: true, data: a } + } else { + return { valid: false } + } + } } diff --git a/packages/zui/src/z/types/lazy/index.ts b/packages/zui/src/z/types/lazy/index.ts index 4bbb881f91c..ee47ade9d08 100644 --- a/packages/zui/src/z/types/lazy/index.ts +++ b/packages/zui/src/z/types/lazy/index.ts @@ -7,7 +7,7 @@ import { ParseReturnType, output, input, -} from '../index' +} from '../basetype' export type ZodLazyDef = { getter: () => T diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index c92214b9e35..d5ea8f4dbd6 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -9,7 +9,7 @@ import { INVALID, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodLiteralDef = { value: T diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index 06c61e09d01..15247fb58c1 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -10,7 +10,7 @@ import { ParseInput, ParseReturnType, SyncParseReturnType, -} from '../index' +} from '../basetype' export type ZodMapDef = { valueType: Value diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index 3fe6d8bfc54..1e2c4773cbb 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -7,7 +7,7 @@ import { INVALID, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodNaNDef = { typeName: 'ZodNaN' diff --git a/packages/zui/src/z/types/native.ts b/packages/zui/src/z/types/native.ts index 033848829df..1bef2f35312 100644 --- a/packages/zui/src/z/types/native.ts +++ b/packages/zui/src/z/types/native.ts @@ -1,42 +1,40 @@ -import { - ZodAny, - ZodArray, - ZodBigInt, - ZodBoolean, - ZodBranded, - ZodCatch, - ZodDate, - ZodDefault, - ZodDiscriminatedUnion, - ZodEffects, - ZodEnum, - ZodFunction, - ZodIntersection, - ZodLazy, - ZodLiteral, - ZodMap, - ZodNaN, - ZodNativeEnum, - ZodNever, - ZodNull, - ZodNullable, - ZodNumber, - ZodObject, - ZodOptional, - ZodPipeline, - ZodPromise, - ZodReadonly, - ZodRecord, - ZodRef, - ZodSet, - ZodString, - ZodSymbol, - ZodTuple, - ZodUndefined, - ZodUnion, - ZodUnknown, - ZodVoid, -} from './index' +import { ZodAny } from './any' +import { ZodArray } from './array' +import { ZodBigInt } from './bigint' +import { ZodBoolean } from './boolean' +import { ZodBranded } from './branded' +import { ZodCatch } from './catch' +import { ZodDate } from './date' +import { ZodDefault } from './default' +import { ZodDiscriminatedUnion } from './discriminatedUnion' +import { ZodEnum } from './enum' +import { ZodFunction } from './function' +import { ZodIntersection } from './intersection' +import { ZodLazy } from './lazy' +import { ZodLiteral } from './literal' +import { ZodMap } from './map' +import { ZodNaN } from './nan' +import { ZodNativeEnum } from './nativeEnum' +import { ZodNever } from './never' +import { ZodNull } from './null' +import { ZodNullable } from './nullable' +import { ZodNumber } from './number' +import { ZodObject } from './object' +import { ZodOptional } from './optional' +import { ZodPipeline } from './pipeline' +import { ZodPromise } from './promise' +import { ZodReadonly } from './readonly' +import { ZodRecord } from './record' +import { ZodRef } from './ref' +import { ZodSet } from './set' +import { ZodString } from './string' +import { ZodSymbol } from './symbol' +import { ZodEffects } from './transformer' +import { ZodTuple } from './tuple' +import { ZodUndefined } from './undefined' +import { ZodUnion } from './union' +import { ZodUnknown } from './unknown' +import { ZodVoid } from './void' /** * @deprecated - use ZodNativeSchema instead diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index e10ca82436d..9ab886b30f1 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -10,7 +10,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodNativeEnumDef = { values: T diff --git a/packages/zui/src/z/types/never/index.ts b/packages/zui/src/z/types/never/index.ts index d7acd84cd5e..62366dcb966 100644 --- a/packages/zui/src/z/types/never/index.ts +++ b/packages/zui/src/z/types/never/index.ts @@ -7,7 +7,7 @@ import { INVALID, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodNeverDef = { typeName: 'ZodNever' diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index 6c18cfcdaa7..804d067d075 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -8,7 +8,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodNullDef = { typeName: 'ZodNull' diff --git a/packages/zui/src/z/types/nullable/index.ts b/packages/zui/src/z/types/nullable/index.ts index 0758095a204..ce4075d4506 100644 --- a/packages/zui/src/z/types/nullable/index.ts +++ b/packages/zui/src/z/types/nullable/index.ts @@ -7,15 +7,13 @@ import { ZodType, ZodTypeDef, processCreateParams, -} from '../index' +} from '../basetype' export type ZodNullableDef = { innerType: T typeName: 'ZodNullable' } & ZodTypeDef -export type ZodNullableType = ZodNullable - export class ZodNullable extends ZodType< T['_output'] | null, ZodNullableDef, diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 8a0c8c0b812..546b6e8ca4f 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -10,7 +10,7 @@ import { ParseInput, ParseReturnType, ParseStatus, -} from '../index' +} from '../basetype' export type ZodNumberCheck = | { kind: 'min'; value: number; inclusive: boolean; message?: string } @@ -19,14 +19,6 @@ export type ZodNumberCheck = | { kind: 'multipleOf'; value: number; message?: string } | { kind: 'finite'; message?: string } // https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034 -function floatSafeRemainder(val: number, step: number) { - const valDecCount = (val.toString().split('.')[1] || '').length - const stepDecCount = (step.toString().split('.')[1] || '').length - const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount - const valInt = parseInt(val.toFixed(decCount).replace('.', '')) - const stepInt = parseInt(step.toFixed(decCount).replace('.', '')) - return (valInt % stepInt) / Math.pow(10, decCount) -} export type ZodNumberDef = { checks: ZodNumberCheck[] @@ -94,7 +86,7 @@ export class ZodNumber extends ZodType { status.dirty() } } else if (check.kind === 'multipleOf') { - if (floatSafeRemainder(input.data, check.value) !== 0) { + if (this._floatSafeRemainder(input.data, check.value) !== 0) { ctx = this._getOrReturnCtx(input, ctx) addIssueToContext(ctx, { code: 'not_multiple_of', @@ -289,4 +281,13 @@ export class ZodNumber extends ZodType { const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) } + + private _floatSafeRemainder(val: number, step: number) { + const valDecCount = (val.toString().split('.')[1] || '').length + const stepDecCount = (step.toString().split('.')[1] || '').length + const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount + const valInt = parseInt(val.toFixed(decCount).replace('.', '')) + const stepInt = parseInt(step.toFixed(decCount).replace('.', '')) + return (valInt % stepInt) / Math.pow(10, decCount) + } } diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 9ab380635e0..3210332de40 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,10 +1,7 @@ import * as utils from '../../utils' +import { ZodAny } from '../any' +import { ZodArray } from '../array' import { - ZodArray, - ZodEnum, - ZodNullable, - ZodOptional, - ZodTuple, addIssueToContext, INVALID, ParseInput, @@ -12,15 +9,19 @@ import { ParseStatus, ParseInputLazyPath, RawCreateParams, - ZodRawShape, ZodType, ZodTypeDef, processCreateParams, - createZodEnum, - ZodNever, - ZodAny, - ZodTupleItems, -} from '../index' +} from '../basetype' + +// TODO(circle): these may potentially cause circular dependencies errors +import { ZodEnum } from '../enum' +import { ZodNever } from '../never' +import { ZodNullable } from '../nullable' +import { ZodOptional } from '../optional' +import { ZodTuple, type ZodTupleItems } from '../tuple' + +export type ZodRawShape = { [k: string]: ZodType } export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodType @@ -33,41 +34,38 @@ export type ZodObjectDef< unknownKeys: UnknownKeys } & ZodTypeDef -export type mergeTypes = { - [k in keyof A | keyof B]: k extends keyof B ? B[k] : k extends keyof A ? A[k] : never -} - -export type objectOutputType< +type _ObjectOutputType< Shape extends ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = UnknownKeysOutputType & utils.types.Flatten>> +> = _UnknownKeysOutputType & + utils.types.Flatten>> -export type baseObjectOutputType = { +type _BaseObjectOutputType = { [k in keyof Shape]: Shape[k]['_output'] } -export type objectInputType< +type _ObjectInputType< Shape extends ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = utils.types.Flatten> & UnknownKeysInputType +> = utils.types.Flatten<_BaseObjectInputType> & _UnknownKeysInputType -export type baseObjectInputType = utils.types.AddQuestionMarks<{ +type _BaseObjectInputType = utils.types.AddQuestionMarks<{ [k in keyof Shape]: Shape[k]['_input'] }> -export type UnknownKeysInputType = T extends ZodType +type _UnknownKeysInputType = T extends ZodType ? { [k: string]: T['_input'] | unknown } // extra properties cannot contradict the main properties : T extends 'passthrough' ? { [k: string]: unknown } : {} -export type UnknownKeysOutputType = T extends ZodType +type _UnknownKeysOutputType = T extends ZodType ? { [k: string]: T['_output'] | unknown } // extra properties cannot contradict the main properties : T extends 'passthrough' ? { [k: string]: unknown } : {} -export type AdditionalProperties = T extends ZodType +type _AdditionalProperties = T extends ZodType ? T : T extends 'passthrough' ? ZodAny @@ -75,34 +73,32 @@ export type AdditionalProperties = T extends ZodType ? ZodNever : undefined -export type deoptional = - T extends ZodOptional ? deoptional : T extends ZodNullable ? ZodNullable> : T +type _Deoptional = + T extends ZodOptional ? _Deoptional : T extends ZodNullable ? ZodNullable<_Deoptional> : T /** * @deprecated use ZodObject instead */ export type SomeZodObject = ZodObject -export type noUnrecognized = { - [k in keyof Obj]: k extends keyof Shape ? Obj[k] : never -} +/** + * @deprecated use ZodObject instead + */ +export type AnyZodObject = ZodObject -export type KeyOfObject = utils.types.Cast< - utils.types.UnionToTuple, - [string, ...string[]] -> +type _KeyOfObject = utils.types.Cast, [string, ...string[]]> -export type DeepPartial = T extends ZodObject - ? ZodObject<{ [k in keyof T['shape']]: ZodOptional> }, T['_def']['unknownKeys']> +type _DeepPartial = T extends ZodObject + ? ZodObject<{ [k in keyof T['shape']]: ZodOptional<_DeepPartial> }, T['_def']['unknownKeys']> : T extends ZodArray - ? ZodArray, Card> + ? ZodArray<_DeepPartial, Card> : T extends ZodOptional - ? ZodOptional> + ? ZodOptional<_DeepPartial> : T extends ZodNullable - ? ZodNullable> + ? ZodNullable<_DeepPartial> : T extends ZodTuple ? { - [k in keyof Items]: Items[k] extends ZodType ? DeepPartial : never + [k in keyof Items]: Items[k] extends ZodType ? _DeepPartial : never } extends infer PI ? PI extends ZodTupleItems ? ZodTuple @@ -110,39 +106,11 @@ export type DeepPartial = T extends ZodObject : never : T -function deepPartialify(schema: ZodType): any { - if (schema instanceof ZodObject) { - const newShape: any = {} - - for (const key in schema.shape) { - const fieldSchema = schema.shape[key] - newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)) - } - return new ZodObject({ - ...schema._def, - shape: () => newShape, - }) - } else if (schema instanceof ZodArray) { - return new ZodArray({ - ...schema._def, - type: deepPartialify(schema.element), - }) - } else if (schema instanceof ZodOptional) { - return ZodOptional.create(deepPartialify(schema.unwrap())) - } else if (schema instanceof ZodNullable) { - return ZodNullable.create(deepPartialify(schema.unwrap())) - } else if (schema instanceof ZodTuple) { - return ZodTuple.create(schema.items.map((item: any) => deepPartialify(item))) - } else { - return schema - } -} - export class ZodObject< T extends ZodRawShape = ZodRawShape, UnknownKeys extends UnknownKeysParam = UnknownKeysParam, - Output = objectOutputType, - Input = objectInputType, + Output = _ObjectOutputType, + Input = _ObjectInputType, > extends ZodType, Input> { private _cached: { shape: T; keys: string[] } | null = null @@ -323,17 +291,17 @@ export class ZodObject< /** * @returns The ZodType that is used to validate additional properties or undefined if extra keys are stripped. */ - additionalProperties(): AdditionalProperties { + additionalProperties(): _AdditionalProperties { if (this._def.unknownKeys instanceof ZodType) { - return this._def.unknownKeys as AdditionalProperties + return this._def.unknownKeys as _AdditionalProperties } if (this._def.unknownKeys === 'passthrough') { - return ZodAny.create() as AdditionalProperties + return ZodAny.create() as _AdditionalProperties } if (this._def.unknownKeys === 'strict') { - return ZodNever.create() as AdditionalProperties + return ZodNever.create() as _AdditionalProperties } - return undefined as AdditionalProperties + return undefined as _AdditionalProperties } /** @@ -546,8 +514,8 @@ export class ZodObject< /** * @deprecated */ - deepPartial(): DeepPartial { - return deepPartialify(this) + deepPartial(): _DeepPartial { + return this._deepPartialify(this) } partial(): ZodObject< @@ -589,7 +557,7 @@ export class ZodObject< required(): ZodObject< { - [k in keyof T]: deoptional + [k in keyof T]: _Deoptional }, UnknownKeys > @@ -601,7 +569,7 @@ export class ZodObject< mask: Mask ): ZodObject< utils.types.NoNever<{ - [k in keyof T]: k extends keyof Mask ? deoptional : T[k] + [k in keyof T]: k extends keyof Mask ? _Deoptional : T[k] }>, UnknownKeys > @@ -629,8 +597,8 @@ export class ZodObject< }) } - keyof(): ZodEnum> { - return createZodEnum(Object.keys(this.shape) as [string, ...string[]]) as any + keyof(): ZodEnum<_KeyOfObject> { + return ZodEnum.create(Object.keys(this.shape) as [string, ...string[]]) as any } isEqual(schema: ZodType): boolean { @@ -683,9 +651,32 @@ export class ZodObject< ...processCreateParams(params), }) } -} -/** - * @deprecated use ZodObject instead - */ -export type AnyZodObject = ZodObject + private _deepPartialify(schema: ZodType): any { + if (schema instanceof ZodObject) { + const newShape: any = {} + + for (const key in schema.shape) { + const fieldSchema = schema.shape[key] + newShape[key] = ZodOptional.create(this._deepPartialify(fieldSchema)) + } + return new ZodObject({ + ...schema._def, + shape: () => newShape, + }) + } else if (schema instanceof ZodArray) { + return new ZodArray({ + ...schema._def, + type: this._deepPartialify(schema.element), + }) + } else if (schema instanceof ZodOptional) { + return ZodOptional.create(this._deepPartialify(schema.unwrap())) + } else if (schema instanceof ZodNullable) { + return ZodNullable.create(this._deepPartialify(schema.unwrap())) + } else if (schema instanceof ZodTuple) { + return ZodTuple.create(schema.items.map((item: any) => this._deepPartialify(item))) + } else { + return schema + } + } +} diff --git a/packages/zui/src/z/types/optional/index.ts b/packages/zui/src/z/types/optional/index.ts index b843d75904b..e47dd736168 100644 --- a/packages/zui/src/z/types/optional/index.ts +++ b/packages/zui/src/z/types/optional/index.ts @@ -7,15 +7,13 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodOptionalDef = { innerType: T typeName: 'ZodOptional' } & ZodTypeDef -export type ZodOptionalType = ZodOptional - export class ZodOptional extends ZodType< T['_output'] | undefined, ZodOptionalDef, diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index e7c0fa34246..7c849784529 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,5 +1,5 @@ import * as utils from '../../utils' -import { ZodType, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../index' +import { ZodType, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../basetype' export type ZodPipelineDef = { in: A diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index 5e2a7f4924c..dcda2b68922 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -8,7 +8,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodPromiseDef = { type: T diff --git a/packages/zui/src/z/types/readonly/index.ts b/packages/zui/src/z/types/readonly/index.ts index d92682938cb..f2921899392 100644 --- a/packages/zui/src/z/types/readonly/index.ts +++ b/packages/zui/src/z/types/readonly/index.ts @@ -6,9 +6,9 @@ import { isValid, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' -type BuiltIn = +type _BuiltIn = | (((...args: any[]) => any) | (new (...args: any[]) => any)) | { readonly [Symbol.toStringTag]: string } | Date @@ -17,7 +17,7 @@ type BuiltIn = | Promise | RegExp -type MakeReadonly = +type _MakeReadonly = T extends Map ? ReadonlyMap : T extends Set @@ -26,7 +26,7 @@ type MakeReadonly = ? readonly [Head, ...Tail] : T extends Array ? ReadonlyArray - : T extends BuiltIn + : T extends _BuiltIn ? T : Readonly @@ -36,9 +36,9 @@ export type ZodReadonlyDef = { } & ZodTypeDef export class ZodReadonly extends ZodType< - MakeReadonly, + _MakeReadonly, ZodReadonlyDef, - MakeReadonly + _MakeReadonly > { dereference(defs: Record): ZodType { return new ZodReadonly({ diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 405aaa13ae7..d89b297abd2 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,28 +1,30 @@ import * as utils from '../../utils' import { - BRAND, ParseInputLazyPath, RawCreateParams, ZodType, ZodTypeDef, - ZodString, processCreateParams, addIssueToContext, INVALID, ParseInput, ParseReturnType, ParseStatus, -} from '../index' +} from '../basetype' -export type ZodRecordDef = { +// TODO(circle): these may potentially cause circular dependencies errors +import { BRAND } from '../branded' +import { ZodString } from '../string' + +export type ZodRecordDef = { valueType: Value keyType: Key typeName: 'ZodRecord' } & ZodTypeDef -export type KeySchema = ZodType +type _KeySchema = ZodType -export type RecordType = [string] extends [K] +type _RecordType = [string] extends [K] ? Record : [number] extends [K] ? Record @@ -32,10 +34,10 @@ export type RecordType = [string] extends ? Record : Partial> -export class ZodRecord extends ZodType< - RecordType, +export class ZodRecord extends ZodType< + _RecordType, ZodRecordDef, - RecordType + _RecordType > { get keySchema() { return this._def.keyType @@ -104,7 +106,7 @@ export class ZodRecord(valueType: Value, params?: RawCreateParams): ZodRecord - static create( + static create( keySchema: Keys, valueType: Value, params?: RawCreateParams diff --git a/packages/zui/src/z/types/ref/index.ts b/packages/zui/src/z/types/ref/index.ts index 2b88f8f5476..f7e6281572e 100644 --- a/packages/zui/src/z/types/ref/index.ts +++ b/packages/zui/src/z/types/ref/index.ts @@ -6,16 +6,14 @@ import { ParseInput, ParseReturnType, addIssueToContext, -} from '../index' +} from '../basetype' export type ZodRefDef = { typeName: 'ZodRef' uri: string } & ZodTypeDef -type ZodRefOutput = NonNullable - -export class ZodRef extends ZodType { +export class ZodRef extends ZodType, ZodRefDef> { dereference(defs: Record): ZodType { const def = defs[this._def.uri] if (!def) { diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 329e3d3b13a..ea84f9aca1c 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -10,7 +10,7 @@ import { ParseInput, ParseReturnType, SyncParseReturnType, -} from '../index' +} from '../basetype' export type ZodSetDef = { valueType: Value diff --git a/packages/zui/src/z/types/string/datetime.ts b/packages/zui/src/z/types/string/datetime.ts index f59cbcabe81..092e6f8ec59 100644 --- a/packages/zui/src/z/types/string/datetime.ts +++ b/packages/zui/src/z/types/string/datetime.ts @@ -1,13 +1,4 @@ -// Adapted from https://stackoverflow.com/a/3143231 - -const DATETIME_REGEX_BASE = '\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}' -const DATETIME_REGEX_OFFSET = '(([+-]\\d{2}(:?\\d{2})?)|Z)' -const DATETIME_REGEX_OFFSET_NONE = 'Z' -const DATETIME_REGEX_PRECISION_ARBITRARY = '(\\.\\d+)?' -const DATETIME_REGEX_PRECISION_SPECIFIC_BEGIN = '\\.\\d{' -const DATETIME_REGEX_PRECISION_SPECIFIC_END = '}' - -type DateTimeArgs = { precision: number | null; offset: boolean } +export type DateTimeArgs = { precision: number | null; offset: boolean } export const generateDatetimeRegex = (args: DateTimeArgs) => { const precision = args.precision @@ -26,6 +17,15 @@ export const extractPrecisionAndOffset = (regexSource: string): DateTimeArgs => offset: regexSource.endsWith(`${DATETIME_REGEX_OFFSET}$`), }) +// Adapted from https://stackoverflow.com/a/3143231 + +const DATETIME_REGEX_BASE = '\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}' +const DATETIME_REGEX_OFFSET = '(([+-]\\d{2}(:?\\d{2})?)|Z)' +const DATETIME_REGEX_OFFSET_NONE = 'Z' +const DATETIME_REGEX_PRECISION_ARBITRARY = '(\\.\\d+)?' +const DATETIME_REGEX_PRECISION_SPECIFIC_BEGIN = '\\.\\d{' +const DATETIME_REGEX_PRECISION_SPECIFIC_END = '}' + const _extractPrecision = (regexSource: string): DateTimeArgs['precision'] => { const slicedRegex = regexSource.slice(1 + DATETIME_REGEX_BASE.length) diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 3cf035f178f..dbbe7241f8b 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -12,8 +12,7 @@ import { ParseInput, ParseReturnType, ParseStatus, -} from '../index' -import { generateDatetimeRegex } from './datetime' +} from '../basetype' export type IpVersion = 'v4' | 'v6' export type ZodStringCheck = @@ -279,7 +278,7 @@ export class ZodString extends ZodType { status.dirty() } } else if (check.kind === 'datetime') { - const regex = generateDatetimeRegex(check) + const regex = utils.strings.generateDatetimeRegex(check) if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx) diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index de1e3c8e35c..d5b46860fb0 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -8,7 +8,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodSymbolDef = { typeName: 'ZodSymbol' diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 9da70b9e4f9..eea12897348 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -14,10 +14,7 @@ import { isValid, ParseInput, ParseReturnType, -} from '../index' - -export type Refinement = (arg: T, ctx: RefinementCtx) => any -export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void | Promise +} from '../basetype' export type RefinementEffect = { type: 'refinement' diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index 32a070d794f..5f9df7a1c7c 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' import * as utils from '../../utils' import * as z from '../../index' +import { NEVER } from '../basetype' const stringToNumber = z.string().transform((arg) => parseFloat(arg)) // const numberToString = z @@ -78,7 +79,7 @@ test('z.NEVER in transform', () => { .transform((val, ctx) => { if (!val) { ctx.addIssue({ code: 'custom', message: 'bad' }) - return z.NEVER + return NEVER } return val }) diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index e25ac371c78..bf1d23d41f6 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -11,25 +11,26 @@ import { ParseReturnType, ParseStatus, SyncParseReturnType, -} from '../index' +} from '../basetype' export type ZodTupleItems = [ZodType, ...ZodType[]] -export type AssertArray = T extends any[] ? T : never -export type OutputTypeOfTuple = AssertArray<{ + +type _AssertArray = T extends any[] ? T : never +type _OutputTypeOfTuple = _AssertArray<{ [k in keyof T]: T[k] extends ZodType ? T[k]['_output'] : never }> -export type OutputTypeOfTupleWithRest< - T extends ZodTupleItems | [], - Rest extends ZodType | null = null, -> = Rest extends ZodType ? [...OutputTypeOfTuple, ...Rest['_output'][]] : OutputTypeOfTuple -export type InputTypeOfTuple = AssertArray<{ +type _OutputTypeOfTupleWithRest = Rest extends ZodType + ? [..._OutputTypeOfTuple, ...Rest['_output'][]] + : _OutputTypeOfTuple + +type _InputTypeOfTuple = _AssertArray<{ [k in keyof T]: T[k] extends ZodType ? T[k]['_input'] : never }> -export type InputTypeOfTupleWithRest< - T extends ZodTupleItems | [], - Rest extends ZodType | null = null, -> = Rest extends ZodType ? [...InputTypeOfTuple, ...Rest['_input'][]] : InputTypeOfTuple + +type _InputTypeOfTupleWithRest = Rest extends ZodType + ? [..._InputTypeOfTuple, ...Rest['_input'][]] + : _InputTypeOfTuple export type ZodTupleDef = { items: T @@ -37,11 +38,15 @@ export type ZodTupleDef + export class ZodTuple< T extends [ZodType, ...ZodType[]] | [] = [ZodType, ...ZodType[]], Rest extends ZodType | null = null, -> extends ZodType, ZodTupleDef, InputTypeOfTupleWithRest> { +> extends ZodType<_OutputTypeOfTupleWithRest, ZodTupleDef, _InputTypeOfTupleWithRest> { dereference(defs: Record): ZodType { const items = this._def.items.map((item) => item.dereference(defs)) as [ZodType, ...ZodType[]] const rest = this._def.rest ? this._def.rest.dereference(defs) : null diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index fb27685620b..099384ce5d0 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -8,8 +8,10 @@ import { OK, ParseInput, ParseReturnType, - ZodNever, -} from '../index' +} from '../basetype' + +// TODO(circle): these may potentially cause circular dependencies errors +import { ZodNever } from '../never' export type ZodUndefinedDef = { typeName: 'ZodUndefined' diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index e069bd29569..a8172071e58 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -12,18 +12,21 @@ import { ParseInput, ParseReturnType, SyncParseReturnType, - ZodUndefined, - ZodNever, -} from '../index' +} from '../basetype' + +// TODO(circle): these may potentially cause circular dependencies errors +import { ZodNever } from '../never' +import { ZodUndefined } from '../undefined' + +type _DefaultZodUnionOptions = Readonly<[ZodType, ZodType, ...ZodType[]]> -type DefaultZodUnionOptions = Readonly<[ZodType, ZodType, ...ZodType[]]> export type ZodUnionOptions = Readonly<[ZodType, ...ZodType[]]> -export type ZodUnionDef = { +export type ZodUnionDef = { options: T typeName: 'ZodUnion' } & ZodTypeDef -export class ZodUnion extends ZodType< +export class ZodUnion extends ZodType< T[number]['_output'], ZodUnionDef, T[number]['_input'] diff --git a/packages/zui/src/z/types/unknown/index.ts b/packages/zui/src/z/types/unknown/index.ts index a22aa6486a4..1d2b4b9ec10 100644 --- a/packages/zui/src/z/types/unknown/index.ts +++ b/packages/zui/src/z/types/unknown/index.ts @@ -1,4 +1,4 @@ -import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, OK, ParseInput, ParseReturnType } from '../index' +import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, OK, ParseInput, ParseReturnType } from '../basetype' export type ZodUnknownDef = { typeName: 'ZodUnknown' diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index 8afd0192cb8..e54d12d310d 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -8,7 +8,7 @@ import { OK, ParseInput, ParseReturnType, -} from '../index' +} from '../basetype' export type ZodVoidDef = { typeName: 'ZodVoid' diff --git a/packages/zui/src/z/utils/index.ts b/packages/zui/src/z/utils/index.ts index 79ff08327ce..f6368524b11 100644 --- a/packages/zui/src/z/utils/index.ts +++ b/packages/zui/src/z/utils/index.ts @@ -4,3 +4,4 @@ export * as fn from './fn-utils' export * as types from './type-utils' export * as assert from './assert-utils' export * as others from './other-utils' +export * as strings from '../types/string/datetime' diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts index df16f6482a0..326e93b05a1 100644 --- a/packages/zui/src/z/utils/type-utils.ts +++ b/packages/zui/src/z/utils/type-utils.ts @@ -7,6 +7,10 @@ export type SafeOmit = Omit export type Primitive = string | number | bigint | boolean | symbol | null | undefined export type Cast = A extends B ? A : B +export type Writeable = { + -readonly [P in keyof T]: T[P] +} + type NormalizeObject = T extends infer O ? { [K in keyof O]: Normalize } : never export type Normalize = T extends (...args: infer A) => infer R ? (...args: Normalize) => Normalize diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index e87229fce5e..681ebb6b072 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -1,14 +1,4 @@ -import { ZodType } from './types' - -export { ZodType as Schema, ZodType as ZodSchema } - export * from './builders' export { default } from './builders' // Re-export 'default' explicitly since export * doesn't handle it - export * from './types' export * from './error' - -/** - * @deprecated - use ZodType instead - */ -export type ZodTypeAny = ZodType From afa0f649c7b0e4f00edbae2449c6d5e7f23e71bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Fri, 20 Feb 2026 14:25:20 -0500 Subject: [PATCH 17/50] chore(zui): rm a bunch of any types --- packages/zui/src/z/types/basetype/parseUtil.ts | 15 +++++++-------- packages/zui/src/z/types/object/index.ts | 6 ++++-- packages/zui/src/z/types/record/index.ts | 3 ++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/zui/src/z/types/basetype/parseUtil.ts b/packages/zui/src/z/types/basetype/parseUtil.ts index b5c3565b4e8..3308eaf5524 100644 --- a/packages/zui/src/z/types/basetype/parseUtil.ts +++ b/packages/zui/src/z/types/basetype/parseUtil.ts @@ -76,6 +76,12 @@ export type ParseInput = { parent: ParseContext } +export type MergeObjectPair = { + key: SyncParseReturnType + value: SyncParseReturnType + alwaysSet?: boolean +} + export function addIssueToContext(ctx: ParseContext, issueData: IssueData): void { const issue = makeIssue({ issueData, @@ -129,14 +135,7 @@ export class ParseStatus { return ParseStatus.mergeObjectSync(status, syncPairs) } - static mergeObjectSync( - status: ParseStatus, - pairs: { - key: SyncParseReturnType - value: SyncParseReturnType - alwaysSet?: boolean - }[] - ): SyncParseReturnType { + static mergeObjectSync(status: ParseStatus, pairs: MergeObjectPair[]): SyncParseReturnType { const finalObject: any = {} for (const pair of pairs) { const { key, value } = pair diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 3210332de40..d8e54d1e4f0 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -12,6 +12,7 @@ import { ZodType, ZodTypeDef, processCreateParams, + type MergeObjectPair, } from '../basetype' // TODO(circle): these may potentially cause circular dependencies errors @@ -243,7 +244,7 @@ export class ZodObject< return ParseStatus.mergeObjectSync(status, syncPairs) }) } else { - return ParseStatus.mergeObjectSync(status, pairs as any) + return ParseStatus.mergeObjectSync(status, pairs as MergeObjectPair[]) } } @@ -598,7 +599,8 @@ export class ZodObject< } keyof(): ZodEnum<_KeyOfObject> { - return ZodEnum.create(Object.keys(this.shape) as [string, ...string[]]) as any + const keys = Object.keys(this.shape) as _KeyOfObject + return ZodEnum.create(keys) as ZodEnum<_KeyOfObject> } isEqual(schema: ZodType): boolean { diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index d89b297abd2..5df9ae2c38b 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -10,6 +10,7 @@ import { ParseInput, ParseReturnType, ParseStatus, + type MergeObjectPair, } from '../basetype' // TODO(circle): these may potentially cause circular dependencies errors @@ -97,7 +98,7 @@ export class ZodRecord Date: Thu, 26 Feb 2026 13:16:26 -0500 Subject: [PATCH 18/50] feat(zui): completly remove classes from API + remove circular deps (#14976) --- packages/zui/src/index.ts | 16 +- packages/zui/src/transforms/common/errors.ts | 10 +- .../src/transforms/common/eval-zui-string.ts | 2 +- .../zui/src/transforms/common/json-schema.ts | 5 +- packages/zui/src/transforms/index.ts | 1 + .../src/transforms/transform-pipeline.test.ts | 5 +- .../zui-from-json-schema-legacy/index.ts | 6 +- .../json-schema-to-zui.test.ts | 6 +- .../parsers/parseBoolean.ts | 2 +- .../parsers/parseNumber.ts | 2 +- .../parsers/parseObject.test.ts | 2 +- .../parsers/parseString.ts | 2 +- .../zui-from-json-schema-legacy/types.ts | 3 +- .../zui-from-json-schema/index.test.ts | 11 +- .../transforms/zui-from-json-schema/index.ts | 11 +- .../zui-from-json-schema/primitives/string.ts | 2 +- .../zui-to-json-schema-legacy/Options.ts | 4 +- .../zui-to-json-schema-legacy/parseDef.ts | 7 +- .../zui-to-json-schema-legacy/parsers/any.ts | 3 +- .../parsers/array.ts | 4 +- .../parsers/bigint.ts | 4 +- .../parsers/boolean.ts | 4 +- .../zui-to-json-schema-legacy/parsers/date.ts | 4 +- .../zui-to-json-schema-legacy/parsers/enum.ts | 4 +- .../parsers/intersection.ts | 4 +- .../parsers/literal.ts | 4 +- .../zui-to-json-schema-legacy/parsers/map.ts | 4 +- .../parsers/nativeEnum.ts | 4 +- .../parsers/never.ts | 3 +- .../zui-to-json-schema-legacy/parsers/null.ts | 3 +- .../parsers/nullable.ts | 4 +- .../parsers/number.ts | 4 +- .../parsers/object.ts | 6 +- .../parsers/record.ts | 6 +- .../zui-to-json-schema-legacy/parsers/ref.ts | 3 +- .../zui-to-json-schema-legacy/parsers/set.ts | 4 +- .../parsers/string.ts | 4 +- .../parsers/tuple.ts | 4 +- .../parsers/undefined.ts | 3 +- .../parsers/union.ts | 11 +- .../parsers/unknown.ts | 3 +- .../test/allParsers.test.ts | 2 +- .../test/issues.test.ts | 3 +- .../test/meta.test.ts | 3 +- .../test/openApiMode.test.ts | 3 +- .../test/parseDef.test.ts | 3 +- .../test/parsers/array.test.ts | 3 +- .../test/parsers/bigint.test.ts | 2 +- .../test/parsers/branded.test.ts | 3 +- .../test/parsers/date.test.ts | 2 +- .../test/parsers/default.test.ts | 3 +- .../test/parsers/effects.test.ts | 3 +- .../test/parsers/intersection.test.ts | 3 +- .../test/parsers/map.test.ts | 3 +- .../test/parsers/nativeEnum.test.ts | 2 +- .../test/parsers/nullable.test.ts | 3 +- .../test/parsers/number.test.ts | 2 +- .../test/parsers/object.test.ts | 3 +- .../test/parsers/optional.test.ts | 3 +- .../test/parsers/pipe.test.ts | 3 +- .../test/parsers/promise.test.ts | 3 +- .../test/parsers/record.test.ts | 3 +- .../test/parsers/set.test.ts | 3 +- .../test/parsers/string.test.ts | 2 +- .../test/parsers/tuple.test.ts | 3 +- .../test/parsers/union.test.ts | 3 +- .../test/readme.test.ts | 3 +- .../test/references.test.ts | 3 +- .../test/zodToJsonSchema.test.ts | 3 +- .../zodToJsonSchema.ts | 8 +- .../zui-extension.test.ts | 3 +- .../zui-extension.ts | 2 +- .../transforms/zui-to-json-schema/index.ts | 6 +- .../type-processors/array.ts | 3 +- .../type-processors/number.ts | 3 +- .../zui-to-json-schema/type-processors/set.ts | 3 +- .../type-processors/string.ts | 5 +- .../type-processors/tuple.ts | 3 +- .../zui-to-typescript-schema/array-checks.ts | 2 +- .../zui-to-typescript-schema/bigint-checks.ts | 2 +- .../zui-to-typescript-schema/date-checks.ts | 2 +- .../zui-to-typescript-schema/index.test.ts | 12 +- .../zui-to-typescript-schema/index.ts | 12 +- .../zui-to-typescript-schema/number-checks.ts | 2 +- .../zui-to-typescript-schema/set-checks.ts | 2 +- .../zui-to-typescript-type/index.ts | 60 +- .../zui-to-typescript-type/primitives.test.ts | 2 +- packages/zui/src/ui/types.ts | 65 - .../zui/src/z/__tests__/async-parsing.test.ts | 39 +- packages/zui/src/z/__tests__/base.test.ts | 2 +- .../zui/src/z/{ => __tests__}/clone.test.ts | 15 +- packages/zui/src/z/__tests__/complex.test.ts | 1 - .../zui/src/z/{ => __tests__}/deref.test.ts | 4 +- packages/zui/src/z/__tests__/generics.test.ts | 2 +- .../zui/src/z/__tests__/instanceof.test.ts | 2 +- .../src/z/{ => __tests__}/is-equal.test.ts | 8 +- .../src/z/{ => __tests__}/mandatory.test.ts | 17 +- packages/zui/src/z/__tests__/naked.test.ts | 85 +- packages/zui/src/z/__tests__/partials.test.ts | 64 +- packages/zui/src/z/__tests__/pickomit.test.ts | 2 +- .../zui/src/z/__tests__/preprocess.test.ts | 8 +- .../zui/src/z/__tests__/primitive.test.ts | 2 +- .../zui/src/z/__tests__/recursive.test.ts | 12 +- packages/zui/src/z/__tests__/refine.test.ts | 30 +- .../zui/src/z/__tests__/safeparse.test.ts | 3 +- packages/zui/src/z/__tests__/set.test.ts | 3 +- .../zui/src/{ => z/__tests__}/zui.test.ts | 6 +- packages/zui/src/z/builders.ts | 527 +++-- .../zui/src/{ui/constants.ts => z/consts.ts} | 0 packages/zui/src/z/error/error.test.ts | 11 +- packages/zui/src/z/error/index.ts | 174 +- packages/zui/src/z/error/locales/en.ts | 26 +- packages/zui/src/z/guards.ts | 11 + packages/zui/src/z/internal-builders.ts | 30 + packages/zui/src/z/native.ts | 135 ++ packages/zui/src/z/types/any/index.ts | 20 +- packages/zui/src/z/types/array/index.ts | 77 +- packages/zui/src/z/types/basetype/index.ts | 272 +-- .../zui/src/z/types/basetype/parseUtil.ts | 74 +- packages/zui/src/z/types/bigint/index.ts | 38 +- packages/zui/src/z/types/boolean/index.ts | 32 +- .../zui/src/z/types/branded/branded.test.ts | 13 +- packages/zui/src/z/types/branded/index.ts | 48 +- packages/zui/src/z/types/catch/catch.test.ts | 21 +- packages/zui/src/z/types/catch/index.ts | 70 +- packages/zui/src/z/types/date/index.ts | 32 +- .../zui/src/z/types/default/default.test.ts | 16 +- packages/zui/src/z/types/default/index.ts | 60 +- .../discriminatedUnion.test.ts | 2 +- .../src/z/types/discriminatedUnion/index.ts | 171 +- packages/zui/src/z/types/enum/index.ts | 66 +- .../zui/src/z/types/function/function.test.ts | 15 +- packages/zui/src/z/types/function/index.ts | 125 +- packages/zui/src/z/types/index.ts | 1 - .../zui/src/z/types/intersection/index.ts | 72 +- packages/zui/src/z/types/lazy/index.ts | 52 +- packages/zui/src/z/types/literal/index.ts | 34 +- packages/zui/src/z/types/map/index.ts | 66 +- packages/zui/src/z/types/map/map.test.ts | 1 - packages/zui/src/z/types/nan/index.ts | 29 +- packages/zui/src/z/types/native.test.ts | 123 -- packages/zui/src/z/types/native.ts | 137 -- packages/zui/src/z/types/nativeEnum/index.ts | 37 +- packages/zui/src/z/types/never/index.ts | 29 +- packages/zui/src/z/types/null/index.ts | 30 +- packages/zui/src/z/types/nullable/index.ts | 58 +- .../zui/src/z/types/nullable/nullable.test.ts | 18 +- packages/zui/src/z/types/number/index.ts | 37 +- packages/zui/src/z/types/object/index.ts | 351 ++-- .../zui/src/z/types/object/object.test.ts | 10 +- packages/zui/src/z/types/optional/index.ts | 56 +- .../zui/src/z/types/optional/optional.test.ts | 16 +- packages/zui/src/z/types/pipeline/index.ts | 53 +- packages/zui/src/z/types/promise/index.ts | 54 +- .../zui/src/z/types/promise/promise.test.ts | 7 +- packages/zui/src/z/types/readonly/index.ts | 79 +- packages/zui/src/z/types/record/index.ts | 89 +- packages/zui/src/z/types/ref/index.ts | 27 +- packages/zui/src/z/types/set/index.ts | 58 +- packages/zui/src/z/types/string/index.ts | 75 +- packages/zui/src/z/types/symbol/index.ts | 30 +- packages/zui/src/z/types/transformer/index.ts | 140 +- .../z/types/transformer/transformer.test.ts | 3 +- packages/zui/src/z/types/tuple/index.ts | 97 +- packages/zui/src/z/types/undefined/index.ts | 39 +- packages/zui/src/z/types/union/index.ts | 83 +- packages/zui/src/z/types/unknown/index.ts | 20 +- packages/zui/src/z/types/void/index.ts | 30 +- packages/zui/src/z/typings.ts | 1800 +++++++++++++++++ .../datestring-utils.test.ts} | 2 +- .../datetime.ts => utils/datestring-utils.ts} | 0 packages/zui/src/z/utils/index.ts | 2 +- packages/zui/src/z/z.ts | 250 ++- 173 files changed, 3878 insertions(+), 3057 deletions(-) delete mode 100644 packages/zui/src/ui/types.ts rename packages/zui/src/z/{ => __tests__}/clone.test.ts (93%) rename packages/zui/src/z/{ => __tests__}/deref.test.ts (98%) rename packages/zui/src/z/{ => __tests__}/is-equal.test.ts (98%) rename packages/zui/src/z/{ => __tests__}/mandatory.test.ts (88%) rename packages/zui/src/{ => z/__tests__}/zui.test.ts (96%) rename packages/zui/src/{ui/constants.ts => z/consts.ts} (100%) create mode 100644 packages/zui/src/z/guards.ts create mode 100644 packages/zui/src/z/internal-builders.ts create mode 100644 packages/zui/src/z/native.ts delete mode 100644 packages/zui/src/z/types/native.test.ts delete mode 100644 packages/zui/src/z/types/native.ts create mode 100644 packages/zui/src/z/typings.ts rename packages/zui/src/z/{types/string/datetime.test.ts => utils/datestring-utils.test.ts} (97%) rename packages/zui/src/z/{types/string/datetime.ts => utils/datestring-utils.ts} (100%) diff --git a/packages/zui/src/index.ts b/packages/zui/src/index.ts index a0bd8cab47e..3b52d24902a 100644 --- a/packages/zui/src/index.ts +++ b/packages/zui/src/index.ts @@ -1,5 +1,19 @@ -export type { JSONSchema7 } from 'json-schema' +import * as transforms from './transforms' +import { ZodBaseTypeImpl } from './z/types' +export type { JSONSchema7 } from 'json-schema' export * as json from './transforms/common/json-schema' export * as transforms from './transforms' export * from './z' + +ZodBaseTypeImpl.prototype.toJSONSchema = function () { + return transforms.toJSONSchema(this) +} + +ZodBaseTypeImpl.prototype.toTypescriptType = function (opts) { + return transforms.toTypescriptType(this, opts) +} + +ZodBaseTypeImpl.prototype.toTypescriptSchema = function () { + return transforms.toTypescriptSchema(this) +} diff --git a/packages/zui/src/transforms/common/errors.ts b/packages/zui/src/transforms/common/errors.ts index 45ae0fa361e..964369bd2ed 100644 --- a/packages/zui/src/transforms/common/errors.ts +++ b/packages/zui/src/transforms/common/errors.ts @@ -1,5 +1,5 @@ import { JSONSchema7 } from 'json-schema' -import { ZodNativeSchemaType } from '../../z' +import { ZodNativeTypeName } from '../../z' type Transform = | 'json-schema-to-zui' @@ -38,7 +38,7 @@ export class ZuiToJSONSchemaError extends ZuiTransformError { } } export class UnsupportedZuiToJSONSchemaError extends ZuiToJSONSchemaError { - public constructor(type: ZodNativeSchemaType, { suggestedAlternative }: { suggestedAlternative?: string } = {}) { + public constructor(type: ZodNativeTypeName, { suggestedAlternative }: { suggestedAlternative?: string } = {}) { super( `Zod type ${type} cannot be transformed to JSON Schema.` + (suggestedAlternative ? ` Suggested alternative: ${suggestedAlternative}` : '') @@ -46,7 +46,7 @@ export class UnsupportedZuiToJSONSchemaError extends ZuiToJSONSchemaError { } } export class UnsupportedZuiCheckToJSONSchemaError extends ZuiToJSONSchemaError { - public constructor({ zodType, checkKind }: { zodType: ZodNativeSchemaType; checkKind: string }) { + public constructor({ zodType, checkKind }: { zodType: ZodNativeTypeName; checkKind: string }) { super(`Zod check .${checkKind}() of type ${zodType} cannot be transformed to JSON Schema.`) } } @@ -64,7 +64,7 @@ export class ZuiToTypescriptSchemaError extends ZuiTransformError { } } export class UnsupportedZuiToTypescriptSchemaError extends ZuiToTypescriptSchemaError { - public constructor(type: ZodNativeSchemaType) { + public constructor(type: ZodNativeTypeName) { super(`Zod type ${type} cannot be transformed to TypeScript schema.`) } } @@ -76,7 +76,7 @@ export class ZuiToTypescriptTypeError extends ZuiTransformError { } } export class UnsupportedZuiToTypescriptTypeError extends ZuiToTypescriptTypeError { - public constructor(type: ZodNativeSchemaType) { + public constructor(type: ZodNativeTypeName) { super(`Zod type ${type} cannot be transformed to TypeScript type.`) } } diff --git a/packages/zui/src/transforms/common/eval-zui-string.ts b/packages/zui/src/transforms/common/eval-zui-string.ts index 37fc479bd58..cdeeb83ed00 100644 --- a/packages/zui/src/transforms/common/eval-zui-string.ts +++ b/packages/zui/src/transforms/common/eval-zui-string.ts @@ -20,7 +20,7 @@ export const evalZuiString = (zuiString: string): EvalZuiStringResult => { return { sucess: false, error: `Failed to evaluate schema: ${err.message}` } } - if (!(result instanceof z.ZodType)) { + if (!z.isZuiType(result)) { return { sucess: false, error: `String "${zuiString}" does not evaluate to a Zod schema` } } diff --git a/packages/zui/src/transforms/common/json-schema.ts b/packages/zui/src/transforms/common/json-schema.ts index 7062a788b61..7cf4f7a5fcd 100644 --- a/packages/zui/src/transforms/common/json-schema.ts +++ b/packages/zui/src/transforms/common/json-schema.ts @@ -1,5 +1,4 @@ import { JSONSchema7 } from 'json-schema' -import { ZuiExtensionObject } from '../../ui/types' import z from '../../z' import * as utils from '../../z/utils/type-utils' @@ -24,9 +23,9 @@ type DiscriminatedUnionDef = utils.Satisfies< * A ZUI flavored subset of JSONSchema7 */ -type ZuiExtension = {}> = { def?: Def } & ZuiExtensionObject +type ZuiExtension = {}> = { def?: Def } & z.ZuiExtensionObject type JsonData = string | number | boolean | null | JsonData[] | { [key: string]: JsonData } -type BaseZuiJSONSchema = {}> = utils.Satisfies< +type BaseZuiJSONSchema = {}> = utils.Satisfies< { description?: string readOnly?: boolean diff --git a/packages/zui/src/transforms/index.ts b/packages/zui/src/transforms/index.ts index b4c522dda92..760c2e4c259 100644 --- a/packages/zui/src/transforms/index.ts +++ b/packages/zui/src/transforms/index.ts @@ -7,4 +7,5 @@ export { toJSONSchema } from './zui-to-json-schema' export { toTypescriptType, type TypescriptGenerationOptions } from './zui-to-typescript-type' export { toTypescriptSchema } from './zui-to-typescript-schema' +export type { Schema as ZuiJSONSchema } from './common/json-schema' export * as errors from './common/errors' diff --git a/packages/zui/src/transforms/transform-pipeline.test.ts b/packages/zui/src/transforms/transform-pipeline.test.ts index 83970000430..a306c664184 100644 --- a/packages/zui/src/transforms/transform-pipeline.test.ts +++ b/packages/zui/src/transforms/transform-pipeline.test.ts @@ -3,15 +3,16 @@ import z from '../z' import { toJSONSchema } from './zui-to-json-schema' import { fromJSONSchema } from './zui-from-json-schema' import * as errors from './common/errors' +import * as transforms from '../transforms' -const assert = (src: z.Schema) => ({ +const assert = (src: z.ZodType) => ({ toTransformBackToItself: () => { const jsonSchema = toJSONSchema(src) const actual = fromJSONSchema(jsonSchema) const expected = src let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${transforms.toTypescriptSchema(actual)} to equal ${transforms.toTypescriptSchema(expected)}` } catch {} const result = actual.isEqual(expected) expect(result, msg).toBe(true) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts index d039fce1307..4c9582adc34 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts @@ -1,6 +1,6 @@ -import { zuiKey } from '../../ui/constants' -import { ZuiExtensionObject } from '../../ui/types' import { + zuiKey, + ZuiExtensionObject, type ZodAnyDef, type ZodArrayDef, type ZodBooleanDef, @@ -78,7 +78,7 @@ const applyZuiPropsRecursively = (zodField: ZodTypeAny, jsonSchemaField: any) => } } else if (Array.isArray(items)) { items.forEach((item, index) => { - const def: z.ZodDef = zodField._def + const def: z.ZodNativeTypeDef = zodField._def if (def.typeName === z.ZodFirstPartyTypeKind.ZodTuple) { applyZuiPropsRecursively(def.items[index]!, item) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts index 1fcc97fa71d..933acf72e2a 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts @@ -1,12 +1,12 @@ import { describe, expect, test, it } from 'vitest' -import { ZodType, z } from '../../z/index' -import { zuiKey } from '../../ui/constants' +import { ZodNativeType, z, zuiKey } from '../../z' import { jsonSchemaToZodStr, fromJSONSchemaLegacy, traverseZodDefinitions } from '.' import { toJSONSchemaLegacy } from '../zui-to-json-schema-legacy/zui-extension' import { JSONSchema7 } from 'json-schema' import { assert } from '../../assertions.utils.test' +import { JsonSchema7Type } from '../zui-to-json-schema-legacy/parseDef' -const testZuiConversion = (zuiObject: ZodType) => { +const testZuiConversion = (zuiObject: ZodNativeType) => { const jsonSchema = toJSONSchemaLegacy(zuiObject) const asZui = fromJSONSchemaLegacy(jsonSchema) const convertedJsonSchema = toJSONSchemaLegacy(asZui) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseBoolean.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseBoolean.ts index c887215bbda..408055aa832 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseBoolean.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseBoolean.ts @@ -1,4 +1,4 @@ -import { zuiKey } from '../../../ui/constants' +import { zuiKey } from '../../../z' import { JsonSchemaObject } from '../types' export const parseBoolean = (_schema: JsonSchemaObject & { type: 'boolean' }) => { diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseNumber.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseNumber.ts index 19dbc747a63..8cf5a2804d2 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseNumber.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseNumber.ts @@ -1,4 +1,4 @@ -import { zuiKey } from '../../../ui/constants' +import { zuiKey } from '../../../z' import { JsonSchemaObject } from '../types' import { withMessage } from '../utils' diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseObject.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseObject.test.ts index 47addf6c31c..1e36bfaba50 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseObject.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseObject.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7 } from 'json-schema' -import { ZodError } from '../../../z' import { parseObject } from './parseObject' +import { ZodError } from '../../../z/error' describe('parseObject', () => { it('With properties - should handle optional and required properties', () => { diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseString.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseString.ts index 2ba8fe7726a..e9e067c9184 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseString.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/parsers/parseString.ts @@ -1,4 +1,4 @@ -import { zuiKey } from '../../../ui/constants' +import { zuiKey } from '../../../z' import { JsonSchemaObject } from '../types' import { withMessage } from '../utils' diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/types.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/types.ts index 49ffec13d0a..e0b36bdac29 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/types.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/types.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../ui/constants' -import { ZuiExtensionObject } from '../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../z' export type Serializable = { [key: string]: Serializable } | Serializable[] | string | number | boolean | null diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts index c36e4fde572..8baa86718fd 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts @@ -6,6 +6,7 @@ import { Schema as ZuiJSONSchema } from '../common/json-schema' import { toJSONSchema } from '../zui-to-json-schema' import { toTypescriptType } from '../zui-to-typescript-type' import { toZuiPrimitive } from './primitives' +import { toTypescriptSchema } from '../zui-to-typescript-schema' const buildSchema = (s: JSONSchema7, xZui: ZuiJSONSchema['x-zui'] = undefined): JSONSchema7 => { return { ...s, 'x-zui': xZui } as JSONSchema7 @@ -16,12 +17,12 @@ const undefinedSchema = (xZui?: ZuiJSONSchema['x-zui']): JSONSchema7 => const nullSchema = (xZui?: ZuiJSONSchema['x-zui']): JSONSchema7 => buildSchema({ type: 'null' }, xZui) -const assert = (actual: z.Schema) => ({ - toEqual: (expected: z.Schema) => { +const assert = (actual: z.ZodType) => ({ + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${toTypescriptSchema(actual)} to equal ${toTypescriptSchema(expected)}` } catch {} expect(result, msg).toBe(true) }, @@ -464,12 +465,12 @@ describe.concurrent('zuifromJSONSchemaNext', () => { }) describe.concurrent('round-trip: zui → json → zui preserves typescript types', () => { - const roundTrip = (schema: z.Schema): z.Schema => { + const roundTrip = (schema: z.ZodType): z.ZodType => { const jsonSchema = toJSONSchema(schema) return fromJSONSchema(jsonSchema as JSONSchema7) } - const getTypescriptType = (schema: z.Schema, title = 'Test'): string => { + const getTypescriptType = (schema: z.ZodType, title = 'Test'): string => { return toTypescriptType(schema.title(title), { declaration: true }) } diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index b8d775d6ed4..983fa50db34 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -1,6 +1,5 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema' import z from '../../z' -import type { ZodDiscriminatedUnionOption } from '../../z/types/discriminatedUnion' import * as utils from '../../z/utils' import * as errors from '../common/errors' import { ArraySchema, SetSchema, TupleSchema } from '../common/json-schema' @@ -103,8 +102,8 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { } if (schema.type === 'integer') { - const zSchema = toZuiPrimitive('number', schema) - if (zSchema instanceof z.ZodNumber) { + const zSchema = toZuiPrimitive('number', schema) as z.ZodNativeType + if (zSchema.typeName === 'ZodNumber') { return zSchema.int() } @@ -175,9 +174,9 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { if (guards.isDiscriminatedUnionSchema(schema) && schema['x-zui']?.def?.discriminator) { const { discriminator } = schema['x-zui'].def const options = schema.anyOf.map(_fromJSONSchema) as [ - ZodDiscriminatedUnionOption, - ZodDiscriminatedUnionOption, - ...ZodDiscriminatedUnionOption[], + z.ZodDiscriminatedUnionOption, + z.ZodDiscriminatedUnionOption, + ...z.ZodDiscriminatedUnionOption[], ] return z.discriminatedUnion(discriminator, options) } diff --git a/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts b/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts index 2f912b1c28c..ebb8d54e3a4 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts @@ -1,6 +1,6 @@ import { JSONSchema7 } from 'json-schema' import z from '../../../z' -import * as datetime from '../../../z/types/string/datetime' +import * as datetime from '../../../z/utils/datestring-utils' import { zodPatterns } from '../../zui-to-json-schema-legacy/parsers/string' export const stringJSONSchemaToZuiString = ({ diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts index f199f8c20b5..05f8c87ad89 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/Options.ts @@ -1,4 +1,4 @@ -import type { ZodSchema } from '../../z' +import type { ZodType } from '../../z' export type Targets = 'jsonSchema7' | 'jsonSchema2019-09' | 'openApi3' @@ -13,7 +13,7 @@ export type Options = { target: Target strictUnions: boolean definitionPath: string - definitions: Record + definitions: Record errorMessages: boolean markdownDescription: boolean patternStrategy: 'escape' | 'preserve' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts index 854a3f7276e..9f5a5546ef9 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../ui/constants' -import { ZodFirstPartyTypeKind, ZodDef } from '../../z' +import { ZodNativeTypeDef, zuiKey, ZodFirstPartyTypeKind } from '../../z' import { JsonSchema7AnyType, parseAnyDef } from './parsers/any' import { JsonSchema7ArrayType, parseArrayDef } from './parsers/array' import { JsonSchema7BigintType, parseBigintDef } from './parsers/bigint' @@ -68,7 +67,7 @@ export type JsonSchema7TypeUnion = export type JsonSchema7Type = JsonSchema7TypeUnion & JsonSchema7Meta export function parseDef( - def: ZodDef, + def: ZodNativeTypeDef, refs: Refs, forceResolution = false // Forces a new schema to be instantiated even though its def has been seen. Used for improving refs in definitions. See https://github.com/StefanTerdell/zod-to-json-schema/pull/61. ): JsonSchema7Type | undefined { @@ -212,7 +211,7 @@ const selectParser = (def: any, typeName: ZodFirstPartyTypeKind, refs: Refs): Js } } -export const addMeta = (def: ZodDef, refs: Refs, jsonSchema: S): S => { +export const addMeta = (def: ZodNativeTypeDef, refs: Refs, jsonSchema: S): S => { if (def.description) { jsonSchema.description = def.description diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/any.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/any.ts index 2cd44e16dbf..a190678425f 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/any.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/any.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' export type JsonSchema7AnyType = { [zuiKey]?: ZuiExtensionObject diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts index b58dd5f7193..927569ab5fc 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts index 087e678b7d4..eab473be3de 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/bigint.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodBigIntDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodBigIntDef } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/boolean.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/boolean.ts index 07c1e7ad9d5..56da115aca3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/boolean.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/boolean.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodBooleanDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodBooleanDef } from '../../../z' export type JsonSchema7BooleanType = { type: 'boolean' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts index eeda4bed18e..81f4a5203db 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/date.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodDateDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodDateDef } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' import { JsonSchema7NumberType } from './number' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts index 346443f9c5e..92367324cf8 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/enum.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodEnumDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodEnumDef } from '../../../z' export type JsonSchema7EnumType = { type: 'string' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts index 8953e644cee..4e30782f6d3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/intersection.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodIntersectionDef, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodIntersectionDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7StringType } from './string' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts index ead804e3dc0..2fefb6a2c68 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/literal.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodLiteralDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodLiteralDef } from '../../../z' import { Refs } from '../Refs' export type JsonSchema7LiteralType = diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts index c7c678f6871..405f3de550f 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/map.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodMapDef, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodMapDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7RecordType, parseRecordDef } from './record' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts index ce450232731..fa518bfdc0b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nativeEnum.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNativeEnumDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodNativeEnumDef } from '../../../z' export type JsonSchema7NativeEnumType = { type: 'string' | 'number' | ['string', 'number'] diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/never.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/never.ts index 7d8cb2ad5d6..37823d04c7d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/never.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/never.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' export type JsonSchema7NeverType = { not: {} diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/null.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/null.ts index 69a80510de9..d69e0463c26 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/null.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/null.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' import { Refs } from '../Refs' export type JsonSchema7NullType = { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts index 91ce8dd2851..ec7da646be9 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/nullable.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNullableDef, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodNullableDef, ZodTypeAny } from '../../../z' import { addMeta, JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7NullType } from './null' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts index 46cbb3669d0..7044b7440da 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/number.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodNumberDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodNumberDef } from '../../../z' import { addErrorMessage, ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts index 4262add5ec7..5ddee9ce494 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodObjectDef, ZodType, ZodTypeAny } from '../../../z' +import z, { zuiKey, ZuiExtensionObject, ZodObjectDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' @@ -13,7 +11,7 @@ export type JsonSchema7ObjectType = { } const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonSchema7Type => { - if (def.unknownKeys instanceof ZodType) { + if (z.isZuiType(def.unknownKeys)) { return ( parseDef((def.unknownKeys as ZodTypeAny)._def, { ...refs, diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts index 9ea2146c94d..7e5379a6b46 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodType, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7EnumType } from './enum' @@ -16,7 +14,7 @@ export type JsonSchema7RecordType = { [zuiKey]?: ZuiExtensionObject } -export function parseRecordDef(def: ZodRecordDef | ZodMapDef, refs: Refs): JsonSchema7RecordType { +export function parseRecordDef(def: ZodRecordDef | ZodMapDef, refs: Refs): JsonSchema7RecordType { if (refs.target === 'openApi3' && def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) { return { type: 'object', diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/ref.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/ref.ts index 18f563ac4f8..07877ba37c1 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/ref.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/ref.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' import { ZodRefDef } from '../../../z/types/ref' export type JsonSchema7RefType = { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts index 46cab43420f..53325d32da6 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/set.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodSetDef, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodSetDef, ZodTypeAny } from '../../../z' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts index 0343287ba31..5547128f251 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/string.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodStringDef } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodStringDef } from '../../../z' import { regexUtils } from '../../common' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts index 4eb3491d24c..6725ea1dc3b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/tuple.ts @@ -1,6 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodTupleDef, ZodTupleItems, ZodType, ZodTypeAny } from '../../../z' +import { ZodType, zuiKey, ZuiExtensionObject, ZodTupleDef, ZodTupleItems, ZodTypeAny } from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/undefined.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/undefined.ts index 841a844547c..507c8d4d0f2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/undefined.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/undefined.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' export type JsonSchema7UndefinedType = { not: {} diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts index a0c23e2c0d9..550311c45e6 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/union.ts @@ -1,6 +1,11 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' -import { ZodDiscriminatedUnionDef, ZodLiteralDef, ZodTypeAny, ZodUnionDef } from '../../../z' +import { + zuiKey, + ZuiExtensionObject, + ZodDiscriminatedUnionDef, + ZodLiteralDef, + ZodTypeAny, + ZodUnionDef, +} from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/unknown.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/unknown.ts index d893a86eb08..db60c340e75 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/unknown.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/unknown.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import { ZuiExtensionObject } from '../../../ui/types' +import { zuiKey, ZuiExtensionObject } from '../../../z' export type JsonSchema7UnknownType = { [zuiKey]?: ZuiExtensionObject diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts index a8fff349d65..221ce990241 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { zodToJsonSchema } from '../zodToJsonSchema' -import { z } from '../../../z/index' +import { z } from '../../../z' enum nativeEnum { 'a', diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts index 532a5a9e917..e322f7fdc06 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts @@ -1,6 +1,5 @@ import { describe, test, expect } from 'vitest' -import { zuiKey } from '../../../ui/constants' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' describe('Issue tests', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts index d77d2a910ce..25117c7aa1b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts @@ -1,7 +1,6 @@ import { describe, it, expect } from 'vitest' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' -import { zuiKey } from '../../../ui/constants' describe('Meta data', () => { it('should be possible to use description', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts index b1e22a8e483..dbeb7c176d7 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../ui/constants' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' describe('Open API target', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts index f034f354a02..c24377b76cc 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts @@ -1,10 +1,9 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { parseDef } from '../parseDef' import Ajv from 'ajv' import { getRefs } from '../Refs' -import { zuiKey } from '../../../ui/constants' const ajv = new Ajv() diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts index 6151d333f42..91c2e5d0c04 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts @@ -1,11 +1,10 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseArrayDef } from '../../parsers/array' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' import deref from 'local-ref-resolver' -import { zuiKey } from '../../../../ui/constants' describe('Arrays and array validations', () => { it('should be possible to describe a simple array', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts index 8338acffe83..195b3bbae2e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' import { parseBigintDef } from '../../parsers/bigint' -import { z } from '../../../../z/index' +import { z } from '../../../../z' import { getRefs } from '../../Refs' describe('bigint', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts index 0cee92fdd99..6ce3343c869 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseBrandedDef } from '../../parsers/branded' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts index 51ababd9ab4..a7e115aa73a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z } from '../../../../z' import { parseDateDef } from '../../parsers/date' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts index 9c1a88acf6d..83625cc5e83 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseDefaultDef } from '../../parsers/default' import { getRefs } from '../../Refs' -import { zuiKey } from '../../../../ui/constants' describe('promise', () => { it('should be possible to use default on objects', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts index 248f6ee7180..368b8400998 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseEffectsDef } from '../../parsers/effects' import { getRefs } from '../../Refs' -import { zuiKey } from '../../../../ui/constants' describe('effects', () => { it('should be possible to use refine', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts index 7da5e50123f..cdda74d2429 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseIntersectionDef } from '../../parsers/intersection' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts index a9f161bbffa..bb3842c1782 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts @@ -1,10 +1,9 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseMapDef } from '../../parsers/map' import Ajv from 'ajv' import { getRefs } from '../../Refs' -import { zuiKey } from '../../../../ui/constants' const ajv = new Ajv({ strict: false }) describe('map', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts index eddcc18b3e3..3ad84e4597a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z } from '../../../../z' import { parseNativeEnumDef } from '../../parsers/nativeEnum' describe('Native enums', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts index 0649e71f254..2ffa6e108f2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseObjectDef } from '../../parsers/object' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts index b449b3e3dad..fb6d05ae0bb 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z } from '../../../../z' import { parseNumberDef } from '../../parsers/number' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts index ea49907169f..af6c8b6ff1a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseObjectDef } from '../../parsers/object' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts index 387cf834042..26327a0a148 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseDef } from '../../parseDef' import { getRefs } from '../../Refs' -import { zuiKey } from '../../../../ui/constants' describe('Standalone optionals', () => { it('should work as unions with undefined', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts index cc510fac8e3..5fc2981c64e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parsePipelineDef } from '../../parsers/pipeline' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts index a274b2b977e..5133a1c3641 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parsePromiseDef } from '../../parsers/promise' import { getRefs } from '../../Refs' -import { zuiKey } from '../../../../ui/constants' describe('promise', () => { it('should be possible to use promise', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts index ab401ab40c1..d759050f1ee 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseRecordDef } from '../../parsers/record' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts index ce575fc4b55..23ac436612d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts @@ -1,10 +1,9 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseSetDef } from '../../parsers/set' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' -import { zuiKey } from '../../../../ui/constants' describe('set', () => { it("should include min and max size error messages if they're passed.", () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts index 268fb692fe0..8216cb8feb8 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z } from '../../../../z' import { JsonSchema7Type } from '../../parseDef' import { JsonSchema7StringType, zodPatterns, parseStringDef } from '../../parsers/string' import Ajv from 'ajv' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts index 36ee08e8c0f..a47662cc589 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../../ui/constants' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseTupleDef } from '../../parsers/tuple' import { getRefs } from '../../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts index 66114b456b5..d7e48545d5a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts @@ -1,10 +1,9 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z/index' +import { z, zuiKey } from '../../../../z' import { parseUnionDef } from '../../parsers/union' import { getRefs } from '../../Refs' import deref from 'local-ref-resolver' -import { zuiKey } from '../../../../ui/constants' describe('Unions', () => { it('Should be possible to get a simple type array from a union of only unvalidated primitives', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts index 9d590688a39..92bc64a7581 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../ui/constants' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' describe('The readme example', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts index 8bdf9124250..65875cac73d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts @@ -1,10 +1,9 @@ import { describe, test, expect } from 'vitest' import Ajv from 'ajv' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' const ajv = new Ajv() import deref from 'local-ref-resolver' -import { zuiKey } from '../../../ui/constants' describe('Pathing', () => { test('should handle recurring properties with paths', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts index 0d93447cc99..f35ff9c8cb2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest' -import { zuiKey } from '../../../ui/constants' -import { z } from '../../../z/index' +import { z, zuiKey } from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' describe('Root schema result after parsing', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts index 8c2a57b6200..1d2d49dcbf3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zodToJsonSchema.ts @@ -1,10 +1,10 @@ -import type { ZodDef, ZodSchema } from '../../z' +import type { ZodNativeTypeDef, ZodType } from '../../z' import { Options, Targets } from './Options' import { JsonSchema7Type, parseDef } from './parseDef' import { getRefs } from './Refs' const zodToJsonSchema = ( - schema: ZodSchema, + schema: ZodType, options?: Partial> | string ): (Target extends 'jsonSchema7' ? JsonSchema7Type : object) & { $schema?: string @@ -25,7 +25,7 @@ const zodToJsonSchema = ( ...acc, [name]: parseDef( - schema._def as ZodDef, + schema._def as ZodNativeTypeDef, { ...refs, currentPath: [...refs.basePath, refs.definitionPath, name], @@ -41,7 +41,7 @@ const zodToJsonSchema = ( const main = parseDef( - schema._def as ZodDef, + schema._def as ZodNativeTypeDef, name === undefined ? refs : { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts index e348597e295..bf2c4b981b2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts @@ -1,7 +1,6 @@ import { describe, test, expect, it } from 'vitest' import { toJSONSchemaLegacy } from './zui-extension' -import { z } from '../../z/index' -import { zuiKey } from '../../ui/constants' +import { z, zuiKey } from '../../z' describe('zuiToJsonSchema', () => { test('should work', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts index 45223edaa3e..ba48db0b241 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts @@ -26,7 +26,7 @@ export const toJSONSchemaLegacy = ( zuiType: z.ZodType, opts: ZuiSchemaOptions = { target: 'openApi3' } ): JSONSchema7 => { - const jsonSchema = zodToJsonSchema(zuiType as z.ZodType, opts) + const jsonSchema = zodToJsonSchema(zuiType, opts) if (opts.$schemaUrl === false) { delete jsonSchema.$schema } else if (typeof opts.$schemaUrl === 'string') { diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index 96c30372936..b78c96e5723 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -13,8 +13,8 @@ import { zodTupleToJsonTuple } from './type-processors/tuple' * @param schema zui schema * @returns ZUI flavored JSON schema */ -export function toJSONSchema(schema: z.Schema): json.Schema { - const s = schema as z.ZodNativeSchema +export function toJSONSchema(schema: z.ZodType): json.Schema { + const s = schema as z.ZodNativeType switch (s.typeName) { case 'ZodString': @@ -83,7 +83,7 @@ export function toJSONSchema(schema: z.Schema): json.Schema { .map(([key, value]) => [key, toJSONSchema(value)] satisfies [string, json.Schema]) let additionalProperties: json.ObjectSchema['additionalProperties'] = false - if (s._def.unknownKeys instanceof z.ZodType) { + if (z.isZuiType(s._def.unknownKeys)) { additionalProperties = toJSONSchema(s._def.unknownKeys) } else if (s._def.unknownKeys === 'passthrough') { additionalProperties = true diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts index 00837d45836..420f11765c3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import z from '../../../z' +import z, { zuiKey } from '../../../z' import * as json from '../../common/json-schema' export const zodArrayToJsonArray = ( diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts index 1269c4f1ade..41c789a397a 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import z from '../../../z' +import z, { zuiKey } from '../../../z' import * as json from '../../common/json-schema' export const zodNumberToJsonNumber = (zodNumber: z.ZodNumber): json.NumberSchema => { diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts index 7c8610af569..68acc1108ef 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import z from '../../../z' +import z, { zuiKey } from '../../../z' import * as json from '../../common/json-schema' export const zodSetToJsonSet = (zodSet: z.ZodSet, toSchema: (x: z.ZodType) => json.Schema): json.SetSchema => { diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts index 99af891bbd4..c7e98f5f3c3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts @@ -1,6 +1,5 @@ -import { zuiKey } from '../../../ui/constants' -import z from '../../../z' -import { generateDatetimeRegex } from '../../../z/types/string/datetime' +import z, { zuiKey } from '../../../z' +import { generateDatetimeRegex } from '../../../z/utils/datestring-utils' import { regexUtils } from '../../common' import * as errors from '../../common/errors' import * as json from '../../common/json-schema' diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts index 31c2d49bf0f..361a6b2e6f7 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts @@ -1,5 +1,4 @@ -import { zuiKey } from '../../../ui/constants' -import z from '../../../z' +import z, { zuiKey } from '../../../z' import * as json from '../../common/json-schema' export const zodTupleToJsonTuple = ( diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/array-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/array-checks.ts index b4c40258412..74ed12ccc90 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/array-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/array-checks.ts @@ -1,4 +1,4 @@ -import { ZodArrayDef } from '../../z/types/array' +import { ZodArrayDef } from '../../z' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateArrayChecks = (def: ZodArrayDef): string => { diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts index 212c8ccd74d..47a82dcfc3b 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts @@ -1,4 +1,4 @@ -import { ZodBigIntCheck, ZodBigIntDef } from '../../z/types/bigint' +import { ZodBigIntCheck, ZodBigIntDef } from '../../z' import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts index 38a3e29d309..4836fbf79e7 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts @@ -1,4 +1,4 @@ -import { ZodDateCheck, ZodDateDef } from '../../z/types/date' +import { ZodDateCheck, ZodDateDef } from '../../z' import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts index e5b9bffee8e..7f7937e019f 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts @@ -2,10 +2,10 @@ import { describe, expect, test, it } from 'vitest' import { toTypescriptSchema as toTypescript } from '.' import { evalZuiString } from '../common/eval-zui-string' import * as errors from '../common/errors' -import z, { ZodLiteral, ZodSchema, ZodType } from '../../z' -import { UIComponentDefinitions } from '../../ui/types' +import z, { ZodLiteral } from '../../z' +import { UIComponentDefinitions } from '../../z/typings' -const evalZui = (source: string): ZodSchema => { +const evalZui = (source: string): z.ZodNativeType => { const evalResult = evalZuiString(source) if (!evalResult.sucess) { throw new Error(`${evalResult.error}: ${source}`) @@ -13,9 +13,9 @@ const evalZui = (source: string): ZodSchema => { return evalResult.value } -const generate = (source: Z): Z => evalZui(toTypescript(source)) as Z +const generate = (source: Z): Z => evalZui(toTypescript(source)) as Z -const assert = (source: ZodType) => ({ +const assert = (source: z.ZodType) => ({ toGenerateItself() { const destination = generate(source) let msg: string | undefined @@ -464,7 +464,7 @@ describe.concurrent('toTypescriptSchema', () => { const source = z.literal(Symbol('banana')) const dest = evalZui(toTypescript(source)) as ZodLiteral - expect(dest instanceof ZodLiteral).toBe(true) + expect(dest.typeName === 'ZodLiteral').toBe(true) const value = dest.value as symbol expect(typeof value).toBe('symbol') expect(value.description).toBe('banana') diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts index 2a66952c412..d69bca437c4 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts @@ -1,7 +1,6 @@ import { mapValues, isEqual } from 'lodash-es' -import { zuiKey } from '../../ui/constants' -import z from '../../z' +import z, { zuiKey } from '../../z' import * as utils from '../../z/utils' import * as errors from '../common/errors' import { @@ -22,15 +21,14 @@ import { generateStringChecks } from './string-checks' * @param options generation options * @returns a typescript program that would construct the given schema if executed */ -export function toTypescriptSchema(schema: z.Schema): string { - const wrappedSchema: z.Schema = schema +export function toTypescriptSchema(schema: z.ZodType): string { + const wrappedSchema: z.ZodType = schema const dts = sUnwrapZod(wrappedSchema) return dts } -function sUnwrapZod(schema: z.Schema): string { - const s = schema as z.ZodNativeSchema - +function sUnwrapZod(schema: z.ZodType): string { + const s = schema as z.ZodNativeType switch (s.typeName) { case 'ZodString': return `z.string()${generateStringChecks(s._def)}${_addMetadata(s._def)}`.trim() diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts index 03a79563991..69172ae6b8c 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts @@ -1,4 +1,4 @@ -import { ZodNumberCheck, ZodNumberDef } from '../../z/types/number' +import { ZodNumberCheck, ZodNumberDef } from '../../z/' import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/set-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/set-checks.ts index 0f4d8c01d72..8b787dd5d13 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/set-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/set-checks.ts @@ -1,4 +1,4 @@ -import { ZodSetDef } from '../../z/types/set' +import { ZodSetDef } from '../../z' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateSetChecks = (def: ZodSetDef): string => { const checks: string[] = [] diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index 03766901e4a..ffe44bbf4cf 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -34,16 +34,16 @@ const stripSpaces = (typings: string) => typings.replace(/ +/g, ' ').trim() class KeyValue { constructor( public key: string, - public value: z.Schema + public value: z.ZodType ) {} } class FnParameters { - constructor(public schema: z.Schema) {} + constructor(public schema: z.ZodType) {} } class FnReturn { - constructor(public schema: z.Schema) {} + constructor(public schema: z.ZodType) {} } class Declaration { @@ -53,18 +53,18 @@ class Declaration { type DeclarationProps = | { type: 'variable' - schema: z.Schema + schema: z.ZodType identifier: string } | { type: 'type' - schema: z.Schema + schema: z.ZodType identifier: string args: string[] // type arguments / generics } | { type: 'none' - schema: z.Schema + schema: z.ZodType } export type TypescriptDeclarationType = DeclarationProps['type'] @@ -79,7 +79,7 @@ export type TypescriptGenerationOptions = { treatDefaultAsOptional?: boolean } -type SchemaTypes = z.Schema | KeyValue | FnParameters | Declaration | null +type SchemaTypes = z.ZodType | KeyValue | FnParameters | Declaration | null type InternalOptions = { parent?: SchemaTypes @@ -94,7 +94,7 @@ type InternalOptions = { * @param options generation options * @returns a string of the TypeScript **type** representing the schema */ -export function toTypescriptType(schema: z.Schema, options: TypescriptGenerationOptions = {}): string { +export function toTypescriptType(schema: z.ZodType, options: TypescriptGenerationOptions = {}): string { const wrappedSchema: Declaration = getDeclarationProps(schema, options) let dts = sUnwrapZod(wrappedSchema, options) @@ -108,7 +108,7 @@ export function toTypescriptType(schema: z.Schema, options: TypescriptGeneration const _optionalKey = (key: string): string => (key.endsWith('?') ? key : `${key}?`) -function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | null, config: InternalOptions): string { +function sUnwrapZod(schema: z.ZodType | KeyValue | FnParameters | Declaration | null, config: InternalOptions): string { const newConfig: InternalOptions = { ...config, declaration: false, @@ -125,15 +125,17 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n if (schema instanceof KeyValue) { let optionalValue: z.ZodOptional | undefined = undefined - if (schema.value instanceof z.ZodOptional) { - optionalValue = schema.value - } else if (schema.value instanceof z.ZodDefault && config.treatDefaultAsOptional) { - optionalValue = schema.value._def.innerType.optional() + + const schemaValue = schema.value as z.ZodNativeType + if (schemaValue.typeName === 'ZodOptional') { + optionalValue = schemaValue + } else if (schemaValue.typeName === 'ZodDefault' && config.treatDefaultAsOptional) { + optionalValue = schemaValue._def.innerType.optional() } if (optionalValue) { let innerType = optionalValue._def.innerType - if (innerType instanceof z.Schema && !innerType.description && optionalValue.description) { + if (z.isZuiType(innerType) && !innerType.description && optionalValue.description) { innerType = innerType?.describe(optionalValue.description) } @@ -144,24 +146,27 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n const delimiter = description?.trim().length > 0 ? '\n' : '' const withoutDesc = schema.value.describe('') - const isOptional = schema.value instanceof z.ZodAny // any is treated as optional for backwards compatibility + const isOptional = (schema.value as z.ZodNativeType).typeName === 'ZodAny' // any is treated as optional for backwards compatibility const key = isOptional ? _optionalKey(schema.key) : schema.key return `${delimiter}${description}${delimiter}${key}: ${sUnwrapZod(withoutDesc, newConfig)}${delimiter}` } if (schema instanceof FnParameters) { - if (schema.schema instanceof z.ZodTuple) { + const schemaSchema = schema.schema as z.ZodNativeType + if (schemaSchema.typeName === 'ZodTuple') { let args = '' - for (let i = 0; i < schema.schema.items.length; i++) { - const argName = schema.schema.items[i]?.ui?.title ?? `arg${i}` - const item = schema.schema.items[i] - args += `${sUnwrapZod(new KeyValue(toPropertyKey(argName), item), newConfig)}${i < schema.schema.items.length - 1 ? ', ' : ''} ` + for (let i = 0; i < schemaSchema.items.length; i++) { + const argName = (schemaSchema.items[i]?.ui?.title as string) ?? `arg${i}` + const item = schemaSchema.items[i]! + args += `${sUnwrapZod(new KeyValue(toPropertyKey(argName), item), newConfig)}${ + i < schemaSchema.items.length - 1 ? ', ' : '' + } ` } return args } - const isLiteral = schema.schema.naked() instanceof z.ZodLiteral + const isLiteral = (schema.schema.naked() as z.ZodNativeType).typeName === 'ZodLiteral' const typings = sUnwrapZod(schema.schema, newConfig).trim() const startsWithPairs = @@ -180,11 +185,12 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n } if (schema instanceof FnReturn) { - if (schema.schema instanceof z.ZodOptional) { - return `${sUnwrapZod(schema.schema.unwrap(), newConfig)} | undefined` + const schemaSchema = schema.schema as z.ZodNativeType + if (schemaSchema.typeName === 'ZodOptional') { + return `${sUnwrapZod(schemaSchema.unwrap(), newConfig)} | undefined` } - return sUnwrapZod(schema.schema, newConfig) + return sUnwrapZod(schemaSchema, newConfig) } const s = schema as z.ZodFirstPartySchemaTypes @@ -233,7 +239,7 @@ function sUnwrapZod(schema: z.Schema | KeyValue | FnParameters | Declaration | n case 'ZodObject': const props = Object.entries(s._def.shape()).map(([key, value]) => { - if (value instanceof z.Schema) { + if (z.isZuiType(value)) { return sUnwrapZod(new KeyValue(toPropertyKey(key), value), newConfig) } return `${key}: unknown` @@ -357,7 +363,7 @@ const unwrapDeclaration = (declaration: Declaration, options: InternalOptions): const isLargeDeclaration = typings.split('\n').length >= LARGE_DECLARATION_LINES const closingTag = isLargeDeclaration && options.includeClosingTags ? `// end of ${identifier}` : '' - if (declaration.props.type !== 'type' && schema instanceof z.ZodFunction) { + if (declaration.props.type !== 'type' && schema.typeName === 'ZodFunction') { return stripSpaces(`${description} declare function ${identifier}${typings};${closingTag}`) } @@ -381,7 +387,7 @@ const getDeclarationType = (options: TypescriptGenerationOptions): TypescriptDec return options.declaration } -const getDeclarationProps = (schema: z.Schema, options: TypescriptGenerationOptions): Declaration => { +const getDeclarationProps = (schema: z.ZodType, options: TypescriptGenerationOptions): Declaration => { const declarationType = getDeclarationType(options) const args = schema.getReferences() diff --git a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts index 5bad3cbcd87..0c55c0b030d 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts @@ -3,7 +3,7 @@ import { toTypescriptType as toTs } from '.' import z from '../../z' import { assert } from '../../assertions.utils.test' -const toTypescriptType = (schema: z.Schema) => toTs(schema, { declaration: 'variable' }) +const toTypescriptType = (schema: z.ZodType) => toTs(schema, { declaration: 'variable' }) test('string', async () => { const schema = z.string().title('x') diff --git a/packages/zui/src/ui/types.ts b/packages/zui/src/ui/types.ts deleted file mode 100644 index b49766c2e08..00000000000 --- a/packages/zui/src/ui/types.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ZodTypeDef, ZodType, TypeOf } from '../z/types/basetype' -import { ZodObject } from '../z/types/object' - -export type ZuiMetadata = string | number | boolean | null | undefined | ZuiMetadata[] | { [key: string]: ZuiMetadata } - -type SerializedFunction = string -export type ZuiExtensionObject = { - tooltip?: boolean - displayAs?: [string, any] - title?: string - disabled?: boolean | SerializedFunction - hidden?: boolean | SerializedFunction - placeholder?: string - secret?: boolean - coerce?: boolean - [key: string]: ZuiMetadata -} - -export type BaseType = 'number' | 'string' | 'boolean' | 'object' | 'array' | 'discriminatedUnion' - -export type ContainerType = 'object' | 'array' | 'discriminatedUnion' - -export type UIComponentDefinitions = { - [T in BaseType]: { - [K: string]: { - id: string - params: ZodObject - } - } -} - -export type ZodKindToBaseType = T extends infer U - ? U extends { typeName: 'ZodString' } - ? 'string' - : U extends { typeName: 'ZodNumber' } - ? 'number' - : U extends { typeName: 'ZodBoolean' } - ? 'boolean' - : U extends { typeName: 'ZodArray' } - ? 'array' - : U extends { typeName: 'ZodObject' } - ? 'object' - : U extends { typeName: 'ZodTuple' } - ? never - : U extends { typeName: 'ZodEnum' } - ? 'string' - : U extends { typeName: 'ZodDefault'; innerType: ZodType } - ? ZodKindToBaseType - : U extends { typeName: 'ZodOptional'; innerType: ZodType } - ? ZodKindToBaseType - : U extends { typeName: 'ZodNullable'; innerType: ZodType } - ? ZodKindToBaseType - : U extends { typeName: 'ZodDiscriminatedUnion' } - ? 'discriminatedUnion' - : never - : never - -export type ParseSchema = I extends infer U - ? U extends { id: string; params: ZodObject } - ? { - id: U['id'] - params: TypeOf - } - : object - : never diff --git a/packages/zui/src/z/__tests__/async-parsing.test.ts b/packages/zui/src/z/__tests__/async-parsing.test.ts index f1346470dc1..63814b65fa3 100644 --- a/packages/zui/src/z/__tests__/async-parsing.test.ts +++ b/packages/zui/src/z/__tests__/async-parsing.test.ts @@ -1,5 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' +import { ZodError } from '../error' /// string const stringSchema = z.string() @@ -14,7 +15,7 @@ test('string async parse', async () => { const badResult = await stringSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// number @@ -29,7 +30,7 @@ test('number async parse', async () => { const badResult = await numberSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// bigInt @@ -44,7 +45,7 @@ test('bigInt async parse', async () => { const badResult = await bigIntSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// boolean @@ -59,7 +60,7 @@ test('boolean async parse', async () => { const badResult = await booleanSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// date @@ -74,7 +75,7 @@ test('date async parse', async () => { const badResult = await dateSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// undefined @@ -89,7 +90,7 @@ test('undefined async parse', async () => { const badResult = await undefinedSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// null @@ -104,7 +105,7 @@ test('null async parse', async () => { const badResult = await nullSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// any @@ -119,7 +120,7 @@ test('any async parse', async () => { // const badResult = await anySchema.safeParseAsync(badData); // expect(badResult.success).toBe(false); - // if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); + // if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError); }) /// unknown @@ -134,7 +135,7 @@ test('unknown async parse', async () => { // const badResult = await unknownSchema.safeParseAsync(badData); // expect(badResult.success).toBe(false); - // if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError); + // if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError); }) /// void @@ -149,7 +150,7 @@ test('void async parse', async () => { const badResult = await voidSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// array @@ -164,7 +165,7 @@ test('array async parse', async () => { const badResult = await arraySchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// object @@ -179,7 +180,7 @@ test('object async parse', async () => { const badResult = await objectSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// union @@ -194,7 +195,7 @@ test('union async parse', async () => { const badResult = await unionSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// record @@ -209,7 +210,7 @@ test('record async parse', async () => { const badResult = await recordSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// function @@ -224,7 +225,7 @@ test('function async parse', async () => { const badResult = await functionSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// literal @@ -239,7 +240,7 @@ test('literal async parse', async () => { const badResult = await literalSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// enum @@ -254,7 +255,7 @@ test('enum async parse', async () => { const badResult = await enumSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// nativeEnum @@ -273,7 +274,7 @@ test('nativeEnum async parse', async () => { const badResult = await nativeEnumSchema.safeParseAsync(badData) expect(badResult.success).toBe(false) - if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError) + if (!badResult.success) expect(badResult.error).toBeInstanceOf(ZodError) }) /// promise @@ -299,7 +300,7 @@ test('promise async parse bad', async () => { const badResult = await promiseSchema.safeParseAsync(badData) expect(badResult.success).toBe(true) if (badResult.success) { - await expect(badResult.data).rejects.toBeInstanceOf(z.ZodError) + await expect(badResult.data).rejects.toBeInstanceOf(ZodError) } else { throw new Error('success should be true') } diff --git a/packages/zui/src/z/__tests__/base.test.ts b/packages/zui/src/z/__tests__/base.test.ts index c208db0d2ac..c200cef8097 100644 --- a/packages/zui/src/z/__tests__/base.test.ts +++ b/packages/zui/src/z/__tests__/base.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import * as utils from '../../z/utils' +import * as utils from '../utils' test('type guard', () => { const stringToNumber = z.string().transform((arg) => arg.length) diff --git a/packages/zui/src/z/clone.test.ts b/packages/zui/src/z/__tests__/clone.test.ts similarity index 93% rename from packages/zui/src/z/clone.test.ts rename to packages/zui/src/z/__tests__/clone.test.ts index cbd9458c259..a3adf6045cc 100644 --- a/packages/zui/src/z/clone.test.ts +++ b/packages/zui/src/z/__tests__/clone.test.ts @@ -1,22 +1,25 @@ import { test, expect } from 'vitest' -import { z } from '.' +import { z } from '../index' +import * as transforms from '../../transforms' -const expectZui = (actual: z.Schema) => ({ +const expectZui = (actual: z.ZodType) => ({ not: { - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} not to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${transforms.toTypescriptSchema(actual)} not to equal ${transforms.toTypescriptSchema( + expected + )}` } catch {} expect(result, msg).toBe(true) }, }, - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${transforms.toTypescriptSchema(actual)} to equal ${transforms.toTypescriptSchema(expected)}` } catch {} expect(result, msg).toBe(true) }, diff --git a/packages/zui/src/z/__tests__/complex.test.ts b/packages/zui/src/z/__tests__/complex.test.ts index 4fb86423b92..6133a5c497a 100644 --- a/packages/zui/src/z/__tests__/complex.test.ts +++ b/packages/zui/src/z/__tests__/complex.test.ts @@ -1,6 +1,5 @@ import { test } from 'vitest' import { crazySchema } from './crazySchema' -// import z from "../index"; test('parse', () => { crazySchema.parse({ diff --git a/packages/zui/src/z/deref.test.ts b/packages/zui/src/z/__tests__/deref.test.ts similarity index 98% rename from packages/zui/src/z/deref.test.ts rename to packages/zui/src/z/__tests__/deref.test.ts index c9ea4f31210..5639e4a5f10 100644 --- a/packages/zui/src/z/deref.test.ts +++ b/packages/zui/src/z/__tests__/deref.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest' -import { z } from './index' +import { z } from '../index' const foo = z.ref('foo') const bar = z.ref('bar') @@ -11,7 +11,7 @@ const deref = { baz: z.boolean(), } -const intersect = (...schemas: z.ZodType[]) => { +const intersect = (...schemas: z.ZodNativeType[]) => { if (schemas.length === 0) { throw new Error('Intersection expects at least one schema') } diff --git a/packages/zui/src/z/__tests__/generics.test.ts b/packages/zui/src/z/__tests__/generics.test.ts index b8be5705500..febacf59789 100644 --- a/packages/zui/src/z/__tests__/generics.test.ts +++ b/packages/zui/src/z/__tests__/generics.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import z from '../index' -import * as utils from '../../z/utils' +import * as utils from '../utils' test('generics', () => { async function stripOuter(schema: TData, data: unknown) { diff --git a/packages/zui/src/z/__tests__/instanceof.test.ts b/packages/zui/src/z/__tests__/instanceof.test.ts index b0d23fe5a15..5b9e4f3385e 100644 --- a/packages/zui/src/z/__tests__/instanceof.test.ts +++ b/packages/zui/src/z/__tests__/instanceof.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' +import * as utils from '../utils' import z from '../index' test('instanceof', async () => { diff --git a/packages/zui/src/z/is-equal.test.ts b/packages/zui/src/z/__tests__/is-equal.test.ts similarity index 98% rename from packages/zui/src/z/is-equal.test.ts rename to packages/zui/src/z/__tests__/is-equal.test.ts index fcafe3c4646..9dfac715517 100644 --- a/packages/zui/src/z/is-equal.test.ts +++ b/packages/zui/src/z/__tests__/is-equal.test.ts @@ -1,14 +1,14 @@ import { describe, test, expect } from 'vitest' -import { z } from './index' +import { z } from '../index' -const expectZui = (actual: z.Schema) => ({ +const expectZui = (actual: z.ZodType) => ({ not: { - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) expect(result).toBe(false) }, }, - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) expect(result).toBe(true) }, diff --git a/packages/zui/src/z/mandatory.test.ts b/packages/zui/src/z/__tests__/mandatory.test.ts similarity index 88% rename from packages/zui/src/z/mandatory.test.ts rename to packages/zui/src/z/__tests__/mandatory.test.ts index 74ef2eb3103..d8cbd409439 100644 --- a/packages/zui/src/z/mandatory.test.ts +++ b/packages/zui/src/z/__tests__/mandatory.test.ts @@ -1,22 +1,27 @@ import { describe, test, expect } from 'vitest' -import { z } from './index' +import { z } from '../index' +import * as transforms from '../../transforms' -const expectZui = (actual: z.Schema) => ({ +const expectZui = (actual: z.ZodType) => ({ not: { - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} not to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${transforms.toTypescriptSchema( + actual as z.ZodNativeType + )} not to equal ${transforms.toTypescriptSchema(expected as z.ZodNativeType)}` } catch {} expect(result, msg).toBe(true) }, }, - toEqual: (expected: z.Schema) => { + toEqual: (expected: z.ZodType) => { const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${actual.toTypescriptSchema()} to equal ${expected.toTypescriptSchema()}` + msg = `Expected ${transforms.toTypescriptSchema(actual as z.ZodNativeType)} to equal ${transforms.toTypescriptSchema( + expected as z.ZodNativeType + )}` } catch {} expect(result, msg).toBe(true) }, diff --git a/packages/zui/src/z/__tests__/naked.test.ts b/packages/zui/src/z/__tests__/naked.test.ts index 534aa9edad5..e7e55ae70e6 100644 --- a/packages/zui/src/z/__tests__/naked.test.ts +++ b/packages/zui/src/z/__tests__/naked.test.ts @@ -1,20 +1,19 @@ import { test, assert } from 'vitest' - -import z, { ZodArray, ZodObject, ZodString, ZodUnion } from '../index' +import z from '../index' test('naked object', () => { - assert.instanceOf(z.object({ name: z.string() }).naked(), ZodObject) - assert.instanceOf(z.object({ name: z.string() }).nullable().naked(), ZodObject) - assert.instanceOf( + assert.equal(z.object({ name: z.string() }).naked().typeName, 'ZodObject') + assert.equal(z.object({ name: z.string() }).nullable().naked().typeName, 'ZodObject') + assert.equal( z .object({ name: z.string() }) .catch(() => ({ name: '' })) - .naked(), - ZodObject + .naked().typeName, + 'ZodObject' ) - assert.instanceOf(z.object({ name: z.string() }).optional().nullable().naked(), ZodObject) - assert.instanceOf(z.object({ name: z.string() }).promise().nullable().naked(), ZodObject) - assert.instanceOf( + assert.equal(z.object({ name: z.string() }).optional().nullable().naked().typeName, 'ZodObject') + assert.equal(z.object({ name: z.string() }).promise().nullable().naked().typeName, 'ZodObject') + assert.equal( z .object({ name: z.string() }) .catch(() => ({ name: '' })) @@ -22,68 +21,68 @@ test('naked object', () => { .promise() .optional() .nullable() - .naked(), - ZodObject + .naked().typeName, + 'ZodObject' ) - assert.instanceOf(z.object({ name: z.string() }).readonly().naked(), ZodObject) + assert.equal(z.object({ name: z.string() }).readonly().naked().typeName, 'ZodObject') }) test('lazy', () => { - assert.instanceOf(z.lazy(() => z.string()).naked(), ZodString) - assert.instanceOf( + assert.equal(z.lazy(() => z.string()).naked().typeName, 'ZodString') + assert.equal( z .lazy(() => z.string()) .nullable() - .naked(), - ZodString + .naked().typeName, + 'ZodString' ) - assert.instanceOf( + assert.equal( z .lazy(() => z.string()) .optional() .nullable() - .naked(), - ZodString + .naked().typeName, + 'ZodString' ) - assert.instanceOf( + assert.equal( z .lazy(() => z.string()) .promise() .nullable() - .naked(), - ZodString + .naked().typeName, + 'ZodString' ) - assert.instanceOf(z.lazy(() => z.object({ name: z.string() })).naked(), ZodObject) - assert.instanceOf( + assert.equal(z.lazy(() => z.object({ name: z.string() })).naked().typeName, 'ZodObject') + assert.equal( z .lazy(() => z.object({ name: z.string() })) .nullable() - .naked(), - ZodObject + .naked().typeName, + 'ZodObject' ) }) test('naked array', () => { - assert.instanceOf(z.array(z.string()).naked(), ZodArray) - assert.instanceOf(z.array(z.string()).nullable().naked(), ZodArray) - assert.instanceOf(z.array(z.string()).optional().nullable().naked(), ZodArray) - assert.instanceOf(z.array(z.string()).promise().nullable().naked(), ZodArray) + assert.equal(z.array(z.string()).naked().typeName, 'ZodArray') + assert.equal(z.array(z.string()).nullable().naked().typeName, 'ZodArray') + assert.equal(z.array(z.string()).optional().nullable().naked().typeName, 'ZodArray') + assert.equal(z.array(z.string()).promise().nullable().naked().typeName, 'ZodArray') }) test('naked string', () => { - assert.instanceOf(z.string().naked(), ZodString) - assert.instanceOf(z.string().nullable().naked(), ZodString) - assert.instanceOf(z.string().optional().nullable().naked(), ZodString) - assert.instanceOf(z.string().promise().nullable().naked(), ZodString) + assert.equal(z.string().naked().typeName, 'ZodString') + assert.equal(z.string().nullable().naked().typeName, 'ZodString') + assert.equal(z.string().optional().nullable().naked().typeName, 'ZodString') + assert.equal(z.string().promise().nullable().naked().typeName, 'ZodString') }) test('naked union', () => { - assert.instanceOf(z.string().or(z.number()).naked(), ZodUnion) - assert.instanceOf(z.string().or(z.number()).nullable().naked(), ZodUnion) - assert.instanceOf(z.string().or(z.number()).optional().nullable().naked(), ZodUnion) - assert.instanceOf(z.string().or(z.number()).promise().nullable().naked(), ZodUnion) + assert.equal(z.string().or(z.number()).naked().typeName, 'ZodUnion') + assert.equal(z.string().or(z.number()).nullable().naked().typeName, 'ZodUnion') + assert.equal(z.string().or(z.number()).optional().nullable().naked().typeName, 'ZodUnion') + assert.equal(z.string().or(z.number()).promise().nullable().naked().typeName, 'ZodUnion') }) test('get constructor names', () => { @@ -91,7 +90,7 @@ test('get constructor names', () => { z .string() .catch(() => '') - .naked().constructor.name, + .naked().typeName, 'ZodString' ) @@ -100,19 +99,19 @@ test('get constructor names', () => { .string() .catch(() => '') .nullable() - .naked().constructor.name, + .naked().typeName, 'ZodString' ) }) test('not naked constructors', () => { - assert.equal(z.string().catch(() => '').constructor.name, 'ZodCatch') + assert.equal(z.string().catch(() => '').typeName, 'ZodCatch') assert.equal( z .string() .catch(() => '') - .nullable().constructor.name, + .nullable().typeName, 'ZodNullable' ) }) diff --git a/packages/zui/src/z/__tests__/partials.test.ts b/packages/zui/src/z/__tests__/partials.test.ts index 08eb35d9cd9..c14a8fba30b 100644 --- a/packages/zui/src/z/__tests__/partials.test.ts +++ b/packages/zui/src/z/__tests__/partials.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' -import z, { ZodNullable, ZodOptional } from '../index' +import * as utils from '../utils' +import z from '../index' const nested = z.object({ name: z.string(), @@ -50,11 +50,11 @@ test('deep partial inference', () => { test('deep partial parse', () => { const deep = nested.deepPartial() - expect(deep.shape.name instanceof z.ZodOptional).toBe(true) - expect(deep.shape.outer instanceof z.ZodOptional).toBe(true) - expect(deep.shape.outer._def.innerType instanceof z.ZodObject).toBe(true) - expect(deep.shape.outer._def.innerType.shape.inner instanceof z.ZodOptional).toBe(true) - expect(deep.shape.outer._def.innerType.shape.inner._def.innerType instanceof z.ZodString).toBe(true) + expect(deep.shape.name.typeName).toBe('ZodOptional') + expect(deep.shape.outer.typeName).toBe('ZodOptional') + expect(deep.shape.outer._def.innerType.typeName).toBe('ZodObject') + expect(deep.shape.outer._def.innerType.shape.inner.typeName).toBe('ZodOptional') + expect(deep.shape.outer._def.innerType.shape.inner._def.innerType.typeName).toBe('ZodString') }) test('deep partial runtime tests', () => { @@ -80,8 +80,8 @@ test('deep partial optional/nullable', () => { }) .deepPartial() - expect(schema.shape.name.unwrap()).toBeInstanceOf(ZodOptional) - expect(schema.shape.age.unwrap()).toBeInstanceOf(ZodNullable) + expect(schema.shape.name.unwrap().typeName).toBe('ZodOptional') + expect(schema.shape.age.unwrap().typeName).toBe('ZodNullable') }) test('deep partial tuple', () => { @@ -96,7 +96,7 @@ test('deep partial tuple', () => { }) .deepPartial() - expect(schema.shape.tuple.unwrap().items[0].shape.name).toBeInstanceOf(ZodOptional) + expect(schema.shape.tuple.unwrap().items[0].shape.name.typeName).toBe('ZodOptional') }) test('deep partial inference', () => { @@ -130,11 +130,11 @@ test('required', () => { }) const requiredObject = object.required() - expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString) - expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber) - expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault) - expect(requiredObject.shape.nullableField).toBeInstanceOf(z.ZodNullable) - expect(requiredObject.shape.nullishField).toBeInstanceOf(z.ZodNullable) + expect(requiredObject.shape.name.typeName).toBe('ZodString') + expect(requiredObject.shape.age.typeName).toBe('ZodNumber') + expect(requiredObject.shape.field.typeName).toBe('ZodDefault') + expect(requiredObject.shape.nullableField.typeName).toBe('ZodNullable') + expect(requiredObject.shape.nullishField.typeName).toBe('ZodNullable') }) test('required inference', () => { @@ -168,10 +168,10 @@ test('required with mask', () => { }) const requiredObject = object.required({ age: true }) - expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString) - expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber) - expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault) - expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional) + expect(requiredObject.shape.name.typeName).toBe('ZodString') + expect(requiredObject.shape.age.typeName).toBe('ZodNumber') + expect(requiredObject.shape.field.typeName).toBe('ZodDefault') + expect(requiredObject.shape.country.typeName).toBe('ZodOptional') }) test('required with mask -- ignore falsy values', () => { @@ -184,10 +184,10 @@ test('required with mask -- ignore falsy values', () => { // @ts-expect-error const requiredObject = object.required({ age: true, country: false }) - expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString) - expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber) - expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault) - expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional) + expect(requiredObject.shape.name.typeName).toBe('ZodString') + expect(requiredObject.shape.age.typeName).toBe('ZodNumber') + expect(requiredObject.shape.field.typeName).toBe('ZodDefault') + expect(requiredObject.shape.country.typeName).toBe('ZodOptional') }) test('partial with mask', async () => { @@ -200,10 +200,10 @@ test('partial with mask', async () => { const masked = object.partial({ age: true, field: true, name: true }).strict() - expect(masked.shape.name).toBeInstanceOf(z.ZodOptional) - expect(masked.shape.age).toBeInstanceOf(z.ZodOptional) - expect(masked.shape.field).toBeInstanceOf(z.ZodOptional) - expect(masked.shape.country).toBeInstanceOf(z.ZodString) + expect(masked.shape.name.typeName).toBe('ZodOptional') + expect(masked.shape.age.typeName).toBe('ZodOptional') + expect(masked.shape.field.typeName).toBe('ZodOptional') + expect(masked.shape.country.typeName).toBe('ZodString') masked.parse({ country: 'US' }) await masked.parseAsync({ country: 'US' }) @@ -220,10 +220,10 @@ test('partial with mask -- ignore falsy values', async () => { // @ts-expect-error const masked = object.partial({ name: true, country: false }).strict() - expect(masked.shape.name).toBeInstanceOf(z.ZodOptional) - expect(masked.shape.age).toBeInstanceOf(z.ZodOptional) - expect(masked.shape.field).toBeInstanceOf(z.ZodDefault) - expect(masked.shape.country).toBeInstanceOf(z.ZodString) + expect(masked.shape.name.typeName).toBe('ZodOptional') + expect(masked.shape.age.typeName).toBe('ZodOptional') + expect(masked.shape.field.typeName).toBe('ZodDefault') + expect(masked.shape.country.typeName).toBe('ZodString') masked.parse({ country: 'US' }) await masked.parseAsync({ country: 'US' }) @@ -232,9 +232,7 @@ test('partial with mask -- ignore falsy values', async () => { test('deeppartial array', () => { const schema = z.object({ array: z.string().array().min(42) }).deepPartial() - // works as expected schema.parse({}) - // should be false, but is true expect(schema.safeParse({ array: [] }).success).toBe(false) }) diff --git a/packages/zui/src/z/__tests__/pickomit.test.ts b/packages/zui/src/z/__tests__/pickomit.test.ts index 081301ac3ac..ebdfd9ea810 100644 --- a/packages/zui/src/z/__tests__/pickomit.test.ts +++ b/packages/zui/src/z/__tests__/pickomit.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' +import * as utils from '../utils' import z from '../index' const fish = z.object({ diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index a28a246d7e0..8c3024b9a67 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -1,7 +1,8 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' +import * as utils from '../utils' import z from '../index' import { NEVER } from '../types/basetype' +import { ZodError } from '../error' test('preprocess', () => { const schema = z.preprocess((data) => [data], z.string().array()) @@ -52,7 +53,7 @@ test('preprocess ctx.addIssue non-fatal by default', () => { return data }, z.string()).parse(1234) } catch (err) { - z.ZodError.assert(err) + ZodError.assert(err) expect(err.issues.length).toEqual(2) } }) @@ -68,7 +69,7 @@ test('preprocess ctx.addIssue fatal true', () => { return data }, z.string()).parse(1234) } catch (err) { - z.ZodError.assert(err) + ZodError.assert(err) expect(err.issues.length).toEqual(1) } }) @@ -111,6 +112,7 @@ test('preprocess ctx.addIssue with parseAsync', async () => { expect(JSON.parse(JSON.stringify(result))).toEqual({ success: false, error: { + __type__: 'ZuiError', issues: [ { code: 'custom', diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index c38d03045c9..3fe2a15abb0 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import * as utils from '../../z/utils' +import * as utils from '../utils' import { Mocker } from './Mocker' const literalStringSchema = z.literal('asdf') diff --git a/packages/zui/src/z/__tests__/recursive.test.ts b/packages/zui/src/z/__tests__/recursive.test.ts index dabc2c132e5..4cd1312ff67 100644 --- a/packages/zui/src/z/__tests__/recursive.test.ts +++ b/packages/zui/src/z/__tests__/recursive.test.ts @@ -26,11 +26,13 @@ const testCategory: Category = { ], } -test('recursion with z.late.object', () => { - const Category: z.ZodType = z.late.object(() => ({ - name: z.string(), - subcategories: z.array(Category), - })) +test('recursion with lazy object', () => { + const Category: z.ZodType = z.lazy(() => + z.object({ + name: z.string(), + subcategories: z.array(Category), + }) + ) Category.parse(testCategory) }) diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index 8da4b53c20a..ca300a450c3 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -1,7 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' +import * as utils from '../utils' import z from '../index' -import { ZodIssueCode } from '../error' test('refinement', () => { const obj1 = z.object({ @@ -88,33 +87,6 @@ test('custom path', async () => { } }) -test('use path in refinement context', async () => { - const noNested = z.string()._refinement((_val, ctx) => { - if (ctx.path.length > 0) { - ctx.addIssue({ - code: 'custom', - message: `schema cannot be nested. path: ${ctx.path.join('.')}`, - }) - return false - } else { - return true - } - }) - - const data = z.object({ - foo: noNested, - }) - - const t1 = await noNested.spa('asdf') - const t2 = await data.spa({ foo: 'asdf' }) - - expect(t1.success).toBe(true) - expect(t2.success).toBe(false) - if (t2.success === false) { - expect(t2.error.issues[0]?.message).toEqual('schema cannot be nested. path: foo') - } -}) - test('superRefine', () => { const Strings = z.array(z.string()).superRefine((val, ctx) => { if (val.length > 3) { diff --git a/packages/zui/src/z/__tests__/safeparse.test.ts b/packages/zui/src/z/__tests__/safeparse.test.ts index 0e2e2fa9108..0b239d9bdc8 100644 --- a/packages/zui/src/z/__tests__/safeparse.test.ts +++ b/packages/zui/src/z/__tests__/safeparse.test.ts @@ -1,11 +1,12 @@ import { test, expect } from 'vitest' import z from '../index' +import { ZodError } from '../error' const stringSchema = z.string() test('safeparse fail', () => { const safe = stringSchema.safeParse(12) expect(safe.success).toEqual(false) - expect(safe.error).toBeInstanceOf(z.ZodError) + expect(safe.error).toBeInstanceOf(ZodError) }) test('safeparse pass', () => { diff --git a/packages/zui/src/z/__tests__/set.test.ts b/packages/zui/src/z/__tests__/set.test.ts index 422733a033d..233f241645b 100644 --- a/packages/zui/src/z/__tests__/set.test.ts +++ b/packages/zui/src/z/__tests__/set.test.ts @@ -1,7 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../z/utils' +import * as utils from '../utils' import * as z from '../index' -import { ZodIssueCode } from '../index' const stringSet = z.set(z.string()) type stringSet = z.infer diff --git a/packages/zui/src/zui.test.ts b/packages/zui/src/z/__tests__/zui.test.ts similarity index 96% rename from packages/zui/src/zui.test.ts rename to packages/zui/src/z/__tests__/zui.test.ts index 403c3d53d67..5a7c445f1fb 100644 --- a/packages/zui/src/zui.test.ts +++ b/packages/zui/src/z/__tests__/zui.test.ts @@ -1,5 +1,5 @@ -import { test, describe, it, expect } from 'vitest' -import * as zui from './z/index' +import { test } from 'vitest' +import * as zui from '../z' type ExampleSchema = { schema: zui.ZodObject @@ -94,7 +94,7 @@ test('Discriminated Unions', () => { }) test('ZuiTypeAny', () => { - const func = (type: zui.ZodType) => { + const func = (type: zui.ZodNativeType) => { return type } diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index d948d22dca9..e59f315171b 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -1,61 +1,105 @@ -import type { CustomErrorParams } from './error' +import { zuiKey } from './consts' +import { setBuilders } from './internal-builders' import { - ZodAny, - ZodArray, - ZodBigInt, - ZodBoolean, - ZodDate, - ZodDefault, - ZodDiscriminatedUnion, - ZodEffects, - ZodEnum, - ZodFunction, - ZodIntersection, - ZodLazy, - ZodLiteral, - ZodMap, - ZodNaN, - ZodNativeEnum, - ZodNever, - ZodNull, - ZodNullable, - ZodNumber, - ZodObject, - ZodOptional, - ZodPipeline, - ZodPromise, - ZodReadonly, - ZodRecord, - ZodRef, - ZodSet, - ZodString, - ZodSymbol, - ZodTuple, - ZodType, - ZodUndefined, - ZodUnion, - ZodUnknown, - ZodVoid, + ZodAnyImpl, + ZodArrayImpl, + ZodBigIntImpl, + ZodBooleanImpl, + ZodBrandedImpl, + ZodCatchImpl, + ZodDateImpl, + ZodDefaultImpl, + ZodDiscriminatedUnionImpl, + ZodEffectsImpl, + ZodEnumImpl, + ZodFunctionImpl, + ZodIntersectionImpl, + ZodLazyImpl, + ZodLiteralImpl, + ZodMapImpl, + ZodNaNImpl, + ZodNativeEnumImpl, + ZodNeverImpl, + ZodNullImpl, + ZodNullableImpl, + ZodNumberImpl, + ZodObjectImpl, + ZodOptionalImpl, + ZodPipelineImpl, + ZodPromiseImpl, + ZodReadonlyImpl, + ZodRecordImpl, + ZodRefImpl, + ZodSetImpl, + ZodStringImpl, + ZodSymbolImpl, + ZodTupleImpl, + ZodUndefinedImpl, + ZodUnionImpl, + ZodUnknownImpl, + ZodVoidImpl, } from './types' -type CustomParams = CustomErrorParams & { fatal?: boolean } -const customType = ( - check?: (data: unknown) => any, - params: string | CustomParams | ((input: any) => CustomParams) = {}, - /** - * @deprecated - * - * Pass `fatal` into the params object instead: - * - * ```ts - * z.string().custom((val) => val.length > 5, { fatal: false }) - * ``` - * - */ - fatal?: boolean -): ZodType => { +import { ZodBaseTypeImpl } from './types/basetype' + +import type { + IZodRecord, + IZodTuple, + IZodType, + KeySchema, + RawCreateParams, + ZodErrorMap, + ZuiExtensionObject, + ZodBuilders, +} from './typings' + +type _ProcessedCreateParams = { + errorMap?: ZodErrorMap + description?: string + [zuiKey]?: ZuiExtensionObject +} + +const _processCreateParams = ( + params: RawCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) +): _ProcessedCreateParams => { + if (!params) return {} + + const { + errorMap, + invalid_type_error, + required_error, + description, + supportsExtensions, + [zuiKey]: zuiExtensions, + } = params as any + + if (errorMap && (invalid_type_error || required_error)) { + throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.') + } + + const filteredZuiExtensions = ( + zuiExtensions + ? Object.fromEntries( + Object.entries(zuiExtensions).filter(([key]) => key !== 'secret' || supportsExtensions?.includes('secret')) + ) + : undefined + ) as ZuiExtensionObject | undefined + + if (errorMap) return { errorMap, description, [zuiKey]: filteredZuiExtensions } + + const customMap: ZodErrorMap = (iss, ctx) => { + if (iss.code !== 'invalid_type') return { message: ctx.defaultError } + if (typeof ctx.data === 'undefined') { + return { message: required_error ?? ctx.defaultError } + } + return { message: invalid_type_error ?? ctx.defaultError } + } + return { errorMap: customMap, description, [zuiKey]: filteredZuiExtensions } +} + +export const customType: ZodBuilders['custom'] = (check?, params = {}, fatal?) => { if (check) { - return ZodAny.create().superRefine((data, ctx) => { + return anyType().superRefine((data, ctx) => { if (!check(data)) { const p = typeof params === 'function' ? params(data) : typeof params === 'string' ? { message: params } : params @@ -65,113 +109,288 @@ const customType = ( } }) } - return ZodAny.create() + return anyType() } -abstract class Cls { - constructor(..._: any[]) {} +export const instanceOfType: ZodBuilders['instanceof'] = ( + cls, + params = { + message: `Input not instance of ${cls.name}`, + } +) => customType((data) => data instanceof cls, params) + +export const anyType: ZodBuilders['any'] = (params) => + new ZodAnyImpl({ typeName: 'ZodAny', ..._processCreateParams(params) }) + +export const unknownType: ZodBuilders['unknown'] = (params) => + new ZodUnknownImpl({ typeName: 'ZodUnknown', ..._processCreateParams(params) }) + +export const neverType: ZodBuilders['never'] = (params) => + new ZodNeverImpl({ typeName: 'ZodNever', ..._processCreateParams(params) }) + +export const voidType: ZodBuilders['void'] = (params) => + new ZodVoidImpl({ typeName: 'ZodVoid', ..._processCreateParams(params) }) + +export const nullType: ZodBuilders['null'] = (params) => + new ZodNullImpl({ typeName: 'ZodNull', ..._processCreateParams(params) }) + +export const undefinedType: ZodBuilders['undefined'] = (params) => + new ZodUndefinedImpl({ typeName: 'ZodUndefined', ..._processCreateParams(params) }) + +export const symbolType: ZodBuilders['symbol'] = (params) => + new ZodSymbolImpl({ typeName: 'ZodSymbol', ..._processCreateParams(params) }) + +export const nanType: ZodBuilders['nan'] = (params) => + new ZodNaNImpl({ typeName: 'ZodNaN', ..._processCreateParams(params) }) + +export const stringType: ZodBuilders['string'] = (params) => + new ZodStringImpl({ + checks: [], + typeName: 'ZodString', + coerce: params?.coerce ?? false, + ..._processCreateParams({ ...params, supportsExtensions: ['secret'] }), + }) + +export const numberType: ZodBuilders['number'] = (params) => + new ZodNumberImpl({ + checks: [], + typeName: 'ZodNumber', + coerce: params?.coerce || false, + ..._processCreateParams(params), + }) + +export const booleanType: ZodBuilders['boolean'] = (params) => + new ZodBooleanImpl({ + typeName: 'ZodBoolean', + coerce: params?.coerce || false, + ..._processCreateParams(params), + }) + +export const bigIntType: ZodBuilders['bigint'] = (params) => + new ZodBigIntImpl({ + checks: [], + typeName: 'ZodBigInt', + coerce: params?.coerce ?? false, + ..._processCreateParams(params), + }) + +export const dateType: ZodBuilders['date'] = (params) => + new ZodDateImpl({ + checks: [], + coerce: params?.coerce || false, + typeName: 'ZodDate', + ..._processCreateParams(params), + }) + +export const refType: ZodBuilders['ref'] = (uri) => new ZodRefImpl({ typeName: 'ZodRef', uri }) + +export const literalType: ZodBuilders['literal'] = (value, params) => + new ZodLiteralImpl({ value, typeName: 'ZodLiteral', ..._processCreateParams(params) }) + +export const enumType: ZodBuilders['enum'] = ((values: [string, ...string[]], params?: RawCreateParams) => + new ZodEnumImpl({ values, typeName: 'ZodEnum', ..._processCreateParams(params) })) as ZodBuilders['enum'] + +export const nativeEnumType: ZodBuilders['nativeEnum'] = (values, params) => + new ZodNativeEnumImpl({ values, typeName: 'ZodNativeEnum', ..._processCreateParams(params) }) + +export const arrayType: ZodBuilders['array'] = (schema, params) => + new ZodArrayImpl({ + type: schema, + minLength: null, + maxLength: null, + exactLength: null, + typeName: 'ZodArray', + ..._processCreateParams(params), + }) + +export const objectType: ZodBuilders['object'] = (shape, params) => + new ZodObjectImpl({ + shape: () => shape, + unknownKeys: 'strip', + typeName: 'ZodObject', + ..._processCreateParams(params), + }) + +export const strictObjectType: ZodBuilders['strictObject'] = (shape, params) => + new ZodObjectImpl({ + shape: () => shape, + unknownKeys: 'strict', + typeName: 'ZodObject', + ..._processCreateParams(params), + }) + +export const unionType: ZodBuilders['union'] = (types, params) => + new ZodUnionImpl({ options: types, typeName: 'ZodUnion', ..._processCreateParams(params) }) + +export const discriminatedUnionType: ZodBuilders['discriminatedUnion'] = (discriminator, options, params) => + new ZodDiscriminatedUnionImpl({ + typeName: 'ZodDiscriminatedUnion', + discriminator, + options, + ..._processCreateParams(params), + }) + +export const intersectionType: ZodBuilders['intersection'] = (left, right, params) => + new ZodIntersectionImpl({ left, right, typeName: 'ZodIntersection', ..._processCreateParams(params) }) + +export const tupleType: ZodBuilders['tuple'] = (schemas, params) => { + if (!Array.isArray(schemas)) { + throw new Error('You must pass an array of schemas to z.tuple([ ... ])') + } + return new ZodTupleImpl({ items: schemas, typeName: 'ZodTuple', rest: null, ..._processCreateParams(params) }) } -const instanceOfType = ( - cls: T, - params: CustomParams = { - message: `Input not instance of ${cls.name}`, +export const recordType: ZodBuilders['record'] = ( + first: KeySchema | IZodType, + second?: RawCreateParams | IZodType, + third?: RawCreateParams +): IZodRecord => { + if (second instanceof ZodBaseTypeImpl) { + return new ZodRecordImpl({ + keyType: first, + valueType: second, + typeName: 'ZodRecord', + ..._processCreateParams(third), + }) } -) => customType>((data) => data instanceof cls, params) - -const stringType = ZodString.create -const numberType = ZodNumber.create -const nanType = ZodNaN.create -const bigIntType = ZodBigInt.create -const booleanType = ZodBoolean.create -const dateType = ZodDate.create -const symbolType = ZodSymbol.create -const undefinedType = ZodUndefined.create -const nullType = ZodNull.create -const anyType = ZodAny.create -const unknownType = ZodUnknown.create -const neverType = ZodNever.create -const voidType = ZodVoid.create -const arrayType = ZodArray.create -const objectType = ZodObject.create -const strictObjectType = ZodObject.strictCreate -const unionType = ZodUnion.create -const discriminatedUnionType = ZodDiscriminatedUnion.create -const intersectionType = ZodIntersection.create -const tupleType = ZodTuple.create -const recordType = ZodRecord.create -const refType = ZodRef.create -const readonlyType = ZodReadonly.create -const mapType = ZodMap.create -const setType = ZodSet.create -const functionType = ZodFunction.create -const lazyType = ZodLazy.create -const literalType = ZodLiteral.create -const enumType = ZodEnum.create -const nativeEnumType = ZodNativeEnum.create -const promiseType = ZodPromise.create -const effectsType = ZodEffects.create -const optionalType = ZodOptional.create -const nullableType = ZodNullable.create -const defaultType = ZodDefault.create -const preprocessType = ZodEffects.createWithPreprocess -const pipelineType = ZodPipeline.create - -export const late = { - object: ZodObject.lazycreate, + return new ZodRecordImpl({ + keyType: stringType(), + valueType: first, + typeName: 'ZodRecord', + ..._processCreateParams(second), + }) } -export const coerce = { - string: ((arg) => ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)['create'], - number: ((arg) => ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)['create'], - boolean: ((arg) => - ZodBoolean.create({ - ...arg, - coerce: true, - })) as (typeof ZodBoolean)['create'], - bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)['create'], - date: ((arg) => ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)['create'], +export const mapType: ZodBuilders['map'] = (keyType, valueType, params) => + new ZodMapImpl({ valueType, keyType, typeName: 'ZodMap', ..._processCreateParams(params) }) + +export const setType: ZodBuilders['set'] = (valueType, params) => + new ZodSetImpl({ valueType, minSize: null, maxSize: null, typeName: 'ZodSet', ..._processCreateParams(params) }) + +export const lazyType: ZodBuilders['lazy'] = (getter, params) => + new ZodLazyImpl({ getter, typeName: 'ZodLazy', ..._processCreateParams(params) }) + +export const promiseType: ZodBuilders['promise'] = (schema, params) => + new ZodPromiseImpl({ type: schema, typeName: 'ZodPromise', ..._processCreateParams(params) }) + +export const functionType: ZodBuilders['function'] = ( + args?: IZodTuple, + returns?: IZodType, + params?: RawCreateParams +) => { + return new ZodFunctionImpl({ + args: args ? args : tupleType([]).rest(unknownType()), + returns: returns || unknownType(), + typeName: 'ZodFunction', + ..._processCreateParams(params), + }) } -export { - anyType as any, - arrayType as array, - bigIntType as bigint, - booleanType as boolean, - customType as custom, - dateType as date, - defaultType as default, - discriminatedUnionType as discriminatedUnion, - effectsType as effects, - enumType as enum, - functionType as function, - instanceOfType as instanceof, - intersectionType as intersection, - lazyType as lazy, - literalType as literal, - mapType as map, - nanType as nan, - nativeEnumType as nativeEnum, - neverType as never, - nullType as null, - nullableType as nullable, - numberType as number, - objectType as object, - optionalType as optional, - pipelineType as pipeline, - preprocessType as preprocess, - promiseType as promise, - recordType as record, - refType as ref, - readonlyType as readonly, - setType as set, - strictObjectType as strictObject, - stringType as string, - symbolType as symbol, - effectsType as transformer, - tupleType as tuple, - undefinedType as undefined, - unionType as union, - unknownType as unknown, - voidType as void, +export const effectsType: ZodBuilders['effects'] = (schema, effect, params) => + new ZodEffectsImpl({ schema, typeName: 'ZodEffects', effect, ..._processCreateParams(params) }) + +export const preprocessType: ZodBuilders['preprocess'] = (preprocess, schema, params) => + new ZodEffectsImpl({ + schema, + effect: { type: 'preprocess', transform: preprocess }, + typeName: 'ZodEffects', + ..._processCreateParams(params), + }) + +export const optionalType: ZodBuilders['optional'] = (type, params) => + new ZodOptionalImpl({ innerType: type, typeName: 'ZodOptional', ..._processCreateParams(params) }) + +export const nullableType: ZodBuilders['nullable'] = (type, params) => + new ZodNullableImpl({ innerType: type, typeName: 'ZodNullable', ..._processCreateParams(params) }) + +export const readonlyType: ZodBuilders['readonly'] = (type, params) => + new ZodReadonlyImpl({ innerType: type, typeName: 'ZodReadonly', ..._processCreateParams(params) }) + +export const defaultType: ZodBuilders['default'] = (type, value, params) => + new ZodDefaultImpl({ + innerType: type, + typeName: 'ZodDefault', + defaultValue: typeof value === 'function' ? value : () => value, + ..._processCreateParams(params), + }) + +export const catchType: ZodBuilders['catch'] = (type, catcher, params) => + new ZodCatchImpl({ + innerType: type, + typeName: 'ZodCatch', + catchValue: typeof catcher === 'function' ? catcher : () => catcher, + ..._processCreateParams(params), + }) + +export const pipelineType: ZodBuilders['pipeline'] = (a, b) => + new ZodPipelineImpl({ in: a, out: b, typeName: 'ZodPipeline' }) + +export const brandedType: ZodBuilders['branded'] = (type) => + new ZodBrandedImpl({ + typeName: 'ZodBranded', + type, + ..._processCreateParams({ supportsExtensions: ['secret'] }), + }) + +setBuilders({ + any: anyType, + array: arrayType, + bigint: bigIntType, + boolean: booleanType, + branded: brandedType, + catch: catchType, + custom: customType, + date: dateType, + default: defaultType, + discriminatedUnion: discriminatedUnionType, + effects: effectsType, + enum: enumType, + function: functionType, + instanceof: instanceOfType, + intersection: intersectionType, + lazy: lazyType, + literal: literalType, + map: mapType, + nan: nanType, + nativeEnum: nativeEnumType, + never: neverType, + null: nullType, + nullable: nullableType, + number: numberType, + object: objectType, + optional: optionalType, + pipeline: pipelineType, + preprocess: preprocessType, + promise: promiseType, + record: recordType, + ref: refType, + readonly: readonlyType, + set: setType, + strictObject: strictObjectType, + string: stringType, + symbol: symbolType, + transformer: effectsType, + tuple: tupleType, + undefined: undefinedType, + union: unionType, + unknown: unknownType, + void: voidType, +}) + +export const coerce = { + string(arg?: RawCreateParams & { coerce?: true }): ReturnType { + return stringType({ ...arg, coerce: true }) + }, + number(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + return numberType({ ...arg, coerce: true }) + }, + boolean(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + return booleanType({ ...arg, coerce: true }) + }, + bigint(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + return bigIntType({ ...arg, coerce: true }) + }, + date(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + return dateType({ ...arg, coerce: true }) + }, } diff --git a/packages/zui/src/ui/constants.ts b/packages/zui/src/z/consts.ts similarity index 100% rename from packages/zui/src/ui/constants.ts rename to packages/zui/src/z/consts.ts diff --git a/packages/zui/src/z/error/error.test.ts b/packages/zui/src/z/error/error.test.ts index bd53546e150..967176a5287 100644 --- a/packages/zui/src/z/error/error.test.ts +++ b/packages/zui/src/z/error/error.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' import * as z from '../index' -import { ZodError } from './index' +import { defaultErrorMap, setErrorMap, ZodError } from './index' +import { ZodErrorMap } from '../typings' test('error creation', () => { const err1 = ZodError.create([]) @@ -23,7 +24,7 @@ test('error creation', () => { err3.message }) -const errorMap: z.ZodErrorMap = (error, ctx) => { +const errorMap: ZodErrorMap = (error, ctx) => { if (error.code === 'invalid_type') { if (error.expected === 'string') { return { message: 'bad type!' } @@ -136,7 +137,7 @@ test('custom path in custom error map', () => { }), }) - const errorMap: z.ZodErrorMap = (error) => { + const errorMap: ZodErrorMap = (error) => { expect(error.path.length).toBe(2) return { message: 'doesnt matter' } } @@ -360,13 +361,13 @@ test('schema-bound error map', () => { test('overrideErrorMap', () => { // support overrideErrorMap - z.setErrorMap(() => ({ message: 'OVERRIDE' })) + setErrorMap(() => ({ message: 'OVERRIDE' })) const result4 = stringWithCustomError.min(10).safeParse('tooshort') expect(result4.success).toEqual(false) if (!result4.success) { expect(result4.error.issues[0]?.message).toEqual('OVERRIDE') } - z.setErrorMap(z.defaultErrorMap) + setErrorMap(defaultErrorMap) }) test('invalid and required', () => { diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index 710c565d2d7..24ead0601a3 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -1,164 +1,10 @@ -import type { ZodParsedType } from '../types/basetype' +import type { ZodIssue, ZodFormattedError, ZodErrorMap, IZodError } from '../typings' import * as utils from '../utils' import { errorMap as defaultErrorMap } from './locales/en' -export type ZodIssueBase = { - path: (string | number)[] - message?: string -} - -export type ZodInvalidTypeIssue = { - code: 'invalid_type' - expected: ZodParsedType - received: ZodParsedType -} & ZodIssueBase - -export type ZodInvalidLiteralIssue = { - code: 'invalid_literal' - expected: unknown - received: unknown -} & ZodIssueBase - -export type ZodUnrecognizedKeysIssue = { - code: 'unrecognized_keys' - keys: string[] -} & ZodIssueBase - -export type ZodInvalidUnionIssue = { - code: 'invalid_union' - unionErrors: ZodError[] -} & ZodIssueBase - -export type ZodInvalidUnionDiscriminatorIssue = { - code: 'invalid_union_discriminator' - options: utils.types.Primitive[] -} & ZodIssueBase - -export type ZodInvalidEnumValueIssue = { - received: string | number - code: 'invalid_enum_value' - options: (string | number)[] -} & ZodIssueBase - -export type ZodInvalidArgumentsIssue = { - code: 'invalid_arguments' - argumentsError: ZodError -} & ZodIssueBase - -export type ZodInvalidReturnTypeIssue = { - code: 'invalid_return_type' - returnTypeError: ZodError -} & ZodIssueBase - -export type ZodInvalidDateIssue = { - code: 'invalid_date' -} & ZodIssueBase - -export type StringValidation = - | 'email' - | 'url' - | 'emoji' - | 'uuid' - | 'regex' - | 'cuid' - | 'cuid2' - | 'ulid' - | 'datetime' - | 'ip' - | { includes: string; position?: number } - | { startsWith: string } - | { endsWith: string } - -export type ZodInvalidStringIssue = { - code: 'invalid_string' - validation: StringValidation -} & ZodIssueBase - -export type ZodTooSmallIssue = { - code: 'too_small' - minimum: number | bigint - inclusive: boolean - exact?: boolean - type: 'array' | 'string' | 'number' | 'set' | 'date' | 'bigint' -} & ZodIssueBase - -export type ZodTooBigIssue = { - code: 'too_big' - maximum: number | bigint - inclusive: boolean - exact?: boolean - type: 'array' | 'string' | 'number' | 'set' | 'date' | 'bigint' -} & ZodIssueBase - -export type ZodInvalidIntersectionTypesIssue = { - code: 'invalid_intersection_types' -} & ZodIssueBase - -export type ZodNotMultipleOfIssue = { - code: 'not_multiple_of' - multipleOf: number | bigint -} & ZodIssueBase - -export type ZodNotFiniteIssue = { - code: 'not_finite' -} & ZodIssueBase +export class ZodError extends Error implements IZodError { + readonly __type__ = 'ZuiError' -export type ZodUnresolvedReferenceIssue = { - code: 'unresolved_reference' -} & ZodIssueBase - -export type ZodCustomIssue = { - code: 'custom' - params?: { [k: string]: any } -} & ZodIssueBase - -export type DenormalizedError = { [k: string]: DenormalizedError | string[] } - -export type ZodIssueCode = ZodIssueOptionalMessage['code'] -export type ZodIssueOptionalMessage = - | ZodInvalidTypeIssue - | ZodInvalidLiteralIssue - | ZodUnrecognizedKeysIssue - | ZodInvalidUnionIssue - | ZodInvalidUnionDiscriminatorIssue - | ZodInvalidEnumValueIssue - | ZodInvalidArgumentsIssue - | ZodInvalidReturnTypeIssue - | ZodInvalidDateIssue - | ZodInvalidStringIssue - | ZodTooSmallIssue - | ZodTooBigIssue - | ZodInvalidIntersectionTypesIssue - | ZodNotMultipleOfIssue - | ZodNotFiniteIssue - | ZodUnresolvedReferenceIssue - | ZodCustomIssue - -export type ZodIssue = ZodIssueOptionalMessage & { - fatal?: boolean - message: string -} - -export type CustomErrorParams = Partial> - -export const quotelessJson = (obj: any) => { - const json = JSON.stringify(obj, null, 2) - return json.replace(/"([^"]+)":/g, '$1:') -} - -type recursiveZodFormattedError = T extends [any, ...any[]] - ? { [K in keyof T]?: ZodFormattedError } - : T extends any[] - ? { [k: number]: ZodFormattedError } - : T extends object - ? { [K in keyof T]?: ZodFormattedError } - : unknown - -export type ZodFormattedError = { - _errors: U[] -} & recursiveZodFormattedError> - -export class ZodError extends Error { issues: ZodIssue[] = [] get errors() { @@ -260,20 +106,6 @@ export class ZodError extends Error { } } -type stripPath = T extends any ? Omit : never - -export type IssueData = stripPath & { - path?: (string | number)[] - fatal?: boolean -} - -export type ErrorMapCtx = { - defaultError: string - data: any -} - -export type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => { message: string } - let overrideErrorMap = defaultErrorMap export { defaultErrorMap } diff --git a/packages/zui/src/z/error/locales/en.ts b/packages/zui/src/z/error/locales/en.ts index a5259934b9f..68d26c66a0d 100644 --- a/packages/zui/src/z/error/locales/en.ts +++ b/packages/zui/src/z/error/locales/en.ts @@ -1,5 +1,5 @@ +import { ZodErrorMap } from '../../typings' import * as utils from '../../utils' -import { type ZodErrorMap } from '../index' export const errorMap: ZodErrorMap = (issue, _ctx) => { let message: string @@ -58,13 +58,13 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { break case 'too_small': if (issue.type === 'array') { - message = `Array must contain ${ - issue.exact ? 'exactly' : issue.inclusive ? 'at least' : 'more than' - } ${issue.minimum} element(s)` + message = `Array must contain ${issue.exact ? 'exactly' : issue.inclusive ? 'at least' : 'more than'} ${ + issue.minimum + } element(s)` } else if (issue.type === 'string') { - message = `String must contain ${ - issue.exact ? 'exactly' : issue.inclusive ? 'at least' : 'over' - } ${issue.minimum} character(s)` + message = `String must contain ${issue.exact ? 'exactly' : issue.inclusive ? 'at least' : 'over'} ${ + issue.minimum + } character(s)` } else if (issue.type === 'number') { message = `Number must be ${ issue.exact ? 'exactly equal to ' : issue.inclusive ? 'greater than or equal to ' : 'greater than ' @@ -77,13 +77,13 @@ export const errorMap: ZodErrorMap = (issue, _ctx) => { break case 'too_big': if (issue.type === 'array') { - message = `Array must contain ${ - issue.exact ? 'exactly' : issue.inclusive ? 'at most' : 'less than' - } ${issue.maximum} element(s)` + message = `Array must contain ${issue.exact ? 'exactly' : issue.inclusive ? 'at most' : 'less than'} ${ + issue.maximum + } element(s)` } else if (issue.type === 'string') { - message = `String must contain ${ - issue.exact ? 'exactly' : issue.inclusive ? 'at most' : 'under' - } ${issue.maximum} character(s)` + message = `String must contain ${issue.exact ? 'exactly' : issue.inclusive ? 'at most' : 'under'} ${ + issue.maximum + } character(s)` } else if (issue.type === 'number') { message = `Number must be ${ issue.exact ? 'exactly' : issue.inclusive ? 'less than or equal to' : 'less than' diff --git a/packages/zui/src/z/guards.ts b/packages/zui/src/z/guards.ts new file mode 100644 index 00000000000..2d17faacdd2 --- /dev/null +++ b/packages/zui/src/z/guards.ts @@ -0,0 +1,11 @@ +import { ZodError } from './error' +import { ZodNativeType } from './native' +import { ZodBaseTypeImpl } from './types' +import { IZodError } from './typings' + +export const isZuiError = (thrown: unknown): thrown is IZodError => + thrown instanceof ZodError || (thrown instanceof Error && '__type__' in thrown && thrown.__type__ === 'ZuiError') + +export const isZuiType = (value: unknown): value is ZodNativeType => value instanceof ZodBaseTypeImpl +// TODO: also accept objects with a __type__ property set to 'ZuiType' to allow for cross-realm compatibility +// || (typeof value === 'object' && value !== null && '__type__' in value && value.__type__ === 'ZuiType') diff --git a/packages/zui/src/z/internal-builders.ts b/packages/zui/src/z/internal-builders.ts new file mode 100644 index 00000000000..e19927da7fc --- /dev/null +++ b/packages/zui/src/z/internal-builders.ts @@ -0,0 +1,30 @@ +import type { ZodBuilders } from './typings' + +/** + * Just like builders, but with no depencies on the Zod types implementations. + * This allows us to break the circular dependency between builders and types. + * Types can then import the internal builders to build other types. + * + * Check out this mermaid diagram for a visual representation of the dependencies: + * + * ```mermaid + * flowchart LR + * Typings["typings.ts"] + * Internals["internal-builders.ts"] + * Types["types/*"] + * Builders["builders.ts"] + * + * Builders --> Types + * Builders --> Typings + * Types --> Internals + * Builders --> Internals + * Builders --> Typings + * Types --> Typings + * Internals --> Typings + * ``` + */ +export const builders = {} as ZodBuilders + +export function setBuilders(b: ZodBuilders): void { + Object.assign(builders, b) +} diff --git a/packages/zui/src/z/native.ts b/packages/zui/src/z/native.ts new file mode 100644 index 00000000000..21042c79c04 --- /dev/null +++ b/packages/zui/src/z/native.ts @@ -0,0 +1,135 @@ +import { + IZodAny, + IZodArray, + IZodBigInt, + IZodBoolean, + IZodBranded, + IZodCatch, + IZodDate, + IZodDefault, + IZodDiscriminatedUnion, + IZodEnum, + IZodFunction, + IZodIntersection, + IZodLazy, + IZodLiteral, + IZodMap, + IZodNaN, + IZodNativeEnum, + IZodNever, + IZodNull, + IZodNullable, + IZodNumber, + IZodObject, + IZodOptional, + IZodPipeline, + IZodPromise, + IZodReadonly, + IZodRecord, + IZodRef, + IZodSet, + IZodString, + IZodSymbol, + IZodEffects, + IZodTuple, + IZodUndefined, + IZodUnion, + IZodUnknown, + IZodVoid, +} from './typings' + +/** + * @deprecated - use ZodNativeSchema instead + */ +export type ZodFirstPartySchemaTypes = ZodNativeType +export type ZodNativeType = + | IZodAny + | IZodArray + | IZodBigInt + | IZodBoolean + | IZodBranded + | IZodCatch + | IZodDate + | IZodDefault + | IZodDiscriminatedUnion + | IZodEnum + | IZodFunction + | IZodIntersection + | IZodLazy + | IZodLiteral + | IZodMap + | IZodNaN + | IZodNativeEnum + | IZodNever + | IZodNull + | IZodNullable + | IZodNumber + | IZodObject + | IZodOptional + | IZodPipeline + | IZodPromise + | IZodReadonly + | IZodRecord + | IZodRef + | IZodSet + | IZodString + | IZodSymbol + | IZodEffects + | IZodTuple + | IZodUndefined + | IZodUnion + | IZodUnknown + | IZodVoid + +export type ZodNativeTypeDef = ZodNativeType['_def'] + +/** + * @deprecated - use ZodNativeSchemaType instead + */ +export type ZodFirstPartyTypeKind = ZodNativeTypeName +export type ZodNativeTypeName = ZodNativeTypeDef['typeName'] + +/** + * @deprecated - use ZodNativeSchemaType instead + */ +export const ZodFirstPartyTypeKind = { + ZodString: 'ZodString', + ZodNumber: 'ZodNumber', + ZodNaN: 'ZodNaN', + ZodBigInt: 'ZodBigInt', + ZodBoolean: 'ZodBoolean', + ZodDate: 'ZodDate', + ZodSymbol: 'ZodSymbol', + ZodUndefined: 'ZodUndefined', + ZodNull: 'ZodNull', + ZodAny: 'ZodAny', + ZodUnknown: 'ZodUnknown', + ZodNever: 'ZodNever', + ZodVoid: 'ZodVoid', + ZodArray: 'ZodArray', + ZodObject: 'ZodObject', + ZodUnion: 'ZodUnion', + ZodDiscriminatedUnion: 'ZodDiscriminatedUnion', + ZodIntersection: 'ZodIntersection', + ZodTuple: 'ZodTuple', + ZodRecord: 'ZodRecord', + ZodRef: 'ZodRef', + ZodMap: 'ZodMap', + ZodSet: 'ZodSet', + ZodFunction: 'ZodFunction', + ZodLazy: 'ZodLazy', + ZodLiteral: 'ZodLiteral', + ZodEnum: 'ZodEnum', + ZodEffects: 'ZodEffects', + ZodNativeEnum: 'ZodNativeEnum', + ZodOptional: 'ZodOptional', + ZodNullable: 'ZodNullable', + ZodDefault: 'ZodDefault', + ZodCatch: 'ZodCatch', + ZodPromise: 'ZodPromise', + ZodBranded: 'ZodBranded', + ZodPipeline: 'ZodPipeline', + ZodReadonly: 'ZodReadonly', +} satisfies { + [K in ZodNativeTypeName]: K +} diff --git a/packages/zui/src/z/types/any/index.ts b/packages/zui/src/z/types/any/index.ts index e118c3f3123..8f20b222842 100644 --- a/packages/zui/src/z/types/any/index.ts +++ b/packages/zui/src/z/types/any/index.ts @@ -1,23 +1,13 @@ -import { RawCreateParams, ZodType, ZodTypeDef, OK, ParseInput, ParseReturnType, processCreateParams } from '../basetype' +import type { IZodAny, IZodType, ZodAnyDef } from '../../typings' +import { ParseReturnType, ZodBaseTypeImpl, OK, ParseInput } from '../basetype' -export type ZodAnyDef = { - typeName: 'ZodAny' -} & ZodTypeDef - -export class ZodAny extends ZodType { +export class ZodAnyImpl extends ZodBaseTypeImpl implements IZodAny { // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject. _any = true as const _parse(input: ParseInput): ParseReturnType { return OK(input.data) } - static create = (params?: RawCreateParams): ZodAny => { - return new ZodAny({ - typeName: 'ZodAny', - ...processCreateParams(params), - }) - } - - public isEqual(schema: ZodType) { - return schema instanceof ZodAny + public isEqual(schema: IZodType) { + return schema instanceof ZodAnyImpl } } diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index 15d05f755bd..5068f84c012 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -1,11 +1,9 @@ import { isEqual } from 'lodash-es' +import type { ArrayCardinality, ArrayOutputType, IZodArray, IZodType, ZodArrayDef } from '../../typings' import * as utils from '../../utils' import { ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, @@ -13,28 +11,16 @@ import { ParseStatus, } from '../basetype' -export type ZodArrayDef = { - type: T - typeName: 'ZodArray' - exactLength: { value: number; message?: string } | null - minLength: { value: number; message?: string } | null - maxLength: { value: number; message?: string } | null -} & ZodTypeDef - -type _ArrayCardinality = 'many' | 'atleastone' - -type _ArrayOutputType< - T extends ZodType, - Cardinality extends _ArrayCardinality = 'many', -> = Cardinality extends 'atleastone' ? [T['_output'], ...T['_output'][]] : T['_output'][] - -export class ZodArray extends ZodType< - _ArrayOutputType, - ZodArrayDef, - Cardinality extends 'atleastone' ? [T['_input'], ...T['_input'][]] : T['_input'][] -> { - dereference(defs: Record): ZodType { - return new ZodArray({ +export class ZodArrayImpl + extends ZodBaseTypeImpl< + ArrayOutputType, + ZodArrayDef, + Cardinality extends 'atleastone' ? [T['_input'], ...T['_input'][]] : T['_input'][] + > + implements IZodArray +{ + dereference(defs: Record): IZodType { + return new ZodArrayImpl({ ...this._def, type: this._def.type.dereference(defs), }) @@ -44,15 +30,15 @@ export class ZodArray { - return new ZodArray({ + clone(): ZodArrayImpl { + return new ZodArrayImpl({ ...this._def, - type: this._def.type.clone(), - }) as ZodArray + type: this._def.type.clone() as T, + }) } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodArray)) { + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodArrayImpl)) { return false } return ( @@ -126,7 +112,7 @@ export class ZodArray { - return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)) + return ZodArrayImpl.fromInterface(def.type)._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)) }) ).then((result) => { return ParseStatus.mergeArray(status, result) @@ -134,7 +120,7 @@ export class ZodArray { - return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)) + return ZodArrayImpl.fromInterface(def.type)._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)) }) return ParseStatus.mergeArray(status, result) @@ -145,40 +131,27 @@ export class ZodArray { - return this.min(1, message) as ZodArray - } - - static create = (schema: T, params?: RawCreateParams): ZodArray => { - return new ZodArray({ - type: schema, - minLength: null, - maxLength: null, - exactLength: null, - typeName: 'ZodArray', - ...processCreateParams(params), - }) + nonempty(message?: utils.errors.ErrMessage): ZodArrayImpl { + return this.min(1, message) as ZodArrayImpl } } - -export type ZodNonEmptyArray = ZodArray diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 495e316ddc7..66f53ce051b 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -1,112 +1,64 @@ -import { Schema as ZuiJSONSchema } from '../../../transforms/common/json-schema' -import { toJSONSchema } from '../../../transforms/zui-to-json-schema' -import { toTypescriptSchema } from '../../../transforms/zui-to-typescript-schema' -import { toTypescriptType, TypescriptGenerationOptions } from '../../../transforms/zui-to-typescript-type' -import { zuiKey } from '../../../ui/constants' +import type * as transforms from '../../../transforms' +import { zuiKey } from '../../consts' +import { ZodError } from '../../error' +import { builders } from '../../internal-builders' import type { - BaseType, + BaseDisplayAsType, + DisplayAsOptions, UIComponentDefinitions, ZodKindToBaseType, - ParseSchema, - ZuiExtensionObject, ZuiMetadata, -} from '../../../ui/types' -import { type CustomErrorParams, type IssueData, type ZodErrorMap, ZodError } from '../../error' + DeepPartialBoolean, + IZodType, + ZodTypeDef, + SafeParseReturnType, + CatchFn, + IZodArray, + IZodBranded, + IZodCatch, + IZodDefault, + IZodIntersection, + IZodNullable, + IZodOptional, + IZodPipeline, + IZodPromise, + IZodReadonly, + IZodEffects, + IZodUnion, + RefinementEffect, + RefinementCtx, + CustomErrorParams, + IssueData, +} from '../../typings' import * as utils from '../../utils' -// TODO(circle): these may potentially cause circular dependencies errors -import { - ZodArray, - ZodBranded, - ZodCatch, - type CatchFn, - ZodDefault, - ZodIntersection, - ZodNullable, - ZodOptional, - ZodPipeline, - ZodPromise, - ZodReadonly, - ZodEffects, - type RefinementEffect, - ZodUnion, -} from '../index' +// TODO(circle): get rid of circular dependency between zui core and transforms import { - AsyncParseReturnType, getParsedType, isAsync, isValid, ParseContext, ParseInput, ParseParams, - ParseReturnType, ParseStatus, - processCreateParams, + ParseReturnType, + AsyncParseReturnType, SyncParseReturnType, } from './parseUtil' export * from './parseUtil' -/** - * This type is not part of the original Zod library, it's been added in Zui to: - * - Brand the type as a ZuiType and avoid conflicts with 'zod' types - * - Simplify the type checks and inference for `infer`, `input`, and `output` - * - * The original `infer` type inference on ZodType takes a lot of compute because the TS compiler has to check all the methods and properties of the class. - * The fact that we add __type__ here allows the TS compiler to shortcircuit the type inference when it's not present and prevents infinite circular inferences - */ -type __ZodType = { - readonly __type__: 'ZuiType' - readonly _output: Output - readonly _input: Input -} - -type _DeepPartialBoolean = { - [K in keyof T]?: T[K] extends object ? _DeepPartialBoolean | boolean : boolean -} - -export type RefinementCtx = { - addIssue: (arg: IssueData) => void - path: (string | number)[] -} - -export type TypeOf = T['_output'] -export type OfType = T extends __ZodType ? T : never -export type input = T['_input'] -export type output = T['_output'] -export type { TypeOf as infer } - -export type ZodTypeDef = { - typeName: string - errorMap?: ZodErrorMap - description?: string - [zuiKey]?: ZuiExtensionObject -} - -export type SafeParseSuccess = { - success: true - data: Output - error?: never -} - -export type SafeParseError = { - success: false - error: ZodError - data?: never +class _CircularDependencyError extends Error { + public constructor(private _propName: keyof IZodType) { + super( + `Cannot access property ${_propName} before initialization. You're probably importing ZUI incorrectly. If not, reach out to the maintainers.` + ) + } } -export type SafeParseReturnType = SafeParseSuccess | SafeParseError - -export { ZodType as Schema, ZodType as ZodSchema } - -/** - * @deprecated - use ZodType instead - */ -export type ZodTypeAny = ZodType - -export abstract class ZodType - implements __ZodType +export abstract class ZodBaseTypeImpl + implements IZodType { readonly __type__ = 'ZuiType' readonly _type!: Output @@ -125,7 +77,7 @@ export abstract class ZodType /** deeply replace all references in the schema */ - dereference(_defs: Record): ZodType { + dereference(_defs: Record): IZodType { return this } @@ -134,7 +86,7 @@ export abstract class ZodType { + clone(): IZodType { const This = (this as any).constructor return new This({ ...this._def, @@ -142,7 +94,7 @@ export abstract class ZodType( check: (arg: Output) => arg is RefinedOutput, message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) - ): ZodEffects + ): IZodEffects refine( check: (arg: Output) => unknown | Promise, message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) - ): ZodEffects + ): IZodEffects refine( check: (arg: Output) => unknown, message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) - ): ZodEffects { + ): IZodEffects { const getIssueProperties = (val: Output) => { if (typeof message === 'string' || typeof message === 'undefined') { return { message } @@ -268,7 +220,7 @@ export abstract class ZodType { + return this._refinement((val: Output, ctx: RefinementCtx) => { const result = check(val) const setError = () => ctx.addIssue({ @@ -297,16 +249,16 @@ export abstract class ZodType( check: (arg: Output) => arg is RefinedOutput, refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) - ): ZodEffects + ): IZodEffects refinement( check: (arg: Output) => boolean, refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) - ): ZodEffects + ): IZodEffects refinement( check: (arg: Output) => unknown, refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) - ): ZodEffects { - return this._refinement((val, ctx) => { + ): IZodEffects { + return this._refinement((val: Output, ctx: RefinementCtx) => { if (!check(val)) { ctx.addIssue(typeof refinementData === 'function' ? refinementData(val, ctx) : refinementData) return false @@ -316,22 +268,18 @@ export abstract class ZodType['refinement']): ZodEffects { - return new ZodEffects({ - schema: this, - typeName: 'ZodEffects', - effect: { type: 'refinement', refinement }, - }) + _refinement(refinement: RefinementEffect['refinement']): IZodEffects { + return builders.effects(this, { type: 'refinement', refinement }) } superRefine( refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput - ): ZodEffects - superRefine(refinement: (arg: Output, ctx: RefinementCtx) => void): ZodEffects - superRefine(refinement: (arg: Output, ctx: RefinementCtx) => Promise): ZodEffects + ): IZodEffects + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => void): IZodEffects + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => Promise): IZodEffects superRefine( refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise - ): ZodEffects { + ): IZodEffects { return this._refinement(refinement) } @@ -363,20 +311,20 @@ export abstract class ZodType { - return ZodOptional.create(this, this._def) + optional(): IZodOptional { + return builders.optional(this, this._def) // TODO(why): find out why def is passed as second argument } - nullable(): ZodNullable { - return ZodNullable.create(this, this._def) + nullable(): IZodNullable { + return builders.nullable(this, this._def) // TODO(why): find out why def is passed as second argument } - nullish(): ZodOptional> { + nullish(): IZodOptional> { return this.nullable().optional() } - array(): ZodArray { - return ZodArray.create(this, this._def) + array(): IZodArray { + return builders.array(this, this._def) // TODO(why): find out why def is passed as second argument } - promise(): ZodPromise { - return ZodPromise.create(this, this._def) + promise(): IZodPromise { + return builders.promise(this, this._def) // TODO(why): find out why def is passed as second argument } /** * # \#\#\# Experimental \#\#\# @@ -392,60 +340,40 @@ export abstract class ZodType(option: T): ZodUnion<[this, T]> { - return ZodUnion.create([this, option], this._def) + or(option: T): IZodUnion<[this, T]> { + return builders.union([this, option]) } - and(incoming: T): ZodIntersection { - return ZodIntersection.create(this, incoming, this._def) + and(incoming: T): IZodIntersection { + return builders.intersection(this, incoming) } transform( transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise - ): ZodEffects { - return new ZodEffects({ - ...processCreateParams(this._def), - schema: this, - typeName: 'ZodEffects', - effect: { type: 'transform', transform }, + ): IZodEffects { + return builders.effects(this, { + type: 'transform', + transform, }) } - default(def: utils.types.NoUndefined): ZodDefault - default(def: () => utils.types.NoUndefined): ZodDefault + default(def: utils.types.NoUndefined): IZodDefault + default(def: () => utils.types.NoUndefined): IZodDefault default(def: any) { const defaultValueFunc = typeof def === 'function' ? def : () => def - - return new ZodDefault({ - ...processCreateParams(this._def), - innerType: this, - defaultValue: defaultValueFunc, - typeName: 'ZodDefault', - }) + return builders.default(this, defaultValueFunc) } - brand(brand?: B): ZodBranded - brand(): ZodBranded { - return new ZodBranded({ - typeName: 'ZodBranded', - type: this, - ...processCreateParams(this._def), - }) + brand(): IZodBranded { + return builders.branded(this) } - catch(def: Output | CatchFn): ZodCatch { - const catchValueFunc = typeof def === 'function' ? (def as CatchFn) : () => def - - return new ZodCatch({ - ...processCreateParams(this._def), - innerType: this, - catchValue: catchValueFunc, - typeName: 'ZodCatch', - }) + catch(catcher: Output | CatchFn): IZodCatch { + return builders.catch(this, catcher) } describe(description: string): this { @@ -454,12 +382,12 @@ export abstract class ZodType(target: T): ZodPipeline { - return ZodPipeline.create(this, target) + pipe(target: T): IZodPipeline { + return builders.pipeline(this, target) } - readonly(): ZodReadonly { - return ZodReadonly.create(this) + readonly(): IZodReadonly { + return builders.readonly(this) } isOptional(): boolean { @@ -510,17 +438,14 @@ export abstract class ZodType, - >(options: ParseSchema): this { + Type extends BaseDisplayAsType = ZodKindToBaseType, + >(options: DisplayAsOptions): this { return this.metadata({ displayAs: [options.id, options.params] }) } @@ -536,7 +461,7 @@ export abstract class ZodType( - value?: boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) + value?: boolean | ((shape: T | null) => DeepPartialBoolean | boolean) ): this { let data: ZuiMetadata if (value === undefined) { @@ -554,7 +479,7 @@ export abstract class ZodType( - value?: boolean | ((shape: T | null) => _DeepPartialBoolean | boolean) + value?: boolean | ((shape: T | null) => DeepPartialBoolean | boolean) ): this { let data: ZuiMetadata if (value === undefined) { @@ -578,8 +503,8 @@ export abstract class ZodType(x: ParseReturnType): x is OK => (x as SyncParse export const isAsync = (x: ParseReturnType): x is AsyncParseReturnType => typeof Promise !== 'undefined' && x instanceof Promise -export type ZodParsedType = - | 'string' - | 'nan' - | 'number' - | 'integer' - | 'float' - | 'boolean' - | 'date' - | 'bigint' - | 'symbol' - | 'function' - | 'undefined' - | 'null' - | 'array' - | 'object' - | 'unknown' - | 'promise' - | 'void' - | 'never' - | 'map' - | 'set' - export const getParsedType = (data: any): ZodParsedType => { const t = typeof data @@ -255,42 +223,6 @@ export const getParsedType = (data: any): ZodParsedType => { } } -export function processCreateParams( - params: RawCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) -): ProcessedCreateParams { - if (!params) return {} - - const { - errorMap, - invalid_type_error, - required_error, - description, - supportsExtensions, - [zuiKey]: zuiExtensions, - } = params - - if (errorMap && (invalid_type_error || required_error)) { - throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.') - } - - const filteredZuiExtensions = zuiExtensions - ? Object.fromEntries( - Object.entries(zuiExtensions).filter(([key]) => key !== 'secret' || supportsExtensions?.includes('secret')) - ) - : undefined - - if (errorMap) return { errorMap, description, [zuiKey]: filteredZuiExtensions } - - const customMap: ZodErrorMap = (iss, ctx) => { - if (iss.code !== 'invalid_type') return { message: ctx.defaultError } - if (typeof ctx.data === 'undefined') { - return { message: required_error ?? ctx.defaultError } - } - return { message: invalid_type_error ?? ctx.defaultError } - } - return { errorMap: customMap, description, [zuiKey]: filteredZuiExtensions } -} - export class ParseInputLazyPath implements ParseInput { parent: ParseContext data: any diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 9a366382242..c1883311a32 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -1,29 +1,16 @@ +import { type IZodBigInt, ZodBigIntCheck, ZodBigIntDef } from '../../typings' import * as utils from '../../utils' import { addIssueToContext, INVALID, ParseContext, ParseInput, - ParseReturnType, ParseStatus, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, + ParseReturnType, } from '../basetype' -export type ZodBigIntCheck = - | { kind: 'min'; value: bigint; inclusive: boolean; message?: string } - | { kind: 'max'; value: bigint; inclusive: boolean; message?: string } - | { kind: 'multipleOf'; value: bigint; message?: string } - -export type ZodBigIntDef = { - checks: ZodBigIntCheck[] - typeName: 'ZodBigInt' - coerce: boolean -} & ZodTypeDef - -export class ZodBigInt extends ZodType { +export class ZodBigIntImpl extends ZodBaseTypeImpl implements IZodBigInt { _parse(input: ParseInput): ParseReturnType { if (this._def.coerce) { input.data = BigInt(input.data) @@ -87,17 +74,8 @@ export class ZodBigInt extends ZodType { return { status: status.value, value: input.data } } - static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBigInt => { - return new ZodBigInt({ - checks: [], - typeName: 'ZodBigInt', - coerce: params?.coerce ?? false, - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodBigInt)) { + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodBigIntImpl)) { return false } if (this._def.coerce !== schema._def.coerce) return false @@ -127,7 +105,7 @@ export class ZodBigInt extends ZodType { } protected setLimit(kind: 'min' | 'max', value: bigint, inclusive: boolean, message?: string) { - return new ZodBigInt({ + return new ZodBigIntImpl({ ...this._def, checks: [ ...this._def.checks, @@ -142,7 +120,7 @@ export class ZodBigInt extends ZodType { } _addCheck(check: ZodBigIntCheck) { - return new ZodBigInt({ + return new ZodBigIntImpl({ ...this._def, checks: [...this._def.checks, check], }) diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index 00f65636da9..ce47774f1e2 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -1,21 +1,7 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodBoolean, ZodBooleanDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodBooleanDef = { - typeName: 'ZodBoolean' - coerce: boolean -} & ZodTypeDef - -export class ZodBoolean extends ZodType { +export class ZodBooleanImpl extends ZodBaseTypeImpl implements IZodBoolean { _parse(input: ParseInput): ParseReturnType { if (this._def.coerce) { input.data = Boolean(input.data) @@ -34,16 +20,8 @@ export class ZodBoolean extends ZodType { return OK(input.data) } - static create = (params?: RawCreateParams & { coerce?: boolean }): ZodBoolean => { - return new ZodBoolean({ - typeName: 'ZodBoolean', - coerce: params?.coerce || false, - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodBoolean)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodBooleanImpl)) return false return this._def.coerce === schema._def.coerce } } diff --git a/packages/zui/src/z/types/branded/branded.test.ts b/packages/zui/src/z/types/branded/branded.test.ts index 048e05ff088..6da90a450d8 100644 --- a/packages/zui/src/z/types/branded/branded.test.ts +++ b/packages/zui/src/z/types/branded/branded.test.ts @@ -1,6 +1,7 @@ import { test } from 'vitest' import * as z from '../../index' import * as utils from '../../utils' +import { BRAND } from '../../typings' test('branded types', () => { const mySchema = z @@ -11,7 +12,7 @@ test('branded types', () => { // simple branding type MySchema = z.infer - utils.assert.assertEqual(true) + utils.assert.assertEqual(true) const doStuff = (arg: MySchema) => arg doStuff(mySchema.parse({ name: 'hello there' })) @@ -19,22 +20,22 @@ test('branded types', () => { // inheritance const extendedSchema = mySchema.brand<'subschema'>() type ExtendedSchema = z.infer - utils.assert.assertEqual & z.BRAND<'subschema'>>(true) + utils.assert.assertEqual & BRAND<'subschema'>>(true) doStuff(extendedSchema.parse({ name: 'hello again' })) // number branding const numberSchema = z.number().brand<42>() type NumberSchema = z.infer - utils.assert.assertEqual(true) + utils.assert.assertEqual(true) // symbol branding const MyBrand: unique symbol = Symbol('hello') type MyBrand = typeof MyBrand const symbolBrand = z.number().brand<'sup'>().brand() type SymbolBrand = z.infer - // number & { [z.BRAND]: { sup: true, [MyBrand]: true } } - utils.assert.assertEqual & z.BRAND>(true) + // number & { [BRAND]: { sup: true, [MyBrand]: true } } + utils.assert.assertEqual & BRAND>(true) // keeping brands out of input types const age = z.number().brand<'age'>() @@ -44,7 +45,7 @@ test('branded types', () => { utils.assert.assertEqual(false) utils.assert.assertEqual(true) - utils.assert.assertEqual, Age>(true) + utils.assert.assertEqual, Age>(true) // @ts-expect-error doStuff({ name: 'hello there!' }) diff --git a/packages/zui/src/z/types/branded/index.ts b/packages/zui/src/z/types/branded/index.ts index 0e9e83d6b43..a51c0369046 100644 --- a/packages/zui/src/z/types/branded/index.ts +++ b/packages/zui/src/z/types/branded/index.ts @@ -1,26 +1,14 @@ -import { ZodType, ZodTypeDef, ParseInput, ParseReturnType } from '../basetype' +import type { IZodBranded, IZodType, ZodBrandedDef, BRAND } from '../../typings' +import { ZodBaseTypeImpl, ParseInput, ParseReturnType } from '../basetype' type Key = string | number | symbol -export type ZodBrandedDef = { - type: T - typeName: 'ZodBranded' -} & ZodTypeDef - -export const BRAND: unique symbol = Symbol('zod_brand') -export type BRAND = { - [BRAND]: { - [k in T]: true - } -} - -export class ZodBranded extends ZodType< - T['_output'] & BRAND, - ZodBrandedDef, - T['_input'] -> { - dereference(defs: Record): ZodType { - return new ZodBranded({ +export class ZodBrandedImpl + extends ZodBaseTypeImpl, ZodBrandedDef, T['_input']> + implements IZodBranded +{ + dereference(defs: Record): IZodType { + return new ZodBrandedImpl({ ...this._def, type: this._def.type.dereference(defs), }) @@ -30,17 +18,17 @@ export class ZodBranded extend return this._def.type.getReferences() } - clone(): ZodBranded { - return new ZodBranded({ + clone(): IZodBranded { + return new ZodBrandedImpl({ ...this._def, - type: this._def.type.clone(), - }) as ZodBranded + type: this._def.type.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) const data = ctx.data - return this._def.type._parse({ + return ZodBaseTypeImpl.fromInterface(this._def.type)._parse({ data, path: ctx.path, parent: ctx, @@ -51,17 +39,17 @@ export class ZodBranded extend return this._def.type } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodBranded)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodBrandedImpl)) return false return this._def.type.isEqual(schema._def.type) } - naked(): ZodType { + naked(): IZodType { return this._def.type.naked() } - mandatory(): ZodBranded { - return new ZodBranded({ + mandatory(): IZodBranded { + return new ZodBrandedImpl({ ...this._def, type: this._def.type.mandatory(), }) diff --git a/packages/zui/src/z/types/catch/catch.test.ts b/packages/zui/src/z/types/catch/catch.test.ts index f5e8d6b9a98..a4526f0cdc4 100644 --- a/packages/zui/src/z/types/catch/catch.test.ts +++ b/packages/zui/src/z/types/catch/catch.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' -import { z } from '../..' +import { z } from '../../../index' import * as utils from '../../utils' +import { ZodError } from '../../error' test('basic catch', () => { expect(z.string().catch('default').parse(undefined)).toBe('default') @@ -38,9 +39,9 @@ test('catch with transform', () => { .catch('default') expect(stringWithDefault.parse(undefined)).toBe('default') expect(stringWithDefault.parse(15)).toBe('default') - expect(stringWithDefault).toBeInstanceOf(z.ZodCatch) - expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects) - expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema) + expect(stringWithDefault.typeName).toBe('ZodCatch') + expect(stringWithDefault._def.innerType.typeName).toBe('ZodEffects') + expect(stringWithDefault._def.innerType._def.schema.typeName).toBe('ZodString') type inp = z.input utils.assert.assertEqual(true) @@ -52,9 +53,9 @@ test('catch on existing optional', () => { const stringWithDefault = z.string().optional().catch('asdf') expect(stringWithDefault.parse(undefined)).toBe(undefined) expect(stringWithDefault.parse(15)).toBe('asdf') - expect(stringWithDefault).toBeInstanceOf(z.ZodCatch) - expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional) - expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString) + expect(stringWithDefault.typeName).toBe('ZodCatch') + expect(stringWithDefault._def.innerType.typeName).toBe('ZodOptional') + expect(stringWithDefault._def.innerType._def.innerType.typeName).toBe('ZodString') type inp = z.input utils.assert.assertEqual(true) @@ -117,9 +118,7 @@ test('chained catch', () => { }) test('factory', () => { - z.ZodCatch.create(z.string(), { - catch: 'asdf', - }).parse(undefined) + z.catch(z.string(), 'asdf').parse(undefined) }) test('native enum', () => { @@ -204,7 +203,7 @@ test('catch error', () => { expect(!result.success && result.error.issues.length).toEqual(1) expect(!result.success && result.error.issues[0]?.message).toMatch('number') - expect(catchError).toBeInstanceOf(z.ZodError) + expect(catchError).toBeInstanceOf(ZodError) expect(catchError !== undefined && (catchError as z.ZodError).issues.length).toEqual(1) expect(catchError !== undefined && (catchError as z.ZodError).issues[0]?.message).toMatch('string') }) diff --git a/packages/zui/src/z/types/catch/index.ts b/packages/zui/src/z/types/catch/index.ts index b50622d4fd5..8a5029da42a 100644 --- a/packages/zui/src/z/types/catch/index.ts +++ b/packages/zui/src/z/types/catch/index.ts @@ -1,28 +1,16 @@ import { ZodError } from '../../error' +import type { IZodCatch, IZodType, ZodCatchDef } from '../../typings' import * as utils from '../../utils' -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - isAsync, - ParseContext, - ParseInput, - ParseReturnType, -} from '../basetype' +import { ZodBaseTypeImpl, isAsync, ParseContext, ParseInput, ParseReturnType } from '../basetype' -export type CatchFn = (ctx: { error: ZodError; input: unknown }) => Y -export type ZodCatchDef = { - innerType: T - catchValue: CatchFn - typeName: 'ZodCatch' -} & ZodTypeDef - -export class ZodCatch extends ZodType< - T['_output'], - ZodCatchDef, - unknown // any input will pass validation // T["_input"] -> { +export class ZodCatchImpl + extends ZodBaseTypeImpl< + T['_output'], + ZodCatchDef, + unknown // any input will pass validation // T["_input"] + > + implements IZodCatch +{ _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) @@ -35,7 +23,7 @@ export class ZodCatch extends ZodType< }, } - const result = this._def.innerType._parse({ + const result = ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse({ data: newCtx.data, path: newCtx.path, parent: { @@ -78,30 +66,16 @@ export class ZodCatch extends ZodType< return this._def.innerType } - static create = ( - type: T, - params: RawCreateParams & { - catch: T['_output'] | CatchFn - } - ): ZodCatch => { - return new ZodCatch({ - innerType: type, - typeName: 'ZodCatch', - catchValue: typeof params.catch === 'function' ? params.catch : () => params.catch, - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodCatch)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodCatchImpl)) return false return ( this._def.innerType.isEqual(schema._def.innerType) && utils.others.compareFunctions(this._def.catchValue, schema._def.catchValue) ) } - dereference(defs: Record): ZodType { - return new ZodCatch({ + dereference(defs: Record): IZodType { + return new ZodCatchImpl({ ...this._def, innerType: this._def.innerType.dereference(defs), }) @@ -111,21 +85,21 @@ export class ZodCatch extends ZodType< return this._def.innerType.getReferences() } - clone(): ZodCatch { - return new ZodCatch({ + clone(): IZodCatch { + return new ZodCatchImpl({ ...this._def, - innerType: this._def.innerType.clone(), - }) as ZodCatch + innerType: this._def.innerType.clone() as T, + }) } naked() { return this._def.innerType.naked() } - mandatory(): ZodCatch { - return new ZodCatch({ + mandatory(): IZodCatch { + return new ZodCatchImpl({ ...this._def, innerType: this._def.innerType.mandatory(), - }) + }) as IZodCatch } } diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index 206649a4117..ddcd0dc1532 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,27 +1,16 @@ +import { type IZodDate, ZodDateCheck, ZodDateDef } from '../../typings' import * as utils from '../../utils' import { - processCreateParams, - ZodTypeDef, addIssueToContext, INVALID, ParseContext, ParseInput, ParseReturnType, ParseStatus, - ZodType, - RawCreateParams, + ZodBaseTypeImpl, } from '../basetype' -export type ZodDateCheck = - | { kind: 'min'; value: number; message?: string } - | { kind: 'max'; value: number; message?: string } -export type ZodDateDef = { - checks: ZodDateCheck[] - coerce: boolean - typeName: 'ZodDate' -} & ZodTypeDef - -export class ZodDate extends ZodType { +export class ZodDateImpl extends ZodBaseTypeImpl implements IZodDate { _parse(input: ParseInput): ParseReturnType { if (this._def.coerce) { input.data = new Date(input.data) @@ -88,7 +77,7 @@ export class ZodDate extends ZodType { } _addCheck(check: ZodDateCheck) { - return new ZodDate({ + return new ZodDateImpl({ ...this._def, checks: [...this._def.checks, check], }) @@ -132,17 +121,8 @@ export class ZodDate extends ZodType { return max != null ? new Date(max) : null } - static create = (params?: RawCreateParams & { coerce?: boolean }): ZodDate => { - return new ZodDate({ - checks: [], - coerce: params?.coerce || false, - typeName: 'ZodDate', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodDate)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodDateImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) && this._def.coerce === schema._def.coerce diff --git a/packages/zui/src/z/types/default/default.test.ts b/packages/zui/src/z/types/default/default.test.ts index 972b36081b9..0809d79763c 100644 --- a/packages/zui/src/z/types/default/default.test.ts +++ b/packages/zui/src/z/types/default/default.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { z } from '../..' +import { z } from '../../..' import * as utils from '../../utils' test('basic defaults', () => { @@ -12,9 +12,9 @@ test('default with transform', () => { .transform((val) => val.toUpperCase()) .default('default') expect(stringWithDefault.parse(undefined)).toBe('DEFAULT') - expect(stringWithDefault).toBeInstanceOf(z.ZodDefault) - expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects) - expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema) + expect(stringWithDefault.typeName).toBe('ZodDefault') + expect(stringWithDefault._def.innerType.typeName).toBe('ZodEffects') + expect(stringWithDefault._def.innerType._def.schema.typeName).toBe('ZodString') type inp = z.input utils.assert.assertEqual(true) @@ -25,9 +25,9 @@ test('default with transform', () => { test('default on existing optional', () => { const stringWithDefault = z.string().optional().default('asdf') expect(stringWithDefault.parse(undefined)).toBe('asdf') - expect(stringWithDefault).toBeInstanceOf(z.ZodDefault) - expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional) - expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString) + expect(stringWithDefault.typeName).toBe('ZodDefault') + expect(stringWithDefault._def.innerType.typeName).toBe('ZodOptional') + expect(stringWithDefault._def.innerType._def.innerType.typeName).toBe('ZodString') type inp = z.input utils.assert.assertEqual(true) @@ -85,7 +85,7 @@ test('chained defaults', () => { }) test('factory', () => { - expect(z.ZodDefault.create(z.string(), 'asdf').parse(undefined)).toEqual('asdf') + expect(z.default(z.string(), 'asdf').parse(undefined)).toEqual('asdf') }) test('native enum', () => { diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 02289eb6d3b..13d10c0d74b 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -1,34 +1,19 @@ import { isEqual } from 'lodash-es' +import type { IZodType, IZodDefault, ZodDefaultDef } from '../../typings' import * as utils from '../../utils' +import { ZodBaseTypeImpl, ParseInput, ParseReturnType } from '../basetype' -import { - // - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - ParseInput, - ParseReturnType, -} from '../basetype' - -export type ZodDefaultDef = { - innerType: T - defaultValue: () => utils.types.NoUndefined - typeName: 'ZodDefault' -} & ZodTypeDef - -export class ZodDefault extends ZodType< - utils.types.NoUndefined, - ZodDefaultDef, - T['_input'] | undefined -> { +export class ZodDefaultImpl + extends ZodBaseTypeImpl, ZodDefaultDef, T['_input'] | undefined> + implements IZodDefault +{ _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) let data = ctx.data if (ctx.parsedType === 'undefined') { data = this._def.defaultValue() } - return this._def.innerType._parse({ + return ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse({ data, path: ctx.path, parent: ctx, @@ -39,8 +24,8 @@ export class ZodDefault extends ZodType< return this._def.innerType } - dereference(defs: Record): ZodType { - return new ZodDefault({ + dereference(defs: Record): IZodType { + return new ZodDefaultImpl({ ...this._def, innerType: this._def.innerType.dereference(defs), }) @@ -50,28 +35,15 @@ export class ZodDefault extends ZodType< return this._def.innerType.getReferences() } - clone(): ZodDefault { - return new ZodDefault({ + clone(): IZodDefault { + return new ZodDefaultImpl({ ...this._def, - innerType: this._def.innerType.clone(), - }) as ZodDefault - } - - static create = ( - type: T, - value: T['_input'] | (() => utils.types.NoUndefined), - params?: RawCreateParams - ): ZodDefault => { - return new ZodDefault({ - innerType: type, - typeName: 'ZodDefault', - defaultValue: typeof value === 'function' ? value : () => value, - ...processCreateParams(params), + innerType: this._def.innerType.clone() as T, }) } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodDefault)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodDefaultImpl)) return false return ( this._def.innerType.isEqual(schema._def.innerType) && isEqual(this._def.defaultValue(), schema._def.defaultValue()) @@ -86,8 +58,8 @@ export class ZodDefault extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodDefault { - return new ZodDefault({ + mandatory(): IZodDefault { + return new ZodDefaultImpl({ ...this._def, innerType: this._def.innerType.mandatory(), }) diff --git a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts index 3e28524e9c1..9a62734b7f2 100644 --- a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts +++ b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts @@ -128,7 +128,7 @@ test('wrong schema - missing discriminator', () => { ]) throw new Error() } catch (e: any) { - expect(e.message.includes('could not be extracted')).toBe(true) + expect(e.message).toContain('could not be extracted') } }) diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index ee7604aba48..bde9fc742b1 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,98 +1,77 @@ -import * as utils from '../../utils' -import { +import type { ZodNativeType } from '../../native' +import type { + IZodType, + IZodDiscriminatedUnion, + ZodDiscriminatedUnionDef, + ZodDiscriminatedUnionOption, input, output, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - ParseInput, - ParseReturnType, -} from '../basetype' - -// TODO(circle): these may potentially cause circular dependencies errors -import { ZodBranded } from '../branded' -import { ZodCatch } from '../catch' -import { ZodDefault } from '../default' -import { ZodEnum } from '../enum' -import { ZodLazy } from '../lazy' -import { ZodLiteral } from '../literal' -import { ZodNativeEnum } from '../nativeEnum' -import { ZodNull } from '../null' -import { ZodNullable } from '../nullable' -import { ZodObject, type ZodRawShape, type UnknownKeysParam } from '../object' -import { ZodOptional } from '../optional' -import { ZodReadonly } from '../readonly' -import { ZodEffects } from '../transformer' -import { ZodUndefined } from '../undefined' - -const getDiscriminator = (type: T): utils.types.Primitive[] => { - if (type instanceof ZodLazy) { + IZodObject, +} from '../../typings' +import * as utils from '../../utils' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' + +const getDiscriminator = (_type: IZodType | undefined): utils.types.Primitive[] => { + const type = _type as ZodNativeType | undefined + if (!type) return [] + if (type.typeName === 'ZodLazy') { return getDiscriminator(type.schema) - } else if (type instanceof ZodEffects) { + } else if (type.typeName === 'ZodEffects') { return getDiscriminator(type.innerType()) - } else if (type instanceof ZodLiteral) { + } else if (type.typeName === 'ZodLiteral') { return [type.value] - } else if (type instanceof ZodEnum) { + } else if (type.typeName === 'ZodEnum') { return type.options - } else if (type instanceof ZodNativeEnum) { + } else if (type.typeName === 'ZodNativeEnum') { return Object.values(type.enum) - } else if (type instanceof ZodDefault) { + } else if (type.typeName === 'ZodDefault') { return getDiscriminator(type._def.innerType) - } else if (type instanceof ZodUndefined) { + } else if (type.typeName === 'ZodUndefined') { return [undefined] - } else if (type instanceof ZodNull) { + } else if (type.typeName === 'ZodNull') { return [null] - } else if (type instanceof ZodOptional) { + } else if (type.typeName === 'ZodOptional') { return [undefined, ...getDiscriminator(type.unwrap())] - } else if (type instanceof ZodNullable) { + } else if (type.typeName === 'ZodNullable') { return [null, ...getDiscriminator(type.unwrap())] - } else if (type instanceof ZodBranded) { + } else if (type.typeName === 'ZodBranded') { return getDiscriminator(type.unwrap()) - } else if (type instanceof ZodReadonly) { + } else if (type.typeName === 'ZodReadonly') { return getDiscriminator(type.unwrap()) - } else if (type instanceof ZodCatch) { + } else if (type.typeName === 'ZodCatch') { return getDiscriminator(type._def.innerType) } else { return [] } } -export type ZodDiscriminatedUnionOption = ZodObject< - { - [key in Discriminator]: ZodType - } & ZodRawShape, - UnknownKeysParam -> - -export type ZodDiscriminatedUnionDef< - Discriminator extends string = string, - Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], -> = { - discriminator: Discriminator - options: Options - optionsMap: Map> - typeName: 'ZodDiscriminatedUnion' -} & ZodTypeDef - -export class ZodDiscriminatedUnion< - Discriminator extends string = string, - Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], -> extends ZodType, ZodDiscriminatedUnionDef, input> { - dereference(defs: Record): ZodType { +export class ZodDiscriminatedUnionImpl< + Discriminator extends string = string, + Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], + > + extends ZodBaseTypeImpl< + output, + ZodDiscriminatedUnionDef, + input + > + implements IZodDiscriminatedUnion +{ + constructor(def: utils.types.SafeOmit, 'optionsMap'>) { + const optionsMap = ZodDiscriminatedUnionImpl._getOptionsMap(def.discriminator, def.options) + super({ + ...def, + optionsMap, + }) + } + + dereference(defs: Record): ZodBaseTypeImpl { const options = this.options.map((option) => option.dereference(defs)) as [ ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[], ] - - const optionsMap = ZodDiscriminatedUnion._getOptionsMap(this.discriminator, options) - - return new ZodDiscriminatedUnion({ + return new ZodDiscriminatedUnionImpl({ ...this._def, options, - optionsMap, }) } @@ -100,14 +79,12 @@ export class ZodDiscriminatedUnion< return utils.fn.unique(this.options.flatMap((option) => option.getReferences())) } - clone(): ZodDiscriminatedUnion { - const options: ZodDiscriminatedUnionOption[] = this.options.map( - (option) => option.clone() as ZodDiscriminatedUnionOption - ) - return new ZodDiscriminatedUnion({ + clone(): ZodDiscriminatedUnionImpl { + const options = this.options.map((option) => option.clone() as ZodDiscriminatedUnionOption) + return new ZodDiscriminatedUnionImpl({ ...this._def, options: options as [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], - }) as ZodDiscriminatedUnion + }) as ZodDiscriminatedUnionImpl } _parse(input: ParseInput): ParseReturnType { @@ -138,13 +115,13 @@ export class ZodDiscriminatedUnion< } if (ctx.common.async) { - return option._parseAsync({ + return ZodBaseTypeImpl.fromInterface(option)._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }) as ParseReturnType } else { - return option._parseSync({ + return ZodBaseTypeImpl.fromInterface(option)._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -172,34 +149,12 @@ export class ZodDiscriminatedUnion< * @param types an array of object schemas * @param params */ - static create< - Discriminator extends string, - Types extends [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], - >( - discriminator: Discriminator, - options: Types, - params?: RawCreateParams - ): ZodDiscriminatedUnion { - const optionsMap = ZodDiscriminatedUnion._getOptionsMap(discriminator, options) - return new ZodDiscriminatedUnion< - Discriminator, - // DiscriminatorValue, - Types - >({ - typeName: 'ZodDiscriminatedUnion', - discriminator, - options, - optionsMap, - ...processCreateParams(params), - }) - } - private static _getOptionsMap< - Discriminator extends string, - Types extends [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], - >(discriminator: Discriminator, options: Types) { + Discriminator extends string = string, + Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], + >(discriminator: Discriminator, options: Options) { // Get all the valid discriminator values - const optionsMap: Map = new Map() + const optionsMap: Map = new Map() // try { for (const type of options) { @@ -221,13 +176,13 @@ export class ZodDiscriminatedUnion< return optionsMap } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodDiscriminatedUnion)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodDiscriminatedUnionImpl)) return false if (this._def.discriminator !== schema._def.discriminator) return false - const compare = (a: ZodObject, b: ZodObject) => a.isEqual(b) - const thisOptions = new utils.ds.CustomSet(this._def.options, { compare }) - const thatOptions = new utils.ds.CustomSet(schema._def.options, { compare }) + const compare = (a: IZodObject, b: IZodObject) => a.isEqual(b) + const thisOptions = new utils.ds.CustomSet(this._def.options, { compare }) + const thatOptions = new utils.ds.CustomSet(schema._def.options, { compare }) // no need to compare optionsMap, as it is derived from discriminator + options diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index 204f2809594..034148ef0cf 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,9 +1,9 @@ +import { builders } from '../../internal-builders' +import type { FilterEnum, IZodEnum, EnumValuesMap, NeverCast, ZodEnumDef, EnumValues } from '../../typings' import * as utils from '../../utils' import { RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, OK, @@ -11,31 +11,10 @@ import { ParseReturnType, } from '../basetype' -export type EnumValues = [string, ...string[]] - -export type EnumValuesMap = { - [k in T[number]]: k -} - -export type ZodEnumDef = { - values: T - typeName: 'ZodEnum' -} & ZodTypeDef - -type _FilterEnum = Values extends [] - ? [] - : Values extends [infer Head, ...infer Rest] - ? Head extends ToExclude - ? _FilterEnum - : [Head, ..._FilterEnum] - : never - -type _NeverCast = A extends T ? A : never - -export class ZodEnum extends ZodType< - T[number], - ZodEnumDef -> { +export class ZodEnumImpl + extends ZodBaseTypeImpl> + implements IZodEnum +{ _parse(input: ParseInput): ParseReturnType { if (typeof input.data !== 'string') { const ctx = this._getOrReturnCtx(input) @@ -62,7 +41,7 @@ export class ZodEnum ex return OK(input.data) } - get options() { + get options(): T { return this._def.values } @@ -93,8 +72,9 @@ export class ZodEnum ex extract( values: ToExtract, newDef: RawCreateParams = this._def - ): ZodEnum> { - return ZodEnum.create(values, { + ): IZodEnum> { + // TODO(why): find out why the ctor is not used directly + return builders.enum(values, { ...this._def, ...newDef, }) @@ -103,28 +83,16 @@ export class ZodEnum ex exclude( values: ToExclude, newDef: RawCreateParams = this._def - ): ZodEnum<_NeverCast>, [string, ...string[]]>> { - return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)) as _FilterEnum, { + ): IZodEnum>, [string, ...string[]]>> { + // TODO(why): find out why the ctor is not used directly + return builders.enum(this.options.filter((opt) => !values.includes(opt)) as FilterEnum, { ...this._def, ...newDef, - }) as ZodEnum<_NeverCast>, [string, ...string[]]>> - } - - static create>( - values: T, - params?: RawCreateParams - ): ZodEnum> - static create(values: T, params?: RawCreateParams): ZodEnum - static create(values: [string, ...string[]], params?: RawCreateParams) { - return new ZodEnum({ - values, - typeName: 'ZodEnum', - ...processCreateParams(params), - }) + }) as IZodEnum>, [string, ...string[]]>> } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodEnum)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodEnumImpl)) return false const thisValues = new utils.ds.CustomSet(this._def.values) const thatValues = new utils.ds.CustomSet(schema._def.values) return thisValues.isEqual(thatValues) diff --git a/packages/zui/src/z/types/function/function.test.ts b/packages/zui/src/z/types/function/function.test.ts index a5168785ed7..8120d3185e4 100644 --- a/packages/zui/src/z/types/function/function.test.ts +++ b/packages/zui/src/z/types/function/function.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' import * as z from '../../index' import * as utils from '../../utils' +import { ZodError } from '../../error' const args1 = z.tuple([z.string()]) const returns1 = z.number() @@ -133,16 +134,18 @@ test('output validation error', () => { expect(checker).toThrow() }) -z.function(z.tuple([z.string()])).args()._def.args +const singleStringTuple = z.tuple([z.string()]) +z.function(singleStringTuple).args()._def.args test('special function error codes', () => { - const checker = z.function(z.tuple([z.string()]), z.boolean()).implement((arg) => { - return arg.length as any + const s = z.function(z.tuple([z.string()]), z.boolean()) + const checker = s.implement((arg) => { + return !!arg.length }) try { checker('12' as any) } catch (err) { - const zerr = err as z.ZodError + const zerr = err as ZodError const first = zerr.issues[0] if (first?.code !== 'invalid_return_type') throw new Error() } @@ -150,10 +153,10 @@ test('special function error codes', () => { try { checker(12 as any) } catch (err) { - const zerr = err as z.ZodError + const zerr = err as ZodError const first = zerr.issues[0] if (first?.code !== 'invalid_arguments') throw new Error() - expect(first?.argumentsError).toBeInstanceOf(z.ZodError) + expect(first?.argumentsError).toBeInstanceOf(ZodError) } }) diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index b86850eb9bf..651170b9ca8 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,44 +1,35 @@ -import { defaultErrorMap, getErrorMap, ZodError, ZodErrorMap, ZodIssue } from '../../error' +import { defaultErrorMap, getErrorMap, ZodError } from '../../error' +import { builders } from '../../internal-builders' +import type { ZodNativeType } from '../../native' +import type { + IZodType, + IZodFunction, + ZodFunctionDef, + IZodTuple, + ZodErrorMap, + ZodIssue, + OuterTypeOfFunction, + InnerTypeOfFunction, + IZodUnknown, + IZodPromise, +} from '../../typings' + import * as utils from '../../utils' -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - makeIssue, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' - -// TODO(circle): these may potentially cause circular dependencies errors -import { ZodPromise } from '../promise' -import { ZodTuple, type AnyZodTuple } from '../tuple' -import { ZodUnknown } from '../unknown' - -export type ZodFunctionDef = ZodTuple, Returns extends ZodType = ZodType> = { - args: Args - returns: Returns - typeName: 'ZodFunction' -} & ZodTypeDef - -type _OuterTypeOfFunction, Returns extends ZodType> = - Args['_input'] extends Array ? (...args: Args['_input']) => Returns['_output'] : never - -type _InnerTypeOfFunction, Returns extends ZodType> = - Args['_output'] extends Array ? (...args: Args['_output']) => Returns['_input'] : never - -export class ZodFunction = ZodTuple, Returns extends ZodType = ZodType> extends ZodType< - _OuterTypeOfFunction, - ZodFunctionDef, - _InnerTypeOfFunction -> { - dereference(defs: Record): ZodType { - const args = this._def.args.dereference(defs) as ZodTuple<[], ZodUnknown> + +import { ZodBaseTypeImpl, addIssueToContext, INVALID, makeIssue, OK, ParseInput, ParseReturnType } from '../basetype' + +export class ZodFunctionImpl = IZodTuple, Returns extends IZodType = IZodType> + extends ZodBaseTypeImpl< + OuterTypeOfFunction, + ZodFunctionDef, + InnerTypeOfFunction + > + implements IZodFunction +{ + dereference(defs: Record): IZodType { + const args = this._def.args.dereference(defs) as IZodTuple<[], IZodUnknown> const returns = this._def.returns.dereference(defs) - return new ZodFunction({ + return new ZodFunctionImpl({ ...this._def, args, returns, @@ -49,12 +40,12 @@ export class ZodFunction = ZodTuple, Returns ext return utils.fn.unique([...this._def.args.getReferences(), ...this._def.returns.getReferences()]) } - clone(): ZodFunction { - return new ZodFunction({ + clone(): IZodFunction { + return new ZodFunctionImpl({ ...this._def, - args: this._def.args.clone() as ZodTuple, - returns: this._def.returns.clone(), - }) as ZodFunction + args: this._def.args.clone() as Args, + returns: this._def.returns.clone() as Returns, + }) } _parse(input: ParseInput): ParseReturnType { @@ -99,7 +90,8 @@ export class ZodFunction = ZodTuple, Returns ext const params = { errorMap: ctx.common.contextualErrorMap } const fn = ctx.data - if (this._def.returns instanceof ZodPromise) { + const returns = this._def.returns as ZodNativeType + if (returns.typeName === 'ZodPromise') { // Would love a way to avoid disabling this rule, but we need // an alias (using an arrow function was what caused 2651). @@ -111,7 +103,7 @@ export class ZodFunction = ZodTuple, Returns ext throw error }) const result = await Reflect.apply(fn, this, parsedArgs) - const parsedReturns = await (me._def.returns as unknown as ZodPromise)._def.type + const parsedReturns = await (me._def.returns as unknown as IZodPromise)._def.type .parseAsync(result, params) .catch((e: any) => { // TODO: type e properly @@ -148,58 +140,41 @@ export class ZodFunction = ZodTuple, Returns ext return this._def.returns } - args[0]>( + args( ...items: Items - ): ZodFunction, Returns> { - return new ZodFunction({ + ): IZodFunction, Returns> { + return new ZodFunctionImpl({ ...this._def, - args: ZodTuple.create(items).rest(ZodUnknown.create()), - }) + args: builders.tuple(items).rest(builders.unknown()), + }) as IZodFunction, Returns> } - returns>(returnType: NewReturnType): ZodFunction { - return new ZodFunction({ + returns>(returnType: NewReturnType): IZodFunction { + return new ZodFunctionImpl({ ...this._def, returns: returnType, }) } - implement>( + implement>( func: F ): ReturnType extends Returns['_output'] ? (...args: Args['_input']) => ReturnType - : _OuterTypeOfFunction { + : OuterTypeOfFunction { const validatedFunc = this.parse(func) return validatedFunc } - strictImplement(func: _InnerTypeOfFunction): _InnerTypeOfFunction { + strictImplement(func: InnerTypeOfFunction): InnerTypeOfFunction { const validatedFunc = this.parse(func) return validatedFunc } validate = this.implement - static create(): ZodFunction, ZodUnknown> - static create>(args: T): ZodFunction - static create(args: T, returns: U): ZodFunction - static create, U extends ZodType = ZodUnknown>( - args: T, - returns: U, - params?: RawCreateParams - ): ZodFunction - static create(args?: AnyZodTuple, returns?: ZodType, params?: RawCreateParams) { - return new ZodFunction({ - args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()), - returns: returns || ZodUnknown.create(), - typeName: 'ZodFunction', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { + isEqual(schema: IZodType): boolean { return ( - schema instanceof ZodFunction && + schema instanceof ZodFunctionImpl && this._def.args.isEqual(schema._def.args) && this._def.returns.isEqual(schema._def.returns) ) diff --git a/packages/zui/src/z/types/index.ts b/packages/zui/src/z/types/index.ts index 68581b6785d..d78f8878dba 100644 --- a/packages/zui/src/z/types/index.ts +++ b/packages/zui/src/z/types/index.ts @@ -36,4 +36,3 @@ export * from './undefined' export * from './union' export * from './unknown' export * from './void' -export * from './native' diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index ae23f1a7940..1ae759fe5d8 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -1,10 +1,7 @@ +import type { IZodIntersection, IZodType, ZodIntersectionDef } from '../../typings' import * as utils from '../../utils' import { - RawCreateParams, - ZodType, - ZodTypeDef, getParsedType, - processCreateParams, addIssueToContext, INVALID, isAborted, @@ -12,21 +9,17 @@ import { ParseInput, ParseReturnType, SyncParseReturnType, + ZodBaseTypeImpl, } from '../basetype' -export type ZodIntersectionDef = { - left: T - right: U - typeName: 'ZodIntersection' -} & ZodTypeDef - -export class ZodIntersection extends ZodType< - T['_output'] & U['_output'], - ZodIntersectionDef, - T['_input'] & U['_input'] -> { - dereference(defs: Record): ZodType { - return new ZodIntersection({ +export type { ZodIntersectionDef } + +export class ZodIntersectionImpl + extends ZodBaseTypeImpl, T['_input'] & U['_input']> + implements IZodIntersection +{ + dereference(defs: Record): IZodType { + return new ZodIntersectionImpl({ ...this._def, left: this._def.left.dereference(defs), right: this._def.right.dereference(defs), @@ -37,19 +30,19 @@ export class ZodIntersection { - return new ZodIntersection({ + clone(): IZodIntersection { + return new ZodIntersectionImpl({ ...this._def, - left: this._def.left.clone(), - right: this._def.right.clone(), - }) as ZodIntersection + left: this._def.left.clone() as T, + right: this._def.right.clone() as U, + }) } _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) const handleParsed = ( - parsedLeft: SyncParseReturnType, - parsedRight: SyncParseReturnType + parsedLeft: SyncParseReturnType, + parsedRight: SyncParseReturnType ): SyncParseReturnType => { if (isAborted(parsedLeft) || isAborted(parsedRight)) { return INVALID @@ -73,12 +66,12 @@ export class ZodIntersection handleParsed(left, right)) } else { return handleParsed( - this._def.left._parseSync({ + ZodBaseTypeImpl.fromInterface(this._def.left)._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }), - this._def.right._parseSync({ + ZodBaseTypeImpl.fromInterface(this._def.right)._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -100,25 +93,12 @@ export class ZodIntersection( - left: T, - right: U, - params?: RawCreateParams - ): ZodIntersection => { - return new ZodIntersection({ - left, - right, - typeName: 'ZodIntersection', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodIntersection)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodIntersectionImpl)) return false - const compare = (a: ZodType, b: ZodType) => a.isEqual(b) - const thisItems = new utils.ds.CustomSet([this._def.left, this._def.right], { compare }) - const thatItems = new utils.ds.CustomSet([schema._def.left, schema._def.right], { compare }) + const compare = (a: IZodType, b: IZodType) => a.isEqual(b) + const thisItems = new utils.ds.CustomSet([this._def.left, this._def.right], { compare }) + const thatItems = new utils.ds.CustomSet([schema._def.left, schema._def.right], { compare }) return thisItems.isEqual(thatItems) } diff --git a/packages/zui/src/z/types/lazy/index.ts b/packages/zui/src/z/types/lazy/index.ts index ee47ade9d08..6f5d08f4a3e 100644 --- a/packages/zui/src/z/types/lazy/index.ts +++ b/packages/zui/src/z/types/lazy/index.ts @@ -1,26 +1,16 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - ParseInput, - ParseReturnType, - output, - input, -} from '../basetype' +import type { IZodLazy, IZodType, ZodLazyDef, input, output } from '../../typings' +import { ZodBaseTypeImpl, ParseInput, ParseReturnType } from '../basetype' -export type ZodLazyDef = { - getter: () => T - typeName: 'ZodLazy' -} & ZodTypeDef - -export class ZodLazy extends ZodType, ZodLazyDef, input> { +export class ZodLazyImpl + extends ZodBaseTypeImpl, ZodLazyDef, input> + implements IZodLazy +{ get schema(): T { return this._def.getter() } - dereference(defs: Record): ZodType { - return new ZodLazy({ + dereference(defs: Record): IZodType { + return new ZodLazyImpl({ ...this._def, getter: () => this._def.getter().dereference(defs), }) @@ -30,29 +20,21 @@ export class ZodLazy extends ZodType, Zod return this._def.getter().getReferences() } - clone(): ZodLazy { - return new ZodLazy({ + clone(): IZodLazy { + return new ZodLazyImpl({ ...this._def, - getter: () => this._def.getter().clone(), - }) as ZodLazy + getter: () => this._def.getter().clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) const lazySchema = this._def.getter() - return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx }) - } - - static create = (getter: () => T, params?: RawCreateParams): ZodLazy => { - return new ZodLazy({ - getter, - typeName: 'ZodLazy', - ...processCreateParams(params), - }) + return ZodBaseTypeImpl.fromInterface(lazySchema)._parse({ data: ctx.data, path: ctx.path, parent: ctx }) } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodLazy)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodLazyImpl)) return false return this._def.getter().isEqual(schema._def.getter()) } @@ -60,8 +42,8 @@ export class ZodLazy extends ZodType, Zod return this._def.getter().naked() } - mandatory(): ZodLazy { - return new ZodLazy({ + mandatory(): IZodLazy { + return new ZodLazyImpl({ ...this._def, getter: () => this._def.getter().mandatory(), }) diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index d5ea8f4dbd6..dbd95b2f61e 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,22 +1,12 @@ import { isEqual } from 'lodash-es' +import type { IZodLiteral, ZodLiteralDef } from '../../typings' import * as utils from '../../utils' -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - ParseInput, - ParseReturnType, -} from '../basetype' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' -export type ZodLiteralDef = { - value: T - typeName: 'ZodLiteral' -} & ZodTypeDef - -export class ZodLiteral extends ZodType> { +export class ZodLiteralImpl + extends ZodBaseTypeImpl> + implements IZodLiteral +{ _parse(input: ParseInput): ParseReturnType { if (input.data !== this._def.value) { const ctx = this._getOrReturnCtx(input) @@ -34,16 +24,8 @@ export class ZodLiteral return this._def.value } - static create = (value: T, params?: RawCreateParams): ZodLiteral => { - return new ZodLiteral({ - value, - typeName: 'ZodLiteral', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodLiteral)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodLiteralImpl)) return false return isEqual(this._def.value, schema._def.value) } } diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index 15247fb58c1..1b9c9e2cf32 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -1,10 +1,8 @@ +import type { IZodMap, IZodType, ZodMapDef } from '../../typings' import * as utils from '../../utils' import { ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, @@ -12,17 +10,14 @@ import { SyncParseReturnType, } from '../basetype' -export type ZodMapDef = { - valueType: Value - keyType: Key - typeName: 'ZodMap' -} & ZodTypeDef - -export class ZodMap extends ZodType< - Map, - ZodMapDef, - Map -> { +export class ZodMapImpl + extends ZodBaseTypeImpl< + Map, + ZodMapDef, + Map + > + implements IZodMap +{ get keySchema() { return this._def.keyType } @@ -30,10 +25,10 @@ export class ZodMap): ZodType { + dereference(defs: Record): ZodBaseTypeImpl { const keyType = this._def.keyType.dereference(defs) const valueType = this._def.valueType.dereference(defs) - return new ZodMap({ + return new ZodMapImpl({ ...this._def, keyType, valueType, @@ -44,12 +39,12 @@ export class ZodMap { - return new ZodMap({ + clone(): IZodMap { + return new ZodMapImpl({ ...this._def, - keyType: this._def.keyType.clone(), - valueType: this._def.valueType.clone(), - }) as ZodMap + keyType: this._def.keyType.clone() as Key, + valueType: this._def.valueType.clone() as Value, + }) } _parse(input: ParseInput): ParseReturnType { @@ -68,8 +63,10 @@ export class ZodMap).entries()].map(([key, value], index) => { return { - key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, 'key'])), - value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, 'value'])), + key: ZodBaseTypeImpl.fromInterface(keyType)._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, 'key'])), + value: ZodBaseTypeImpl.fromInterface(valueType)._parse( + new ParseInputLazyPath(ctx, value, ctx.path, [index, 'value']) + ), } }) @@ -93,8 +90,8 @@ export class ZodMap + const value = pair.value as SyncParseReturnType if (key.status === 'aborted' || value.status === 'aborted') { return INVALID } @@ -107,21 +104,8 @@ export class ZodMap( - keyType: Key, - valueType: Value, - params?: RawCreateParams - ): ZodMap => { - return new ZodMap({ - valueType, - keyType, - typeName: 'ZodMap', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodMap)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodMapImpl)) return false if (!this._def.keyType.isEqual(schema._def.keyType)) return false if (!this._def.valueType.isEqual(schema._def.valueType)) return false return true diff --git a/packages/zui/src/z/types/map/map.test.ts b/packages/zui/src/z/types/map/map.test.ts index d588ccbdceb..8a0961d04c0 100644 --- a/packages/zui/src/z/types/map/map.test.ts +++ b/packages/zui/src/z/types/map/map.test.ts @@ -1,7 +1,6 @@ import { test, expect } from 'vitest' import * as utils from '../../utils' import * as z from '../../index' -import { ZodIssueCode } from '../../index' const stringMap = z.map(z.string(), z.string()) type stringMap = z.infer diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index 1e2c4773cbb..b51228d01f5 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -1,19 +1,7 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodNaN, ZodNaNDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' -export type ZodNaNDef = { - typeName: 'ZodNaN' -} & ZodTypeDef - -export class ZodNaN extends ZodType { +export class ZodNaNImpl extends ZodBaseTypeImpl implements IZodNaN { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'nan') { @@ -29,14 +17,7 @@ export class ZodNaN extends ZodType { return { status: 'valid', value: input.data } } - static create = (params?: RawCreateParams): ZodNaN => { - return new ZodNaN({ - typeName: 'ZodNaN', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodNaN + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodNaNImpl } } diff --git a/packages/zui/src/z/types/native.test.ts b/packages/zui/src/z/types/native.test.ts deleted file mode 100644 index 58338e778dd..00000000000 --- a/packages/zui/src/z/types/native.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { test } from 'vitest' -import * as z from '../index' -import * as utils from '../utils' - -test('first party switch', () => { - const myType = z.ZodString.create() as z.ZodNativeSchema - - switch (myType.typeName) { - case 'ZodString': - myType satisfies z.ZodString - break - case 'ZodNumber': - myType satisfies z.ZodNumber - break - case 'ZodNaN': - myType satisfies z.ZodNaN - break - case 'ZodBigInt': - myType satisfies z.ZodBigInt - break - case 'ZodBoolean': - myType satisfies z.ZodBoolean - break - case 'ZodDate': - myType satisfies z.ZodDate - break - case 'ZodUndefined': - myType satisfies z.ZodUndefined - break - case 'ZodNull': - myType satisfies z.ZodNull - break - case 'ZodAny': - myType satisfies z.ZodAny - break - case 'ZodUnknown': - myType satisfies z.ZodUnknown - break - case 'ZodNever': - myType satisfies z.ZodNever - break - case 'ZodVoid': - myType satisfies z.ZodVoid - break - case 'ZodArray': - myType satisfies z.ZodArray - break - case 'ZodObject': - myType satisfies z.ZodObject - break - case 'ZodUnion': - myType satisfies z.ZodUnion - break - case 'ZodDiscriminatedUnion': - myType satisfies z.ZodDiscriminatedUnion - break - case 'ZodIntersection': - myType satisfies z.ZodIntersection - break - case 'ZodTuple': - myType satisfies z.ZodTuple - break - case 'ZodRecord': - myType satisfies z.ZodRecord - break - case 'ZodRef': - myType satisfies z.ZodRef - break - case 'ZodMap': - myType satisfies z.ZodMap - break - case 'ZodSet': - myType satisfies z.ZodSet - break - case 'ZodFunction': - myType satisfies z.ZodFunction - break - case 'ZodLazy': - myType satisfies z.ZodLazy - break - case 'ZodLiteral': - myType satisfies z.ZodLiteral - break - case 'ZodEnum': - myType satisfies z.ZodEnum - break - case 'ZodEffects': - myType satisfies z.ZodEffects - break - case 'ZodNativeEnum': - myType satisfies z.ZodNativeEnum - break - case 'ZodOptional': - myType satisfies z.ZodOptional - break - case 'ZodNullable': - myType satisfies z.ZodNullable - break - case 'ZodDefault': - myType satisfies z.ZodDefault - break - case 'ZodCatch': - myType satisfies z.ZodCatch - break - case 'ZodPromise': - myType satisfies z.ZodPromise - break - case 'ZodBranded': - myType satisfies z.ZodBranded - break - case 'ZodPipeline': - myType satisfies z.ZodPipeline - break - case 'ZodSymbol': - myType satisfies z.ZodSymbol - break - case 'ZodReadonly': - myType satisfies z.ZodReadonly - break - default: - utils.assert.assertNever(myType) - } -}) diff --git a/packages/zui/src/z/types/native.ts b/packages/zui/src/z/types/native.ts deleted file mode 100644 index 1bef2f35312..00000000000 --- a/packages/zui/src/z/types/native.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { ZodAny } from './any' -import { ZodArray } from './array' -import { ZodBigInt } from './bigint' -import { ZodBoolean } from './boolean' -import { ZodBranded } from './branded' -import { ZodCatch } from './catch' -import { ZodDate } from './date' -import { ZodDefault } from './default' -import { ZodDiscriminatedUnion } from './discriminatedUnion' -import { ZodEnum } from './enum' -import { ZodFunction } from './function' -import { ZodIntersection } from './intersection' -import { ZodLazy } from './lazy' -import { ZodLiteral } from './literal' -import { ZodMap } from './map' -import { ZodNaN } from './nan' -import { ZodNativeEnum } from './nativeEnum' -import { ZodNever } from './never' -import { ZodNull } from './null' -import { ZodNullable } from './nullable' -import { ZodNumber } from './number' -import { ZodObject } from './object' -import { ZodOptional } from './optional' -import { ZodPipeline } from './pipeline' -import { ZodPromise } from './promise' -import { ZodReadonly } from './readonly' -import { ZodRecord } from './record' -import { ZodRef } from './ref' -import { ZodSet } from './set' -import { ZodString } from './string' -import { ZodSymbol } from './symbol' -import { ZodEffects } from './transformer' -import { ZodTuple } from './tuple' -import { ZodUndefined } from './undefined' -import { ZodUnion } from './union' -import { ZodUnknown } from './unknown' -import { ZodVoid } from './void' - -/** - * @deprecated - use ZodNativeSchema instead - */ -export type ZodFirstPartySchemaTypes = ZodNativeSchema -export type ZodNativeSchema = - | ZodString - | ZodNumber - | ZodNaN - | ZodBigInt - | ZodBoolean - | ZodDate - | ZodUndefined - | ZodNull - | ZodAny - | ZodUnknown - | ZodNever - | ZodVoid - | ZodArray - | ZodObject - | ZodUnion - | ZodDiscriminatedUnion - | ZodIntersection - | ZodTuple - | ZodRecord - | ZodMap - | ZodSet - | ZodFunction - | ZodLazy - | ZodLiteral - | ZodEnum - | ZodEffects - | ZodNativeEnum - | ZodOptional - | ZodNullable - | ZodDefault - | ZodCatch - | ZodPromise - | ZodBranded - | ZodPipeline - | ZodReadonly - | ZodSymbol - | ZodRef - -/** - * @deprecated - use ZodNativeSchemaDef instead - */ -export type ZodDef = ZodNativeSchemaDef -export type ZodNativeSchemaDef = ZodNativeSchema['_def'] - -/** - * @deprecated - use ZodNativeSchemaType instead - */ -export type ZodFirstPartyTypeKind = ZodNativeSchemaType -export type ZodNativeSchemaType = ZodNativeSchemaDef['typeName'] - -/** - * @deprecated - use ZodNativeSchemaType instead - */ -export const ZodFirstPartyTypeKind = { - ZodString: 'ZodString', - ZodNumber: 'ZodNumber', - ZodNaN: 'ZodNaN', - ZodBigInt: 'ZodBigInt', - ZodBoolean: 'ZodBoolean', - ZodDate: 'ZodDate', - ZodSymbol: 'ZodSymbol', - ZodUndefined: 'ZodUndefined', - ZodNull: 'ZodNull', - ZodAny: 'ZodAny', - ZodUnknown: 'ZodUnknown', - ZodNever: 'ZodNever', - ZodVoid: 'ZodVoid', - ZodArray: 'ZodArray', - ZodObject: 'ZodObject', - ZodUnion: 'ZodUnion', - ZodDiscriminatedUnion: 'ZodDiscriminatedUnion', - ZodIntersection: 'ZodIntersection', - ZodTuple: 'ZodTuple', - ZodRecord: 'ZodRecord', - ZodRef: 'ZodRef', - ZodMap: 'ZodMap', - ZodSet: 'ZodSet', - ZodFunction: 'ZodFunction', - ZodLazy: 'ZodLazy', - ZodLiteral: 'ZodLiteral', - ZodEnum: 'ZodEnum', - ZodEffects: 'ZodEffects', - ZodNativeEnum: 'ZodNativeEnum', - ZodOptional: 'ZodOptional', - ZodNullable: 'ZodNullable', - ZodDefault: 'ZodDefault', - ZodCatch: 'ZodCatch', - ZodPromise: 'ZodPromise', - ZodBranded: 'ZodBranded', - ZodPipeline: 'ZodPipeline', - ZodReadonly: 'ZodReadonly', -} satisfies { - [K in ZodNativeSchemaType]: K -} diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index 9ab886b30f1..3a604a14116 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,25 +1,12 @@ import { isEqual } from 'lodash-es' +import type { EnumLike, IZodNativeEnum, ZodNativeEnumDef } from '../../typings' import * as utils from '../../utils' -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodNativeEnumDef = { - values: T - typeName: 'ZodNativeEnum' -} & ZodTypeDef - -export type EnumLike = { [k: string]: string | number; [nu: number]: string } - -export class ZodNativeEnum extends ZodType> { +export class ZodNativeEnumImpl + extends ZodBaseTypeImpl> + implements IZodNativeEnum +{ _parse(input: ParseInput): ParseReturnType { const nativeEnumValues = this._getValidEnumValues(this._def.values) @@ -51,16 +38,8 @@ export class ZodNativeEnum extends ZodType(values: T, params?: RawCreateParams): ZodNativeEnum => { - return new ZodNativeEnum({ - values, - typeName: 'ZodNativeEnum', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodNativeEnum)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodNativeEnumImpl)) return false return isEqual(this._def.values, schema._def.values) } diff --git a/packages/zui/src/z/types/never/index.ts b/packages/zui/src/z/types/never/index.ts index 62366dcb966..02a16e60429 100644 --- a/packages/zui/src/z/types/never/index.ts +++ b/packages/zui/src/z/types/never/index.ts @@ -1,19 +1,9 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodNever, ZodNeverDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' -export type ZodNeverDef = { - typeName: 'ZodNever' -} & ZodTypeDef +export type { ZodNeverDef } -export class ZodNever extends ZodType { +export class ZodNeverImpl extends ZodBaseTypeImpl implements IZodNever { _parse(input: ParseInput): ParseReturnType { const ctx = this._getOrReturnCtx(input) addIssueToContext(ctx, { @@ -23,14 +13,7 @@ export class ZodNever extends ZodType { }) return INVALID } - static create = (params?: RawCreateParams): ZodNever => { - return new ZodNever({ - typeName: 'ZodNever', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodNever + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodNeverImpl } } diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index 804d067d075..5d790ac7ac8 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -1,20 +1,7 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodNull, ZodNullDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodNullDef = { - typeName: 'ZodNull' -} & ZodTypeDef - -export class ZodNull extends ZodType { +export class ZodNullImpl extends ZodBaseTypeImpl implements IZodNull { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'null') { @@ -28,14 +15,7 @@ export class ZodNull extends ZodType { } return OK(input.data) } - static create = (params?: RawCreateParams): ZodNull => { - return new ZodNull({ - typeName: 'ZodNull', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodNull + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodNullImpl } } diff --git a/packages/zui/src/z/types/nullable/index.ts b/packages/zui/src/z/types/nullable/index.ts index ce4075d4506..0f25e22c103 100644 --- a/packages/zui/src/z/types/nullable/index.ts +++ b/packages/zui/src/z/types/nullable/index.ts @@ -1,26 +1,12 @@ -import { - // - OK, - ParseInput, - ParseReturnType, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, -} from '../basetype' - -export type ZodNullableDef = { - innerType: T - typeName: 'ZodNullable' -} & ZodTypeDef - -export class ZodNullable extends ZodType< - T['_output'] | null, - ZodNullableDef, - T['_input'] | null -> { - dereference(defs: Record): ZodType { - return new ZodNullable({ +import type { IZodNullable, IZodType, ZodNullableDef } from '../../typings' +import { OK, ParseInput, ParseReturnType, ZodBaseTypeImpl } from '../basetype' + +export class ZodNullableImpl + extends ZodBaseTypeImpl, T['_input'] | null> + implements IZodNullable +{ + dereference(defs: Record): ZodBaseTypeImpl { + return new ZodNullableImpl({ ...this._def, innerType: this._def.innerType.dereference(defs), }) @@ -30,11 +16,11 @@ export class ZodNullable extends ZodType< return this._def.innerType.getReferences() } - clone(): ZodNullable { - return new ZodNullable({ + clone(): IZodNullable { + return new ZodNullableImpl({ ...this._def, - innerType: this._def.innerType.clone(), - }) as ZodNullable + innerType: this._def.innerType.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { @@ -42,23 +28,15 @@ export class ZodNullable extends ZodType< if (parsedType === 'null') { return OK(null) } - return this._def.innerType._parse(input) + return ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse(input) } unwrap() { return this._def.innerType } - static create = (type: T, params?: RawCreateParams): ZodNullable => { - return new ZodNullable({ - innerType: type, - typeName: 'ZodNullable', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodNullable)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodNullableImpl)) return false return this._def.innerType.isEqual(schema._def.innerType) } @@ -66,8 +44,8 @@ export class ZodNullable extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodNullable { - return new ZodNullable({ + mandatory(): IZodNullable { + return new ZodNullableImpl({ ...this._def, innerType: this._def.innerType.mandatory(), }) diff --git a/packages/zui/src/z/types/nullable/nullable.test.ts b/packages/zui/src/z/types/nullable/nullable.test.ts index d81de983055..812701faad9 100644 --- a/packages/zui/src/z/types/nullable/nullable.test.ts +++ b/packages/zui/src/z/types/nullable/nullable.test.ts @@ -2,16 +2,26 @@ import { test, expect } from 'vitest' import * as z from '../../index' function checkErrors(a: z.ZodType, bad: any) { - let expected + let expected: z.ZodError | undefined = undefined try { a.parse(bad) } catch (error) { expected = error as z.ZodError } + + let actual: z.ZodError | undefined = undefined try { - a.nullable().parse(bad) + a.optional().parse(bad) } catch (error) { - expect(error as z.ZodError).toEqual(expected) + actual = error as z.ZodError + } + + const actualErrors = actual?.errors || [] + const expectedErrors = expected?.errors || [] + + expect(actualErrors.length).toEqual(expectedErrors.length) + for (let i = 0; i < expectedErrors.length; i++) { + expect(actualErrors[i]).toEqual(expectedErrors[i]) } } @@ -36,5 +46,5 @@ test('Should have error messages appropriate for the underlying type', () => { test('unwrap', () => { const unwrapped = z.string().nullable().unwrap() - expect(unwrapped).toBeInstanceOf(z.ZodString) + expect(unwrapped.typeName).toBe('ZodString') }) diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 546b6e8ca4f..56abc86e8c8 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,9 +1,7 @@ +import { type IZodNumber, ZodNumberCheck, ZodNumberDef } from '../../typings' import * as utils from '../../utils' import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseContext, @@ -12,21 +10,9 @@ import { ParseStatus, } from '../basetype' -export type ZodNumberCheck = - | { kind: 'min'; value: number; inclusive: boolean; message?: string } - | { kind: 'max'; value: number; inclusive: boolean; message?: string } - | { kind: 'int'; message?: string } - | { kind: 'multipleOf'; value: number; message?: string } - | { kind: 'finite'; message?: string } // https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034 -export type ZodNumberDef = { - checks: ZodNumberCheck[] - typeName: 'ZodNumber' - coerce: boolean -} & ZodTypeDef - -export class ZodNumber extends ZodType { +export class ZodNumberImpl extends ZodBaseTypeImpl implements IZodNumber { _parse(input: ParseInput): ParseReturnType { if (this._def.coerce) { input.data = Number(input.data) @@ -112,15 +98,6 @@ export class ZodNumber extends ZodType { return { status: status.value, value: input.data } } - static create = (params?: RawCreateParams & { coerce?: boolean }): ZodNumber => { - return new ZodNumber({ - checks: [], - typeName: 'ZodNumber', - coerce: params?.coerce || false, - ...processCreateParams(params), - }) - } - gte(value: number, message?: utils.errors.ErrMessage) { return this.setLimit('min', value, true, utils.errors.toString(message)) } @@ -140,7 +117,7 @@ export class ZodNumber extends ZodType { } protected setLimit(kind: 'min' | 'max', value: number, inclusive: boolean, message?: string) { - return new ZodNumber({ + return new ZodNumberImpl({ ...this._def, checks: [ ...this._def.checks, @@ -155,7 +132,7 @@ export class ZodNumber extends ZodType { } _addCheck(check: ZodNumberCheck) { - return new ZodNumber({ + return new ZodNumberImpl({ ...this._def, checks: [...this._def.checks, check], }) @@ -275,8 +252,8 @@ export class ZodNumber extends ZodType { return Number.isFinite(min) && Number.isFinite(max) } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodNumber)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodNumberImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index d8e54d1e4f0..170954185a3 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,118 +1,42 @@ +import { builders } from '../../internal-builders' +import { ZodNativeType } from '../../native' +import type { + IZodObject, + IZodType, + ZodObjectDef, + UnknownKeysParam, + ZodRawShape, + ObjectOutputType, + ObjectInputType, + AdditionalProperties, + Deoptional, + KeyOfObject, + IZodOptional, + IZodEnum, +} from '../../typings' import * as utils from '../../utils' -import { ZodAny } from '../any' -import { ZodArray } from '../array' import { addIssueToContext, INVALID, ParseInput, - ParseReturnType, ParseStatus, ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, type MergeObjectPair, + ParseReturnType, } from '../basetype' -// TODO(circle): these may potentially cause circular dependencies errors -import { ZodEnum } from '../enum' -import { ZodNever } from '../never' -import { ZodNullable } from '../nullable' -import { ZodOptional } from '../optional' -import { ZodTuple, type ZodTupleItems } from '../tuple' - -export type ZodRawShape = { [k: string]: ZodType } - -export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | ZodType - -export type ZodObjectDef< - T extends ZodRawShape = ZodRawShape, - UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = { - typeName: 'ZodObject' - shape: () => T - unknownKeys: UnknownKeys -} & ZodTypeDef - -type _ObjectOutputType< - Shape extends ZodRawShape, - UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = _UnknownKeysOutputType & - utils.types.Flatten>> - -type _BaseObjectOutputType = { - [k in keyof Shape]: Shape[k]['_output'] -} +export class ZodObjectImpl< + T extends ZodRawShape = ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, + Output = ObjectOutputType, + Input = ObjectInputType, + > + extends ZodBaseTypeImpl, Input> + implements IZodObject +{ + /** Safe cast: ZodObject structurally satisfies IZodObject but TS can't prove it due to recursive type depth */ -type _ObjectInputType< - Shape extends ZodRawShape, - UnknownKeys extends UnknownKeysParam = UnknownKeysParam, -> = utils.types.Flatten<_BaseObjectInputType> & _UnknownKeysInputType - -type _BaseObjectInputType = utils.types.AddQuestionMarks<{ - [k in keyof Shape]: Shape[k]['_input'] -}> - -type _UnknownKeysInputType = T extends ZodType - ? { [k: string]: T['_input'] | unknown } // extra properties cannot contradict the main properties - : T extends 'passthrough' - ? { [k: string]: unknown } - : {} - -type _UnknownKeysOutputType = T extends ZodType - ? { [k: string]: T['_output'] | unknown } // extra properties cannot contradict the main properties - : T extends 'passthrough' - ? { [k: string]: unknown } - : {} - -type _AdditionalProperties = T extends ZodType - ? T - : T extends 'passthrough' - ? ZodAny - : T extends 'strict' - ? ZodNever - : undefined - -type _Deoptional = - T extends ZodOptional ? _Deoptional : T extends ZodNullable ? ZodNullable<_Deoptional> : T - -/** - * @deprecated use ZodObject instead - */ -export type SomeZodObject = ZodObject - -/** - * @deprecated use ZodObject instead - */ -export type AnyZodObject = ZodObject - -type _KeyOfObject = utils.types.Cast, [string, ...string[]]> - -type _DeepPartial = T extends ZodObject - ? ZodObject<{ [k in keyof T['shape']]: ZodOptional<_DeepPartial> }, T['_def']['unknownKeys']> - : T extends ZodArray - ? ZodArray<_DeepPartial, Card> - : T extends ZodOptional - ? ZodOptional<_DeepPartial> - : T extends ZodNullable - ? ZodNullable<_DeepPartial> - : T extends ZodTuple - ? { - [k in keyof Items]: Items[k] extends ZodType ? _DeepPartial : never - } extends infer PI - ? PI extends ZodTupleItems - ? ZodTuple - : never - : never - : T - -export class ZodObject< - T extends ZodRawShape = ZodRawShape, - UnknownKeys extends UnknownKeysParam = UnknownKeysParam, - Output = _ObjectOutputType, - Input = _ObjectInputType, -> extends ZodType, Input> { private _cached: { shape: T; keys: string[] } | null = null _getCached(): { shape: T; keys: string[] } { @@ -122,13 +46,13 @@ export class ZodObject< return (this._cached = { shape, keys }) } - dereference(defs: Record): ZodType { + dereference(defs: Record): IZodType { const currentShape = this._def.shape() - const shape: Record = {} + const shape: Record = {} for (const key in currentShape) { shape[key] = currentShape[key]!.dereference(defs) } - return new ZodObject({ + return new ZodObjectImpl({ ...this._def, shape: () => shape, }) @@ -143,16 +67,18 @@ export class ZodObject< return utils.fn.unique(refs) } - clone(): ZodObject { - const newShape: Record = {} + clone(): IZodObject { + const newShape: Record = {} const currentShape = this._def.shape() for (const [key, value] of Object.entries(currentShape)) { newShape[key] = value.clone() } - return new ZodObject({ + const objSchema = new ZodObjectImpl({ ...this._def, - shape: () => newShape, - }) as ZodObject + shape: () => newShape as T, + }) + + return objSchema } _parse(input: ParseInput): ParseReturnType { @@ -190,7 +116,7 @@ export class ZodObject< const value = ctx.data[key] pairs.push({ key: { status: 'valid', value: key }, - value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), + value: ZodBaseTypeImpl.fromInterface(keyValidator)._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), alwaysSet: key in ctx.data, }) } @@ -218,7 +144,7 @@ export class ZodObject< const value = ctx.data[key] pairs.push({ key: { status: 'valid', value: key }, - value: unknownKeys._parse( + value: ZodBaseTypeImpl.fromInterface(unknownKeys)._parse( new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value) ), alwaysSet: key in ctx.data, @@ -252,9 +178,9 @@ export class ZodObject< return this._def.shape() } - strict(message?: utils.errors.ErrMessage): ZodObject { + strict(message?: utils.errors.ErrMessage): IZodObject { utils.errors.errToObj - return new ZodObject({ + return new ZodObjectImpl({ ...this._def, unknownKeys: 'strict', ...(message !== undefined @@ -275,34 +201,34 @@ export class ZodObject< }) } - strip(): ZodObject { - return new ZodObject({ + strip(): IZodObject { + return new ZodObjectImpl({ ...this._def, unknownKeys: 'strip', }) } - passthrough(): ZodObject { - return new ZodObject({ + passthrough(): IZodObject { + return new ZodObjectImpl({ ...this._def, unknownKeys: 'passthrough', }) } /** - * @returns The ZodType that is used to validate additional properties or undefined if extra keys are stripped. + * @returns The IZodType that is used to validate additional properties or undefined if extra keys are stripped. */ - additionalProperties(): _AdditionalProperties { - if (this._def.unknownKeys instanceof ZodType) { - return this._def.unknownKeys as _AdditionalProperties + additionalProperties(): AdditionalProperties { + if (typeof this._def.unknownKeys === 'object') { + return this._def.unknownKeys as AdditionalProperties } if (this._def.unknownKeys === 'passthrough') { - return ZodAny.create() as _AdditionalProperties + return builders.any() as unknown as AdditionalProperties } if (this._def.unknownKeys === 'strict') { - return ZodNever.create() as _AdditionalProperties + return builders.never() as unknown as AdditionalProperties } - return undefined as _AdditionalProperties + return undefined as AdditionalProperties } /** @@ -315,29 +241,29 @@ export class ZodObject< // (def: Def) => // ( // augmentation: Augmentation - // ): ZodObject< + // ): IZodObject< // extendShape, Augmentation>, // Def["unknownKeys"], // Def["catchall"] // > => { - // return new ZodObject({ + // return (new ZodObjectImpl({ // ...def, // shape: () => ({ // ...def.shape(), // ...augmentation, // }), - // }) + // })) // }; extend( augmentation: Augmentation - ): ZodObject, UnknownKeys> { - return new ZodObject({ + ): IZodObject, UnknownKeys> { + return new ZodObjectImpl({ ...this._def, shape: () => ({ ...this._def.shape(), ...augmentation, }), - }) + }) as unknown as IZodObject, UnknownKeys> } // extend< // Augmentation extends ZodRawShape, @@ -357,20 +283,20 @@ export class ZodObject< // }> // >( // augmentation: Augmentation - // ): ZodObject< + // ): IZodObject< // extendShape, // UnknownKeys, // Catchall, // NewOutput, // NewInput // > { - // return new ZodObject({ + // return (new ZodObjectImpl({ // ...this._def, // shape: () => ({ // ...this._def.shape(), // ...augmentation, // }), - // }) + // })) // } /** * @deprecated Use `.extend` instead @@ -382,10 +308,10 @@ export class ZodObject< * inferred type of merged objects. Please * upgrade if you are experiencing issues. */ - merge( + merge, Augmentation extends Incoming['shape']>( merging: Incoming - ): ZodObject, Incoming['_def']['unknownKeys']> { - const merged: any = new ZodObject({ + ): IZodObject, Incoming['_def']['unknownKeys']> { + const merged: any = new ZodObjectImpl({ unknownKeys: merging._def.unknownKeys, shape: () => ({ ...this._def.shape(), @@ -414,14 +340,14 @@ export class ZodObject< // } // >( // merging: Incoming - // ): ZodObject< + // ): IZodObject< // extendShape>, // Incoming["_def"]["unknownKeys"], // Incoming["_def"]["catchall"], // NewOutput, // NewInput // > { - // const merged: any = new ZodObject({ + // const merged: any = new ZodObjectImpl({ // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => @@ -430,16 +356,16 @@ export class ZodObject< // }); // return merged; // } - setKey( + setKey( key: Key, schema: Schema - ): ZodObject< + ): IZodObject< T & { [k in Key]: Schema }, UnknownKeys > { - return this.augment({ [key]: schema }) as ZodObject< + return this.augment({ [key]: schema }) as unknown as IZodObject< T & { [k in Key]: Schema }, @@ -458,7 +384,7 @@ export class ZodObject< // // this._def.shape(), // // merging._def.shape() // // ); - // const merged: any = new ZodObject({ + // const merged: any = new ZodObjectImpl({ // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => @@ -467,8 +393,8 @@ export class ZodObject< // }); // return merged; // } - catchall(index: Index): ZodObject { - return new ZodObject({ + catchall(index: Index): IZodObject { + return new ZodObjectImpl({ ...this._def, unknownKeys: index, }) @@ -478,7 +404,7 @@ export class ZodObject< Mask extends { [k in keyof T]?: true }, - >(mask: Mask): ZodObject>, UnknownKeys> { + >(mask: Mask): IZodObject>, UnknownKeys> { const shape: any = {} Object.keys(mask).forEach((key) => { @@ -487,17 +413,19 @@ export class ZodObject< } }) - return new ZodObject({ + const objSchema: IZodObject>, UnknownKeys> = new ZodObjectImpl({ ...this._def, - shape: () => shape, + shape: () => shape as Pick>, }) + + return objSchema } omit< Mask extends { [k in keyof T]?: true }, - >(mask: Mask): ZodObject, UnknownKeys> { + >(mask: Mask): IZodObject, UnknownKeys> { const shape: any = {} Object.keys(this.shape).forEach((key) => { @@ -506,22 +434,24 @@ export class ZodObject< } }) - return new ZodObject({ + const objSchema: IZodObject, UnknownKeys> = new ZodObjectImpl({ ...this._def, - shape: () => shape, + shape: () => shape as Omit, }) + + return objSchema } /** * @deprecated */ - deepPartial(): _DeepPartial { + deepPartial(): any { return this._deepPartialify(this) } - partial(): ZodObject< + partial(): IZodObject< { - [k in keyof T]: ZodOptional + [k in keyof T]: IZodOptional }, UnknownKeys > @@ -531,14 +461,14 @@ export class ZodObject< }, >( mask: Mask - ): ZodObject< + ): IZodObject< utils.types.NoNever<{ - [k in keyof T]: k extends keyof Mask ? ZodOptional : T[k] + [k in keyof T]: k extends keyof Mask ? IZodOptional : T[k] }>, UnknownKeys > - partial(mask?: any) { - const newShape: Record = {} + partial(mask?: any): IZodObject { + const newShape: Record = {} Object.keys(this.shape).forEach((key) => { const fieldSchema = this.shape[key] @@ -550,15 +480,17 @@ export class ZodObject< } }) - return new ZodObject({ + const objSchema: IZodObject = new ZodObjectImpl({ ...this._def, shape: () => newShape as ZodRawShape, }) + + return objSchema } - required(): ZodObject< + required(): IZodObject< { - [k in keyof T]: _Deoptional + [k in keyof T]: Deoptional }, UnknownKeys > @@ -568,13 +500,13 @@ export class ZodObject< }, >( mask: Mask - ): ZodObject< + ): IZodObject< utils.types.NoNever<{ - [k in keyof T]: k extends keyof Mask ? _Deoptional : T[k] + [k in keyof T]: k extends keyof Mask ? Deoptional : T[k] }>, UnknownKeys > - required(mask?: any) { + required(mask?: any): IZodObject { const newShape: any = {} Object.keys(this.shape).forEach((key) => { @@ -582,35 +514,35 @@ export class ZodObject< newShape[key] = this.shape[key] } else { const fieldSchema = this.shape[key] - let newField = fieldSchema + let newField = fieldSchema as ZodNativeType - while (newField instanceof ZodOptional) { - newField = (newField as ZodOptional)._def.innerType + while (newField.typeName === 'ZodOptional') { + newField = (newField as IZodOptional)._def.innerType } newShape[key] = newField } }) - return new ZodObject({ + return new ZodObjectImpl({ ...this._def, shape: () => newShape, }) } - keyof(): ZodEnum<_KeyOfObject> { - const keys = Object.keys(this.shape) as _KeyOfObject - return ZodEnum.create(keys) as ZodEnum<_KeyOfObject> + keyof(): IZodEnum> { + const keys = Object.keys(this.shape) as [string, ...string[]] + return builders.enum(keys) as IZodEnum } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodObject)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodObjectImpl)) return false if (!this._unknownKeysEqual(schema)) return false const thisShape = this._def.shape() const thatShape = schema._def.shape() - type Property = [string, ZodType] + type Property = [string, IZodType] const compare = (a: Property, b: Property) => a[0] === b[0] && a[1].isEqual(b[1]) const thisProps = new utils.ds.CustomSet(Object.entries(thisShape), { compare }) const thatProps = new utils.ds.CustomSet(Object.entries(thatShape), { compare }) @@ -618,7 +550,7 @@ export class ZodObject< return thisProps.isEqual(thatProps) } - private _unknownKeysEqual(that: ZodObject): boolean { + private _unknownKeysEqual(that: IZodObject): boolean { const thisAdditionalProperties = this.additionalProperties() const thatAdditionalProperties = that.additionalProperties() if (thisAdditionalProperties === undefined || thatAdditionalProperties === undefined) { @@ -627,56 +559,31 @@ export class ZodObject< return thisAdditionalProperties.isEqual(thatAdditionalProperties) } - static create = (shape: T, params?: RawCreateParams): ZodObject => { - return new ZodObject({ - shape: () => shape, - unknownKeys: 'strip', - typeName: 'ZodObject', - ...processCreateParams(params), - }) - } - - static strictCreate = (shape: T, params?: RawCreateParams): ZodObject => { - return new ZodObject({ - shape: () => shape, - unknownKeys: 'strict', - typeName: 'ZodObject', - ...processCreateParams(params), - }) - } - - static lazycreate = (shape: () => T, params?: RawCreateParams): ZodObject => { - return new ZodObject({ - shape, - unknownKeys: 'strip', - typeName: 'ZodObject', - ...processCreateParams(params), - }) - } + private _deepPartialify(_schema: IZodType): IZodType { + const schema = _schema as ZodNativeType + if (schema.typeName === 'ZodObject') { + const newShape: Record = {} - private _deepPartialify(schema: ZodType): any { - if (schema instanceof ZodObject) { - const newShape: any = {} - - for (const key in schema.shape) { - const fieldSchema = schema.shape[key] - newShape[key] = ZodOptional.create(this._deepPartialify(fieldSchema)) + for (const [key, fieldSchema] of Object.entries(schema.shape)) { + newShape[key] = builders.optional(this._deepPartialify(fieldSchema)) } - return new ZodObject({ + + return new ZodObjectImpl({ ...schema._def, shape: () => newShape, }) - } else if (schema instanceof ZodArray) { - return new ZodArray({ - ...schema._def, - type: this._deepPartialify(schema.element), - }) - } else if (schema instanceof ZodOptional) { - return ZodOptional.create(this._deepPartialify(schema.unwrap())) - } else if (schema instanceof ZodNullable) { - return ZodNullable.create(this._deepPartialify(schema.unwrap())) - } else if (schema instanceof ZodTuple) { - return ZodTuple.create(schema.items.map((item: any) => this._deepPartialify(item))) + } else if (schema.typeName === 'ZodArray') { + const element = this._deepPartialify(schema.element) + const newArray = schema.clone() + newArray._def.type = element // TODO: allow cloning with modifications to avoid this mutation + return newArray + } else if (schema.typeName === 'ZodOptional') { + return builders.optional(this._deepPartialify(schema.unwrap())) + } else if (schema.typeName === 'ZodNullable') { + return builders.nullable(this._deepPartialify(schema.unwrap())) + } else if (schema.typeName === 'ZodTuple') { + const partialItems = schema.items.map((item) => this._deepPartialify(item)) as [IZodType, ...IZodType[]] + return builders.tuple(partialItems) } else { return schema } diff --git a/packages/zui/src/z/types/object/object.test.ts b/packages/zui/src/z/types/object/object.test.ts index 736ab17e806..0ecf891f089 100644 --- a/packages/zui/src/z/types/object/object.test.ts +++ b/packages/zui/src/z/types/object/object.test.ts @@ -32,10 +32,10 @@ test('shape() should return schema of particular key', () => { const f3Schema = Test.shape.f3 const f4Schema = Test.shape.f4 - expect(f1Schema).toBeInstanceOf(z.ZodNumber) - expect(f2Schema).toBeInstanceOf(z.ZodOptional) - expect(f3Schema).toBeInstanceOf(z.ZodNullable) - expect(f4Schema).toBeInstanceOf(z.ZodArray) + expect(f1Schema.typeName).toBe('ZodNumber') + expect(f2Schema.typeName).toBe('ZodOptional') + expect(f3Schema.typeName).toBe('ZodNullable') + expect(f4Schema.typeName).toBe('ZodArray') }) test('correct parsing', () => { @@ -369,7 +369,7 @@ test('unknownkeys merging', () => { type mergedSchema = typeof mergedSchema utils.assert.assertEqual(true) - expect(mergedSchema._def.unknownKeys instanceof z.ZodString).toEqual(true) + expect(mergedSchema._def.unknownKeys.typeName).toBe('ZodString') }) const personToExtend = z.object({ diff --git a/packages/zui/src/z/types/optional/index.ts b/packages/zui/src/z/types/optional/index.ts index e47dd736168..99655809604 100644 --- a/packages/zui/src/z/types/optional/index.ts +++ b/packages/zui/src/z/types/optional/index.ts @@ -1,26 +1,12 @@ -import { - // - processCreateParams, - RawCreateParams, - ZodType, - ZodTypeDef, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' - -export type ZodOptionalDef = { - innerType: T - typeName: 'ZodOptional' -} & ZodTypeDef - -export class ZodOptional extends ZodType< - T['_output'] | undefined, - ZodOptionalDef, - T['_input'] | undefined -> { - dereference(defs: Record): ZodType { - return new ZodOptional({ +import type { IZodOptional, IZodType, ZodOptionalDef } from '../../typings' +import { ZodBaseTypeImpl, OK, ParseInput, ParseReturnType } from '../basetype' + +export class ZodOptionalImpl + extends ZodBaseTypeImpl, T['_input'] | undefined> + implements IZodOptional +{ + dereference(defs: Record): IZodType { + return new ZodOptionalImpl({ ...this._def, innerType: this._def.innerType.dereference(defs), }) @@ -30,11 +16,11 @@ export class ZodOptional extends ZodType< return this._def.innerType.getReferences() } - clone(): ZodOptional { - return new ZodOptional({ + clone(): IZodOptional { + return new ZodOptionalImpl({ ...this._def, - innerType: this._def.innerType.clone(), - }) as ZodOptional + innerType: this._def.innerType.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { @@ -42,23 +28,15 @@ export class ZodOptional extends ZodType< if (parsedType === 'undefined') { return OK(undefined) } - return this._def.innerType._parse(input) + return ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse(input) } unwrap() { return this._def.innerType } - static create = (type: T, params?: RawCreateParams): ZodOptional => { - return new ZodOptional({ - innerType: type, - typeName: 'ZodOptional', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodOptional)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodOptionalImpl)) return false return this._def.innerType.isEqual(schema._def.innerType) } @@ -66,7 +44,7 @@ export class ZodOptional extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodType { + mandatory(): IZodType { return this._def.innerType.mandatory() } } diff --git a/packages/zui/src/z/types/optional/optional.test.ts b/packages/zui/src/z/types/optional/optional.test.ts index d81ec727711..506c8c2c1ad 100644 --- a/packages/zui/src/z/types/optional/optional.test.ts +++ b/packages/zui/src/z/types/optional/optional.test.ts @@ -2,16 +2,26 @@ import { test, expect } from 'vitest' import * as z from '../../index' function checkErrors(a: z.ZodType, bad: any) { - let expected + let expected: z.ZodError | undefined = undefined try { a.parse(bad) } catch (error) { expected = error as z.ZodError } + + let actual: z.ZodError | undefined = undefined try { a.optional().parse(bad) } catch (error) { - expect(error as z.ZodError).toEqual(expected) + actual = error as z.ZodError + } + + const actualErrors = actual?.errors || [] + const expectedErrors = expected?.errors || [] + + expect(actualErrors.length).toEqual(expectedErrors.length) + for (let i = 0; i < expectedErrors.length; i++) { + expect(actualErrors[i]).toEqual(expectedErrors[i]) } } @@ -36,5 +46,5 @@ test('Should have error messages appropriate for the underlying type', () => { test('unwrap', () => { const unwrapped = z.string().optional().unwrap() - expect(unwrapped).toBeInstanceOf(z.ZodString) + expect(unwrapped.typeName).toBe('ZodString') }) diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index 7c849784529..ae7b2291d49 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,19 +1,14 @@ +import type { IZodPipeline, IZodType, ZodPipelineDef } from '../../typings' import * as utils from '../../utils' -import { ZodType, ZodTypeDef, DIRTY, INVALID, ParseInput, ParseReturnType } from '../basetype' +import { ZodBaseTypeImpl, DIRTY, INVALID, ParseInput, ParseReturnType } from '../basetype' +export type { ZodPipelineDef } -export type ZodPipelineDef = { - in: A - out: B - typeName: 'ZodPipeline' -} & ZodTypeDef - -export class ZodPipeline extends ZodType< - B['_output'], - ZodPipelineDef, - A['_input'] -> { - dereference(defs: Record): ZodType { - return new ZodPipeline({ +export class ZodPipelineImpl + extends ZodBaseTypeImpl, A['_input']> + implements IZodPipeline +{ + dereference(defs: Record): ZodBaseTypeImpl { + return new ZodPipelineImpl({ ...this._def, in: this._def.in.dereference(defs), out: this._def.out.dereference(defs), @@ -24,19 +19,19 @@ export class ZodPipeline { - return new ZodPipeline({ + clone(): IZodPipeline { + return new ZodPipelineImpl({ ...this._def, - in: this._def.in.clone(), - out: this._def.out.clone(), - }) as ZodPipeline + in: this._def.in.clone() as A, + out: this._def.out.clone() as B, + }) } _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) if (ctx.common.async) { const handleAsync = async () => { - const inResult = await this._def.in._parseAsync({ + const inResult = await ZodBaseTypeImpl.fromInterface(this._def.in)._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -46,7 +41,7 @@ export class ZodPipeline(a: A, b: B): ZodPipeline { - return new ZodPipeline({ - in: a, - out: b, - typeName: 'ZodPipeline', - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodPipeline)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodPipelineImpl)) return false if (!this._def.in.isEqual(schema._def.in)) return false if (!this._def.out.isEqual(schema._def.out)) return false return true diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index dcda2b68922..7fc7d3b11b1 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -1,31 +1,17 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' - -export type ZodPromiseDef = { - type: T - typeName: 'ZodPromise' -} & ZodTypeDef - -export class ZodPromise extends ZodType< - Promise, - ZodPromiseDef, - Promise -> { +import type { IZodPromise, IZodType, ZodPromiseDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' +export type { ZodPromiseDef } + +export class ZodPromiseImpl + extends ZodBaseTypeImpl, ZodPromiseDef, Promise> + implements IZodPromise +{ unwrap() { return this._def.type } - dereference(defs: Record): ZodType { - return new ZodPromise({ + dereference(defs: Record): IZodType { + return new ZodPromiseImpl({ ...this._def, type: this._def.type.dereference(defs), }) @@ -35,11 +21,11 @@ export class ZodPromise extends ZodType< return this._def.type.getReferences() } - clone(): ZodPromise { - return new ZodPromise({ + clone(): IZodPromise { + return new ZodPromiseImpl({ ...this._def, - type: this._def.type.clone(), - }) as ZodPromise + type: this._def.type.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { @@ -65,16 +51,8 @@ export class ZodPromise extends ZodType< ) } - static create = (schema: T, params?: RawCreateParams): ZodPromise => { - return new ZodPromise({ - type: schema, - typeName: 'ZodPromise', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodPromise)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodPromiseImpl)) return false return this._def.type.isEqual(schema._def.type) } diff --git a/packages/zui/src/z/types/promise/promise.test.ts b/packages/zui/src/z/types/promise/promise.test.ts index 90779818f10..3fc4b2dff65 100644 --- a/packages/zui/src/z/types/promise/promise.test.ts +++ b/packages/zui/src/z/types/promise/promise.test.ts @@ -1,6 +1,7 @@ import { test, expect } from 'vitest' import * as utils from '../../utils' import * as z from '../../index' +import { ZodError } from '../../error' const promSchema = z.promise( z.object({ @@ -38,13 +39,13 @@ test('promise parsing success 2', () => { test('promise parsing fail', async () => { const bad = promSchema.parse(Promise.resolve({ name: 'Bobby', age: '10' })) // return await expect(bad).resolves.toBe({ name: 'Bobby', age: '10' }); - return await expect(bad).rejects.toBeInstanceOf(z.ZodError) + return await expect(bad).rejects.toBeInstanceOf(ZodError) // done(); }) test('promise parsing fail 2', async () => { const failPromise = promSchema.parse(Promise.resolve({ name: 'Bobby', age: '10' })) - await expect(failPromise).rejects.toBeInstanceOf(z.ZodError) + await expect(failPromise).rejects.toBeInstanceOf(ZodError) // done();/z }) @@ -73,7 +74,7 @@ test('async function fail', async () => { const validatedFunction = asyncFunction.implement(() => { return Promise.resolve('asdf' as any) }) - await expect(validatedFunction()).rejects.toBeInstanceOf(z.ZodError) + await expect(validatedFunction()).rejects.toBeInstanceOf(ZodError) }) test('async promise parsing', () => { diff --git a/packages/zui/src/z/types/readonly/index.ts b/packages/zui/src/z/types/readonly/index.ts index f2921899392..aba699bd779 100644 --- a/packages/zui/src/z/types/readonly/index.ts +++ b/packages/zui/src/z/types/readonly/index.ts @@ -1,47 +1,12 @@ -import { - processCreateParams, - RawCreateParams, - ZodType, - ZodTypeDef, - isValid, - ParseInput, - ParseReturnType, -} from '../basetype' - -type _BuiltIn = - | (((...args: any[]) => any) | (new (...args: any[]) => any)) - | { readonly [Symbol.toStringTag]: string } - | Date - | Error - | Generator - | Promise - | RegExp - -type _MakeReadonly = - T extends Map - ? ReadonlyMap - : T extends Set - ? ReadonlySet - : T extends [infer Head, ...infer Tail] - ? readonly [Head, ...Tail] - : T extends Array - ? ReadonlyArray - : T extends _BuiltIn - ? T - : Readonly - -export type ZodReadonlyDef = { - innerType: T - typeName: 'ZodReadonly' -} & ZodTypeDef - -export class ZodReadonly extends ZodType< - _MakeReadonly, - ZodReadonlyDef, - _MakeReadonly -> { - dereference(defs: Record): ZodType { - return new ZodReadonly({ +import type { IZodReadonly, IZodType, MakeReadonly, ZodReadonlyDef } from '../../typings' +import { ZodBaseTypeImpl, isValid, ParseInput, ParseReturnType } from '../basetype' + +export class ZodReadonlyImpl + extends ZodBaseTypeImpl, ZodReadonlyDef, MakeReadonly> + implements IZodReadonly +{ + dereference(defs: Record): ZodBaseTypeImpl { + return new ZodReadonlyImpl({ ...this._def, innerType: this._def.innerType.dereference(defs), }) @@ -51,35 +16,27 @@ export class ZodReadonly extends ZodType< return this._def.innerType.getReferences() } - clone(): ZodReadonly { - return new ZodReadonly({ + clone(): IZodReadonly { + return new ZodReadonlyImpl({ ...this._def, - innerType: this._def.innerType.clone(), - }) as ZodReadonly + innerType: this._def.innerType.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { - const result = this._def.innerType._parse(input) + const result = ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse(input) if (isValid(result)) { result.value = Object.freeze(result.value) } return result } - static create = (type: T, params?: RawCreateParams): ZodReadonly => { - return new ZodReadonly({ - innerType: type, - typeName: 'ZodReadonly', - ...processCreateParams(params), - }) - } - unwrap() { return this._def.innerType } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodReadonly)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodReadonlyImpl)) return false return this._def.innerType.isEqual(schema._def.innerType) } @@ -87,8 +44,8 @@ export class ZodReadonly extends ZodType< return this._def.innerType.naked() } - mandatory(): ZodReadonly { - return new ZodReadonly({ + mandatory(): IZodReadonly { + return new ZodReadonlyImpl({ ...this._def, innerType: this._def.innerType.mandatory(), }) diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 5df9ae2c38b..8195c81d25b 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,10 +1,8 @@ +import type { IZodRecord, IZodString, IZodType, KeySchema, RecordType, ZodRecordDef } from '../../typings' import * as utils from '../../utils' import { ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, @@ -13,33 +11,14 @@ import { type MergeObjectPair, } from '../basetype' -// TODO(circle): these may potentially cause circular dependencies errors -import { BRAND } from '../branded' -import { ZodString } from '../string' - -export type ZodRecordDef = { - valueType: Value - keyType: Key - typeName: 'ZodRecord' -} & ZodTypeDef - -type _KeySchema = ZodType - -type _RecordType = [string] extends [K] - ? Record - : [number] extends [K] - ? Record - : [symbol] extends [K] - ? Record - : [BRAND] extends [K] - ? Record - : Partial> - -export class ZodRecord extends ZodType< - _RecordType, - ZodRecordDef, - _RecordType -> { +export class ZodRecordImpl + extends ZodBaseTypeImpl< + RecordType, + ZodRecordDef, + RecordType + > + implements IZodRecord +{ get keySchema() { return this._def.keyType } @@ -47,10 +26,10 @@ export class ZodRecord): ZodType { + dereference(defs: Record): IZodType { const keyType = this._def.keyType.dereference(defs) const valueType = this._def.valueType.dereference(defs) - return new ZodRecord({ + return new ZodRecordImpl({ ...this._def, keyType, valueType, @@ -61,12 +40,12 @@ export class ZodRecord { - return new ZodRecord({ + clone(): IZodRecord { + return new ZodRecordImpl({ ...this._def, - keyType: this._def.keyType.clone(), - valueType: this._def.valueType.clone(), - }) as ZodRecord + keyType: this._def.keyType.clone() as Key, + valueType: this._def.valueType.clone() as Value, + }) } _parse(input: ParseInput): ParseReturnType { @@ -90,8 +69,10 @@ export class ZodRecord(valueType: Value, params?: RawCreateParams): ZodRecord - static create( - keySchema: Keys, - valueType: Value, - params?: RawCreateParams - ): ZodRecord - static create(first: any, second?: any, third?: any): ZodRecord { - if (second instanceof ZodType) { - return new ZodRecord({ - keyType: first, - valueType: second, - typeName: 'ZodRecord', - ...processCreateParams(third), - }) - } - - return new ZodRecord({ - keyType: ZodString.create(), - valueType: first, - typeName: 'ZodRecord', - ...processCreateParams(second), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodRecord)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodRecordImpl)) return false if (!this._def.keyType.isEqual(schema._def.keyType)) return false if (!this._def.valueType.isEqual(schema._def.valueType)) return false return true diff --git a/packages/zui/src/z/types/ref/index.ts b/packages/zui/src/z/types/ref/index.ts index f7e6281572e..63fbcbc5c3d 100644 --- a/packages/zui/src/z/types/ref/index.ts +++ b/packages/zui/src/z/types/ref/index.ts @@ -1,25 +1,21 @@ +import type { IZodRef, IZodType, ZodRefDef } from '../../typings' import { // - ZodType, - ZodTypeDef, + ZodBaseTypeImpl, INVALID, ParseInput, ParseReturnType, addIssueToContext, } from '../basetype' +export type { ZodRefDef } -export type ZodRefDef = { - typeName: 'ZodRef' - uri: string -} & ZodTypeDef - -export class ZodRef extends ZodType, ZodRefDef> { - dereference(defs: Record): ZodType { +export class ZodRefImpl extends ZodBaseTypeImpl, ZodRefDef> implements IZodRef { + dereference(defs: Record): ZodBaseTypeImpl { const def = defs[this._def.uri] if (!def) { return this } - return def + return def as ZodBaseTypeImpl } getReferences(): string[] { @@ -35,13 +31,6 @@ export class ZodRef extends ZodType, ZodRefDef> { return INVALID } - static create = (uri: string): ZodRef => { - return new ZodRef({ - typeName: 'ZodRef', - uri, - }) - } - public override isOptional(): boolean { return false } @@ -50,8 +39,8 @@ export class ZodRef extends ZodType, ZodRefDef> { return false } - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodRef)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodRefImpl)) return false return this._def.uri === schema._def.uri } } diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index ea84f9aca1c..c71020cbf45 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,10 +1,8 @@ +import type { IZodSet, IZodType, ZodSetDef } from '../../typings' import * as utils from '../../utils' import { ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, @@ -12,20 +10,12 @@ import { SyncParseReturnType, } from '../basetype' -export type ZodSetDef = { - valueType: Value - typeName: 'ZodSet' - minSize: { value: number; message?: string } | null - maxSize: { value: number; message?: string } | null -} & ZodTypeDef - -export class ZodSet extends ZodType< - Set, - ZodSetDef, - Set -> { - dereference(defs: Record): ZodType { - return new ZodSet({ +export class ZodSetImpl + extends ZodBaseTypeImpl, ZodSetDef, Set> + implements IZodSet +{ + dereference(defs: Record): IZodType { + return new ZodSetImpl({ ...this._def, valueType: this._def.valueType.dereference(defs), }) @@ -35,11 +25,11 @@ export class ZodSet extends ZodType< return this._def.valueType.getReferences() } - clone(): ZodSet { - return new ZodSet({ + clone(): IZodSet { + return new ZodSetImpl({ ...this._def, - valueType: this._def.valueType.clone(), - }) as ZodSet + valueType: this._def.valueType.clone() as Value, + }) } _parse(input: ParseInput): ParseReturnType { @@ -96,25 +86,25 @@ export class ZodSet extends ZodType< } const elements = [...(ctx.data as Set).values()].map((item, i) => - valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) + ZodBaseTypeImpl.fromInterface(valueType)._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) ) if (ctx.common.async) { return Promise.all(elements).then((elements) => finalizeSet(elements)) } else { - return finalizeSet(elements as SyncParseReturnType[]) + return finalizeSet(elements as SyncParseReturnType[]) } } min(minSize: number, message?: utils.errors.ErrMessage): this { - return new ZodSet({ + return new ZodSetImpl({ ...this._def, minSize: { value: minSize, message: utils.errors.toString(message) }, }) as this } max(maxSize: number, message?: utils.errors.ErrMessage): this { - return new ZodSet({ + return new ZodSetImpl({ ...this._def, maxSize: { value: maxSize, message: utils.errors.toString(message) }, }) as this @@ -124,22 +114,12 @@ export class ZodSet extends ZodType< return this.min(size, message).max(size, message) as this } - nonempty(message?: utils.errors.ErrMessage): ZodSet { + nonempty(message?: utils.errors.ErrMessage): IZodSet { return this.min(1, message) as this } - static create = (valueType: Value, params?: RawCreateParams): ZodSet => { - return new ZodSet({ - valueType, - minSize: null, - maxSize: null, - typeName: 'ZodSet', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodSet)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodSetImpl)) return false const thisMin = this._def.minSize?.value const thatMin = schema._def.minSize?.value diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index dbbe7241f8b..d25201e8918 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,11 +1,8 @@ -import { zuiKey } from '../../../ui/constants' -import { StringValidation } from '../../error' +import { zuiKey } from '../../consts' +import { type IZodString, ZodStringCheck, ZodStringDef } from '../../typings' import * as utils from '../../utils' import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, INVALID, ParseContext, @@ -14,38 +11,9 @@ import { ParseStatus, } from '../basetype' -export type IpVersion = 'v4' | 'v6' -export type ZodStringCheck = - | { kind: 'min'; value: number; message?: string } - | { kind: 'max'; value: number; message?: string } - | { kind: 'length'; value: number; message?: string } - | { kind: 'email'; message?: string } - | { kind: 'url'; message?: string } - | { kind: 'emoji'; message?: string } - | { kind: 'uuid'; message?: string } - | { kind: 'cuid'; message?: string } - | { kind: 'includes'; value: string; position?: number; message?: string } - | { kind: 'cuid2'; message?: string } - | { kind: 'ulid'; message?: string } - | { kind: 'startsWith'; value: string; message?: string } - | { kind: 'endsWith'; value: string; message?: string } - | { kind: 'regex'; regex: RegExp; message?: string } - | { kind: 'trim'; message?: string } - | { kind: 'toLowerCase'; message?: string } - | { kind: 'toUpperCase'; message?: string } - | { - kind: 'datetime' - offset: boolean - precision: number | null - message?: string - } - | { kind: 'ip'; version?: IpVersion; message?: string } +export type { ZodStringCheck, ZodStringDef } +export type IpVersion = NonNullable['version']> -export type ZodStringDef = { - checks: ZodStringCheck[] - typeName: 'ZodString' - coerce: boolean -} & ZodTypeDef export const cuidRegex = /^c[^\s-]{8,}$/i export const cuid2Regex = /^[a-z][a-z0-9]*$/ export const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/ @@ -77,7 +45,7 @@ function isValidIP(ip: string, version?: IpVersion) { return false } -export class ZodString extends ZodType { +export class ZodStringImpl extends ZodBaseTypeImpl implements IZodString { _parse(input: ParseInput): ParseReturnType { if (this._def.coerce) { input.data = String(input.data) @@ -278,7 +246,7 @@ export class ZodString extends ZodType { status.dirty() } } else if (check.kind === 'datetime') { - const regex = utils.strings.generateDatetimeRegex(check) + const regex = utils.datestring.generateDatetimeRegex(check) if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx) @@ -307,16 +275,8 @@ export class ZodString extends ZodType { return { status: status.value, value: input.data } } - protected _regex(regex: RegExp, validation: StringValidation, message?: utils.errors.ErrMessage) { - return this.refinement((data) => regex.test(data), { - validation, - code: 'invalid_string', - ...utils.errors.errToObj(message), - }) - } - _addCheck(check: ZodStringCheck) { - return new ZodString({ + return new ZodStringImpl({ ...this._def, checks: [...this._def.checks, check], }) @@ -439,7 +399,7 @@ export class ZodString extends ZodType { } trim() { - return new ZodString({ + return new ZodStringImpl({ ...this._def, checks: [...this._def.checks, { kind: 'trim' }], }) @@ -451,14 +411,14 @@ export class ZodString extends ZodType { } toLowerCase() { - return new ZodString({ + return new ZodStringImpl({ ...this._def, checks: [...this._def.checks, { kind: 'toLowerCase' }], }) } toUpperCase() { - return new ZodString({ + return new ZodStringImpl({ ...this._def, checks: [...this._def.checks, { kind: 'toUpperCase' }], }) @@ -512,17 +472,8 @@ export class ZodString extends ZodType { return max } - static create = (params?: RawCreateParams & { coerce?: true }): ZodString => { - return new ZodString({ - checks: [], - typeName: 'ZodString', - coerce: params?.coerce ?? false, - ...processCreateParams({ ...params, supportsExtensions: ['secret'] }), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodString)) return false + isEqual(schema: ZodBaseTypeImpl): boolean { + if (!(schema instanceof ZodStringImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) return thisChecks.isEqual(thatChecks) diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index d5b46860fb0..7c658adf70a 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,20 +1,7 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodSymbol, ZodSymbolDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodSymbolDef = { - typeName: 'ZodSymbol' -} & ZodTypeDef - -export class ZodSymbol extends ZodType { +export class ZodSymbolImpl extends ZodBaseTypeImpl implements IZodSymbol { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'symbol') { @@ -30,14 +17,7 @@ export class ZodSymbol extends ZodType { return OK(input.data) } - static create = (params?: RawCreateParams): ZodSymbol => { - return new ZodSymbol({ - typeName: 'ZodSymbol', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodSymbol + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodSymbolImpl } } diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index eea12897348..f04d6f9ec0d 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -1,46 +1,11 @@ -import { IssueData } from '../../error' +import type { IZodEffects, IZodType, ZodEffectsDef, input, output, RefinementCtx, IssueData } from '../../typings' import * as utils from '../../utils' -import { - input, - output, - RawCreateParams, - RefinementCtx, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - DIRTY, - INVALID, - isValid, - ParseInput, - ParseReturnType, -} from '../basetype' - -export type RefinementEffect = { - type: 'refinement' - refinement: (arg: T, ctx: RefinementCtx) => any -} -export type TransformEffect = { - type: 'transform' - transform: (arg: T, ctx: RefinementCtx) => any -} -export type PreprocessEffect = { - type: 'preprocess' - transform: (arg: T, ctx: RefinementCtx) => any -} -export type Effect = RefinementEffect | TransformEffect | PreprocessEffect - -export type ZodEffectsDef = { - schema: T - typeName: 'ZodEffects' - effect: Effect -} & ZodTypeDef - -export class ZodEffects, Input = input> extends ZodType< - Output, - ZodEffectsDef, - Input -> { +import { ZodBaseTypeImpl, addIssueToContext, DIRTY, INVALID, isValid, ParseInput, ParseReturnType } from '../basetype' + +export class ZodEffectsImpl, Input = input> + extends ZodBaseTypeImpl, Input> + implements IZodEffects +{ innerType() { return this._def.schema } @@ -50,12 +15,12 @@ export class ZodEffects, Input = */ sourceType(): T { return this._def.schema._def.typeName === 'ZodEffects' - ? (this._def.schema as unknown as ZodEffects).sourceType() + ? (this._def.schema as unknown as IZodEffects).sourceType() : (this._def.schema as T) } - dereference(defs: Record): ZodType { - return new ZodEffects({ + dereference(defs: Record): IZodType { + return new ZodEffectsImpl({ ...this._def, schema: this._def.schema.dereference(defs), }) @@ -65,11 +30,11 @@ export class ZodEffects, Input = return this._def.schema.getReferences() } - clone(): ZodEffects { - return new ZodEffects({ + clone(): IZodEffects { + return new ZodEffectsImpl({ ...this._def, - schema: this._def.schema.clone(), - }) as ZodEffects + schema: this._def.schema.clone() as T, + }) } _parse(input: ParseInput): ParseReturnType { @@ -100,7 +65,7 @@ export class ZodEffects, Input = return Promise.resolve(processed).then(async (processed) => { if (status.value === 'aborted') return INVALID - const result = await this._def.schema._parseAsync({ + const result = await ZodEffectsImpl.fromInterface(this._def.schema)._parseAsync({ data: processed, path: ctx.path, parent: ctx, @@ -112,7 +77,7 @@ export class ZodEffects, Input = }) } else { if (status.value === 'aborted') return INVALID - const result = this._def.schema._parseSync({ + const result = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ data: processed, path: ctx.path, parent: ctx, @@ -136,7 +101,7 @@ export class ZodEffects, Input = } if (ctx.common.async === false) { - const inner = this._def.schema._parseSync({ + const inner = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -148,20 +113,22 @@ export class ZodEffects, Input = executeRefinement(inner.value) return { status: status.value, value: inner.value } } else { - return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => { - if (inner.status === 'aborted') return INVALID - if (inner.status === 'dirty') status.dirty() - - return executeRefinement(inner.value).then(() => { - return { status: status.value, value: inner.value } + return ZodEffectsImpl.fromInterface(this._def.schema) + ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) + .then((inner) => { + if (inner.status === 'aborted') return INVALID + if (inner.status === 'dirty') status.dirty() + + return executeRefinement(inner.value).then(() => { + return { status: status.value, value: inner.value } + }) }) - }) } } if (effect.type === 'transform') { if (ctx.common.async === false) { - const base = this._def.schema._parseSync({ + const base = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -178,48 +145,24 @@ export class ZodEffects, Input = return { status: status.value, value: result } } else { - return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => { - if (!isValid(base)) return base - - return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ - status: status.value, - value: result, - })) - }) + return ZodEffectsImpl.fromInterface(this._def.schema) + ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) + .then((base) => { + if (!isValid(base)) return base + + return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ + status: status.value, + value: result, + })) + }) } } utils.assert.assertNever(effect) } - static create = ( - schema: I, - effect: Effect, - params?: RawCreateParams - ): ZodEffects => { - return new ZodEffects({ - schema, - typeName: 'ZodEffects', - effect, - ...processCreateParams(params), - }) - } - - static createWithPreprocess = ( - preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, - schema: I, - params?: RawCreateParams - ): ZodEffects => { - return new ZodEffects({ - schema, - effect: { type: 'preprocess', transform: preprocess }, - typeName: 'ZodEffects', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodEffects)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodEffectsImpl)) return false if (!this._def.schema.isEqual(schema._def.schema)) return false if (this._def.effect.type === 'refinement') { @@ -245,11 +188,10 @@ export class ZodEffects, Input = return this._def.schema.naked() } - mandatory(): ZodEffects { - return new ZodEffects({ + mandatory(): IZodEffects { + return new ZodEffectsImpl({ ...this._def, schema: this._def.schema.mandatory(), }) } } -export { ZodEffects as ZodTransformer } diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index 5f9df7a1c7c..cb407bccf65 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import * as utils from '../../utils' import * as z from '../../index' -import { NEVER } from '../basetype' +import { NEVER } from '..' const stringToNumber = z.string().transform((arg) => parseFloat(arg)) // const numberToString = z @@ -60,6 +60,7 @@ test('transform ctx.addIssue with parseAsync', async () => { expect(JSON.parse(JSON.stringify(result))).toEqual({ success: false, error: { + __type__: 'ZuiError', issues: [ { code: 'custom', diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index bf1d23d41f6..11b220d3ce8 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -1,56 +1,53 @@ +import type { IZodTuple, IZodType, ZodTupleDef } from '../../typings' import * as utils from '../../utils' import { ParseInputLazyPath, - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, addIssueToContext, INVALID, ParseInput, ParseReturnType, ParseStatus, SyncParseReturnType, + ZodBaseTypeImpl, } from '../basetype' -export type ZodTupleItems = [ZodType, ...ZodType[]] +export type ZodTupleItems = [IZodType, ...IZodType[]] type _AssertArray = T extends any[] ? T : never type _OutputTypeOfTuple = _AssertArray<{ - [k in keyof T]: T[k] extends ZodType ? T[k]['_output'] : never + [k in keyof T]: T[k] extends IZodType ? T[k]['_output'] : never }> -type _OutputTypeOfTupleWithRest = Rest extends ZodType - ? [..._OutputTypeOfTuple, ...Rest['_output'][]] - : _OutputTypeOfTuple +type _OutputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends IZodType | null = null, +> = Rest extends IZodType ? [..._OutputTypeOfTuple, ...Rest['_output'][]] : _OutputTypeOfTuple type _InputTypeOfTuple = _AssertArray<{ - [k in keyof T]: T[k] extends ZodType ? T[k]['_input'] : never + [k in keyof T]: T[k] extends IZodType ? T[k]['_input'] : never }> -type _InputTypeOfTupleWithRest = Rest extends ZodType - ? [..._InputTypeOfTuple, ...Rest['_input'][]] - : _InputTypeOfTuple - -export type ZodTupleDef = { - items: T - rest: Rest - typeName: 'ZodTuple' -} & ZodTypeDef +type _InputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends IZodType | null = null, +> = Rest extends IZodType ? [..._InputTypeOfTuple, ...Rest['_input'][]] : _InputTypeOfTuple /** * @deprecated use ZodTuple instead */ -export type AnyZodTuple = ZodTuple<[ZodType, ...ZodType[]] | [], ZodType | null> - -export class ZodTuple< - T extends [ZodType, ...ZodType[]] | [] = [ZodType, ...ZodType[]], - Rest extends ZodType | null = null, -> extends ZodType<_OutputTypeOfTupleWithRest, ZodTupleDef, _InputTypeOfTupleWithRest> { - dereference(defs: Record): ZodType { - const items = this._def.items.map((item) => item.dereference(defs)) as [ZodType, ...ZodType[]] +export type AnyZodTuple = IZodTuple<[IZodType, ...IZodType[]] | [], IZodType | null> + +export class ZodTupleImpl< + T extends [IZodType, ...IZodType[]] | [] = [IZodType, ...IZodType[]], + Rest extends IZodType | null = null, + > + extends ZodBaseTypeImpl<_OutputTypeOfTupleWithRest, ZodTupleDef, _InputTypeOfTupleWithRest> + implements IZodTuple +{ + dereference(defs: Record): IZodType { + const items = this._def.items.map((item) => item.dereference(defs)) as [IZodType, ...IZodType[]] const rest = this._def.rest ? this._def.rest.dereference(defs) : null - return new ZodTuple({ + return new ZodTupleImpl({ ...this._def, items, rest, @@ -64,14 +61,14 @@ export class ZodTuple< ]) } - clone(): ZodTuple { - const items = this._def.items.map((item) => item.clone()) as [ZodType, ...ZodType[]] + clone(): IZodTuple { + const items = this._def.items.map((item) => item.clone()) as [IZodType, ...IZodType[]] const rest = this._def.rest ? this._def.rest.clone() : null - return new ZodTuple({ + return new ZodTupleImpl({ ...this._def, - items, - rest, - }) as ZodTuple + items: items as T, + rest: rest as Rest, + }) } _parse(input: ParseInput): ParseReturnType { @@ -114,7 +111,7 @@ export class ZodTuple< .map((item, itemIndex) => { const schema = this._def.items[itemIndex] || this._def.rest if (!schema) return null - return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)) + return ZodBaseTypeImpl.fromInterface(schema)._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)) }) .filter((x) => !!x) // filter nulls @@ -123,7 +120,7 @@ export class ZodTuple< return ParseStatus.mergeArray(status, results) }) } else { - return ParseStatus.mergeArray(status, items as SyncParseReturnType[]) + return ParseStatus.mergeArray(status, items as SyncParseReturnType[]) } } @@ -131,36 +128,24 @@ export class ZodTuple< return this._def.items } - rest(rest: Rest): ZodTuple { - return new ZodTuple({ + rest(rest: Rest): IZodTuple { + return new ZodTupleImpl({ ...this._def, rest, }) } - static create = (schemas: T, params?: RawCreateParams): ZodTuple => { - if (!Array.isArray(schemas)) { - throw new Error('You must pass an array of schemas to z.tuple([ ... ])') - } - return new ZodTuple({ - items: schemas, - typeName: 'ZodTuple', - rest: null, - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodTuple)) return false + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodTupleImpl)) return false if (!this._restEquals(schema)) return false - const compare = (a: ZodType, b: ZodType) => a.isEqual(b) - const thisItems = new utils.ds.CustomSet(this._def.items, { compare }) - const schemaItems = new utils.ds.CustomSet(schema._def.items, { compare }) + const compare = (a: IZodType, b: IZodType) => a.isEqual(b) + const thisItems = new utils.ds.CustomSet(this._def.items, { compare }) + const schemaItems = new utils.ds.CustomSet(schema._def.items, { compare }) return thisItems.isEqual(schemaItems) } - private _restEquals(schema: ZodTuple) { + private _restEquals(schema: ZodTupleImpl) { if (this._def.rest === null) { return schema._def.rest === null } diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index 099384ce5d0..ed22ac2915c 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,23 +1,8 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import { builders } from '../../internal-builders' +import type { IZodNever, IZodUndefined, ZodUndefinedDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -// TODO(circle): these may potentially cause circular dependencies errors -import { ZodNever } from '../never' - -export type ZodUndefinedDef = { - typeName: 'ZodUndefined' -} & ZodTypeDef - -export class ZodUndefined extends ZodType { +export class ZodUndefinedImpl extends ZodBaseTypeImpl implements IZodUndefined { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'undefined') { @@ -31,21 +16,13 @@ export class ZodUndefined extends ZodType { } return OK(input.data) } - params?: RawCreateParams - - static create = (params?: RawCreateParams): ZodUndefined => { - return new ZodUndefined({ - typeName: 'ZodUndefined', - ...processCreateParams(params), - }) - } - isEqual(schema: ZodType): boolean { - return schema instanceof ZodUndefined + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodUndefinedImpl } - mandatory(): ZodNever { - return ZodNever.create({ + mandatory(): IZodNever { + return builders.never({ ...this._def, }) } diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index a8172071e58..a220b9518e9 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,10 +1,10 @@ -import { ZodError, ZodIssue } from '../../error' +import { ZodError } from '../../error' +import { builders } from '../../internal-builders' +import type { ZodNativeType } from '../../native' +import type { DefaultZodUnionOptions, IZodUnion, IZodType, ZodUnionDef, ZodUnionOptions, ZodIssue } from '../../typings' import * as utils from '../../utils' import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, + ZodBaseTypeImpl, addIssueToContext, DIRTY, INVALID, @@ -14,26 +14,13 @@ import { SyncParseReturnType, } from '../basetype' -// TODO(circle): these may potentially cause circular dependencies errors -import { ZodNever } from '../never' -import { ZodUndefined } from '../undefined' - -type _DefaultZodUnionOptions = Readonly<[ZodType, ZodType, ...ZodType[]]> - -export type ZodUnionOptions = Readonly<[ZodType, ...ZodType[]]> -export type ZodUnionDef = { - options: T - typeName: 'ZodUnion' -} & ZodTypeDef - -export class ZodUnion extends ZodType< - T[number]['_output'], - ZodUnionDef, - T[number]['_input'] -> { - dereference(defs: Record): ZodType { - const options = this._def.options.map((option) => option.dereference(defs)) as [ZodType, ZodType, ...ZodType[]] - return new ZodUnion({ +export class ZodUnionImpl + extends ZodBaseTypeImpl, T[number]['_input']> + implements IZodUnion +{ + dereference(defs: Record): IZodType { + const options = this._def.options.map((option) => option.dereference(defs)) as [IZodType, IZodType, ...IZodType[]] + return new ZodUnionImpl({ ...this._def, options, }) @@ -47,12 +34,12 @@ export class ZodUnion exten ) } - clone(): ZodUnion { - const options = this._def.options.map((option) => option.clone()) as [ZodType, ...ZodType[]] - return new ZodUnion({ + clone(): IZodUnion { + const options = this._def.options.map((option) => option.clone()) as utils.types.Writeable + return new ZodUnionImpl({ ...this._def, - options, - }) as ZodUnion + options: options as T, + }) } _parse(input: ParseInput): ParseReturnType { @@ -97,7 +84,7 @@ export class ZodUnion exten parent: null, } return { - result: await option._parseAsync({ + result: await ZodBaseTypeImpl.fromInterface(option)._parseAsync({ data: ctx.data, path: ctx.path, parent: childCtx, @@ -118,7 +105,7 @@ export class ZodUnion exten }, parent: null, } - const result = option._parseSync({ + const result = ZodBaseTypeImpl.fromInterface(option)._parseSync({ data: ctx.data, path: ctx.path, parent: childCtx, @@ -154,39 +141,31 @@ export class ZodUnion exten return this._def.options } - static create = >( - types: T, - params?: RawCreateParams - ): ZodUnion => { - return new ZodUnion({ - options: types, - typeName: 'ZodUnion', - ...processCreateParams(params), - }) - } + isEqual(schema: IZodType): boolean { + if (!(schema instanceof ZodUnionImpl)) return false - isEqual(schema: ZodType): boolean { - if (!(schema instanceof ZodUnion)) return false - - const compare = (a: ZodType, b: ZodType) => a.isEqual(b) - const thisOptions = new utils.ds.CustomSet([...this._def.options], { compare }) - const thatOptions = new utils.ds.CustomSet([...schema._def.options], { compare }) + const compare = (a: IZodType, b: IZodType) => a.isEqual(b) + const thisOptions = new utils.ds.CustomSet([...this._def.options], { compare }) + const thatOptions = new utils.ds.CustomSet([...schema._def.options], { compare }) return thisOptions.isEqual(thatOptions) } - mandatory(): ZodType { - const options = this._def.options.filter((o) => !(o instanceof ZodUndefined)).map((option) => option.mandatory()) + mandatory(): IZodType { + const options = this._def.options + .filter((o) => !((o as ZodNativeType).typeName === 'ZodUndefined')) + .map((option) => option.mandatory()) + const [first, second, ...others] = options if (!first) { - return ZodNever.create({ + return builders.never({ ...this._def, }) } if (!second) { return first } - return new ZodUnion({ + return new ZodUnionImpl({ ...this._def, options: [first, second, ...others], }) diff --git a/packages/zui/src/z/types/unknown/index.ts b/packages/zui/src/z/types/unknown/index.ts index 1d2b4b9ec10..7784ee1c588 100644 --- a/packages/zui/src/z/types/unknown/index.ts +++ b/packages/zui/src/z/types/unknown/index.ts @@ -1,24 +1,14 @@ -import { RawCreateParams, ZodType, ZodTypeDef, processCreateParams, OK, ParseInput, ParseReturnType } from '../basetype' +import type { IZodUnknown, ZodUnknownDef } from '../../typings' +import { ZodBaseTypeImpl, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodUnknownDef = { - typeName: 'ZodUnknown' -} & ZodTypeDef - -export class ZodUnknown extends ZodType { +export class ZodUnknownImpl extends ZodBaseTypeImpl implements IZodUnknown { // required _unknown = true as const _parse(input: ParseInput): ParseReturnType { return OK(input.data) } - static create = (params?: RawCreateParams): ZodUnknown => { - return new ZodUnknown({ - typeName: 'ZodUnknown', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodUnknown + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodUnknownImpl } } diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index e54d12d310d..0b87294d5d3 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,20 +1,7 @@ -import { - RawCreateParams, - ZodType, - ZodTypeDef, - processCreateParams, - addIssueToContext, - INVALID, - OK, - ParseInput, - ParseReturnType, -} from '../basetype' +import type { IZodVoid, ZodVoidDef } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' -export type ZodVoidDef = { - typeName: 'ZodVoid' -} & ZodTypeDef - -export class ZodVoid extends ZodType { +export class ZodVoidImpl extends ZodBaseTypeImpl implements IZodVoid { _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'undefined') { @@ -29,14 +16,7 @@ export class ZodVoid extends ZodType { return OK(input.data) } - static create = (params?: RawCreateParams): ZodVoid => { - return new ZodVoid({ - typeName: 'ZodVoid', - ...processCreateParams(params), - }) - } - - isEqual(schema: ZodType): boolean { - return schema instanceof ZodVoid + isEqual(schema: ZodBaseTypeImpl): boolean { + return schema instanceof ZodVoidImpl } } diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts new file mode 100644 index 00000000000..79d11003d99 --- /dev/null +++ b/packages/zui/src/z/typings.ts @@ -0,0 +1,1800 @@ +import type * as transforms from '../transforms' +import { Cast, UnionToTuple, NoNever, Flatten, NoUndefined, Primitive, SafeOmit, Writeable } from './utils/type-utils' + +//* ─────────────────────────── UI & Metadata ─────────────────────────────── + +export type ZuiMetadata = + | string + | number + | boolean + | null + | undefined + | ZuiMetadata[] + | { + [key: string]: ZuiMetadata + } + +export type ZuiExtensionObject = { + tooltip?: boolean + displayAs?: [string, any] + title?: string + disabled?: boolean | string + hidden?: boolean | string + placeholder?: string + secret?: boolean + coerce?: boolean + [key: string]: ZuiMetadata +} + +export type BaseDisplayAsType = 'number' | 'string' | 'boolean' | 'object' | 'array' | 'discriminatedUnion' +export type UIComponentDefinitions = { + [T in BaseDisplayAsType]: { + [K: string]: { + id: string + params: IZodObject + } + } +} + +export type ZodKindToBaseType = U extends ZodStringDef + ? 'string' + : U extends ZodNumberDef + ? 'number' + : U extends ZodBooleanDef + ? 'boolean' + : U extends ZodArrayDef + ? 'array' + : U extends ZodObjectDef + ? 'object' + : U extends ZodTupleDef + ? never + : U extends ZodEnumDef + ? 'string' + : U extends ZodDefaultDef + ? ZodKindToBaseType + : U extends ZodOptionalDef + ? ZodKindToBaseType + : U extends ZodNullableDef + ? ZodKindToBaseType + : U extends ZodDiscriminatedUnionDef + ? 'discriminatedUnion' + : never + +export type DisplayAsOptions = U extends { id: string; params: IZodObject } + ? { + id: U['id'] + params: TypeOf + } + : object + +//* ─────────────────────────── Errors & Issues ─────────────────────────────── + +export type ErrMessage = + | string + | { + message?: string + } + +type _ZodIssueBase = { + path: (string | number)[] + message?: string +} + +export type ZodInvalidTypeIssue = { + code: 'invalid_type' + expected: ZodParsedType + received: ZodParsedType +} & _ZodIssueBase + +export type ZodInvalidLiteralIssue = { + code: 'invalid_literal' + expected: unknown + received: unknown +} & _ZodIssueBase + +export type ZodUnrecognizedKeysIssue = { + code: 'unrecognized_keys' + keys: string[] +} & _ZodIssueBase + +export type ZodInvalidUnionIssue = { + code: 'invalid_union' + unionErrors: IZodError[] +} & _ZodIssueBase + +export type ZodInvalidUnionDiscriminatorIssue = { + code: 'invalid_union_discriminator' + options: Primitive[] +} & _ZodIssueBase + +export type ZodInvalidEnumValueIssue = { + received: string | number + code: 'invalid_enum_value' + options: (string | number)[] +} & _ZodIssueBase + +export type ZodInvalidArgumentsIssue = { + code: 'invalid_arguments' + argumentsError: IZodError +} & _ZodIssueBase + +export type ZodInvalidReturnTypeIssue = { + code: 'invalid_return_type' + returnTypeError: IZodError +} & _ZodIssueBase + +export type ZodInvalidDateIssue = { + code: 'invalid_date' +} & _ZodIssueBase + +export type ZodInvalidStringIssue = { + code: 'invalid_string' + validation: + | 'email' + | 'url' + | 'emoji' + | 'uuid' + | 'regex' + | 'cuid' + | 'cuid2' + | 'ulid' + | 'datetime' + | 'ip' + | { + includes: string + position?: number + } + | { + startsWith: string + } + | { + endsWith: string + } +} & _ZodIssueBase + +export type ZodTooSmallIssue = { + code: 'too_small' + minimum: number | bigint + inclusive: boolean + exact?: boolean + type: 'array' | 'string' | 'number' | 'set' | 'date' | 'bigint' +} & _ZodIssueBase + +export type ZodTooBigIssue = { + code: 'too_big' + maximum: number | bigint + inclusive: boolean + exact?: boolean + type: 'array' | 'string' | 'number' | 'set' | 'date' | 'bigint' +} & _ZodIssueBase + +export type ZodInvalidIntersectionTypesIssue = { + code: 'invalid_intersection_types' +} & _ZodIssueBase + +export type ZodNotMultipleOfIssue = { + code: 'not_multiple_of' + multipleOf: number | bigint +} & _ZodIssueBase + +export type ZodNotFiniteIssue = { + code: 'not_finite' +} & _ZodIssueBase + +export type ZodUnresolvedReferenceIssue = { + code: 'unresolved_reference' +} & _ZodIssueBase + +export type ZodCustomIssue = { + code: 'custom' + params?: { + [k: string]: any + } +} & _ZodIssueBase + +type _ZodIssueOptionalMessage = + | ZodInvalidTypeIssue + | ZodInvalidLiteralIssue + | ZodUnrecognizedKeysIssue + | ZodInvalidUnionIssue + | ZodInvalidUnionDiscriminatorIssue + | ZodInvalidEnumValueIssue + | ZodInvalidArgumentsIssue + | ZodInvalidReturnTypeIssue + | ZodInvalidDateIssue + | ZodInvalidStringIssue + | ZodTooSmallIssue + | ZodTooBigIssue + | ZodInvalidIntersectionTypesIssue + | ZodNotMultipleOfIssue + | ZodNotFiniteIssue + | ZodUnresolvedReferenceIssue + | ZodCustomIssue + +export type ZodIssue = _ZodIssueOptionalMessage & { + fatal?: boolean + message: string +} + +export type CustomErrorParams = Partial> + +type _RecursiveZodFormattedError = T extends [any, ...any[]] + ? { + [K in keyof T]?: ZodFormattedError + } + : T extends any[] + ? { + [k: number]: ZodFormattedError + } + : T extends object + ? { + [K in keyof T]?: ZodFormattedError + } + : unknown + +export type ZodFormattedError = { + _errors: U[] +} & _RecursiveZodFormattedError> + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodError extends Error { + readonly __type__: 'ZuiError' + issues: ZodIssue[] + errors: ZodIssue[] + format(): ZodFormattedError + format(mapper: (issue: ZodIssue) => U): ZodFormattedError + toString(): string + message: string + isEmpty: boolean + addIssue: (sub: ZodIssue) => void + addIssues: (subs?: ZodIssue[]) => void +} + +type _StripPath = T extends any ? Omit : never +export type IssueData = _StripPath<_ZodIssueOptionalMessage> & { + path?: (string | number)[] + fatal?: boolean +} + +type _ErrorMapCtx = { + defaultError: string + data: any +} + +export type ZodErrorMap = ( + issue: _ZodIssueOptionalMessage, + _ctx: _ErrorMapCtx +) => { + message: string +} + +//* ─────────────────────────── Parsing ────────────────────────────────────── + +export type ZodParsedType = + | 'string' + | 'nan' + | 'number' + | 'integer' + | 'float' + | 'boolean' + | 'date' + | 'bigint' + | 'symbol' + | 'function' + | 'undefined' + | 'null' + | 'array' + | 'object' + | 'unknown' + | 'promise' + | 'void' + | 'never' + | 'map' + | 'set' + +export type SafeParseSuccess = { + success: true + data: Output + error?: never +} + +export type SafeParseError = { + success: false + error: IZodError + data?: never +} + +export type SafeParseReturnType = SafeParseSuccess | SafeParseError + +type _ParseParams = { + path: (string | number)[] + errorMap: ZodErrorMap + async: boolean +} + +export type RefinementCtx = { + addIssue: (arg: IssueData) => void + path: (string | number)[] +} + +//* ─────────────────────────── Base Type ─────────────────────────────────── + +export type RawCreateParams = + | { + errorMap?: ZodErrorMap + invalid_type_error?: string + required_error?: string + description?: string + ['x-zui']?: ZuiExtensionObject + } + | undefined + +export type TypeOf = T['_output'] +export type { TypeOf as infer } +export type input = T['_input'] +export type output = T['_output'] + +export type DeepPartialBoolean = { + [K in keyof T]?: T[K] extends object ? DeepPartialBoolean | boolean : boolean +} + +export type ZodTypeDef = { + typeName: string + errorMap?: ZodErrorMap + description?: string + ['x-zui']?: ZuiExtensionObject +} + +/** + * @deprecated - use ZodType instead + */ +export type ZodTypeAny = IZodType + +/** + * @deprecated use ZodType instead + */ +export type ZodSchema = IZodType +/** + * @deprecated use ZodType instead + */ +export type Schema = IZodType + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodType { + readonly __type__: 'ZuiType' + _type: Output + _output: Output + _input: Input + _def: Def + description: string | undefined + typeName: Def['typeName'] + /** deeply replace all references in the schema */ + dereference(_defs: Record): IZodType + /** deeply scans the schema to check if it contains references */ + getReferences(): string[] + clone(): IZodType + parse(data: unknown, params?: Partial<_ParseParams>): Output + safeParse(data: unknown, params?: Partial<_ParseParams>): SafeParseReturnType + parseAsync(data: unknown, params?: Partial<_ParseParams>): Promise + safeParseAsync(data: unknown, params?: Partial<_ParseParams>): Promise> + /** Alias of safeParseAsync */ + spa: (data: unknown, params?: Partial<_ParseParams>) => Promise> + refine( + check: (arg: Output) => arg is RefinedOutput, + message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) + ): IZodEffects + refine( + check: (arg: Output) => unknown | Promise, + message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) + ): IZodEffects + refinement( + check: (arg: Output) => arg is RefinedOutput, + refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) + ): IZodEffects + refinement( + check: (arg: Output) => boolean, + refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) + ): IZodEffects + superRefine( + refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput + ): IZodEffects + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => void): IZodEffects + superRefine(refinement: (arg: Output, ctx: RefinementCtx) => Promise): IZodEffects + optional(): IZodOptional + nullable(): IZodNullable + nullish(): IZodOptional> + array(): IZodArray + promise(): IZodPromise + /** + * # \#\#\# Experimental \#\#\# + * + * @experimental This function is experimental and is subject to breaking changes in the future. + * + * Would have been named `required` but a method with that name already exists in ZodObject. + * Makes the schema required; i.e. not optional or undefined. If the schema is already required than it returns itself. + * Null is not considered optional and remains unchanged. + * + * @example z.string().optional().mandatory() // z.string() + * @example z.string().nullable().mandatory() // z.string().nullable() + * @example z.string().or(z.undefined()).mandatory() // z.string() + * @example z.union([z.string(), z.number(), z.undefined()]).mandatory() // z.union([z.string(), z.number()]) + */ + mandatory(): IZodType + or(option: T): IZodUnion<[this, T]> + and(incoming: T): IZodIntersection + transform(transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise): IZodEffects + default(def: NoUndefined): IZodDefault + default(def: () => NoUndefined): IZodDefault + brand(brand?: B): IZodBranded + catch(def: Output | CatchFn): IZodCatch + describe(description: string): this + pipe(target: T): IZodPipeline + readonly(): IZodReadonly + isOptional(): boolean + isNullable(): boolean + /** append metadata to the schema */ + metadata(data: Record): this + /** metadataf the schema */ + getMetadata(): Record + /** set metadata of the schema */ + setMetadata(data: Record): void + /** + * metadataf the schema + * @deprecated use `getMetadata()` instead + */ + ui: Record + /** + * The type of component to use to display the field and its options + */ + // displayAs< + // UI extends UIComponentDefinitions = UIComponentDefinitions, + // Type extends _BaseType = _ZodKindToBaseType, + // >( + // options: ValueOf + // ): this + /** + * The title of the field. Defaults to the field name. + */ + title(title: string): this + /** + * Whether the field is hidden in the UI. Useful for internal fields. + * @default false + */ + hidden(value?: boolean | ((shape: T | null) => DeepPartialBoolean | boolean)): this + /** + * Whether the field is disabled + * @default false + */ + disabled(value?: boolean | ((shape: T | null) => DeepPartialBoolean | boolean)): this + /** + * Placeholder text for the field + */ + placeholder(placeholder: string): this + /** + * Some Schemas aren't meant to contain metadata, like ZodDefault. + * In a zui construction like `z.string().default('hello').title('Hello')`, the user's intention is usually to set a title on the string, not on the default value. + * Also, in JSON-Schema, default is not a data-type like it is in Zui, but an annotation added on the schema itself. Therefore, only one metadata can apply to both the schema and the default value. + * This property is used to theoot schema that should contain the metadata. + * + * TLDR: Allows removing all wrappers around the schema + * @returns either this or the closest children schema that represents the actual data + */ + naked(): IZodType + + /** checks if a schema is equal to another */ + isEqual(schema: IZodType): boolean + + /** + * The type of component to use to display the field and its options + */ + displayAs< + UI extends UIComponentDefinitions = UIComponentDefinitions, + Type extends BaseDisplayAsType = ZodKindToBaseType, + >( + options: DisplayAsOptions + ): this + + /** + * + * @returns a JSON Schema equivalent to the Zui schema + */ + toJSONSchema(): transforms.ZuiJSONSchema + + /** + * + * @param options generation options + * @returns a string of the TypeScript type representing the schema + */ + toTypescriptType(opts?: transforms.TypescriptGenerationOptions): string + + /** + * + * @param options generation options + * @returns a typescript program (a string) that would construct the given schema if executed + */ + toTypescriptSchema(): string +} + +//* ─────────────────────────── ZodAny ─────────────────────────────────────── + +export type ZodAnyDef = { + typeName: 'ZodAny' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodAny extends IZodType {} + +//* ─────────────────────────── ZodArray ───────────────────────────────────── + +export type ZodArrayDef = { + type: T + typeName: 'ZodArray' + exactLength: { + value: number + message?: string + } | null + minLength: { + value: number + message?: string + } | null + maxLength: { + value: number + message?: string + } | null +} & ZodTypeDef + +export type ArrayCardinality = 'many' | 'atleastone' +export type ArrayOutputType< + T extends IZodType, + Cardinality extends ArrayCardinality = 'many', +> = Cardinality extends 'atleastone' ? [T['_output'], ...T['_output'][]] : T['_output'][] + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodArray + extends IZodType< + ArrayOutputType, + ZodArrayDef, + Cardinality extends 'atleastone' ? [T['_input'], ...T['_input'][]] : T['_input'][] + > { + element: T + min(minLength: number, message?: ErrMessage): this + max(maxLength: number, message?: ErrMessage): this + length(len: number, message?: ErrMessage): this + nonempty(message?: ErrMessage): IZodArray +} + +//* ─────────────────────────── ZodBigInt ──────────────────────────────────── + +export type ZodBigIntCheck = + | { + kind: 'min' + value: bigint + inclusive: boolean + message?: string + } + | { + kind: 'max' + value: bigint + inclusive: boolean + message?: string + } + | { + kind: 'multipleOf' + value: bigint + message?: string + } + +export type ZodBigIntDef = { + checks: ZodBigIntCheck[] + typeName: 'ZodBigInt' + coerce: boolean +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodBigInt extends IZodType { + gte(value: bigint, message?: ErrMessage): IZodBigInt + min: (value: bigint, message?: ErrMessage) => IZodBigInt + gt(value: bigint, message?: ErrMessage): IZodBigInt + lte(value: bigint, message?: ErrMessage): IZodBigInt + max: (value: bigint, message?: ErrMessage) => IZodBigInt + lt(value: bigint, message?: ErrMessage): IZodBigInt + positive(message?: ErrMessage): IZodBigInt + negative(message?: ErrMessage): IZodBigInt + nonpositive(message?: ErrMessage): IZodBigInt + nonnegative(message?: ErrMessage): IZodBigInt + multipleOf(value: bigint, message?: ErrMessage): IZodBigInt + minValue: bigint | null + maxValue: bigint | null +} + +//* ─────────────────────────── ZodBoolean ─────────────────────────────────── + +export type ZodBooleanDef = { + typeName: 'ZodBoolean' + coerce: boolean +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodBoolean extends IZodType {} + +//* ─────────────────────────── ZodBranded ─────────────────────────────────── + +type _Key = string | number | symbol + +export type ZodBrandedDef = { + type: T + typeName: 'ZodBranded' +} & ZodTypeDef + +export const BRAND: unique symbol = Symbol('zod_brand') +export type BRAND = { + [BRAND]: { + [k in T]: true + } +} + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodBranded + extends IZodType, ZodBrandedDef, T['_input']> { + unwrap(): T +} + +//* ─────────────────────────── ZodCatch ──────────────────────────────────── + +export type CatchFn = (ctx: { error: IZodError; input: unknown }) => Y +export type ZodCatchDef = { + innerType: T + catchValue: CatchFn + typeName: 'ZodCatch' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodCatch extends IZodType, unknown> { + removeCatch(): T +} + +//* ─────────────────────────── ZodDate ───────────────────────────────────── + +export type ZodDateCheck = + | { + kind: 'min' + value: number + message?: string + } + | { + kind: 'max' + value: number + message?: string + } + +export type ZodDateDef = { + checks: ZodDateCheck[] + coerce: boolean + typeName: 'ZodDate' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodDate extends IZodType { + min(minDate: Date, message?: ErrMessage): IZodDate + max(maxDate: Date, message?: ErrMessage): IZodDate + minDate: Date | null + maxDate: Date | null +} + +//* ─────────────────────────── ZodDefault ─────────────────────────────────── + +export type ZodDefaultDef = { + innerType: T + defaultValue: () => NoUndefined + typeName: 'ZodDefault' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodDefault + extends IZodType, ZodDefaultDef, T['_input'] | undefined> { + removeDefault(): T + unwrap(): T +} + +//* ─────────────────────────── ZodEnum ───────────────────────────────────── + +export type EnumValues = [string, ...string[]] + +export type EnumValuesMap = { + [k in T[number]]: k +} + +export type ZodEnumDef = { + values: T + typeName: 'ZodEnum' +} & ZodTypeDef + +export type FilterEnum = Values extends [] + ? [] + : Values extends [infer Head, ...infer Rest] + ? Head extends ToExclude + ? FilterEnum + : [Head, ...FilterEnum] + : never + +export type NeverCast = A extends T ? A : never + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodEnum + extends IZodType> { + options: T + enum: EnumValuesMap + Values: EnumValuesMap + Enum: EnumValuesMap + extract( + values: ToExtract, + newDef?: RawCreateParams + ): IZodEnum> + exclude( + values: ToExclude, + newDef?: RawCreateParams + ): IZodEnum>, [string, ...string[]]>> +} + +//* ─────────────────────────── ZodNever ──────────────────────────────────── + +export type ZodNeverDef = { + typeName: 'ZodNever' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNever extends IZodType {} + +//* ─────────────────────────── ZodNullable ───────────────────────────────── + +export type ZodNullableDef = { + innerType: T + typeName: 'ZodNullable' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNullable + extends IZodType, T['_input'] | null> { + unwrap(): T +} + +//* ─────────────────────────── ZodOptional ──────────────────────────────── + +export type ZodOptionalDef = { + innerType: T + typeName: 'ZodOptional' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodOptional + extends IZodType, T['_input'] | undefined> { + unwrap(): T +} + +//* ─────────────────────────── ZodTuple ──────────────────────────────────── + +export type ZodTupleItems = [IZodType, ...IZodType[]] + +export type AssertArray = T extends any[] ? T : never + +export type OutputTypeOfTuple = AssertArray<{ + [k in keyof T]: T[k] extends IZodType ? T[k]['_output'] : never +}> + +export type OutputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends IZodType | null = null, +> = Rest extends IZodType ? [...OutputTypeOfTuple, ...Rest['_output'][]] : OutputTypeOfTuple + +export type InputTypeOfTuple = AssertArray<{ + [k in keyof T]: T[k] extends IZodType ? T[k]['_input'] : never +}> + +export type InputTypeOfTupleWithRest< + T extends ZodTupleItems | [], + Rest extends IZodType | null = null, +> = Rest extends IZodType ? [...InputTypeOfTuple, ...Rest['_input'][]] : InputTypeOfTuple + +export type ZodTupleDef = { + items: T + rest: Rest + typeName: 'ZodTuple' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodTuple< + T extends [IZodType, ...IZodType[]] | [] = [IZodType, ...IZodType[]] | [], + Rest extends IZodType | null = IZodType | null, +> extends IZodType, ZodTupleDef, InputTypeOfTupleWithRest> { + items: T + rest(rest: Rest): IZodTuple +} + +//* ─────────────────────────── ZodObject ──────────────────────────────────── + +export type OptionalKeys = { + [k in keyof T]: undefined extends T[k] ? k : never +}[keyof T] + +export type RequiredKeys = { + [k in keyof T]: undefined extends T[k] ? never : k +}[keyof T] + +export type AddQuestionMarks< + T extends object, + R extends keyof T = RequiredKeys, + O extends keyof T = OptionalKeys, +> = Pick & + Partial> & { + [k in keyof T]?: unknown + } + +export type ExtendShape = Flatten & B> + +export type ZodRawShape = { + [k: string]: IZodType +} + +export type UnknownKeysParam = 'passthrough' | 'strict' | 'strip' | IZodType +export type ZodObjectDef< + T extends ZodRawShape = ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, +> = { + typeName: 'ZodObject' + shape: () => T + unknownKeys: UnknownKeys +} & ZodTypeDef + +export type ObjectOutputType< + Shape extends ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, +> = UnknownKeysOutputType & Flatten>> + +export type BaseObjectOutputType = { + [k in keyof Shape]: Shape[k]['_output'] +} +export type ObjectInputType< + Shape extends ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, +> = Flatten> & UnknownKeysInputType + +export type BaseObjectInputType = AddQuestionMarks<{ + [k in keyof Shape]: Shape[k]['_input'] +}> + +export type UnknownKeysInputType = T extends IZodType + ? { + [k: string]: T['_input'] | unknown + } + : T extends 'passthrough' + ? { + [k: string]: unknown + } + : {} + +export type UnknownKeysOutputType = T extends IZodType + ? { + [k: string]: T['_output'] | unknown + } + : T extends 'passthrough' + ? { + [k: string]: unknown + } + : {} + +export type AdditionalProperties = T extends IZodType + ? T + : T extends 'passthrough' + ? IZodAny + : T extends 'strict' + ? IZodNever + : undefined + +export type Deoptional = + T extends IZodOptional ? Deoptional : T extends IZodNullable ? IZodNullable> : T + +export type KeyOfObject = Cast, [string, ...string[]]> + +export type DeepPartial = T extends IZodObject + ? IZodObject< + { + [k in keyof T['shape']]: IZodOptional> + }, + T['_def']['unknownKeys'] + > + : T extends IZodArray + ? IZodArray, Card> + : T extends IZodOptional + ? IZodOptional> + : T extends IZodNullable + ? IZodNullable> + : T extends IZodTuple + ? { + [k in keyof Items]: Items[k] extends IZodType ? DeepPartial : never + } extends infer PI + ? PI extends ZodTupleItems + ? IZodTuple + : never + : never + : T + +/** + * @deprecated use ZodObject instead + */ +export type SomeZodObject = IZodObject + +/** + * @deprecated use ZodObject instead + */ +export type AnyZodObject = IZodObject + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodObject< + T extends ZodRawShape = ZodRawShape, + UnknownKeys extends UnknownKeysParam = UnknownKeysParam, + Output = ObjectOutputType, + Input = ObjectInputType, +> extends IZodType, Input> { + shape: T + strict(message?: ErrMessage): IZodObject + strip(): IZodObject + passthrough(): IZodObject + /** + * @returns The ZodType that is used to validate additional properties or undefined if extra keys are stripped. + */ + additionalProperties(): AdditionalProperties + /** + * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped. + * If you want to pass through unknown properties, use `.passthrough()` instead. + */ + nonstrict: () => IZodObject + extend( + augmentation: Augmentation + ): IZodObject, UnknownKeys> + /** + * @deprecated Use `.extend` instead + * */ + augment: ( + augmentation: Augmentation + ) => IZodObject, UnknownKeys> + /** + * Prior to zod@1.0.12 there was a bug in the + * inferred type of merged objects. Please + * upgrade if you are experiencing issues. + */ + merge, Augmentation extends Incoming['shape']>( + merging: Incoming + ): IZodObject, Incoming['_def']['unknownKeys']> + setKey( + key: Key, + schema: Schema + ): IZodObject< + T & { + [k in Key]: Schema + }, + UnknownKeys + > + catchall(index: Index): IZodObject + pick< + Mask extends { + [k in keyof T]?: true + }, + >( + mask: Mask + ): IZodObject>, UnknownKeys> + omit< + Mask extends { + [k in keyof T]?: true + }, + >( + mask: Mask + ): IZodObject, UnknownKeys> + /** + * @deprecated + */ + deepPartial(): DeepPartial + partial(): IZodObject< + { + [k in keyof T]: IZodOptional + }, + UnknownKeys + > + partial< + Mask extends { + [k in keyof T]?: true + }, + >( + mask: Mask + ): IZodObject< + NoNever<{ + [k in keyof T]: k extends keyof Mask ? IZodOptional : T[k] + }>, + UnknownKeys + > + required(): IZodObject< + { + [k in keyof T]: Deoptional + }, + UnknownKeys + > + required< + Mask extends { + [k in keyof T]?: true + }, + >( + mask: Mask + ): IZodObject< + NoNever<{ + [k in keyof T]: k extends keyof Mask ? Deoptional : T[k] + }>, + UnknownKeys + > + keyof(): IZodEnum> +} + +//* ─────────────────────────── ZodDiscriminatedUnion ────────────────────────── + +export type ZodDiscriminatedUnionOption = IZodObject< + { + [key in Discriminator]: IZodType + } & ZodRawShape, + UnknownKeysParam +> + +export type ZodDiscriminatedUnionDef< + Discriminator extends string = string, + Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], +> = { + discriminator: Discriminator + options: Options + optionsMap: Map> + typeName: 'ZodDiscriminatedUnion' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodDiscriminatedUnion< + Discriminator extends string = string, + Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], +> extends IZodType, ZodDiscriminatedUnionDef, input> { + discriminator: Discriminator + options: Options + optionsMap: Map> +} + +//* ─────────────────────────── ZodUnknown ─────────────────────────────────── + +export type ZodUnknownDef = { + typeName: 'ZodUnknown' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodUnknown extends IZodType {} + +//* ─────────────────────────── ZodFunction ─────────────────────────────────── + +export type ZodFunctionDef = IZodTuple, Returns extends IZodType = IZodType> = { + args: Args + returns: Returns + typeName: 'ZodFunction' +} & ZodTypeDef + +export type OuterTypeOfFunction, Returns extends IZodType> = + Args['_input'] extends Array ? (...args: Args['_input']) => Returns['_output'] : never + +export type InnerTypeOfFunction, Returns extends IZodType> = + Args['_output'] extends Array ? (...args: Args['_output']) => Returns['_input'] : never + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodFunction< + Args extends IZodTuple = IZodTuple, + Returns extends IZodType = IZodType, +> extends IZodType< + OuterTypeOfFunction, + ZodFunctionDef, + InnerTypeOfFunction + > { + parameters(): Args + returnType(): Returns + args( + ...items: Items + ): IZodFunction, Returns> + returns>(returnType: NewReturnType): IZodFunction + implement>( + func: F + ): ReturnType extends Returns['_output'] + ? (...args: Args['_input']) => ReturnType + : OuterTypeOfFunction + strictImplement(func: InnerTypeOfFunction): InnerTypeOfFunction + validate: >( + func: F + ) => ReturnType extends Returns['_output'] + ? (...args: Args['_input']) => ReturnType + : OuterTypeOfFunction +} + +//* ─────────────────────────── ZodIntersection ────────────────────────────── + +export type ZodIntersectionDef = { + left: T + right: U + typeName: 'ZodIntersection' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodIntersection + extends IZodType, T['_input'] & U['_input']> {} + +//* ─────────────────────────── ZodLazy ───────────────────────────────────── + +export type ZodLazyDef = { + getter: () => T + typeName: 'ZodLazy' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodLazy extends IZodType, ZodLazyDef, input> { + schema: T +} + +//* ─────────────────────────── ZodLiteral ─────────────────────────────────── + +export type ZodLiteralDef = { + value: T + typeName: 'ZodLiteral' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodLiteral extends IZodType> { + value: T +} + +//* ─────────────────────────── ZodMap ─────────────────────────────────────── + +export type ZodMapDef = { + valueType: Value + keyType: Key + typeName: 'ZodMap' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodMap + extends IZodType, ZodMapDef, Map> { + keySchema: Key + valueSchema: Value +} + +//* ─────────────────────────── ZodNaN ─────────────────────────────────────── + +export type ZodNaNDef = { + typeName: 'ZodNaN' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNaN extends IZodType {} + +//* ─────────────────────────── ZodNativeEnum ──────────────────────────────── + +export type EnumLike = { + [k: string]: string | number + [nu: number]: string +} + +export type ZodNativeEnumDef = { + values: T + typeName: 'ZodNativeEnum' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNativeEnum extends IZodType> { + enum: T +} + +//* ─────────────────────────── ZodNull ───────────────────────────────────── + +export type ZodNullDef = { + typeName: 'ZodNull' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNull extends IZodType {} + +//* ─────────────────────────── ZodNumber ──────────────────────────────────── + +export type ZodNumberCheck = + | { + kind: 'min' + value: number + inclusive: boolean + message?: string + } + | { + kind: 'max' + value: number + inclusive: boolean + message?: string + } + | { + kind: 'int' + message?: string + } + | { + kind: 'multipleOf' + value: number + message?: string + } + | { + kind: 'finite' + message?: string + } + +export type ZodNumberDef = { + checks: ZodNumberCheck[] + typeName: 'ZodNumber' + coerce: boolean +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodNumber extends IZodType { + gte(value: number, message?: ErrMessage): IZodNumber + min: (value: number, message?: ErrMessage) => IZodNumber + gt(value: number, message?: ErrMessage): IZodNumber + lte(value: number, message?: ErrMessage): IZodNumber + max: (value: number, message?: ErrMessage) => IZodNumber + lt(value: number, message?: ErrMessage): IZodNumber + int(message?: ErrMessage): IZodNumber + positive(message?: ErrMessage): IZodNumber + negative(message?: ErrMessage): IZodNumber + nonpositive(message?: ErrMessage): IZodNumber + nonnegative(message?: ErrMessage): IZodNumber + multipleOf(value: number, message?: ErrMessage): IZodNumber + step: (value: number, message?: ErrMessage) => IZodNumber + finite(message?: ErrMessage): IZodNumber + safe(message?: ErrMessage): IZodNumber + minValue: number | null + maxValue: number | null + isInt: boolean + isFinite: boolean +} + +//* ─────────────────────────── ZodPipeline ────────────────────────────────── + +export type ZodPipelineDef = { + in: A + out: B + typeName: 'ZodPipeline' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodPipeline + extends IZodType, A['_input']> {} + +//* ─────────────────────────── ZodPromise ─────────────────────────────────── + +export type ZodPromiseDef = { + type: T + typeName: 'ZodPromise' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodPromise + extends IZodType, ZodPromiseDef, Promise> { + unwrap(): T +} + +//* ─────────────────────────── ZodReadonly ─────────────────────────────────── + +export type BuiltIn = + | (((...args: any[]) => any) | (new (...args: any[]) => any)) + | { + readonly [Symbol.toStringTag]: string + } + | Date + | Error + | Generator + | Promise + | RegExp + +export type MakeReadonly = + T extends Map + ? ReadonlyMap + : T extends Set + ? ReadonlySet + : T extends [infer Head, ...infer Tail] + ? readonly [Head, ...Tail] + : T extends Array + ? ReadonlyArray + : T extends BuiltIn + ? T + : Readonly + +export type ZodReadonlyDef = { + innerType: T + typeName: 'ZodReadonly' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodReadonly + extends IZodType, ZodReadonlyDef, MakeReadonly> { + unwrap(): T +} + +//* ─────────────────────────── ZodString ──────────────────────────────────── + +export type ZodStringCheck = + | { + kind: 'min' + value: number + message?: string + } + | { + kind: 'max' + value: number + message?: string + } + | { + kind: 'length' + value: number + message?: string + } + | { + kind: 'email' + message?: string + } + | { + kind: 'url' + message?: string + } + | { + kind: 'emoji' + message?: string + } + | { + kind: 'uuid' + message?: string + } + | { + kind: 'cuid' + message?: string + } + | { + kind: 'includes' + value: string + position?: number + message?: string + } + | { + kind: 'cuid2' + message?: string + } + | { + kind: 'ulid' + message?: string + } + | { + kind: 'startsWith' + value: string + message?: string + } + | { + kind: 'endsWith' + value: string + message?: string + } + | { + kind: 'regex' + regex: RegExp + message?: string + } + | { + kind: 'trim' + message?: string + } + | { + kind: 'toLowerCase' + message?: string + } + | { + kind: 'toUpperCase' + message?: string + } + | { + kind: 'datetime' + offset: boolean + precision: number | null + message?: string + } + | { + kind: 'ip' + version?: 'v4' | 'v6' + message?: string + } + +export type ZodStringDef = { + checks: ZodStringCheck[] + typeName: 'ZodString' + coerce: boolean +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodString extends IZodType { + email(message?: ErrMessage): IZodString + url(message?: ErrMessage): IZodString + emoji(message?: ErrMessage): IZodString + uuid(message?: ErrMessage): IZodString + cuid(message?: ErrMessage): IZodString + cuid2(message?: ErrMessage): IZodString + ulid(message?: ErrMessage): IZodString + ip( + options?: + | string + | { + version?: 'v4' | 'v6' + message?: string + } + ): IZodString + datetime( + options?: + | string + | { + message?: string | undefined + precision?: number | null + offset?: boolean + } + ): IZodString + regex(regex: RegExp, message?: ErrMessage): IZodString + includes( + value: string, + options?: { + message?: string + position?: number + } + ): IZodString + startsWith(value: string, message?: ErrMessage): IZodString + endsWith(value: string, message?: ErrMessage): IZodString + min(minLength: number, message?: ErrMessage): IZodString + max(maxLength: number, message?: ErrMessage): IZodString + length(len: number, message?: ErrMessage): IZodString + /** + * @deprecated Use z.string().min(1) instead. + * @see {@link IZodString.min} + */ + nonempty(message?: ErrMessage): IZodString + trim(): IZodString + secret(): this + toLowerCase(): IZodString + toUpperCase(): IZodString + isDatetime: boolean + isEmail: boolean + isURL: boolean + isEmoji: boolean + isUUID: boolean + isCUID: boolean + isCUID2: boolean + isULID: boolean + isIP: boolean + minLength: number | null + maxLength: number | null +} + +//* ─────────────────────────── ZodRecord ──────────────────────────────────── + +export type ZodRecordDef = { + valueType: Value + keyType: Key + typeName: 'ZodRecord' +} & ZodTypeDef + +export type KeySchema = IZodType +export type RecordType = [string] extends [K] + ? Record + : [number] extends [K] + ? Record + : [symbol] extends [K] + ? Record + : [BRAND] extends [K] + ? Record + : Partial> + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodRecord + extends IZodType< + RecordType, + ZodRecordDef, + RecordType + > { + keySchema: Key + valueSchema: Value + element: Value +} + +//* ─────────────────────────── ZodRef ─────────────────────────────────────── + +export type ZodRefDef = { + typeName: 'ZodRef' + uri: string +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodRef extends IZodType, ZodRefDef> {} + +//* ─────────────────────────── ZodSet ─────────────────────────────────────── + +export type ZodSetDef = { + valueType: Value + typeName: 'ZodSet' + minSize: { + value: number + message?: string + } | null + maxSize: { + value: number + message?: string + } | null +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodSet + extends IZodType, ZodSetDef, Set> { + min(minSize: number, message?: ErrMessage): this + max(maxSize: number, message?: ErrMessage): this + size(size: number, message?: ErrMessage): this + nonempty(message?: ErrMessage): IZodSet +} + +//* ─────────────────────────── ZodSymbol ──────────────────────────────────── + +export type ZodSymbolDef = { + typeName: 'ZodSymbol' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodSymbol extends IZodType {} + +//* ─────────────────────────── ZodEffects ─────────────────────────────────── + +export type RefinementEffect = { + type: 'refinement' + refinement: (arg: T, ctx: RefinementCtx) => any +} + +export type TransformEffect = { + type: 'transform' + transform: (arg: T, ctx: RefinementCtx) => any +} + +export type PreprocessEffect = { + type: 'preprocess' + transform: (arg: T, ctx: RefinementCtx) => any +} + +export type Effect = RefinementEffect | TransformEffect | PreprocessEffect +export type ZodEffectsDef = { + schema: T + typeName: 'ZodEffects' + effect: Effect +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodEffects, Input = input> + extends IZodType, Input> { + innerType(): T + /** + * @deprecated use naked() instead + */ + sourceType(): T +} + +//* ─────────────────────────── ZodUndefined ───────────────────────────────── + +export type ZodUndefinedDef = { + typeName: 'ZodUndefined' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodUndefined extends IZodType {} + +//* ─────────────────────────── ZodUnion ──────────────────────────────────── + +export type DefaultZodUnionOptions = Readonly<[IZodType, IZodType, ...IZodType[]]> +export type ZodUnionOptions = Readonly<[IZodType, ...IZodType[]]> +export type ZodUnionDef = { + options: T + typeName: 'ZodUnion' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodUnion + extends IZodType, T[number]['_input']> { + options: T +} + +//* ─────────────────────────── ZodVoid ───────────────────────────────────── + +export type ZodVoidDef = { + typeName: 'ZodVoid' +} & ZodTypeDef + +/* oxlint-disable typescript-eslint(consistent-type-definitions) */ +export interface IZodVoid extends IZodType {} + +//* ─────────────────────────── BuilderRegistry ────────────────────────────── + +type _CustomParams = CustomErrorParams & { fatal?: boolean } + +export declare function createCustom( + check?: (data: unknown) => any, + params?: string | _CustomParams | ((input: any) => _CustomParams), + fatal?: boolean +): IZodType +export declare function createInstanceOf any>( + cls: T, + params?: _CustomParams +): IZodType> +export declare function createAny(params?: RawCreateParams): IZodAny +export declare function createUnknown(params?: RawCreateParams): IZodUnknown +export declare function createNever(params?: RawCreateParams): IZodNever +export declare function createVoid(params?: RawCreateParams): IZodVoid +export declare function createNull(params?: RawCreateParams): IZodNull +export declare function createUndefined(params?: RawCreateParams): IZodUndefined +export declare function createSymbol(params?: RawCreateParams): IZodSymbol +export declare function createNan(params?: RawCreateParams): IZodNaN +export declare function createString(params?: RawCreateParams & { coerce?: true }): IZodString +export declare function createNumber(params?: RawCreateParams & { coerce?: boolean }): IZodNumber +export declare function createBoolean(params?: RawCreateParams & { coerce?: boolean }): IZodBoolean +export declare function createBigInt(params?: RawCreateParams & { coerce?: boolean }): IZodBigInt +export declare function createDate(params?: RawCreateParams & { coerce?: boolean }): IZodDate +export declare function createRef(uri: string): IZodRef +export declare function createLiteral(value: T, params?: RawCreateParams): IZodLiteral + +export declare function createEnum>( + values: T, + params?: RawCreateParams +): IZodEnum> +export declare function createEnum( + values: T, + params?: RawCreateParams +): IZodEnum +export declare function createEnum( + values: [string, ...string[]], + params?: RawCreateParams +): IZodEnum<[string, ...string[]]> + +export declare function createNativeEnum(values: T, params?: RawCreateParams): IZodNativeEnum +export declare function createArray(schema: T, params?: RawCreateParams): IZodArray +export declare function createObject(shape: T, params?: RawCreateParams): IZodObject +export declare function createStrictObject( + shape: T, + params?: RawCreateParams +): IZodObject +export declare function createLazyObject( + shape: () => T, + params?: RawCreateParams +): IZodObject +export declare function createUnion>( + types: T, + params?: RawCreateParams +): IZodUnion +export declare function createDiscriminatedUnion< + Discriminator extends string, + Types extends [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], +>(discriminator: Discriminator, options: Types, params?: RawCreateParams): IZodDiscriminatedUnion +export declare function createIntersection( + left: T, + right: U, + params?: RawCreateParams +): IZodIntersection + +export declare function createTuple( + schemas: T, + params?: RawCreateParams +): IZodTuple +export declare function createRecord( + valueType: Value, + params?: RawCreateParams +): IZodRecord +export declare function createRecord( + keySchema: Keys, + valueType: Value, + params?: RawCreateParams +): IZodRecord +export declare function createRecord( + first: KeySchema | IZodType, + second?: RawCreateParams | IZodType, + third?: RawCreateParams +): IZodRecord +export declare function createMap( + keyType: Key, + valueType: Value, + params?: RawCreateParams +): IZodMap +export declare function createSet(valueType: Value, params?: RawCreateParams): IZodSet +export declare function createLazy(getter: () => T, params?: RawCreateParams): IZodLazy +export declare function createPromise(schema: T, params?: RawCreateParams): IZodPromise +export declare function createFunction(): IZodFunction, IZodUnknown> +export declare function createFunction>( + args: T +): IZodFunction +export declare function createFunction, U extends IZodType>( + args: T, + returns: U +): IZodFunction +export declare function createFunction< + T extends IZodTuple<[IZodType, ...IZodType[]] | [], IZodType | null>, + U extends IZodType, +>(args: T, returns: U, params: RawCreateParams): IZodFunction +export declare function createFunction( + args?: IZodTuple, + returns?: IZodType, + params?: RawCreateParams +): IZodFunction + +export declare function createEffects( + schema: I, + effect: Effect, + params?: RawCreateParams +): IZodEffects +export declare function createPreprocess( + preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, + schema: I, + params?: RawCreateParams +): IZodEffects +export declare function createOptional(type: T, params?: RawCreateParams): IZodOptional +export declare function createNullable(type: T, params?: RawCreateParams): IZodNullable +export declare function createReadonly(type: T, params?: RawCreateParams): IZodReadonly +export declare function createDefault( + type: T, + value: T['_input'] | (() => NoUndefined), + params?: RawCreateParams +): IZodDefault +export declare function createCatch( + type: T, + catcher: T['_output'] | CatchFn, + params?: RawCreateParams +): IZodCatch +export declare function createPipeline(a: A, b: B): IZodPipeline +export declare function createBranded(type: T): IZodBranded + +export type ZodBuilders = { + any: typeof createAny + array: typeof createArray + bigint: typeof createBigInt + boolean: typeof createBoolean + branded: typeof createBranded + catch: typeof createCatch + custom: typeof createCustom + date: typeof createDate + default: typeof createDefault + discriminatedUnion: typeof createDiscriminatedUnion + effects: typeof createEffects + enum: typeof createEnum + function: typeof createFunction + instanceof: typeof createInstanceOf + intersection: typeof createIntersection + lazy: typeof createLazy + literal: typeof createLiteral + map: typeof createMap + nan: typeof createNan + nativeEnum: typeof createNativeEnum + never: typeof createNever + null: typeof createNull + nullable: typeof createNullable + number: typeof createNumber + object: typeof createObject + optional: typeof createOptional + pipeline: typeof createPipeline + preprocess: typeof createPreprocess + promise: typeof createPromise + record: typeof createRecord + ref: typeof createRef + readonly: typeof createReadonly + set: typeof createSet + strictObject: typeof createStrictObject + string: typeof createString + symbol: typeof createSymbol + transformer: typeof createEffects + tuple: typeof createTuple + undefined: typeof createUndefined + union: typeof createUnion + unknown: typeof createUnknown + void: typeof createVoid +} diff --git a/packages/zui/src/z/types/string/datetime.test.ts b/packages/zui/src/z/utils/datestring-utils.test.ts similarity index 97% rename from packages/zui/src/z/types/string/datetime.test.ts rename to packages/zui/src/z/utils/datestring-utils.test.ts index 4cceaefbb12..9b7c35545df 100644 --- a/packages/zui/src/z/types/string/datetime.test.ts +++ b/packages/zui/src/z/utils/datestring-utils.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect } from 'vitest' -import { generateDatetimeRegex, extractPrecisionAndOffset } from './datetime' +import { generateDatetimeRegex, extractPrecisionAndOffset } from './datestring-utils' describe.concurrent('datetime tests', () => { describe.concurrent('extractPrecisionAndOffset', () => { diff --git a/packages/zui/src/z/types/string/datetime.ts b/packages/zui/src/z/utils/datestring-utils.ts similarity index 100% rename from packages/zui/src/z/types/string/datetime.ts rename to packages/zui/src/z/utils/datestring-utils.ts diff --git a/packages/zui/src/z/utils/index.ts b/packages/zui/src/z/utils/index.ts index f6368524b11..e36ef3244b6 100644 --- a/packages/zui/src/z/utils/index.ts +++ b/packages/zui/src/z/utils/index.ts @@ -4,4 +4,4 @@ export * as fn from './fn-utils' export * as types from './type-utils' export * as assert from './assert-utils' export * as others from './other-utils' -export * as strings from '../types/string/datetime' +export * as datestring from './datestring-utils' diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 681ebb6b072..516e863f6ce 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -1,4 +1,246 @@ -export * from './builders' -export { default } from './builders' // Re-export 'default' explicitly since export * doesn't handle it -export * from './types' -export * from './error' +export { zuiKey } from './consts' +export { isZuiError, isZuiType } from './guards' + +export type { + // ui + ZuiMetadata, + ZuiExtensionObject, + UIComponentDefinitions, + + // error + IZodError as ZodError, + ZodIssue, + + // base type + SafeParseSuccess, + SafeParseError, + SafeParseReturnType, + infer, + input, + output, + TypeOf, + ZodTypeDef as ZodTypeDef, + IZodType as ZodType, + ZodTypeAny, + ZodSchema, + + // any + ZodAnyDef, + IZodAny as ZodAny, + + // array + ZodArrayDef, + IZodArray as ZodArray, + + // bigInt + ZodBigIntDef, + IZodBigInt as ZodBigInt, + ZodBigIntCheck, + + // boolean + ZodBooleanDef, + IZodBoolean as ZodBoolean, + + // branded + ZodBrandedDef, + IZodBranded as ZodBranded, + + // catch + ZodCatchDef, + IZodCatch as ZodCatch, + + // date + ZodDateDef, + IZodDate as ZodDate, + ZodDateCheck, + + // default + ZodDefaultDef, + IZodDefault as ZodDefault, + + // enum + ZodEnumDef, + IZodEnum as ZodEnum, + EnumValues, + EnumValuesMap, + + // never + ZodNeverDef, + IZodNever as ZodNever, + + // nullable + ZodNullableDef, + IZodNullable as ZodNullable, + + // optional + ZodOptionalDef, + IZodOptional as ZodOptional, + + // tuple + ZodTupleDef, + IZodTuple as ZodTuple, + ZodTupleItems, + + // object + ZodObjectDef, + IZodObject as ZodObject, + ZodRawShape, + UnknownKeysParam, + AnyZodObject, + SomeZodObject, + + // discriminatedUnion + ZodDiscriminatedUnionDef, + IZodDiscriminatedUnion as ZodDiscriminatedUnion, + ZodDiscriminatedUnionOption, + + // unknown + ZodUnknownDef, + IZodUnknown as ZodUnknown, + + // function + ZodFunctionDef, + IZodFunction as ZodFunction, + + // intersection + ZodIntersectionDef, + IZodIntersection as ZodIntersection, + + // lazy + ZodLazyDef, + IZodLazy as ZodLazy, + + // literal + ZodLiteralDef, + IZodLiteral as ZodLiteral, + + // map + ZodMapDef, + IZodMap as ZodMap, + + // naN + ZodNaNDef, + IZodNaN as ZodNaN, + + // nativeEnum + ZodNativeEnumDef, + IZodNativeEnum as ZodNativeEnum, + + // null + ZodNullDef, + IZodNull as ZodNull, + + // number + ZodNumberDef, + IZodNumber as ZodNumber, + ZodNumberCheck, + + // pipeline + ZodPipelineDef, + IZodPipeline as ZodPipeline, + + // promise + ZodPromiseDef, + IZodPromise as ZodPromise, + + // readonly + ZodReadonlyDef, + IZodReadonly as ZodReadonly, + + // string + ZodStringDef, + IZodString as ZodString, + ZodStringCheck, + + // record + ZodRecordDef, + IZodRecord as ZodRecord, + + // ref + ZodRefDef, + IZodRef as ZodRef, + + // set + ZodSetDef, + IZodSet as ZodSet, + + // symbol + ZodSymbolDef, + IZodSymbol as ZodSymbol, + + // effects + ZodEffectsDef, + IZodEffects as ZodEffects, + RefinementEffect, + TransformEffect, + PreprocessEffect, + Effect, + + // undefined + ZodUndefinedDef, + IZodUndefined as ZodUndefined, + + // union + ZodUnionDef, + IZodUnion as ZodUnion, + + // void + ZodVoidDef, + IZodVoid as ZodVoid, +} from './typings' + +export { + type ZodNativeType, + type ZodNativeTypeDef, + type ZodNativeTypeName, + + // deprecated + type ZodFirstPartySchemaTypes, + ZodFirstPartyTypeKind, +} from './native' + +export { + coerce, + anyType as any, + arrayType as array, + bigIntType as bigint, + booleanType as boolean, + brandedType as branded, + catchType as catch, + customType as custom, + dateType as date, + defaultType as default, + discriminatedUnionType as discriminatedUnion, + effectsType as effects, + enumType as enum, + functionType as function, + instanceOfType as instanceof, + intersectionType as intersection, + lazyType as lazy, + literalType as literal, + mapType as map, + nanType as nan, + nativeEnumType as nativeEnum, + neverType as never, + nullType as null, + nullableType as nullable, + numberType as number, + objectType as object, + optionalType as optional, + pipelineType as pipeline, + preprocessType as preprocess, + promiseType as promise, + recordType as record, + refType as ref, + readonlyType as readonly, + setType as set, + strictObjectType as strictObject, + stringType as string, + symbolType as symbol, + effectsType as transformer, + tupleType as tuple, + undefinedType as undefined, + unionType as union, + unknownType as unknown, + voidType as void, +} from './builders' From a32d262fca6ae0e5152567a5fdfa96016a92988d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Thu, 26 Feb 2026 13:18:43 -0500 Subject: [PATCH 19/50] chore(zui): rename RawCreateParams to ZodCreateParams --- packages/zui/src/z/builders.ts | 22 ++++---- packages/zui/src/z/typings.ts | 92 +++++++++++++++++----------------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index e59f315171b..1aea3a14e5e 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -47,7 +47,7 @@ import type { IZodTuple, IZodType, KeySchema, - RawCreateParams, + ZodCreateParams, ZodErrorMap, ZuiExtensionObject, ZodBuilders, @@ -60,7 +60,7 @@ type _ProcessedCreateParams = { } const _processCreateParams = ( - params: RawCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) + params: ZodCreateParams & ({ supportsExtensions?: 'secret'[] } | undefined) ): _ProcessedCreateParams => { if (!params) return {} @@ -187,7 +187,7 @@ export const refType: ZodBuilders['ref'] = (uri) => new ZodRefImpl({ typeName: ' export const literalType: ZodBuilders['literal'] = (value, params) => new ZodLiteralImpl({ value, typeName: 'ZodLiteral', ..._processCreateParams(params) }) -export const enumType: ZodBuilders['enum'] = ((values: [string, ...string[]], params?: RawCreateParams) => +export const enumType: ZodBuilders['enum'] = ((values: [string, ...string[]], params?: ZodCreateParams) => new ZodEnumImpl({ values, typeName: 'ZodEnum', ..._processCreateParams(params) })) as ZodBuilders['enum'] export const nativeEnumType: ZodBuilders['nativeEnum'] = (values, params) => @@ -242,8 +242,8 @@ export const tupleType: ZodBuilders['tuple'] = (schemas, params) => { export const recordType: ZodBuilders['record'] = ( first: KeySchema | IZodType, - second?: RawCreateParams | IZodType, - third?: RawCreateParams + second?: ZodCreateParams | IZodType, + third?: ZodCreateParams ): IZodRecord => { if (second instanceof ZodBaseTypeImpl) { return new ZodRecordImpl({ @@ -276,7 +276,7 @@ export const promiseType: ZodBuilders['promise'] = (schema, params) => export const functionType: ZodBuilders['function'] = ( args?: IZodTuple, returns?: IZodType, - params?: RawCreateParams + params?: ZodCreateParams ) => { return new ZodFunctionImpl({ args: args ? args : tupleType([]).rest(unknownType()), @@ -378,19 +378,19 @@ setBuilders({ }) export const coerce = { - string(arg?: RawCreateParams & { coerce?: true }): ReturnType { + string(arg?: ZodCreateParams & { coerce?: true }): ReturnType { return stringType({ ...arg, coerce: true }) }, - number(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + number(arg?: ZodCreateParams & { coerce?: boolean }): ReturnType { return numberType({ ...arg, coerce: true }) }, - boolean(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + boolean(arg?: ZodCreateParams & { coerce?: boolean }): ReturnType { return booleanType({ ...arg, coerce: true }) }, - bigint(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + bigint(arg?: ZodCreateParams & { coerce?: boolean }): ReturnType { return bigIntType({ ...arg, coerce: true }) }, - date(arg?: RawCreateParams & { coerce?: boolean }): ReturnType { + date(arg?: ZodCreateParams & { coerce?: boolean }): ReturnType { return dateType({ ...arg, coerce: true }) }, } diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 79d11003d99..14f45d6f394 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -319,7 +319,7 @@ export type RefinementCtx = { //* ─────────────────────────── Base Type ─────────────────────────────────── -export type RawCreateParams = +export type ZodCreateParams = | { errorMap?: ZodErrorMap invalid_type_error?: string @@ -728,11 +728,11 @@ export interface IZodEnum extract( values: ToExtract, - newDef?: RawCreateParams + newDef?: ZodCreateParams ): IZodEnum> exclude( values: ToExclude, - newDef?: RawCreateParams + newDef?: ZodCreateParams ): IZodEnum>, [string, ...string[]]>> } @@ -1630,86 +1630,86 @@ export declare function createInstanceOf> -export declare function createAny(params?: RawCreateParams): IZodAny -export declare function createUnknown(params?: RawCreateParams): IZodUnknown -export declare function createNever(params?: RawCreateParams): IZodNever -export declare function createVoid(params?: RawCreateParams): IZodVoid -export declare function createNull(params?: RawCreateParams): IZodNull -export declare function createUndefined(params?: RawCreateParams): IZodUndefined -export declare function createSymbol(params?: RawCreateParams): IZodSymbol -export declare function createNan(params?: RawCreateParams): IZodNaN -export declare function createString(params?: RawCreateParams & { coerce?: true }): IZodString -export declare function createNumber(params?: RawCreateParams & { coerce?: boolean }): IZodNumber -export declare function createBoolean(params?: RawCreateParams & { coerce?: boolean }): IZodBoolean -export declare function createBigInt(params?: RawCreateParams & { coerce?: boolean }): IZodBigInt -export declare function createDate(params?: RawCreateParams & { coerce?: boolean }): IZodDate +export declare function createAny(params?: ZodCreateParams): IZodAny +export declare function createUnknown(params?: ZodCreateParams): IZodUnknown +export declare function createNever(params?: ZodCreateParams): IZodNever +export declare function createVoid(params?: ZodCreateParams): IZodVoid +export declare function createNull(params?: ZodCreateParams): IZodNull +export declare function createUndefined(params?: ZodCreateParams): IZodUndefined +export declare function createSymbol(params?: ZodCreateParams): IZodSymbol +export declare function createNan(params?: ZodCreateParams): IZodNaN +export declare function createString(params?: ZodCreateParams & { coerce?: true }): IZodString +export declare function createNumber(params?: ZodCreateParams & { coerce?: boolean }): IZodNumber +export declare function createBoolean(params?: ZodCreateParams & { coerce?: boolean }): IZodBoolean +export declare function createBigInt(params?: ZodCreateParams & { coerce?: boolean }): IZodBigInt +export declare function createDate(params?: ZodCreateParams & { coerce?: boolean }): IZodDate export declare function createRef(uri: string): IZodRef -export declare function createLiteral(value: T, params?: RawCreateParams): IZodLiteral +export declare function createLiteral(value: T, params?: ZodCreateParams): IZodLiteral export declare function createEnum>( values: T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodEnum> export declare function createEnum( values: T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodEnum export declare function createEnum( values: [string, ...string[]], - params?: RawCreateParams + params?: ZodCreateParams ): IZodEnum<[string, ...string[]]> -export declare function createNativeEnum(values: T, params?: RawCreateParams): IZodNativeEnum -export declare function createArray(schema: T, params?: RawCreateParams): IZodArray -export declare function createObject(shape: T, params?: RawCreateParams): IZodObject +export declare function createNativeEnum(values: T, params?: ZodCreateParams): IZodNativeEnum +export declare function createArray(schema: T, params?: ZodCreateParams): IZodArray +export declare function createObject(shape: T, params?: ZodCreateParams): IZodObject export declare function createStrictObject( shape: T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodObject export declare function createLazyObject( shape: () => T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodObject export declare function createUnion>( types: T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodUnion export declare function createDiscriminatedUnion< Discriminator extends string, Types extends [ZodDiscriminatedUnionOption, ...ZodDiscriminatedUnionOption[]], ->(discriminator: Discriminator, options: Types, params?: RawCreateParams): IZodDiscriminatedUnion +>(discriminator: Discriminator, options: Types, params?: ZodCreateParams): IZodDiscriminatedUnion export declare function createIntersection( left: T, right: U, - params?: RawCreateParams + params?: ZodCreateParams ): IZodIntersection export declare function createTuple( schemas: T, - params?: RawCreateParams + params?: ZodCreateParams ): IZodTuple export declare function createRecord( valueType: Value, - params?: RawCreateParams + params?: ZodCreateParams ): IZodRecord export declare function createRecord( keySchema: Keys, valueType: Value, - params?: RawCreateParams + params?: ZodCreateParams ): IZodRecord export declare function createRecord( first: KeySchema | IZodType, - second?: RawCreateParams | IZodType, - third?: RawCreateParams + second?: ZodCreateParams | IZodType, + third?: ZodCreateParams ): IZodRecord export declare function createMap( keyType: Key, valueType: Value, - params?: RawCreateParams + params?: ZodCreateParams ): IZodMap -export declare function createSet(valueType: Value, params?: RawCreateParams): IZodSet -export declare function createLazy(getter: () => T, params?: RawCreateParams): IZodLazy -export declare function createPromise(schema: T, params?: RawCreateParams): IZodPromise +export declare function createSet(valueType: Value, params?: ZodCreateParams): IZodSet +export declare function createLazy(getter: () => T, params?: ZodCreateParams): IZodLazy +export declare function createPromise(schema: T, params?: ZodCreateParams): IZodPromise export declare function createFunction(): IZodFunction, IZodUnknown> export declare function createFunction>( args: T @@ -1721,35 +1721,35 @@ export declare function createFunction, U extends IZodType, ->(args: T, returns: U, params: RawCreateParams): IZodFunction +>(args: T, returns: U, params: ZodCreateParams): IZodFunction export declare function createFunction( args?: IZodTuple, returns?: IZodType, - params?: RawCreateParams + params?: ZodCreateParams ): IZodFunction export declare function createEffects( schema: I, effect: Effect, - params?: RawCreateParams + params?: ZodCreateParams ): IZodEffects export declare function createPreprocess( preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, schema: I, - params?: RawCreateParams + params?: ZodCreateParams ): IZodEffects -export declare function createOptional(type: T, params?: RawCreateParams): IZodOptional -export declare function createNullable(type: T, params?: RawCreateParams): IZodNullable -export declare function createReadonly(type: T, params?: RawCreateParams): IZodReadonly +export declare function createOptional(type: T, params?: ZodCreateParams): IZodOptional +export declare function createNullable(type: T, params?: ZodCreateParams): IZodNullable +export declare function createReadonly(type: T, params?: ZodCreateParams): IZodReadonly export declare function createDefault( type: T, value: T['_input'] | (() => NoUndefined), - params?: RawCreateParams + params?: ZodCreateParams ): IZodDefault export declare function createCatch( type: T, catcher: T['_output'] | CatchFn, - params?: RawCreateParams + params?: ZodCreateParams ): IZodCatch export declare function createPipeline(a: A, b: B): IZodPipeline export declare function createBranded(type: T): IZodBranded From f921d175a67f90c3347d2c29d0c4a132fb649c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Thu, 26 Feb 2026 15:12:57 -0500 Subject: [PATCH 20/50] chore(zui): rm dupplicated typings with type-utils --- packages/zui/src/z/typings.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 14f45d6f394..f901c92869f 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -1,5 +1,16 @@ import type * as transforms from '../transforms' -import { Cast, UnionToTuple, NoNever, Flatten, NoUndefined, Primitive, SafeOmit, Writeable } from './utils/type-utils' +import { + Cast, + UnionToTuple, + NoNever, + Flatten, + NoUndefined, + Primitive, + SafeOmit, + Writeable, + AddQuestionMarks, + ExtendShape, +} from './utils/type-utils' //* ─────────────────────────── UI & Metadata ─────────────────────────────── @@ -820,17 +831,6 @@ export type RequiredKeys = { [k in keyof T]: undefined extends T[k] ? never : k }[keyof T] -export type AddQuestionMarks< - T extends object, - R extends keyof T = RequiredKeys, - O extends keyof T = OptionalKeys, -> = Pick & - Partial> & { - [k in keyof T]?: unknown - } - -export type ExtendShape = Flatten & B> - export type ZodRawShape = { [k: string]: IZodType } From a53f2e713a3d814e9b244259be3054065922d768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Thu, 26 Feb 2026 16:14:19 -0500 Subject: [PATCH 21/50] chore(zui): add todo comments --- packages/zui/src/z/typings.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index f901c92869f..2c4b037532a 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -1266,7 +1266,9 @@ export type ZodPipelineDef - extends IZodType, A['_input']> {} + extends IZodType, A['_input']> { + // TODO: allow access to A and B types without accessing _def +} //* ─────────────────────────── ZodPromise ─────────────────────────────────── @@ -1539,6 +1541,7 @@ export interface IZodSet max(maxSize: number, message?: ErrMessage): this size(size: number, message?: ErrMessage): this nonempty(message?: ErrMessage): IZodSet + // TODO: allow access to Value type without accessing _def } //* ─────────────────────────── ZodSymbol ──────────────────────────────────── From 151fc6dd2fe044963650475a7b64f5f28da61af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Fri, 27 Feb 2026 14:04:36 -0500 Subject: [PATCH 22/50] feat(zui): rm deepPartial method on zod objects --- packages/zui/src/z/__tests__/partials.test.ts | 96 ------------------- packages/zui/src/z/types/object/index.ts | 37 ------- packages/zui/src/z/typings.ts | 4 - 3 files changed, 137 deletions(-) diff --git a/packages/zui/src/z/__tests__/partials.test.ts b/packages/zui/src/z/__tests__/partials.test.ts index c14a8fba30b..668752cb47d 100644 --- a/packages/zui/src/z/__tests__/partials.test.ts +++ b/packages/zui/src/z/__tests__/partials.test.ts @@ -32,94 +32,6 @@ test('shallow partial parse', () => { }) }) -test('deep partial inference', () => { - const deep = nested.deepPartial() - const asdf = deep.shape.array.unwrap().element.shape.asdf.unwrap() - asdf.parse('asdf') - type deep = z.infer - type correct = { - array?: { asdf?: string }[] - name?: string | undefined - age?: number | undefined - outer?: { inner?: string | undefined } | undefined - } - - utils.assert.assertEqual(true) -}) - -test('deep partial parse', () => { - const deep = nested.deepPartial() - - expect(deep.shape.name.typeName).toBe('ZodOptional') - expect(deep.shape.outer.typeName).toBe('ZodOptional') - expect(deep.shape.outer._def.innerType.typeName).toBe('ZodObject') - expect(deep.shape.outer._def.innerType.shape.inner.typeName).toBe('ZodOptional') - expect(deep.shape.outer._def.innerType.shape.inner._def.innerType.typeName).toBe('ZodString') -}) - -test('deep partial runtime tests', () => { - const deep = nested.deepPartial() - deep.parse({}) - deep.parse({ - outer: {}, - }) - deep.parse({ - name: 'asdf', - age: 23143, - outer: { - inner: 'adsf', - }, - }) -}) - -test('deep partial optional/nullable', () => { - const schema = z - .object({ - name: z.string().optional(), - age: z.number().nullable(), - }) - .deepPartial() - - expect(schema.shape.name.unwrap().typeName).toBe('ZodOptional') - expect(schema.shape.age.unwrap().typeName).toBe('ZodNullable') -}) - -test('deep partial tuple', () => { - const schema = z - .object({ - tuple: z.tuple([ - z.object({ - name: z.string().optional(), - age: z.number().nullable(), - }), - ]), - }) - .deepPartial() - - expect(schema.shape.tuple.unwrap().items[0].shape.name.typeName).toBe('ZodOptional') -}) - -test('deep partial inference', () => { - const mySchema = z.object({ - name: z.string(), - array: z.array(z.object({ asdf: z.string() })), - tuple: z.tuple([z.object({ value: z.string() })]), - }) - - const partialed = mySchema.deepPartial() - type partialed = z.infer - type expected = { - name?: string | undefined - array?: - | { - asdf?: string | undefined - }[] - | undefined - tuple?: [{ value?: string }] | undefined - } - utils.assert.assertEqual(true) -}) - test('required', () => { const object = z.object({ name: z.string(), @@ -228,11 +140,3 @@ test('partial with mask -- ignore falsy values', async () => { masked.parse({ country: 'US' }) await masked.parseAsync({ country: 'US' }) }) - -test('deeppartial array', () => { - const schema = z.object({ array: z.string().array().min(42) }).deepPartial() - - schema.parse({}) - - expect(schema.safeParse({ array: [] }).success).toBe(false) -}) diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 170954185a3..ccd17c685f9 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -442,13 +442,6 @@ export class ZodObjectImpl< return objSchema } - /** - * @deprecated - */ - deepPartial(): any { - return this._deepPartialify(this) - } - partial(): IZodObject< { [k in keyof T]: IZodOptional @@ -558,34 +551,4 @@ export class ZodObjectImpl< } return thisAdditionalProperties.isEqual(thatAdditionalProperties) } - - private _deepPartialify(_schema: IZodType): IZodType { - const schema = _schema as ZodNativeType - if (schema.typeName === 'ZodObject') { - const newShape: Record = {} - - for (const [key, fieldSchema] of Object.entries(schema.shape)) { - newShape[key] = builders.optional(this._deepPartialify(fieldSchema)) - } - - return new ZodObjectImpl({ - ...schema._def, - shape: () => newShape, - }) - } else if (schema.typeName === 'ZodArray') { - const element = this._deepPartialify(schema.element) - const newArray = schema.clone() - newArray._def.type = element // TODO: allow cloning with modifications to avoid this mutation - return newArray - } else if (schema.typeName === 'ZodOptional') { - return builders.optional(this._deepPartialify(schema.unwrap())) - } else if (schema.typeName === 'ZodNullable') { - return builders.nullable(this._deepPartialify(schema.unwrap())) - } else if (schema.typeName === 'ZodTuple') { - const partialItems = schema.items.map((item) => this._deepPartialify(item)) as [IZodType, ...IZodType[]] - return builders.tuple(partialItems) - } else { - return schema - } - } } diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 2c4b037532a..828abfaa215 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -989,10 +989,6 @@ export interface IZodObject< >( mask: Mask ): IZodObject, UnknownKeys> - /** - * @deprecated - */ - deepPartial(): DeepPartial partial(): IZodObject< { [k in keyof T]: IZodOptional From 97438a8e8985995587dc986fe64d2b35fef37801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Fri, 27 Feb 2026 14:20:24 -0500 Subject: [PATCH 23/50] chore(zui): move back primitive type in typings --- packages/zui/src/transforms/common/utils.ts | 2 +- packages/zui/src/z/types/discriminatedUnion/index.ts | 5 +++-- packages/zui/src/z/types/literal/index.ts | 5 ++--- packages/zui/src/z/typings.ts | 2 +- packages/zui/src/z/utils/type-utils.ts | 1 - 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/zui/src/transforms/common/utils.ts b/packages/zui/src/transforms/common/utils.ts index 09eb7f47175..bc62cc1f49b 100644 --- a/packages/zui/src/transforms/common/utils.ts +++ b/packages/zui/src/transforms/common/utils.ts @@ -1,4 +1,4 @@ -import { Primitive } from '../../z/utils/type-utils' +import { Primitive } from '../../z/typings' /** * @returns a valid typescript literal type usable in `type MyType = ${x}` diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index bde9fc742b1..9610d3b7b3f 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -7,11 +7,12 @@ import type { input, output, IZodObject, + Primitive, } from '../../typings' import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' -const getDiscriminator = (_type: IZodType | undefined): utils.types.Primitive[] => { +const getDiscriminator = (_type: IZodType | undefined): Primitive[] => { const type = _type as ZodNativeType | undefined if (!type) return [] if (type.typeName === 'ZodLazy') { @@ -154,7 +155,7 @@ export class ZodDiscriminatedUnionImpl< Options extends ZodDiscriminatedUnionOption[] = ZodDiscriminatedUnionOption[], >(discriminator: Discriminator, options: Options) { // Get all the valid discriminator values - const optionsMap: Map = new Map() + const optionsMap: Map = new Map() // try { for (const type of options) { diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index dbd95b2f61e..bf5e667ed87 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,9 +1,8 @@ import { isEqual } from 'lodash-es' -import type { IZodLiteral, ZodLiteralDef } from '../../typings' -import * as utils from '../../utils' +import type { IZodLiteral, Primitive, ZodLiteralDef } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' -export class ZodLiteralImpl +export class ZodLiteralImpl extends ZodBaseTypeImpl> implements IZodLiteral { diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 828abfaa215..50c7c73373a 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -5,7 +5,6 @@ import { NoNever, Flatten, NoUndefined, - Primitive, SafeOmit, Writeable, AddQuestionMarks, @@ -1134,6 +1133,7 @@ export interface IZodLazy extends IZodType = { value: T typeName: 'ZodLiteral' diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts index 326e93b05a1..22ae092c209 100644 --- a/packages/zui/src/z/utils/type-utils.ts +++ b/packages/zui/src/z/utils/type-utils.ts @@ -4,7 +4,6 @@ export type IsAny = 0 extends 1 & T ? true : false export type NoUndefined = T extends undefined ? never : T export type Satisfies = X export type SafeOmit = Omit -export type Primitive = string | number | bigint | boolean | symbol | null | undefined export type Cast = A extends B ? A : B export type Writeable = { From 96718da474e256cc21a3244d175145916ad4dc7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Fri, 27 Feb 2026 14:31:50 -0500 Subject: [PATCH 24/50] chore(zui): move zod native type to typings file --- packages/zui/src/z/guards.ts | 3 +- packages/zui/src/z/native.ts | 91 +------------------ .../src/z/types/discriminatedUnion/index.ts | 2 +- packages/zui/src/z/types/function/index.ts | 2 +- packages/zui/src/z/types/object/index.ts | 2 +- packages/zui/src/z/types/union/index.ts | 11 ++- packages/zui/src/z/typings.ts | 50 +++++++++- packages/zui/src/z/z.ts | 16 ++-- 8 files changed, 72 insertions(+), 105 deletions(-) diff --git a/packages/zui/src/z/guards.ts b/packages/zui/src/z/guards.ts index 2d17faacdd2..3852479b5de 100644 --- a/packages/zui/src/z/guards.ts +++ b/packages/zui/src/z/guards.ts @@ -1,7 +1,6 @@ import { ZodError } from './error' -import { ZodNativeType } from './native' import { ZodBaseTypeImpl } from './types' -import { IZodError } from './typings' +import { IZodError, ZodNativeType } from './typings' export const isZuiError = (thrown: unknown): thrown is IZodError => thrown instanceof ZodError || (thrown instanceof Error && '__type__' in thrown && thrown.__type__ === 'ZuiError') diff --git a/packages/zui/src/z/native.ts b/packages/zui/src/z/native.ts index 21042c79c04..ae3395edf02 100644 --- a/packages/zui/src/z/native.ts +++ b/packages/zui/src/z/native.ts @@ -1,96 +1,11 @@ -import { - IZodAny, - IZodArray, - IZodBigInt, - IZodBoolean, - IZodBranded, - IZodCatch, - IZodDate, - IZodDefault, - IZodDiscriminatedUnion, - IZodEnum, - IZodFunction, - IZodIntersection, - IZodLazy, - IZodLiteral, - IZodMap, - IZodNaN, - IZodNativeEnum, - IZodNever, - IZodNull, - IZodNullable, - IZodNumber, - IZodObject, - IZodOptional, - IZodPipeline, - IZodPromise, - IZodReadonly, - IZodRecord, - IZodRef, - IZodSet, - IZodString, - IZodSymbol, - IZodEffects, - IZodTuple, - IZodUndefined, - IZodUnion, - IZodUnknown, - IZodVoid, -} from './typings' +import { ZodNativeTypeName } from './typings' /** - * @deprecated - use ZodNativeSchema instead - */ -export type ZodFirstPartySchemaTypes = ZodNativeType -export type ZodNativeType = - | IZodAny - | IZodArray - | IZodBigInt - | IZodBoolean - | IZodBranded - | IZodCatch - | IZodDate - | IZodDefault - | IZodDiscriminatedUnion - | IZodEnum - | IZodFunction - | IZodIntersection - | IZodLazy - | IZodLiteral - | IZodMap - | IZodNaN - | IZodNativeEnum - | IZodNever - | IZodNull - | IZodNullable - | IZodNumber - | IZodObject - | IZodOptional - | IZodPipeline - | IZodPromise - | IZodReadonly - | IZodRecord - | IZodRef - | IZodSet - | IZodString - | IZodSymbol - | IZodEffects - | IZodTuple - | IZodUndefined - | IZodUnion - | IZodUnknown - | IZodVoid - -export type ZodNativeTypeDef = ZodNativeType['_def'] - -/** - * @deprecated - use ZodNativeSchemaType instead + * @deprecated - use ZodNativeTypeName instead */ export type ZodFirstPartyTypeKind = ZodNativeTypeName -export type ZodNativeTypeName = ZodNativeTypeDef['typeName'] - /** - * @deprecated - use ZodNativeSchemaType instead + * @deprecated - use ZodNativeTypeName instead */ export const ZodFirstPartyTypeKind = { ZodString: 'ZodString', diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index 9610d3b7b3f..ca64ce7c92d 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,4 +1,3 @@ -import type { ZodNativeType } from '../../native' import type { IZodType, IZodDiscriminatedUnion, @@ -8,6 +7,7 @@ import type { output, IZodObject, Primitive, + ZodNativeType, } from '../../typings' import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 651170b9ca8..b02db7c6273 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,6 +1,5 @@ import { defaultErrorMap, getErrorMap, ZodError } from '../../error' import { builders } from '../../internal-builders' -import type { ZodNativeType } from '../../native' import type { IZodType, IZodFunction, @@ -12,6 +11,7 @@ import type { InnerTypeOfFunction, IZodUnknown, IZodPromise, + ZodNativeType, } from '../../typings' import * as utils from '../../utils' diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index ccd17c685f9..0e639187a15 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,5 +1,4 @@ import { builders } from '../../internal-builders' -import { ZodNativeType } from '../../native' import type { IZodObject, IZodType, @@ -13,6 +12,7 @@ import type { KeyOfObject, IZodOptional, IZodEnum, + ZodNativeType, } from '../../typings' import * as utils from '../../utils' import { diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index a220b9518e9..7a99ce6253f 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,7 +1,14 @@ import { ZodError } from '../../error' import { builders } from '../../internal-builders' -import type { ZodNativeType } from '../../native' -import type { DefaultZodUnionOptions, IZodUnion, IZodType, ZodUnionDef, ZodUnionOptions, ZodIssue } from '../../typings' +import type { + DefaultZodUnionOptions, + IZodUnion, + IZodType, + ZodUnionDef, + ZodUnionOptions, + ZodIssue, + ZodNativeType, +} from '../../typings' import * as utils from '../../utils' import { ZodBaseTypeImpl, diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 50c7c73373a..96480028ee5 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -1616,7 +1616,55 @@ export type ZodVoidDef = { /* oxlint-disable typescript-eslint(consistent-type-definitions) */ export interface IZodVoid extends IZodType {} -//* ─────────────────────────── BuilderRegistry ────────────────────────────── +//* ─────────────────────────── ZodNativeType ─────────────────────────────── + +/** + * @deprecated - use ZodNativeType instead + */ +export type ZodFirstPartySchemaTypes = ZodNativeType +export type ZodNativeType = + | IZodAny + | IZodArray + | IZodBigInt + | IZodBoolean + | IZodBranded + | IZodCatch + | IZodDate + | IZodDefault + | IZodDiscriminatedUnion + | IZodEnum + | IZodFunction + | IZodIntersection + | IZodLazy + | IZodLiteral + | IZodMap + | IZodNaN + | IZodNativeEnum + | IZodNever + | IZodNull + | IZodNullable + | IZodNumber + | IZodObject + | IZodOptional + | IZodPipeline + | IZodPromise + | IZodReadonly + | IZodRecord + | IZodRef + | IZodSet + | IZodString + | IZodSymbol + | IZodEffects + | IZodTuple + | IZodUndefined + | IZodUnion + | IZodUnknown + | IZodVoid + +export type ZodNativeTypeDef = ZodNativeType['_def'] +export type ZodNativeTypeName = ZodNativeTypeDef['typeName'] + +//* ─────────────────────────── Builders ────────────────────────────── type _CustomParams = CustomErrorParams & { fatal?: boolean } diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 516e863f6ce..1b795175772 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -187,17 +187,15 @@ export type { // void ZodVoidDef, IZodVoid as ZodVoid, + + // native + ZodNativeType, + ZodNativeTypeDef, + ZodNativeTypeName, + ZodFirstPartySchemaTypes, } from './typings' -export { - type ZodNativeType, - type ZodNativeTypeDef, - type ZodNativeTypeName, - - // deprecated - type ZodFirstPartySchemaTypes, - ZodFirstPartyTypeKind, -} from './native' +export { ZodFirstPartyTypeKind } from './native' export { coerce, From 8683846fb055b2d400e2e8609e2904c75f219afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 2 Mar 2026 13:31:35 -0500 Subject: [PATCH 25/50] fix(zui): simplify outputed json schema --- bots/clog/add.ts | 18 ++++++++++++ .../transforms/zui-to-json-schema/index.ts | 29 ++++++++++++++----- packages/zui/src/z/guards.ts | 10 ++++--- 3 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 bots/clog/add.ts diff --git a/bots/clog/add.ts b/bots/clog/add.ts new file mode 100644 index 00000000000..9868b36fca2 --- /dev/null +++ b/bots/clog/add.ts @@ -0,0 +1,18 @@ +import cmd from '@botpress/cli' + +void cmd.add({ + packageRef: `${__dirname}/../../integrations/slack`, + + botpressHome: '~/.botpress', + confirm: true, + installPath: __dirname, + json: false, + useDev: false, + + alias: undefined, + apiUrl: undefined, + profile: undefined, + token: undefined, + verbose: false, + workspaceId: undefined, +}) diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index b78c96e5723..e40c8d9f5cb 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -82,19 +82,12 @@ export function toJSONSchema(schema: z.ZodType): json.Schema { .map(([key, value]) => [key, value.mandatory()] satisfies [string, z.ZodType]) .map(([key, value]) => [key, toJSONSchema(value)] satisfies [string, json.Schema]) - let additionalProperties: json.ObjectSchema['additionalProperties'] = false - if (z.isZuiType(s._def.unknownKeys)) { - additionalProperties = toJSONSchema(s._def.unknownKeys) - } else if (s._def.unknownKeys === 'passthrough') { - additionalProperties = true - } - return { type: 'object', description: s.description, properties: Object.fromEntries(properties), required, - additionalProperties, + additionalProperties: additionalPropertiesSchema(s._def), 'x-zui': s._def['x-zui'], } satisfies json.ObjectSchema @@ -282,3 +275,23 @@ const nullSchema = (def?: z.ZodTypeDef): json.NullSchema => ({ description: def?.description, 'x-zui': def?.['x-zui'], }) + +const additionalPropertiesSchema = (def: z.ZodObjectDef): NonNullable => { + if (def.unknownKeys === 'passthrough') { + return true + } + + if (def.unknownKeys === 'strict') { + return false + } + + if (!z.isZuiType(def.unknownKeys)) { + return false + } + + if (def.unknownKeys.typeName === 'ZodNever') { + return false + } + + return toJSONSchema(def.unknownKeys) +} diff --git a/packages/zui/src/z/guards.ts b/packages/zui/src/z/guards.ts index 3852479b5de..f0427366ddc 100644 --- a/packages/zui/src/z/guards.ts +++ b/packages/zui/src/z/guards.ts @@ -2,9 +2,11 @@ import { ZodError } from './error' import { ZodBaseTypeImpl } from './types' import { IZodError, ZodNativeType } from './typings' +const _isError = (value: unknown): value is Error => value instanceof Error +const _isObject = (value: unknown): value is object => typeof value === 'object' && value !== null + export const isZuiError = (thrown: unknown): thrown is IZodError => - thrown instanceof ZodError || (thrown instanceof Error && '__type__' in thrown && thrown.__type__ === 'ZuiError') + thrown instanceof ZodError || (_isError(thrown) && '__type__' in thrown && thrown.__type__ === 'ZuiError') -export const isZuiType = (value: unknown): value is ZodNativeType => value instanceof ZodBaseTypeImpl -// TODO: also accept objects with a __type__ property set to 'ZuiType' to allow for cross-realm compatibility -// || (typeof value === 'object' && value !== null && '__type__' in value && value.__type__ === 'ZuiType') +export const isZuiType = (value: unknown): value is ZodNativeType => + value instanceof ZodBaseTypeImpl || (_isObject(value) && '__type__' in value && value.__type__ === 'ZuiType') From 347667a8d9e02fceeb3b34bc0fd8f319048d409c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 2 Mar 2026 15:43:43 -0500 Subject: [PATCH 26/50] feat(zui): export zui guard to discriminate between different zod types (#14983) --- .../src/transforms/common/eval-zui-string.ts | 2 +- .../json-schema-to-zui.test.ts | 5 +- .../transforms/zui-from-json-schema/index.ts | 2 +- .../parsers/object.ts | 2 +- .../transforms/zui-to-json-schema/index.ts | 2 +- .../zui-to-typescript-schema/index.test.ts | 2 +- .../zui-to-typescript-type/index.ts | 35 +++--- packages/zui/src/z/__tests__/deref.test.ts | 2 +- .../zui/src/z/__tests__/mandatory.test.ts | 8 +- packages/zui/src/z/__tests__/zui.test.ts | 2 +- packages/zui/src/z/guards.ts | 104 +++++++++++++++++- packages/zui/src/z/types/function/index.ts | 5 +- packages/zui/src/z/types/object/index.ts | 8 +- packages/zui/src/z/types/union/index.ts | 15 +-- packages/zui/src/z/z.ts | 2 +- 15 files changed, 136 insertions(+), 60 deletions(-) diff --git a/packages/zui/src/transforms/common/eval-zui-string.ts b/packages/zui/src/transforms/common/eval-zui-string.ts index cdeeb83ed00..5e607a65f9f 100644 --- a/packages/zui/src/transforms/common/eval-zui-string.ts +++ b/packages/zui/src/transforms/common/eval-zui-string.ts @@ -20,7 +20,7 @@ export const evalZuiString = (zuiString: string): EvalZuiStringResult => { return { sucess: false, error: `Failed to evaluate schema: ${err.message}` } } - if (!z.isZuiType(result)) { + if (!z.is.zuiType(result)) { return { sucess: false, error: `String "${zuiString}" does not evaluate to a Zod schema` } } diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts index 933acf72e2a..71bc9c6abea 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts @@ -1,12 +1,11 @@ import { describe, expect, test, it } from 'vitest' -import { ZodNativeType, z, zuiKey } from '../../z' +import { z, ZodType, zuiKey } from '../../z' import { jsonSchemaToZodStr, fromJSONSchemaLegacy, traverseZodDefinitions } from '.' import { toJSONSchemaLegacy } from '../zui-to-json-schema-legacy/zui-extension' import { JSONSchema7 } from 'json-schema' import { assert } from '../../assertions.utils.test' -import { JsonSchema7Type } from '../zui-to-json-schema-legacy/parseDef' -const testZuiConversion = (zuiObject: ZodNativeType) => { +const testZuiConversion = (zuiObject: ZodType) => { const jsonSchema = toJSONSchemaLegacy(zuiObject) const asZui = fromJSONSchemaLegacy(jsonSchema) const convertedJsonSchema = toJSONSchemaLegacy(asZui) diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index 983fa50db34..0f088b63a98 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -102,7 +102,7 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { } if (schema.type === 'integer') { - const zSchema = toZuiPrimitive('number', schema) as z.ZodNativeType + const zSchema = toZuiPrimitive('number', schema) if (zSchema.typeName === 'ZodNumber') { return zSchema.int() } diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts index 5ddee9ce494..af8ecce3a89 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts @@ -11,7 +11,7 @@ export type JsonSchema7ObjectType = { } const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonSchema7Type => { - if (z.isZuiType(def.unknownKeys)) { + if (z.is.zuiType(def.unknownKeys)) { return ( parseDef((def.unknownKeys as ZodTypeAny)._def, { ...refs, diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index e40c8d9f5cb..4aa5596552e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -285,7 +285,7 @@ const additionalPropertiesSchema = (def: z.ZodObjectDef): NonNullable { +const evalZui = (source: string): z.ZodType => { const evalResult = evalZuiString(source) if (!evalResult.sucess) { throw new Error(`${evalResult.error}: ${source}`) diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index ffe44bbf4cf..e8062226746 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -126,16 +126,15 @@ function sUnwrapZod(schema: z.ZodType | KeyValue | FnParameters | Declaration | if (schema instanceof KeyValue) { let optionalValue: z.ZodOptional | undefined = undefined - const schemaValue = schema.value as z.ZodNativeType - if (schemaValue.typeName === 'ZodOptional') { - optionalValue = schemaValue - } else if (schemaValue.typeName === 'ZodDefault' && config.treatDefaultAsOptional) { - optionalValue = schemaValue._def.innerType.optional() + if (z.is.zuiOptional(schema.value)) { + optionalValue = schema.value + } else if (z.is.zuiDefault(schema.value) && config.treatDefaultAsOptional) { + optionalValue = schema.value._def.innerType.optional() } if (optionalValue) { let innerType = optionalValue._def.innerType - if (z.isZuiType(innerType) && !innerType.description && optionalValue.description) { + if (z.is.zuiType(innerType) && !innerType.description && optionalValue.description) { innerType = innerType?.describe(optionalValue.description) } @@ -146,27 +145,26 @@ function sUnwrapZod(schema: z.ZodType | KeyValue | FnParameters | Declaration | const delimiter = description?.trim().length > 0 ? '\n' : '' const withoutDesc = schema.value.describe('') - const isOptional = (schema.value as z.ZodNativeType).typeName === 'ZodAny' // any is treated as optional for backwards compatibility + const isOptional = z.is.zuiAny(schema.value) // any is treated as optional for backwards compatibility const key = isOptional ? _optionalKey(schema.key) : schema.key return `${delimiter}${description}${delimiter}${key}: ${sUnwrapZod(withoutDesc, newConfig)}${delimiter}` } if (schema instanceof FnParameters) { - const schemaSchema = schema.schema as z.ZodNativeType - if (schemaSchema.typeName === 'ZodTuple') { + if (z.is.zuiTuple(schema.schema)) { let args = '' - for (let i = 0; i < schemaSchema.items.length; i++) { - const argName = (schemaSchema.items[i]?.ui?.title as string) ?? `arg${i}` - const item = schemaSchema.items[i]! + for (let i = 0; i < schema.schema.items.length; i++) { + const argName = (schema.schema.items[i]?.ui?.title as string) ?? `arg${i}` + const item = schema.schema.items[i]! args += `${sUnwrapZod(new KeyValue(toPropertyKey(argName), item), newConfig)}${ - i < schemaSchema.items.length - 1 ? ', ' : '' + i < schema.schema.items.length - 1 ? ', ' : '' } ` } return args } - const isLiteral = (schema.schema.naked() as z.ZodNativeType).typeName === 'ZodLiteral' + const isLiteral = z.is.zuiLiteral(schema.schema.naked()) const typings = sUnwrapZod(schema.schema, newConfig).trim() const startsWithPairs = @@ -185,12 +183,11 @@ function sUnwrapZod(schema: z.ZodType | KeyValue | FnParameters | Declaration | } if (schema instanceof FnReturn) { - const schemaSchema = schema.schema as z.ZodNativeType - if (schemaSchema.typeName === 'ZodOptional') { - return `${sUnwrapZod(schemaSchema.unwrap(), newConfig)} | undefined` + if (z.is.zuiOptional(schema.schema)) { + return `${sUnwrapZod(schema.schema.unwrap(), newConfig)} | undefined` } - return sUnwrapZod(schemaSchema, newConfig) + return sUnwrapZod(schema.schema, newConfig) } const s = schema as z.ZodFirstPartySchemaTypes @@ -239,7 +236,7 @@ function sUnwrapZod(schema: z.ZodType | KeyValue | FnParameters | Declaration | case 'ZodObject': const props = Object.entries(s._def.shape()).map(([key, value]) => { - if (z.isZuiType(value)) { + if (z.is.zuiType(value)) { return sUnwrapZod(new KeyValue(toPropertyKey(key), value), newConfig) } return `${key}: unknown` diff --git a/packages/zui/src/z/__tests__/deref.test.ts b/packages/zui/src/z/__tests__/deref.test.ts index 5639e4a5f10..f791c5ce35a 100644 --- a/packages/zui/src/z/__tests__/deref.test.ts +++ b/packages/zui/src/z/__tests__/deref.test.ts @@ -11,7 +11,7 @@ const deref = { baz: z.boolean(), } -const intersect = (...schemas: z.ZodNativeType[]) => { +const intersect = (...schemas: z.ZodType[]) => { if (schemas.length === 0) { throw new Error('Intersection expects at least one schema') } diff --git a/packages/zui/src/z/__tests__/mandatory.test.ts b/packages/zui/src/z/__tests__/mandatory.test.ts index d8cbd409439..34eb38b1631 100644 --- a/packages/zui/src/z/__tests__/mandatory.test.ts +++ b/packages/zui/src/z/__tests__/mandatory.test.ts @@ -8,9 +8,7 @@ const expectZui = (actual: z.ZodType) => ({ const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${transforms.toTypescriptSchema( - actual as z.ZodNativeType - )} not to equal ${transforms.toTypescriptSchema(expected as z.ZodNativeType)}` + msg = `Expected ${transforms.toTypescriptSchema(actual)} not to equal ${transforms.toTypescriptSchema(expected)}` } catch {} expect(result, msg).toBe(true) }, @@ -19,9 +17,7 @@ const expectZui = (actual: z.ZodType) => ({ const result = actual.isEqual(expected) let msg: string | undefined = undefined try { - msg = `Expected ${transforms.toTypescriptSchema(actual as z.ZodNativeType)} to equal ${transforms.toTypescriptSchema( - expected as z.ZodNativeType - )}` + msg = `Expected ${transforms.toTypescriptSchema(actual)} to equal ${transforms.toTypescriptSchema(expected)}` } catch {} expect(result, msg).toBe(true) }, diff --git a/packages/zui/src/z/__tests__/zui.test.ts b/packages/zui/src/z/__tests__/zui.test.ts index 5a7c445f1fb..d838e6355cd 100644 --- a/packages/zui/src/z/__tests__/zui.test.ts +++ b/packages/zui/src/z/__tests__/zui.test.ts @@ -94,7 +94,7 @@ test('Discriminated Unions', () => { }) test('ZuiTypeAny', () => { - const func = (type: zui.ZodNativeType) => { + const func = (type: zui.ZodType) => { return type } diff --git a/packages/zui/src/z/guards.ts b/packages/zui/src/z/guards.ts index f0427366ddc..3dd79b5196a 100644 --- a/packages/zui/src/z/guards.ts +++ b/packages/zui/src/z/guards.ts @@ -1,12 +1,106 @@ import { ZodError } from './error' import { ZodBaseTypeImpl } from './types' -import { IZodError, ZodNativeType } from './typings' +import type { + IZodError, + IZodType, + ZodNativeType, + ZodNativeTypeName, + IZodAny, + IZodArray, + IZodBigInt, + IZodBoolean, + IZodBranded, + IZodCatch, + IZodDate, + IZodDefault, + IZodDiscriminatedUnion, + IZodEnum, + IZodFunction, + IZodIntersection, + IZodLazy, + IZodLiteral, + IZodMap, + IZodNaN, + IZodNativeEnum, + IZodNever, + IZodNull, + IZodNullable, + IZodNumber, + IZodObject, + IZodOptional, + IZodPipeline, + IZodPromise, + IZodReadonly, + IZodRecord, + IZodRef, + IZodSet, + IZodString, + IZodSymbol, + IZodEffects, + IZodTuple, + IZodUndefined, + IZodUnion, + IZodUnknown, + IZodVoid, +} from './typings' const _isError = (value: unknown): value is Error => value instanceof Error const _isObject = (value: unknown): value is object => typeof value === 'object' && value !== null -export const isZuiError = (thrown: unknown): thrown is IZodError => - thrown instanceof ZodError || (_isError(thrown) && '__type__' in thrown && thrown.__type__ === 'ZuiError') +type _GuardName = S extends `Zod${infer R}` ? `zui${R}` : never +type _Guards = { + [G in ZodNativeTypeName as _GuardName]: (value: IZodType) => value is Extract +} & { + zuiError: (thrown: unknown) => thrown is IZodError + zuiType: (value: unknown) => value is ZodNativeType +} -export const isZuiType = (value: unknown): value is ZodNativeType => - value instanceof ZodBaseTypeImpl || (_isObject(value) && '__type__' in value && value.__type__ === 'ZuiType') +export const is: _Guards = { + zuiError: (thrown: unknown): thrown is IZodError => + thrown instanceof ZodError || (_isError(thrown) && '__type__' in thrown && thrown.__type__ === 'ZuiError'), + zuiType: (value: unknown): value is ZodNativeType => + value instanceof ZodBaseTypeImpl || (_isObject(value) && '__type__' in value && value.__type__ === 'ZuiType'), + + zuiAny: (s: IZodType): s is IZodAny => s.typeName === 'ZodAny', + zuiArray: (s: IZodType): s is IZodArray => s.typeName === 'ZodArray', + zuiBigInt: (s: IZodType): s is IZodBigInt => s.typeName === 'ZodBigInt', + zuiBoolean: (s: IZodType): s is IZodBoolean => s.typeName === 'ZodBoolean', + zuiBranded: (s: IZodType): s is IZodBranded => s.typeName === 'ZodBranded', + zuiCatch: (s: IZodType): s is IZodCatch => s.typeName === 'ZodCatch', + zuiDate: (s: IZodType): s is IZodDate => s.typeName === 'ZodDate', + zuiDefault: (s: IZodType): s is IZodDefault => s.typeName === 'ZodDefault', + zuiDiscriminatedUnion: (s: IZodType): s is IZodDiscriminatedUnion => s.typeName === 'ZodDiscriminatedUnion', + zuiEnum: (s: IZodType): s is IZodEnum => s.typeName === 'ZodEnum', + zuiFunction: (s: IZodType): s is IZodFunction => s.typeName === 'ZodFunction', + zuiIntersection: (s: IZodType): s is IZodIntersection => s.typeName === 'ZodIntersection', + zuiLazy: (s: IZodType): s is IZodLazy => s.typeName === 'ZodLazy', + zuiLiteral: (s: IZodType): s is IZodLiteral => s.typeName === 'ZodLiteral', + zuiMap: (s: IZodType): s is IZodMap => s.typeName === 'ZodMap', + zuiNaN: (s: IZodType): s is IZodNaN => s.typeName === 'ZodNaN', + zuiNativeEnum: (s: IZodType): s is IZodNativeEnum => s.typeName === 'ZodNativeEnum', + zuiNever: (s: IZodType): s is IZodNever => s.typeName === 'ZodNever', + zuiNull: (s: IZodType): s is IZodNull => s.typeName === 'ZodNull', + zuiNullable: (s: IZodType): s is IZodNullable => s.typeName === 'ZodNullable', + zuiNumber: (s: IZodType): s is IZodNumber => s.typeName === 'ZodNumber', + zuiObject: (s: IZodType): s is IZodObject => s.typeName === 'ZodObject', + zuiOptional: (s: IZodType): s is IZodOptional => s.typeName === 'ZodOptional', + zuiPipeline: (s: IZodType): s is IZodPipeline => s.typeName === 'ZodPipeline', + zuiPromise: (s: IZodType): s is IZodPromise => s.typeName === 'ZodPromise', + zuiReadonly: (s: IZodType): s is IZodReadonly => s.typeName === 'ZodReadonly', + zuiRecord: (s: IZodType): s is IZodRecord => s.typeName === 'ZodRecord', + zuiRef: (s: IZodType): s is IZodRef => s.typeName === 'ZodRef', + zuiSet: (s: IZodType): s is IZodSet => s.typeName === 'ZodSet', + zuiString: (s: IZodType): s is IZodString => s.typeName === 'ZodString', + zuiSymbol: (s: IZodType): s is IZodSymbol => s.typeName === 'ZodSymbol', + zuiEffects: (s: IZodType): s is IZodEffects => s.typeName === 'ZodEffects', + zuiTuple: (s: IZodType): s is IZodTuple => s.typeName === 'ZodTuple', + zuiUndefined: (s: IZodType): s is IZodUndefined => s.typeName === 'ZodUndefined', + zuiUnion: (s: IZodType): s is IZodUnion => s.typeName === 'ZodUnion', + zuiUnknown: (s: IZodType): s is IZodUnknown => s.typeName === 'ZodUnknown', + zuiVoid: (s: IZodType): s is IZodVoid => s.typeName === 'ZodVoid', +} satisfies { + [G in ZodNativeTypeName as _GuardName]: (value: IZodType) => value is Extract +} & { + zuiError: (thrown: unknown) => thrown is IZodError + zuiType: (value: unknown) => value is ZodNativeType +} diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index b02db7c6273..9e70f9e38a4 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,4 +1,5 @@ import { defaultErrorMap, getErrorMap, ZodError } from '../../error' +import { is } from '../../guards' import { builders } from '../../internal-builders' import type { IZodType, @@ -11,7 +12,6 @@ import type { InnerTypeOfFunction, IZodUnknown, IZodPromise, - ZodNativeType, } from '../../typings' import * as utils from '../../utils' @@ -90,8 +90,7 @@ export class ZodFunctionImpl = IZodTuple, Retur const params = { errorMap: ctx.common.contextualErrorMap } const fn = ctx.data - const returns = this._def.returns as ZodNativeType - if (returns.typeName === 'ZodPromise') { + if (is.zuiPromise(this._def.returns)) { // Would love a way to avoid disabling this rule, but we need // an alias (using an arrow function was what caused 2651). diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 0e639187a15..76a2101352b 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,3 +1,4 @@ +import { is } from '../../guards' import { builders } from '../../internal-builders' import type { IZodObject, @@ -12,7 +13,6 @@ import type { KeyOfObject, IZodOptional, IZodEnum, - ZodNativeType, } from '../../typings' import * as utils from '../../utils' import { @@ -507,10 +507,10 @@ export class ZodObjectImpl< newShape[key] = this.shape[key] } else { const fieldSchema = this.shape[key] - let newField = fieldSchema as ZodNativeType - while (newField.typeName === 'ZodOptional') { - newField = (newField as IZodOptional)._def.innerType + let newField = fieldSchema! + while (is.zuiOptional(newField)) { + newField = newField._def.innerType } newShape[key] = newField diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index 7a99ce6253f..7d0b18e24bb 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,14 +1,7 @@ import { ZodError } from '../../error' +import { is } from '../../guards' import { builders } from '../../internal-builders' -import type { - DefaultZodUnionOptions, - IZodUnion, - IZodType, - ZodUnionDef, - ZodUnionOptions, - ZodIssue, - ZodNativeType, -} from '../../typings' +import type { DefaultZodUnionOptions, IZodUnion, IZodType, ZodUnionDef, ZodUnionOptions, ZodIssue } from '../../typings' import * as utils from '../../utils' import { ZodBaseTypeImpl, @@ -159,9 +152,7 @@ export class ZodUnionImpl } mandatory(): IZodType { - const options = this._def.options - .filter((o) => !((o as ZodNativeType).typeName === 'ZodUndefined')) - .map((option) => option.mandatory()) + const options = this._def.options.filter((o) => !is.zuiUndefined(o)).map((option) => option.mandatory()) const [first, second, ...others] = options if (!first) { diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 1b795175772..3238dcdc898 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -1,5 +1,5 @@ export { zuiKey } from './consts' -export { isZuiError, isZuiType } from './guards' +export { is } from './guards' export type { // ui From 1ea68a0b651531565b0a8ce5fb8fb4ed73f3b0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 2 Mar 2026 15:44:52 -0500 Subject: [PATCH 27/50] chore(bots/clog): leftover file --- bots/clog/add.ts | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 bots/clog/add.ts diff --git a/bots/clog/add.ts b/bots/clog/add.ts deleted file mode 100644 index 9868b36fca2..00000000000 --- a/bots/clog/add.ts +++ /dev/null @@ -1,18 +0,0 @@ -import cmd from '@botpress/cli' - -void cmd.add({ - packageRef: `${__dirname}/../../integrations/slack`, - - botpressHome: '~/.botpress', - confirm: true, - installPath: __dirname, - json: false, - useDev: false, - - alias: undefined, - apiUrl: undefined, - profile: undefined, - token: undefined, - verbose: false, - workspaceId: undefined, -}) From 8b4c3365bb2a4aae26b8bc9eb1473b3fb2c9f38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 2 Mar 2026 16:58:44 -0500 Subject: [PATCH 28/50] chore(zui): move test assertion utils together and make sure it's not bundled (#14984) --- packages/zui/src/assertions.utils.test.ts | 17 ++- .../json-schema-to-zui.test.ts | 6 +- .../transforms/zui-from-json-schema/index.ts | 3 +- .../transforms/zui-to-json-schema/index.ts | 2 +- .../zui-to-typescript-schema/bigint-checks.ts | 3 +- .../zui-to-typescript-schema/date-checks.ts | 3 +- .../zui-to-typescript-schema/number-checks.ts | 3 +- .../zui-to-typescript-schema/string-checks.ts | 3 +- .../zui-to-typescript-type/index.test.ts | 143 ++++++++++-------- .../zui-to-typescript-type/primitives.test.ts | 92 +++++------ packages/zui/src/z/__tests__/base.test.ts | 4 +- packages/zui/src/z/__tests__/generics.test.ts | 4 +- .../zui/src/z/__tests__/instanceof.test.ts | 4 +- packages/zui/src/z/__tests__/partials.test.ts | 6 +- packages/zui/src/z/__tests__/pickomit.test.ts | 8 +- .../zui/src/z/__tests__/preprocess.test.ts | 6 +- .../zui/src/z/__tests__/primitive.test.ts | 54 +++---- packages/zui/src/z/__tests__/refine.test.ts | 18 +-- packages/zui/src/z/__tests__/set.test.ts | 4 +- .../zui/src/z/types/any/anyunknown.test.ts | 6 +- packages/zui/src/z/types/array/array.test.ts | 6 +- .../zui/src/z/types/branded/branded.test.ts | 16 +- packages/zui/src/z/types/catch/catch.test.ts | 20 +-- .../zui/src/z/types/default/default.test.ts | 20 +-- .../discriminatedUnion.test.ts | 4 +- packages/zui/src/z/types/enum/enum.test.ts | 14 +- .../zui/src/z/types/function/function.test.ts | 16 +- packages/zui/src/z/types/map/map.test.ts | 4 +- .../src/z/types/nativeEnum/nativeEnum.test.ts | 8 +- .../zui/src/z/types/object/object.test.ts | 40 ++--- .../zui/src/z/types/promise/promise.test.ts | 4 +- .../zui/src/z/types/readonly/readonly.test.ts | 93 ++++++------ .../zui/src/z/types/record/record.test.ts | 8 +- packages/zui/src/z/types/ref/ref.test.ts | 4 +- packages/zui/src/z/types/transformer/index.ts | 2 +- .../z/types/transformer/transformer.test.ts | 8 +- packages/zui/src/z/types/tuple/tuple.test.ts | 10 +- packages/zui/src/z/types/void/void.test.ts | 4 +- packages/zui/src/z/utils/assert-utils.ts | 10 +- packages/zui/src/z/utils/type-utils.ts | 17 --- 40 files changed, 343 insertions(+), 354 deletions(-) diff --git a/packages/zui/src/assertions.utils.test.ts b/packages/zui/src/assertions.utils.test.ts index 7d6961cda2b..fde8ade3518 100644 --- a/packages/zui/src/assertions.utils.test.ts +++ b/packages/zui/src/assertions.utils.test.ts @@ -1,24 +1,29 @@ import { expect } from 'vitest' import { format } from 'prettier' -const formatTs = async (code: string): Promise => { +const _formatTs = async (code: string): Promise => { code = code.replace(/\s+/g, ' ') code = await format(code, { parser: 'typescript' }) return code } -export const assert = (received: string) => ({ +export const assertIs = (_arg: T): void => {} + +export type IsEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false +export const assertEqual = (val: IsEqual) => val + +export const expectTypescript = (received: string) => ({ not: { async toMatchWithoutFormatting(expected: string) { - const transformedReceived = await formatTs(received) - const transformedExpected = await formatTs(expected) + const transformedReceived = await _formatTs(received) + const transformedExpected = await _formatTs(expected) expect(transformedReceived).not.toBe(transformedExpected) }, }, async toMatchWithoutFormatting(expected: string) { - const transformedReceived = await formatTs(received) - const transformedExpected = await formatTs(expected) + const transformedReceived = await _formatTs(received) + const transformedExpected = await _formatTs(expected) expect(transformedReceived).toBe(transformedExpected) }, }) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts index 71bc9c6abea..ae96d26c68e 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts @@ -3,7 +3,7 @@ import { z, ZodType, zuiKey } from '../../z' import { jsonSchemaToZodStr, fromJSONSchemaLegacy, traverseZodDefinitions } from '.' import { toJSONSchemaLegacy } from '../zui-to-json-schema-legacy/zui-extension' import { JSONSchema7 } from 'json-schema' -import { assert } from '../../assertions.utils.test' +import * as assert from '../../assertions.utils.test' const testZuiConversion = (zuiObject: ZodType) => { const jsonSchema = toJSONSchemaLegacy(zuiObject) @@ -209,7 +209,7 @@ describe('Coercion deserialization', () => { required: ['foo'], } const zStr = jsonSchemaToZodStr(schema) - await assert(zStr).toMatchWithoutFormatting(` + await assert.expectTypescript(zStr).toMatchWithoutFormatting(` z.object({ foo: z.ref("#Foo") }) `) }) @@ -235,7 +235,7 @@ describe('Coercion deserialization', () => { required: ['foo', 'bar'], } const zStr = jsonSchemaToZodStr(schema) - await assert(zStr).toMatchWithoutFormatting(` + await assert.expectTypescript(zStr).toMatchWithoutFormatting(` z.object({ foo: z.literal("foo"), bar: z.literal("bar") }) `) }) diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index 0f088b63a98..f3944b1236e 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -1,6 +1,5 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema' import z from '../../z' -import * as utils from '../../z/utils' import * as errors from '../common/errors' import { ArraySchema, SetSchema, TupleSchema } from '../common/json-schema' import * as guards from './guards' @@ -198,7 +197,7 @@ function _fromJSONSchema(schema: JSONSchema7Definition | undefined): z.ZodType { return z.intersection(zLeft, zRight) } - type _expectUndefined = utils.assert.AssertTrue> + schema.type satisfies undefined if (guards.isUnknownSchema(schema)) { return z.unknown() diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index 4aa5596552e..9624095685c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -184,7 +184,7 @@ export function toJSONSchema(schema: z.ZodType): json.Schema { } else if (s.value === undefined) { return undefinedSchema(s._def) } else { - utils.assert.assertEqual(true) + s.value satisfies bigint | symbol const unsupportedLiteral = typeof s.value throw new err.ZuiToJSONSchemaError(`Unsupported literal type: "${unsupportedLiteral}"`) } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts index 47a82dcfc3b..6af57ba0f1b 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/bigint-checks.ts @@ -1,5 +1,4 @@ import { ZodBigIntCheck, ZodBigIntDef } from '../../z' -import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateBigIntChecks = (def: ZodBigIntDef): string => { @@ -19,7 +18,7 @@ const _generateBigIntCheck = (check: ZodBigIntCheck): string => { case 'multipleOf': return `.multipleOf(${toTs(check.value)}, ${toTs(check.message)})` default: - type _assertion = utils.assert.AssertNever + check satisfies never return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts index 4836fbf79e7..b0fe234437b 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/date-checks.ts @@ -1,5 +1,4 @@ import { ZodDateCheck, ZodDateDef } from '../../z' -import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateDateChecks = (def: ZodDateDef): string => { @@ -19,7 +18,7 @@ const _generateDateCheck = (check: ZodDateCheck): string => { const maxDate = dateTs(check.value) return `.max(${maxDate}, ${toTs(check.message)})` default: - type _assertion = utils.assert.AssertNever + check satisfies never return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts index 69172ae6b8c..766a0bcec05 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/number-checks.ts @@ -1,5 +1,4 @@ import { ZodNumberCheck, ZodNumberDef } from '../../z/' -import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs } from '../common/utils' export const generateNumberChecks = (def: ZodNumberDef): string => { @@ -23,7 +22,7 @@ const _generateNumberCheck = (check: ZodNumberCheck): string => { case 'finite': return `.finite(${toTs(check.message)})` default: - type _assertion = utils.assert.AssertNever + check satisfies never return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts b/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts index 48bdd25d4e7..229f58bcf4f 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/string-checks.ts @@ -1,5 +1,4 @@ import { ZodStringCheck, ZodStringDef } from '../../z/types/string' -import * as utils from '../../z/utils' import { primitiveToTypescriptValue as toTs, unknownToTypescriptValue } from '../common/utils' export const generateStringChecks = (def: ZodStringDef): string => { @@ -60,7 +59,7 @@ const _generateStringCheck = (check: ZodStringCheck): string => { const ipOptions = unknownToTypescriptValue({ message: check.message, version: check.version }) return `.ip(${ipOptions})` default: - type _assertion = utils.assert.AssertNever + check satisfies never return '' } } diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts index f7894ea4ce2..b60968091f0 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from 'vitest' import { toTypescriptType as toTs } from '.' -import * as utils from '../../z/utils' import z, { ZodType } from '../../z' import * as errors from '../common/errors' -import { assert } from '../../assertions.utils.test' +import * as assert from '../../assertions.utils.test' const toTypescript = (schema: ZodType): string => { const hasTitle = 'title' in schema.ui @@ -33,7 +32,7 @@ describe.concurrent('functions', () => { const typings = toTs(fn, { declaration: true }) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * Add two numbers together. * This is a multiline description @@ -51,7 +50,7 @@ describe.concurrent('functions', () => { .describe('Add two numbers together.\nThis is a multiline description') const typings = toTs(fn, { declaration: 'type' }) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * Add two numbers together. * This is a multiline description @@ -70,7 +69,7 @@ describe.concurrent('functions', () => { const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * Add two numbers together. * This is a multiline description @@ -84,7 +83,7 @@ describe.concurrent('functions', () => { const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(): unknown;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare function fn(): unknown;') }) it('function with no args and void return', async () => { @@ -92,7 +91,7 @@ describe.concurrent('functions', () => { const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(): void;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare function fn(): void;') }) it('async function returning union', async () => { @@ -103,7 +102,7 @@ describe.concurrent('functions', () => { const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(): Promise;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare function fn(): Promise;') }) it('function with multiple args', async () => { @@ -121,7 +120,7 @@ describe.concurrent('functions', () => { const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare function fn( arg0: { a?: number; @@ -138,19 +137,23 @@ describe.concurrent('functions', () => { it('function with optional args', async () => { const fn = z.function().title('fn').args(z.string().optional()) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(arg0?: string): unknown;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare function fn(arg0?: string): unknown;') }) it('function with readonly args', async () => { const fn = z.function().title('fn').args(z.string().readonly()) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(arg0: Readonly): unknown;') + await assert + .expectTypescript(typings) + .toMatchWithoutFormatting('declare function fn(arg0: Readonly): unknown;') }) it('function with readonly enumerable args', async () => { const fn = z.function().title('fn').args(z.array(z.string()).readonly()) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(arg0: Readonly): unknown;') + await assert + .expectTypescript(typings) + .toMatchWithoutFormatting('declare function fn(arg0: Readonly): unknown;') }) it('string literals', async () => { @@ -160,7 +163,7 @@ describe.concurrent('functions', () => { .describe('yoyoyo\nmultiline') .title('x') ) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * yoyoyo * multiline @@ -171,34 +174,34 @@ describe.concurrent('functions', () => { it('number literals', async () => { const code = toTypescript(z.literal(1).title('x')) - await assert(code).toMatchWithoutFormatting('declare const x: 1') + await assert.expectTypescript(code).toMatchWithoutFormatting('declare const x: 1') }) it('boolean literals', async () => { const code = toTypescript(z.literal(true)) - await assert(code).toMatchWithoutFormatting('declare const x: true') + await assert.expectTypescript(code).toMatchWithoutFormatting('declare const x: true') }) it('undefined literals', async () => { const typings = toTypescript(z.literal(undefined)) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined') }) it('null literals', async () => { const typings = toTypescript(z.literal(null)) - await assert(typings).toMatchWithoutFormatting('declare const x: null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null') }) it('bigint literals', async () => { const n = BigInt(100) const typings = toTypescript(z.literal(n)) - await assert(typings).toMatchWithoutFormatting('declare const x: 100n') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: 100n') }) it('symbol literals', async () => { const n = Symbol('hello') const typings = toTypescript(z.literal(n)) - await assert(typings).toMatchWithoutFormatting('declare const x: symbol') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: symbol') }) it('non explicitly discriminated union', async () => { @@ -207,7 +210,7 @@ describe.concurrent('functions', () => { z.object({ enabled: z.literal(false), bar: z.number() }), ]) const typings = toTypescript(schema) - await assert(typings).toMatchWithoutFormatting(`declare const x: { + await assert.expectTypescript(typings).toMatchWithoutFormatting(`declare const x: { enabled: true; foo: string } | { @@ -220,7 +223,7 @@ describe.concurrent('functions', () => { it('function with named args', async () => { const fn = z.function().title('fn').args(z.string().title('firstName').optional()) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting('declare function fn(firstName?: string): unknown;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare function fn(firstName?: string): unknown;') }) it('mix of named and unnammed params', async () => { @@ -229,7 +232,7 @@ describe.concurrent('functions', () => { .title('fn') .args(z.string().title('firstName').optional(), z.number(), z.object({ a: z.string() }).title('obj')) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare function fn( firstName?: string, arg1: number, @@ -246,7 +249,7 @@ describe.concurrent('functions', () => { .returns(z.string().nullable().optional()) const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare function fn( arg0?: string | null, arg1?: number @@ -266,7 +269,7 @@ describe.concurrent('objects', () => { const typings = toTs(obj, { declaration: 'type' }) - await assert(typings).toMatchWithoutFormatting('type MyObject = { a: number; b: string };') + await assert.expectTypescript(typings).toMatchWithoutFormatting('type MyObject = { a: number; b: string };') }) it('normal object', async () => { @@ -274,7 +277,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting('declare const MyObject: { a: number; b: string };') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const MyObject: { a: number; b: string };') }) it('object with title and description', async () => { @@ -285,7 +288,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * This is my object. * This is a multiline description. @@ -317,7 +320,7 @@ describe.concurrent('objects', () => { const typings = toTs(obj, { declaration: true, includeClosingTags: true }) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` /** * This is my object. * This is a multiline description. @@ -347,7 +350,9 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting('declare const MyObject: { a: number; b: string } | null;') + await assert + .expectTypescript(typings) + .toMatchWithoutFormatting('declare const MyObject: { a: number; b: string } | null;') }) it('optionals with default values', async () => { @@ -355,7 +360,9 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting('declare const MyObject: { a: number; b: string } | undefined;') + await assert + .expectTypescript(typings) + .toMatchWithoutFormatting('declare const MyObject: { a: number; b: string } | undefined;') }) it('enum', async () => { @@ -363,7 +370,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { a: 'hello' | 'world' }; @@ -379,7 +386,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** Description */ someStr?: string @@ -396,7 +403,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** Description */ someStr?: string @@ -413,7 +420,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting('declare const MyObject: { address: {} | null };') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const MyObject: { address: {} | null };') }) it('object with a description & readonly', async () => { @@ -425,7 +432,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** Description */ someStr: Readonly }; @@ -441,7 +448,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** Description */ someStr: Readonly @@ -466,7 +473,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** This is a record */ address: { [key: number]: { street: string; number: number } } @@ -491,7 +498,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting( + await assert.expectTypescript(typings).toMatchWithoutFormatting( ` declare const MyObject: { computed: { [key: string]: { status: string; error?: string } | undefined } @@ -569,7 +576,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const payment: | { type: 'Credit Card'; @@ -621,7 +628,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const UserPayment: { value: | { @@ -657,7 +664,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** This is a record */ address: /** This is a record */ { [key: number]: { street: string; number: number } @@ -673,16 +680,16 @@ describe.concurrent('objects', () => { .title('MyObject') const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting( - 'declare function MyObject(arg0: Array<{ a: number; b: string }>): unknown;' - ) + await assert + .expectTypescript(typings) + .toMatchWithoutFormatting('declare function MyObject(arg0: Array<{ a: number; b: string }>): unknown;') }) it('array of primitives as input params', async () => { const fn = z.function().args(z.array(z.number()).describe('This is an array of numbers')).title('MyObject') const typings = toTypescript(fn) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare function MyObject( /** This is an array of numbers */ arg0: number[] @@ -703,7 +710,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { /** This is A */ a: string @@ -722,7 +729,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { 'Hello World!': string; 'Hey?'?: string; @@ -748,7 +755,7 @@ describe.concurrent('objects', () => { const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const MyObject: { stringLiteral: "1"; numberLiteral: 1; @@ -784,11 +791,15 @@ describe.concurrent('objects', () => { const typings2 = toTypescript(fn2) const typings3 = toTypescript(fn3) - await assert(typings1).toMatchWithoutFormatting(`declare function fn1(arg0: number | string): number | string`) - await assert(typings2).toMatchWithoutFormatting(`declare function fn2(arg0: { id: number[] } | string): unknown`) - await assert(typings3).toMatchWithoutFormatting( - `declare function fn3(arg0: { id: number[] } | { name: string }): unknown` - ) + await assert + .expectTypescript(typings1) + .toMatchWithoutFormatting(`declare function fn1(arg0: number | string): number | string`) + await assert + .expectTypescript(typings2) + .toMatchWithoutFormatting(`declare function fn2(arg0: { id: number[] } | string): unknown`) + await assert + .expectTypescript(typings3) + .toMatchWithoutFormatting(`declare function fn3(arg0: { id: number[] } | { name: string }): unknown`) }) it('records', async () => { @@ -800,7 +811,7 @@ describe.concurrent('objects', () => { .required({ Date: true }) const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(` + await assert.expectTypescript(typings).toMatchWithoutFormatting(` declare const x: { /** Test2 */ Date: string @@ -816,7 +827,7 @@ describe.concurrent('objects', () => { .required({ Date: false } as any) const typings = toTypescript(obj) - await assert(typings).toMatchWithoutFormatting(`declare const x: { Date?: string }`) + await assert.expectTypescript(typings).toMatchWithoutFormatting(`declare const x: { Date?: string }`) }) it('chaining optionals only make properties optional once', async () => { @@ -832,7 +843,7 @@ describe.concurrent('objects', () => { foo?: string } ` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) it('chaining optional nullable should still be optional', async () => { @@ -846,7 +857,7 @@ describe.concurrent('objects', () => { foo: string | undefined | null } ` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) it('should not treat default property as optional by default', async () => { @@ -860,7 +871,7 @@ describe.concurrent('objects', () => { foo: string } ` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) it('should treat default property as optional when treatDefaultAsOptional is true', async () => { @@ -876,7 +887,7 @@ describe.concurrent('objects', () => { foo?: string } ` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) it('should treat an any key as optional for backward compatibility', async () => { @@ -892,10 +903,10 @@ describe.concurrent('objects', () => { a?: any } ` - await assert(actual).toMatchWithoutFormatting(expected) + await assert.expectTypescript(actual).toMatchWithoutFormatting(expected) type S = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) it('should treat an optional any key as optional with a single question mark', async () => { @@ -909,7 +920,7 @@ describe.concurrent('objects', () => { a?: any } ` - await assert(actual).toMatchWithoutFormatting(expected) + await assert.expectTypescript(actual).toMatchWithoutFormatting(expected) }) }) @@ -926,14 +937,14 @@ describe.concurrent('generics', () => { const schema = z.object({ a: z.string(), b: z.ref('T') }).title('MyObject') const typings = toTs(schema, { declaration: 'type' }) - await assert(typings).toMatchWithoutFormatting('type MyObject = { a: string; b: T };') + await assert.expectTypescript(typings).toMatchWithoutFormatting('type MyObject = { a: string; b: T };') }) it('can generate a generic type by formating ref Uri', async () => { const schema = z.object({ a: z.string(), b: z.ref('#/$defs/T') }).title('MyObject') const typings = toTs(schema, { declaration: 'type' }) - await assert(typings).toMatchWithoutFormatting('type MyObject = { a: string; b: DefsT };') + await assert.expectTypescript(typings).toMatchWithoutFormatting('type MyObject = { a: string; b: DefsT };') }) }) @@ -1000,7 +1011,7 @@ describe.concurrent('optional', () => { it('should handle top level optional schemas as union with undefined', async () => { const schema = z.string().optional().title('MyString') const typings = toTs(schema, { declaration: true }) - await assert(typings).toMatchWithoutFormatting('declare const MyString: string | undefined;') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const MyString: string | undefined;') }) it('should not treat default schema as optional', async () => { @@ -1008,7 +1019,7 @@ describe.concurrent('optional', () => { const typings = toTypescript(schema) const expected = `declare const x: string` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) it('should treat default schema as optional when treatDefaultAsOptional is true', async () => { @@ -1016,6 +1027,6 @@ describe.concurrent('optional', () => { const typings = toTs(schema, { declaration: true, treatDefaultAsOptional: true }) const expected = `declare const MyString: string | undefined;` - await assert(typings).toMatchWithoutFormatting(expected) + await assert.expectTypescript(typings).toMatchWithoutFormatting(expected) }) }) diff --git a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts index 0c55c0b030d..489a58e6a60 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts @@ -1,232 +1,232 @@ import { test } from 'vitest' import { toTypescriptType as toTs } from '.' import z from '../../z' -import { assert } from '../../assertions.utils.test' +import * as assert from '../../assertions.utils.test' const toTypescriptType = (schema: z.ZodType) => toTs(schema, { declaration: 'variable' }) test('string', async () => { const schema = z.string().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: string') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: string') }) test('string nullable', async () => { const schema = z.string().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: string | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: string | null') }) test('string optional', async () => { const schema = z.string().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: string | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: string | undefined') }) test('string nullable optional', async () => { const schema = z.string().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: string | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: string | null | undefined') }) test('string optional nullable', async () => { const schema = z.string().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: string | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: string | undefined | null') }) test('number', async () => { const schema = z.number().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number') }) test('number nullable', async () => { const schema = z.number().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | null') }) test('number optional', async () => { const schema = z.number().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | undefined') }) test('number nullable optional', async () => { const schema = z.number().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | null | undefined') }) test('number optional nullable', async () => { const schema = z.number().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | undefined | null') }) test('bigint', async () => { const schema = z.bigint().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number') // should be bigint instead of number + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number') // should be bigint instead of number }) test('bigint nullable', async () => { const schema = z.bigint().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | null') // should be bigint instead of number + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | null') // should be bigint instead of number }) test('bigint optional', async () => { const schema = z.bigint().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | undefined') // should be bigint instead of number + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | undefined') // should be bigint instead of number }) test('bigint nullable optional', async () => { const schema = z.bigint().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | null | undefined') // should be bigint instead of number + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | null | undefined') // should be bigint instead of number }) test('bigint optional nullable', async () => { const schema = z.bigint().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: number | undefined | null') // should be bigint instead of number + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: number | undefined | null') // should be bigint instead of number }) test('boolean', async () => { const schema = z.boolean().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: boolean') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: boolean') }) test('boolean nullable', async () => { const schema = z.boolean().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: boolean | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: boolean | null') }) test('boolean optional', async () => { const schema = z.boolean().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: boolean | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: boolean | undefined') }) test('boolean nullable optional', async () => { const schema = z.boolean().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: boolean | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: boolean | null | undefined') }) test('boolean optional nullable', async () => { const schema = z.boolean().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: boolean | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: boolean | undefined | null') }) test('date', async () => { const schema = z.date().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: Date') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: Date') }) test('date nullable', async () => { const schema = z.date().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: Date | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: Date | null') }) test('date optional', async () => { const schema = z.date().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: Date | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: Date | undefined') }) test('date nullable optional', async () => { const schema = z.date().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: Date | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: Date | null | undefined') }) test('date optional nullable', async () => { const schema = z.date().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: Date | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: Date | undefined | null') }) test('undefined', async () => { const schema = z.undefined().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined') }) test('undefined nullable', async () => { const schema = z.undefined().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined | null') }) test('undefined optional', async () => { const schema = z.undefined().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined | undefined') }) test('undefined nullable optional', async () => { const schema = z.undefined().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined | null | undefined') }) test('undefined optional nullable', async () => { const schema = z.undefined().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: undefined | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: undefined | undefined | null') }) test('null', async () => { const schema = z.null().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null') }) test('null nullable', async () => { const schema = z.null().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: null | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null | null') }) test('null optional', async () => { const schema = z.null().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null | undefined') }) test('null nullable optional', async () => { const schema = z.null().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: null | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null | null | undefined') }) test('null optional nullable', async () => { const schema = z.null().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: null | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: null | undefined | null') }) test('unknown', async () => { const schema = z.unknown().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: unknown') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: unknown') }) test('unknown nullable', async () => { const schema = z.unknown().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: unknown | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: unknown | null') }) test('unknown optional', async () => { const schema = z.unknown().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: unknown | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: unknown | undefined') }) test('unknown nullable optional', async () => { const schema = z.unknown().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: unknown | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: unknown | null | undefined') }) test('unknown optional nullable', async () => { const schema = z.unknown().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: unknown | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: unknown | undefined | null') }) test('never', async () => { const schema = z.never().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: never') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: never') }) test('never nullable', async () => { const schema = z.never().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: never | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: never | null') }) test('never optional', async () => { const schema = z.never().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: never | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: never | undefined') }) test('never nullable optional', async () => { const schema = z.never().nullable().optional().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: never | null | undefined') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: never | null | undefined') }) test('never optional nullable', async () => { const schema = z.never().optional().nullable().title('x') const typings: string = toTypescriptType(schema) - await assert(typings).toMatchWithoutFormatting('declare const x: never | undefined | null') + await assert.expectTypescript(typings).toMatchWithoutFormatting('declare const x: never | undefined | null') }) diff --git a/packages/zui/src/z/__tests__/base.test.ts b/packages/zui/src/z/__tests__/base.test.ts index c200cef8097..541c211000f 100644 --- a/packages/zui/src/z/__tests__/base.test.ts +++ b/packages/zui/src/z/__tests__/base.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' test('type guard', () => { const stringToNumber = z.string().transform((arg) => arg.length) @@ -13,7 +13,7 @@ test('type guard', () => { const data = { stringToNumber: 'asdf' } const parsed = s1.safeParse(data) if (parsed.success) { - utils.assert.assertEqual(true) + assert.assertEqual(true) } }) diff --git a/packages/zui/src/z/__tests__/generics.test.ts b/packages/zui/src/z/__tests__/generics.test.ts index febacf59789..88fcca993bd 100644 --- a/packages/zui/src/z/__tests__/generics.test.ts +++ b/packages/zui/src/z/__tests__/generics.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import z from '../index' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' test('generics', () => { async function stripOuter(schema: TData, data: unknown) { @@ -15,7 +15,7 @@ test('generics', () => { } const result = stripOuter(z.object({ a: z.string() }), { a: 'asdf' }) - utils.assert.assertEqual>(true) + assert.assertEqual>(true) }) test('assignability', () => { diff --git a/packages/zui/src/z/__tests__/instanceof.test.ts b/packages/zui/src/z/__tests__/instanceof.test.ts index 5b9e4f3385e..49997f7ffa6 100644 --- a/packages/zui/src/z/__tests__/instanceof.test.ts +++ b/packages/zui/src/z/__tests__/instanceof.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import z from '../index' test('instanceof', async () => { @@ -25,7 +25,7 @@ test('instanceof', async () => { await expect(() => SubtestSchema.parse(new Test())).toThrow(/Input not instance of Subtest/) await expect(() => TestSchema.parse(12)).toThrow(/Input not instance of Test/) - utils.assert.assertEqual>(true) + assert.assertEqual>(true) }) test('instanceof fatal', () => { diff --git a/packages/zui/src/z/__tests__/partials.test.ts b/packages/zui/src/z/__tests__/partials.test.ts index 668752cb47d..31e57db91b1 100644 --- a/packages/zui/src/z/__tests__/partials.test.ts +++ b/packages/zui/src/z/__tests__/partials.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import z from '../index' const nested = z.object({ @@ -20,7 +20,7 @@ test('shallow inference', () => { outer?: { inner: string } | undefined array?: { asdf: string }[] } - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('shallow partial parse', () => { @@ -68,7 +68,7 @@ test('required inference', () => { nullableField: number | null nullishField: string | null } - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('required with mask', () => { diff --git a/packages/zui/src/z/__tests__/pickomit.test.ts b/packages/zui/src/z/__tests__/pickomit.test.ts index ebdfd9ea810..81aa9baaa5b 100644 --- a/packages/zui/src/z/__tests__/pickomit.test.ts +++ b/packages/zui/src/z/__tests__/pickomit.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import z from '../index' const fish = z.object({ @@ -11,7 +11,7 @@ const fish = z.object({ test('pick type inference', () => { const nameonlyFish = fish.pick({ name: true }) type nameonlyFish = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('pick parse - success', () => { @@ -46,7 +46,7 @@ test('pick parse - fail', () => { test('omit type inference', () => { const nonameFish = fish.omit({ name: true }) type nonameFish = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('omit parse - success', () => { @@ -77,7 +77,7 @@ test('omit parse - fail', () => { test('nonstrict inference', () => { const laxfish = fish.pick({ name: true }).catchall(z.any()) type laxfish = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('nonstrict parsing - pass', () => { diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 8c3024b9a67..d18af374888 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import z from '../index' import { NEVER } from '../types/basetype' import { ZodError } from '../error' @@ -9,7 +9,7 @@ test('preprocess', () => { const value = schema.parse('asdf') expect(value).toEqual(['asdf']) - utils.assert.assertEqual<(typeof schema)['_input'], unknown>(true) + assert.assertEqual<(typeof schema)['_input'], unknown>(true) }) test('async preprocess', async () => { @@ -135,7 +135,7 @@ test('z.NEVER in preprocess', () => { }, z.number()) type foo = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) const arg = foo.safeParse(undefined) if (!arg.success) { expect(arg.error.issues[0]?.message).toEqual('bad') diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index 3fe2a15abb0..6e1146f6f57 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import z from '../index' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import { Mocker } from './Mocker' const literalStringSchema = z.literal('asdf') @@ -135,7 +135,7 @@ test('literal bigint object', () => { }) test('literal symbol', () => { - utils.assert.assertEqual, typeof MySymbol>(true) + assert.assertEqual, typeof MySymbol>(true) literalSymbolSchema.parse(MySymbol) expect(() => literalSymbolSchema.parse(Symbol('asdf'))).toThrow() }) @@ -371,31 +371,31 @@ test('parse nullSchema null', () => { }) test('primitive inference', () => { - utils.assert.assertEqual, 'asdf'>(true) - utils.assert.assertEqual, 12>(true) - utils.assert.assertEqual, true>(true) - utils.assert.assertEqual, bigint>(true) - utils.assert.assertEqual, string>(true) - utils.assert.assertEqual, number>(true) - utils.assert.assertEqual, bigint>(true) - utils.assert.assertEqual, boolean>(true) - utils.assert.assertEqual, Date>(true) - utils.assert.assertEqual, symbol>(true) - - utils.assert.assertEqual, null>(true) - utils.assert.assertEqual, undefined>(true) - utils.assert.assertEqual, string | undefined>(true) - utils.assert.assertEqual, string | null>(true) - utils.assert.assertEqual, number | undefined>(true) - utils.assert.assertEqual, number | null>(true) - utils.assert.assertEqual, bigint | undefined>(true) - utils.assert.assertEqual, bigint | null>(true) - utils.assert.assertEqual, boolean | undefined>(true) - utils.assert.assertEqual, boolean | null>(true) - utils.assert.assertEqual, Date | undefined>(true) - utils.assert.assertEqual, Date | null>(true) - utils.assert.assertEqual, symbol | undefined>(true) - utils.assert.assertEqual, symbol | null>(true) + assert.assertEqual, 'asdf'>(true) + assert.assertEqual, 12>(true) + assert.assertEqual, true>(true) + assert.assertEqual, bigint>(true) + assert.assertEqual, string>(true) + assert.assertEqual, number>(true) + assert.assertEqual, bigint>(true) + assert.assertEqual, boolean>(true) + assert.assertEqual, Date>(true) + assert.assertEqual, symbol>(true) + + assert.assertEqual, null>(true) + assert.assertEqual, undefined>(true) + assert.assertEqual, string | undefined>(true) + assert.assertEqual, string | null>(true) + assert.assertEqual, number | undefined>(true) + assert.assertEqual, number | null>(true) + assert.assertEqual, bigint | undefined>(true) + assert.assertEqual, bigint | null>(true) + assert.assertEqual, boolean | undefined>(true) + assert.assertEqual, boolean | null>(true) + assert.assertEqual, Date | undefined>(true) + assert.assertEqual, Date | null>(true) + assert.assertEqual, symbol | undefined>(true) + assert.assertEqual, symbol | null>(true) // [ // literalStringSchemaTest, diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index ca300a450c3..de581dba400 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import z from '../index' test('refinement', () => { @@ -47,11 +47,11 @@ test('refinement type guard', () => { type Input = z.input type Schema = z.infer - utils.assert.assertEqual<'a', Input['a']>(false) - utils.assert.assertEqual(true) + assert.assertEqual<'a', Input['a']>(false) + assert.assertEqual(true) - utils.assert.assertEqual<'a', Schema['a']>(true) - utils.assert.assertEqual(false) + assert.assertEqual<'a', Schema['a']>(true) + assert.assertEqual(false) }) test('refinement Promise', async () => { @@ -166,7 +166,7 @@ test('superRefine - type narrowing', () => { return true }) - utils.assert.assertEqual, NarrowType>(true) + assert.assertEqual, NarrowType>(true) expect(schema.safeParse({ type: 'test', age: 0 }).success).toEqual(true) expect(schema.safeParse(null).success).toEqual(false) @@ -185,7 +185,7 @@ test('chained mixed refining types', () => { .nullable() .refine((arg): arg is firstRefinement => !!arg?.third) .superRefine((arg, ctx): arg is secondRefinement => { - utils.assert.assertEqual(true) + assert.assertEqual(true) if (arg.first !== 'bob') { ctx.addIssue({ code: 'custom', @@ -196,11 +196,11 @@ test('chained mixed refining types', () => { return true }) .refine((arg): arg is thirdRefinement => { - utils.assert.assertEqual(true) + assert.assertEqual(true) return arg.second === 33 }) - utils.assert.assertEqual, thirdRefinement>(true) + assert.assertEqual, thirdRefinement>(true) }) test('get inner type', () => { diff --git a/packages/zui/src/z/__tests__/set.test.ts b/packages/zui/src/z/__tests__/set.test.ts index 233f241645b..a0e70aea05d 100644 --- a/packages/zui/src/z/__tests__/set.test.ts +++ b/packages/zui/src/z/__tests__/set.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../utils' +import * as assert from '../../assertions.utils.test' import * as z from '../index' const stringSet = z.set(z.string()) @@ -12,7 +12,7 @@ const nonEmpty = z.set(z.string()).nonempty() const nonEmptyMax = z.set(z.string()).nonempty().max(2) test('type inference', () => { - utils.assert.assertEqual>(true) + assert.assertEqual>(true) }) test('valid parse', () => { diff --git a/packages/zui/src/z/types/any/anyunknown.test.ts b/packages/zui/src/z/types/any/anyunknown.test.ts index d3b7fd6ee3d..76354940be6 100644 --- a/packages/zui/src/z/types/any/anyunknown.test.ts +++ b/packages/zui/src/z/types/any/anyunknown.test.ts @@ -1,13 +1,13 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' test('check any inference', () => { const t1 = z.any() t1.optional() t1.nullable() type t1 = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('check unknown inference', () => { @@ -15,7 +15,7 @@ test('check unknown inference', () => { t1.optional() t1.nullable() type t1 = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('check never inference', () => { diff --git a/packages/zui/src/z/types/array/array.test.ts b/packages/zui/src/z/types/array/array.test.ts index 987ac658c85..f53a1e3b381 100644 --- a/packages/zui/src/z/types/array/array.test.ts +++ b/packages/zui/src/z/types/array/array.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' const minTwo = z.string().array().min(2) const maxTwo = z.string().array().max(2) @@ -9,10 +9,10 @@ const intNum = z.string().array().nonempty() const nonEmptyMax = z.string().array().nonempty().max(2) type t1 = z.infer -utils.assert.assertEqual<[string, ...string[]], t1>(true) +assert.assertEqual<[string, ...string[]], t1>(true) type t2 = z.infer -utils.assert.assertEqual(true) +assert.assertEqual(true) test('passing validations', () => { minTwo.parse(['a', 'a']) diff --git a/packages/zui/src/z/types/branded/branded.test.ts b/packages/zui/src/z/types/branded/branded.test.ts index 6da90a450d8..fccb32745a8 100644 --- a/packages/zui/src/z/types/branded/branded.test.ts +++ b/packages/zui/src/z/types/branded/branded.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import { BRAND } from '../../typings' test('branded types', () => { @@ -12,7 +12,7 @@ test('branded types', () => { // simple branding type MySchema = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) const doStuff = (arg: MySchema) => arg doStuff(mySchema.parse({ name: 'hello there' })) @@ -20,14 +20,14 @@ test('branded types', () => { // inheritance const extendedSchema = mySchema.brand<'subschema'>() type ExtendedSchema = z.infer - utils.assert.assertEqual & BRAND<'subschema'>>(true) + assert.assertEqual & BRAND<'subschema'>>(true) doStuff(extendedSchema.parse({ name: 'hello again' })) // number branding const numberSchema = z.number().brand<42>() type NumberSchema = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) // symbol branding const MyBrand: unique symbol = Symbol('hello') @@ -35,7 +35,7 @@ test('branded types', () => { const symbolBrand = z.number().brand<'sup'>().brand() type SymbolBrand = z.infer // number & { [BRAND]: { sup: true, [MyBrand]: true } } - utils.assert.assertEqual & BRAND>(true) + assert.assertEqual & BRAND>(true) // keeping brands out of input types const age = z.number().brand<'age'>() @@ -43,9 +43,9 @@ test('branded types', () => { type Age = z.infer type AgeInput = z.input - utils.assert.assertEqual(false) - utils.assert.assertEqual(true) - utils.assert.assertEqual, Age>(true) + assert.assertEqual(false) + assert.assertEqual(true) + assert.assertEqual, Age>(true) // @ts-expect-error doStuff({ name: 'hello there!' }) diff --git a/packages/zui/src/z/types/catch/catch.test.ts b/packages/zui/src/z/types/catch/catch.test.ts index a4526f0cdc4..e966edaf15f 100644 --- a/packages/zui/src/z/types/catch/catch.test.ts +++ b/packages/zui/src/z/types/catch/catch.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import { z } from '../../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import { ZodError } from '../../error' test('basic catch', () => { @@ -44,9 +44,9 @@ test('catch with transform', () => { expect(stringWithDefault._def.innerType._def.schema.typeName).toBe('ZodString') type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('catch on existing optional', () => { @@ -58,18 +58,18 @@ test('catch on existing optional', () => { expect(stringWithDefault._def.innerType._def.innerType.typeName).toBe('ZodString') type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('optional on catch', () => { const stringWithDefault = z.string().catch('asdf').optional() type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('complex chain example', () => { @@ -92,7 +92,7 @@ test('removeCatch', () => { const stringWithRemovedDefault = z.string().catch('asdf').removeCatch() type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('nested', () => { @@ -101,9 +101,9 @@ test('nested', () => { inner: 'asdf', }) type input = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) expect(outer.parse(undefined)).toEqual({ inner: 'asdf' }) expect(outer.parse({})).toEqual({ inner: 'asdf' }) expect(outer.parse({ inner: undefined })).toEqual({ inner: 'asdf' }) diff --git a/packages/zui/src/z/types/default/default.test.ts b/packages/zui/src/z/types/default/default.test.ts index 0809d79763c..8a8f2b9eea2 100644 --- a/packages/zui/src/z/types/default/default.test.ts +++ b/packages/zui/src/z/types/default/default.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import { z } from '../../..' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' test('basic defaults', () => { expect(z.string().default('default').parse(undefined)).toBe('default') @@ -17,9 +17,9 @@ test('default with transform', () => { expect(stringWithDefault._def.innerType._def.schema.typeName).toBe('ZodString') type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('default on existing optional', () => { @@ -30,18 +30,18 @@ test('default on existing optional', () => { expect(stringWithDefault._def.innerType._def.innerType.typeName).toBe('ZodString') type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('optional on default', () => { const stringWithDefault = z.string().default('asdf').optional() type inp = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('complex chain example', () => { @@ -61,7 +61,7 @@ test('removeDefault', () => { const stringWithRemovedDefault = z.string().default('asdf').removeDefault() type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('nested', () => { @@ -70,9 +70,9 @@ test('nested', () => { inner: undefined, }) type input = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type out = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) expect(outer.parse(undefined)).toEqual({ inner: 'asdf' }) expect(outer.parse({})).toEqual({ inner: 'asdf' }) expect(outer.parse({ inner: undefined })).toEqual({ inner: 'asdf' }) diff --git a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts index 9a62734b7f2..e61f3bea33d 100644 --- a/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts +++ b/packages/zui/src/z/types/discriminatedUnion/discriminatedUnion.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' test('valid', () => { expect( @@ -282,7 +282,7 @@ test('optional and nullable', () => { ]) type schema = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) schema.parse({ key: 'a', a: true }) schema.parse({ key: undefined, a: true }) diff --git a/packages/zui/src/z/types/enum/enum.test.ts b/packages/zui/src/z/types/enum/enum.test.ts index 121fa5119b3..b290a32fa75 100644 --- a/packages/zui/src/z/types/enum/enum.test.ts +++ b/packages/zui/src/z/types/enum/enum.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' test('create enum', () => { @@ -12,7 +12,7 @@ test('create enum', () => { test('infer enum', () => { const MyEnum = z.enum(['Red', 'Green', 'Blue']) type MyEnum = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('get options', () => { @@ -23,7 +23,7 @@ test('readonly enum', () => { const HTTP_SUCCESS = ['200', '201'] as const const arg = z.enum(HTTP_SUCCESS) type arg = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) arg.parse('201') expect(() => arg.parse('202')).toThrow() @@ -44,11 +44,11 @@ test('extract/exclude', () => { const UnhealthyEnum = FoodEnum.exclude(['Salad']) const EmptyFoodEnum = FoodEnum.exclude(foods) - utils.assert.assertEqual, 'Pasta' | 'Pizza'>(true) - utils.assert.assertEqual, 'Pasta' | 'Pizza' | 'Tacos' | 'Burgers'>(true) + assert.assertEqual, 'Pasta' | 'Pizza'>(true) + assert.assertEqual, 'Pasta' | 'Pizza' | 'Tacos' | 'Burgers'>(true) // @ts-expect-error TS2344 - utils.assert.assertEqual>(true) - utils.assert.assertEqual, never>(true) + assert.assertEqual>(true) + assert.assertEqual, never>(true) }) test('error map in extract/exclude', () => { diff --git a/packages/zui/src/z/types/function/function.test.ts b/packages/zui/src/z/types/function/function.test.ts index 8120d3185e4..aea30fa1f78 100644 --- a/packages/zui/src/z/types/function/function.test.ts +++ b/packages/zui/src/z/types/function/function.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import { ZodError } from '../../error' const args1 = z.tuple([z.string()]) @@ -24,7 +24,7 @@ test('parsed function fail 2', () => { test('function inference 1', () => { type func1 = z.TypeOf - utils.assert.assertEqual number>(true) + assert.assertEqual number>(true) }) test('method parsing', () => { @@ -60,15 +60,15 @@ test('async method parsing', async () => { test('args method', () => { const t1 = z.function() type t1 = z.infer - utils.assert.assertEqual unknown>(true) + assert.assertEqual unknown>(true) const t2 = t1.args(z.string()) type t2 = z.infer - utils.assert.assertEqual unknown>(true) + assert.assertEqual unknown>(true) const t3 = t2.returns(z.boolean()) type t3 = z.infer - utils.assert.assertEqual boolean>(true) + assert.assertEqual boolean>(true) }) const args2 = z.tuple([ @@ -84,7 +84,7 @@ const func2 = z.function(args2, returns2) test('function inference 2', () => { type func2 = z.TypeOf - utils.assert.assertEqual< + assert.assertEqual< func2, (arg: { f1: number; f2: string | null; f3?: (boolean | undefined)[] | undefined }) => string | number >(true) @@ -235,7 +235,7 @@ test('inference with transforms', () => { }) myFunc('asdf') - utils.assert.assertEqual { val: number; extra: string }>(true) + assert.assertEqual { val: number; extra: string }>(true) }) test('fallback to OuterTypeOfFunction', () => { @@ -248,5 +248,5 @@ test('fallback to OuterTypeOfFunction', () => { return { arg: val, arg2: false } }) - utils.assert.assertEqual number>(true) + assert.assertEqual number>(true) }) diff --git a/packages/zui/src/z/types/map/map.test.ts b/packages/zui/src/z/types/map/map.test.ts index 8a0961d04c0..eb3d8cbfab4 100644 --- a/packages/zui/src/z/types/map/map.test.ts +++ b/packages/zui/src/z/types/map/map.test.ts @@ -1,12 +1,12 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' const stringMap = z.map(z.string(), z.string()) type stringMap = z.infer test('type inference', () => { - utils.assert.assertEqual>(true) + assert.assertEqual>(true) }) test('valid parse', () => { diff --git a/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts b/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts index bb5faab695d..2c4a2726fa4 100644 --- a/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts +++ b/packages/zui/src/z/types/nativeEnum/nativeEnum.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' import * as z from '../../index' +import * as assert from '../../../assertions.utils.test' test('nativeEnum test with consts', () => { const Fruits: { Apple: 'apple'; Banana: 'banana' } = { @@ -13,7 +13,7 @@ test('nativeEnum test with consts', () => { fruitEnum.parse('banana') fruitEnum.parse(Fruits.Apple) fruitEnum.parse(Fruits.Banana) - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('nativeEnum test with real enum', () => { @@ -28,7 +28,7 @@ test('nativeEnum test with real enum', () => { fruitEnum.parse('banana') fruitEnum.parse(Fruits.Apple) fruitEnum.parse(Fruits.Banana) - utils.assert.assertIs(true) + assert.assertIs(true) }) test('nativeEnum test with const with numeric keys', () => { @@ -43,7 +43,7 @@ test('nativeEnum test with const with numeric keys', () => { fruitEnum.parse(20) fruitEnum.parse(FruitValues.Apple) fruitEnum.parse(FruitValues.Banana) - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('from enum', () => { diff --git a/packages/zui/src/z/types/object/object.test.ts b/packages/zui/src/z/types/object/object.test.ts index 0ecf891f089..4dc67308131 100644 --- a/packages/zui/src/z/types/object/object.test.ts +++ b/packages/zui/src/z/types/object/object.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' const Test = z.object({ @@ -18,7 +18,7 @@ test('object type inference', () => { f4: { t: string | boolean }[] } - utils.assert.assertEqual, TestType>(true) + assert.assertEqual, TestType>(true) }) test('unknown throw', () => { @@ -124,8 +124,8 @@ test('catchall inference', () => { const prop1 = d1.first const prop2 = d1.num - utils.assert.assertEqual(true) - utils.assert.assertEqual(true) + assert.assertEqual(true) + assert.assertEqual(true) }) test('catchall overrides strict', () => { @@ -213,7 +213,7 @@ test('test async union', async () => { test('test inferred merged type', async () => { const asdf = z.object({ a: z.string() }).merge(z.object({ a: z.number() })) type asdf = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('inferred merged object type with optional properties', async () => { @@ -221,9 +221,9 @@ test('inferred merged object type with optional properties', async () => { .object({ a: z.string(), b: z.string().optional() }) .merge(z.object({ a: z.string().optional(), b: z.string() })) type Merged = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) // todo - // utils.assert.assertEqual(true); + // assert.assertEqual(true); }) test('inferred unioned object type with optional properties', async () => { @@ -232,7 +232,7 @@ test('inferred unioned object type with optional properties', async () => { z.object({ a: z.string().optional(), b: z.string() }), ]) type Unioned = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('inferred enum type', async () => { @@ -248,19 +248,19 @@ test('inferred enum type', async () => { }) expect(Enum._def.values).toEqual(['a', 'b']) type Enum = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('inferred partial object type with optional properties', async () => { const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial() type Partial = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('inferred picked object type with optional properties', async () => { const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true }) type Picked = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('inferred type for unknown/any keys', () => { @@ -271,7 +271,7 @@ test('inferred type for unknown/any keys', () => { unknownRequired: z.unknown(), }) type myType = z.infer - utils.assert.assertEqual< + assert.assertEqual< myType, { anyOptional?: any @@ -287,7 +287,7 @@ test('setKey', () => { const withNewKey = base.setKey('age', z.number()) type withNewKey = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) withNewKey.parse({ name: 'asdf', age: 1234 }) }) @@ -347,7 +347,7 @@ test('constructor key', () => { }) type Example = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('unknownkeys merging', () => { @@ -368,7 +368,7 @@ test('unknownkeys merging', () => { const mergedSchema = schemaA.merge(schemaB) type mergedSchema = typeof mergedSchema - utils.assert.assertEqual(true) + assert.assertEqual(true) expect(mergedSchema._def.unknownKeys.typeName).toBe('ZodString') }) @@ -385,8 +385,8 @@ test('extend() should return schema with new key', () => { const actual = PersonWithNickname.parse(expected) expect(actual).toEqual(expected) - utils.assert.assertEqual(true) - utils.assert.assertEqual(true) + assert.assertEqual(true) + assert.assertEqual(true) }) test('extend() should have power to override existing key', () => { @@ -399,16 +399,16 @@ test('extend() should have power to override existing key', () => { const actual = PersonWithNumberAsLastName.parse(expected) expect(actual).toEqual(expected) - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('passthrough index signature', () => { const a = z.object({ a: z.string() }) type a = z.infer - utils.assert.assertEqual<{ a: string }, a>(true) + assert.assertEqual<{ a: string }, a>(true) const b = a.passthrough() type b = z.infer - utils.assert.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true) + assert.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true) }) test('xor', () => { diff --git a/packages/zui/src/z/types/promise/promise.test.ts b/packages/zui/src/z/types/promise/promise.test.ts index 3fc4b2dff65..8e826e78a18 100644 --- a/packages/zui/src/z/types/promise/promise.test.ts +++ b/packages/zui/src/z/types/promise/promise.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' import { ZodError } from '../../error' @@ -12,7 +12,7 @@ const promSchema = z.promise( test('promise inference', () => { type promSchemaType = z.infer - utils.assert.assertEqual>(true) + assert.assertEqual>(true) }) test('promise parsing success', async () => { diff --git a/packages/zui/src/z/types/readonly/readonly.test.ts b/packages/zui/src/z/types/readonly/readonly.test.ts index 3b0700c1b75..6ba552e45a3 100644 --- a/packages/zui/src/z/types/readonly/readonly.test.ts +++ b/packages/zui/src/z/types/readonly/readonly.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' enum testEnum { @@ -33,90 +33,89 @@ const schemas = [ ] as const test('flat inference', () => { - utils.assert.assertEqual, string>(true) - utils.assert.assertEqual, number>(true) - utils.assert.assertEqual, number>(true) - utils.assert.assertEqual, bigint>(true) - utils.assert.assertEqual, boolean>(true) - utils.assert.assertEqual, Date>(true) - utils.assert.assertEqual, undefined>(true) - utils.assert.assertEqual, null>(true) - utils.assert.assertEqual, any>(true) - utils.assert.assertEqual, Readonly>(true) - utils.assert.assertEqual, void>(true) - utils.assert.assertEqual< - z.infer<(typeof schemas)[11]>, - (args_0: string, args_1: number, ...args_2: unknown[]) => unknown - >(true) - utils.assert.assertEqual, readonly string[]>(true) + assert.assertEqual, string>(true) + assert.assertEqual, number>(true) + assert.assertEqual, number>(true) + assert.assertEqual, bigint>(true) + assert.assertEqual, boolean>(true) + assert.assertEqual, Date>(true) + assert.assertEqual, undefined>(true) + assert.assertEqual, null>(true) + assert.assertEqual, any>(true) + assert.assertEqual, Readonly>(true) + assert.assertEqual, void>(true) + assert.assertEqual, (args_0: string, args_1: number, ...args_2: unknown[]) => unknown>( + true + ) + assert.assertEqual, readonly string[]>(true) - utils.assert.assertEqual, readonly [string, number]>(true) - utils.assert.assertEqual, ReadonlyMap>(true) - utils.assert.assertEqual, ReadonlySet>>(true) - utils.assert.assertEqual, Readonly>>(true) - utils.assert.assertEqual, Readonly>>(true) - utils.assert.assertEqual, { readonly a: string; readonly 1: number }>(true) - utils.assert.assertEqual, Readonly>(true) - utils.assert.assertEqual, Promise>(true) + assert.assertEqual, readonly [string, number]>(true) + assert.assertEqual, ReadonlyMap>(true) + assert.assertEqual, ReadonlySet>>(true) + assert.assertEqual, Readonly>>(true) + assert.assertEqual, Readonly>>(true) + assert.assertEqual, { readonly a: string; readonly 1: number }>(true) + assert.assertEqual, Readonly>(true) + assert.assertEqual, Promise>(true) }) // test("deep inference", () => { -// utils.assert.assertEqual, string>(true); -// utils.assert.assertEqual, number>(true); -// utils.assert.assertEqual, number>(true); -// utils.assert.assertEqual, bigint>(true); -// utils.assert.assertEqual, boolean>(true); -// utils.assert.assertEqual, Date>(true); -// utils.assert.assertEqual, undefined>(true); -// utils.assert.assertEqual, null>(true); -// utils.assert.assertEqual, any>(true); -// utils.assert.assertEqual< +// assert.assertEqual, string>(true); +// assert.assertEqual, number>(true); +// assert.assertEqual, number>(true); +// assert.assertEqual, bigint>(true); +// assert.assertEqual, boolean>(true); +// assert.assertEqual, Date>(true); +// assert.assertEqual, undefined>(true); +// assert.assertEqual, null>(true); +// assert.assertEqual, any>(true); +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[9]>, // Readonly // >(true); -// utils.assert.assertEqual, void>(true); -// utils.assert.assertEqual< +// assert.assertEqual, void>(true); +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[11]>, // (args_0: string, args_1: number, ...args_2: unknown[]) => unknown // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[12]>, // readonly string[] // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[13]>, // readonly [string, number] // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[14]>, // ReadonlyMap // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[15]>, // ReadonlySet> // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[16]>, // Readonly> // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[17]>, // Readonly> // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[18]>, // { readonly a: string; readonly 1: number } // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[19]>, // Readonly // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer<(typeof deepReadonlySchemas_0)[20]>, // Promise // >(true); -// utils.assert.assertEqual< +// assert.assertEqual< // z.infer, // ReadonlyMap< // ReadonlySet, diff --git a/packages/zui/src/z/types/record/record.test.ts b/packages/zui/src/z/types/record/record.test.ts index 059522a8afa..d005a21a0b6 100644 --- a/packages/zui/src/z/types/record/record.test.ts +++ b/packages/zui/src/z/types/record/record.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' import * as z from '../../index' const booleanRecord = z.record(z.boolean()) @@ -12,11 +12,11 @@ const recordWithLiteralKeys = z.record(z.union([z.literal('Tuna'), z.literal('Sa type recordWithLiteralKeys = z.infer test('type inference', () => { - utils.assert.assertEqual>(true) + assert.assertEqual>(true) - utils.assert.assertEqual>>(true) + assert.assertEqual>>(true) - utils.assert.assertEqual>>(true) + assert.assertEqual>>(true) }) test('methods', () => { diff --git a/packages/zui/src/z/types/ref/ref.test.ts b/packages/zui/src/z/types/ref/ref.test.ts index cda16de61e4..52a85ce9a72 100644 --- a/packages/zui/src/z/types/ref/ref.test.ts +++ b/packages/zui/src/z/types/ref/ref.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' const T = z.ref('T') @@ -20,5 +20,5 @@ test('type inference', () => { data: NonNullable } type Actual = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index f04d6f9ec0d..07caab9a570 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -180,7 +180,7 @@ export class ZodEffectsImpl, I return utils.others.compareFunctions(this._def.effect.transform, schema._def.effect.transform) } - type _assertion = utils.assert.AssertNever + this._def.effect satisfies never return false } diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index cb407bccf65..48b63177384 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' import * as z from '../../index' +import * as assert from '../../../assertions.utils.test' import { NEVER } from '..' const stringToNumber = z.string().transform((arg) => parseFloat(arg)) @@ -85,7 +85,7 @@ test('z.NEVER in transform', () => { return val }) type foo = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) const arg = foo.safeParse(undefined) if (!arg.success) { expect(arg.error.issues[0]?.message).toEqual('bad') @@ -177,8 +177,8 @@ test('object typing', () => { type t1 = z.input type t2 = z.output - utils.assert.assertEqual(true) - utils.assert.assertEqual(true) + assert.assertEqual(true) + assert.assertEqual(true) }) test('transform method overloads', () => { diff --git a/packages/zui/src/z/types/tuple/tuple.test.ts b/packages/zui/src/z/types/tuple/tuple.test.ts index f2fdc5e0432..b0076453480 100644 --- a/packages/zui/src/z/types/tuple/tuple.test.ts +++ b/packages/zui/src/z/types/tuple/tuple.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' -import * as utils from '../../utils' import * as z from '../../index' +import * as assert from '../../../assertions.utils.test' import { ZodError } from '../../error' const testTuple = z.tuple([z.string(), z.object({ name: z.literal('Rudy') }), z.array(z.literal('blue'))]) @@ -12,7 +12,7 @@ test('tuple inference', () => { const returns1 = z.number() const func1 = z.function(args1, returns1) type func1 = z.TypeOf - utils.assert.assertEqual number>(true) + assert.assertEqual number>(true) }) test('successful validation', () => { @@ -58,9 +58,9 @@ test('tuple with transformers', () => { const val = z.tuple([stringToNumber]) type t1 = z.input - utils.assert.assertEqual(true) + assert.assertEqual(true) type t2 = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) expect(val.parse(['1234'])).toEqual([4]) }) @@ -73,7 +73,7 @@ test('tuple with rest schema', () => { expect(() => myTuple.parse(['asdf', 1234, 'asdf'])).toThrow() type t1 = z.output - utils.assert.assertEqual(true) + assert.assertEqual(true) }) test('parse should fail given sparse array as tuple', () => { diff --git a/packages/zui/src/z/types/void/void.test.ts b/packages/zui/src/z/types/void/void.test.ts index 1fe884fc0f3..167840c2b31 100644 --- a/packages/zui/src/z/types/void/void.test.ts +++ b/packages/zui/src/z/types/void/void.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' -import * as utils from '../../utils' +import * as assert from '../../../assertions.utils.test' test('void', () => { const v = z.void() @@ -10,5 +10,5 @@ test('void', () => { expect(() => v.parse('')).toThrow() type v = z.infer - utils.assert.assertEqual(true) + assert.assertEqual(true) }) diff --git a/packages/zui/src/z/utils/assert-utils.ts b/packages/zui/src/z/utils/assert-utils.ts index 433f45b82b9..4c760715351 100644 --- a/packages/zui/src/z/utils/assert-utils.ts +++ b/packages/zui/src/z/utils/assert-utils.ts @@ -1,10 +1,6 @@ -import { IsEqual } from './type-utils' - -export type AssertNever<_T extends never> = true -export type AssertTrue<_T extends true> = true - -export const assertEqual = (val: IsEqual) => val -export function assertIs(_arg: T): void {} +/** + * @deprecated use x satisfies never instead + */ export function assertNever(_x: never): never { throw new Error('assertNever called') } diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/z/utils/type-utils.ts index 22ae092c209..32aa4914216 100644 --- a/packages/zui/src/z/utils/type-utils.ts +++ b/packages/zui/src/z/utils/type-utils.ts @@ -1,6 +1,4 @@ export type ValueOf = T[keyof T] -export type IsEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? true : false -export type IsAny = 0 extends 1 & T ? true : false export type NoUndefined = T extends undefined ? never : T export type Satisfies = X export type SafeOmit = Omit @@ -10,21 +8,6 @@ export type Writeable = { -readonly [P in keyof T]: T[P] } -type NormalizeObject = T extends infer O ? { [K in keyof O]: Normalize } : never -export type Normalize = T extends (...args: infer A) => infer R - ? (...args: Normalize) => Normalize - : T extends Array - ? Array> - : T extends ReadonlyArray - ? ReadonlyArray> - : T extends Promise - ? Promise> - : T extends Buffer - ? Buffer - : T extends object - ? NormalizeObject - : T - type _UnionToIntersectionFn = (T extends unknown ? (k: () => T) => void : never) extends ( k: infer Intersection ) => void From 905e608eaadcf2154da87d1c2886baafb39139bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 4 Mar 2026 11:08:12 -0500 Subject: [PATCH 29/50] chore: update codebase for the new zui API (#14989) --- .../browser/integration.definition.ts | 2 +- .../browser/src/actions/discover-urls.ts | 16 ++-- .../calendly/integration.definition.ts | 2 +- integrations/calendly/src/utils.ts | 6 +- .../mailchimp/integration.definition.ts | 2 +- integrations/mailchimp/src/utils.ts | 4 +- integrations/zapier/integration.definition.ts | 2 +- integrations/zapier/src/helpers.ts | 2 +- packages/llmz/src/component.ts | 7 +- packages/llmz/src/tool.ts | 31 ++++---- packages/llmz/src/typings.ts | 74 ++++++++++--------- packages/sdk/src/zui.ts | 4 +- packages/zai/src/operations/errors.ts | 4 +- packages/zui/src/z/z.ts | 1 + .../plugin.definition.ts | 2 +- .../src/prompt/parse-content.test.ts | 10 ++- .../file-synchronizer/plugin.definition.ts | 2 +- .../src/utils/json-lines/parser.test.ts | 7 +- 18 files changed, 98 insertions(+), 80 deletions(-) diff --git a/integrations/browser/integration.definition.ts b/integrations/browser/integration.definition.ts index 3597b285a83..6cdd8ccb838 100644 --- a/integrations/browser/integration.definition.ts +++ b/integrations/browser/integration.definition.ts @@ -3,7 +3,7 @@ import { IntegrationDefinition } from '@botpress/sdk' import { actionDefinitions } from 'src/definitions/actions' export const INTEGRATION_NAME = 'browser' -export const INTEGRATION_VERSION = '0.8.3' +export const INTEGRATION_VERSION = '0.8.5' export default new IntegrationDefinition({ name: INTEGRATION_NAME, diff --git a/integrations/browser/src/actions/discover-urls.ts b/integrations/browser/src/actions/discover-urls.ts index 5eb601a5ddd..a44d4710e09 100644 --- a/integrations/browser/src/actions/discover-urls.ts +++ b/integrations/browser/src/actions/discover-urls.ts @@ -1,5 +1,5 @@ import { RuntimeError } from '@botpress/client' -import { IntegrationLogger, z, ZodIssueCode } from '@botpress/sdk' +import { IntegrationLogger, z, ZodIssue } from '@botpress/sdk' import Firecrawl, { SdkError } from '@mendable/firecrawl-js' import { trackEvent } from '../tracking' import { isValidGlob, matchGlob } from '../utils/globs' @@ -11,6 +11,8 @@ const COST_PER_FIRECRAWL_MAP = 0.001 type StopReason = Awaited>['stopReason'] +type ZodIssueCode = ZodIssue['code'] + export const urlSchema = z.string().transform((url, ctx) => { url = url.trim() if (!url.includes('://')) { @@ -20,28 +22,28 @@ export const urlSchema = z.string().transform((url, ctx) => { const x = new URL(url) if (x.protocol !== 'http:' && x.protocol !== 'https:') { ctx.addIssue({ - code: ZodIssueCode.custom, + code: 'custom' satisfies ZodIssueCode, message: 'Invalid protocol, only URLs starting with HTTP and HTTPS are supported', }) - return z.NEVER + return { status: 'aborted' } as never } if (!/.\.[a-zA-Z]{2,}$/.test(x.hostname)) { ctx.addIssue({ - code: ZodIssueCode.custom, + code: 'custom' satisfies ZodIssueCode, message: 'Invalid TLD', }) - return z.NEVER + return { status: 'aborted' } as never } const pathName = x.pathname.endsWith('/') ? x.pathname.slice(0, -1) : x.pathname return `${x.origin}${pathName}${x.search ? x.search : ''}` } catch (caught) { const err = caught instanceof Error ? caught : new Error('Unknown error while parsing URL') ctx.addIssue({ - code: ZodIssueCode.custom, + code: 'custom' satisfies ZodIssueCode, message: 'Invalid URL: ' + err.message, }) - return z.NEVER + return { status: 'aborted' } as never } }) diff --git a/integrations/calendly/integration.definition.ts b/integrations/calendly/integration.definition.ts index 0194aa5a04b..db8b5fe370d 100644 --- a/integrations/calendly/integration.definition.ts +++ b/integrations/calendly/integration.definition.ts @@ -5,7 +5,7 @@ import { inviteeEventOutputSchema } from 'definitions/events' export default new IntegrationDefinition({ name: 'calendly', title: 'Calendly', - version: '0.0.1', + version: '0.0.3', readme: 'hub.md', icon: 'icon.svg', description: 'Schedule meetings and manage events using the Calendly scheduling platform.', diff --git a/integrations/calendly/src/utils.ts b/integrations/calendly/src/utils.ts index 73a4ff1aa80..ff6eb2f2a35 100644 --- a/integrations/calendly/src/utils.ts +++ b/integrations/calendly/src/utils.ts @@ -1,9 +1,9 @@ -import { RuntimeError, ZodError } from '@botpress/sdk' +import { RuntimeError, z } from '@botpress/sdk' import axios from 'axios' import type { Result } from './types' -const _isZodError = (error: any): error is ZodError => { - return error && typeof error === 'object' && error instanceof ZodError && 'errors' in error +const _isZodError = (error: any): error is z.ZodError => { + return error && typeof error === 'object' && z.is.zuiError(error) && 'errors' in error } export function parseError(thrown: unknown): RuntimeError { diff --git a/integrations/mailchimp/integration.definition.ts b/integrations/mailchimp/integration.definition.ts index 92232ce93ae..69f700c8980 100644 --- a/integrations/mailchimp/integration.definition.ts +++ b/integrations/mailchimp/integration.definition.ts @@ -16,7 +16,7 @@ const INTEGRATION_NAME = 'mailchimp' export default new IntegrationDefinition({ name: INTEGRATION_NAME, title: 'Mailchimp', - version: '0.3.9', + version: '0.3.11', readme: 'hub.md', icon: 'icon.svg', description: 'Send mass email campaigns from within your workflows. Manage customers, campaigns, lists and more.', diff --git a/integrations/mailchimp/src/utils.ts b/integrations/mailchimp/src/utils.ts index b6a6b0c0e2b..69ac148a2de 100644 --- a/integrations/mailchimp/src/utils.ts +++ b/integrations/mailchimp/src/utils.ts @@ -1,4 +1,4 @@ -import { ZodError, RuntimeError } from '@botpress/sdk' +import { ZodError, RuntimeError, z } from '@botpress/sdk' import { MailchimpApi } from './client' import { Customer, MailchimpAPIError } from './misc/custom-types' import { Logger } from './misc/types' @@ -28,7 +28,7 @@ export const isMailchimpError = (error: any): error is MailchimpAPIError => { } export const isZodError = (error: any): error is ZodError => { - return error && typeof error === 'object' && error instanceof ZodError && 'errors' in error + return error && typeof error === 'object' && z.is.zuiError(error) && 'errors' in error } export const parseError = (error: any): RuntimeError => { diff --git a/integrations/zapier/integration.definition.ts b/integrations/zapier/integration.definition.ts index 206d4030478..5a3f98d0c59 100644 --- a/integrations/zapier/integration.definition.ts +++ b/integrations/zapier/integration.definition.ts @@ -4,7 +4,7 @@ import { TriggerSchema, EventSchema, ZapierTriggersStateName, ZapierTriggersStat export default new IntegrationDefinition({ name: 'zapier', - version: '0.3.7', + version: '0.3.9', title: 'Zapier', description: "Trigger workflows from Zapier or let Zapier trigger your workflows to automate tasks and enhance your bot's capabilities.", diff --git a/integrations/zapier/src/helpers.ts b/integrations/zapier/src/helpers.ts index d99ba8417c0..9f9666f28b0 100644 --- a/integrations/zapier/src/helpers.ts +++ b/integrations/zapier/src/helpers.ts @@ -44,7 +44,7 @@ export async function getTriggersState(ctx: bp.Context, client: Client) { if ((isApiError(e) && e.type === 'ResourceNotFound') || e.message === 'No State found') { console.info("Zapier triggers state doesn't exist yet and will be initialized") return defaultState - } else if (e instanceof z.ZodError) { + } else if (z.is.zuiError(e)) { console.warn(`Zapier triggers state will be reset as it's corrupted: ${e.message}`) return defaultState } else { diff --git a/packages/llmz/src/component.ts b/packages/llmz/src/component.ts index ae78cb76a4a..d2bd2e04ea7 100644 --- a/packages/llmz/src/component.ts +++ b/packages/llmz/src/component.ts @@ -97,10 +97,9 @@ export function getComponentReference(component: ComponentDefinition): string { const naked = schema.naked() const zodType = naked._def.typeName const defValue = getDefaultValue(schema) - const typings = - naked instanceof z.ZodEnum - ? naked._def.values.map((x: string) => `"${x}"`).join(' | ') - : zodTypeToTsType[zodType] || zodType + const typings = z.is.zuiEnum(naked) + ? naked._def.values.map((x: string) => `"${x}"`).join(' | ') + : zodTypeToTsType[zodType] || zodType const required = !schema.isOptional() ? '**(required)**' : '(optional)' const def = defValue ? ` _Default: \`${defValue}\`_` : '' const description = schema.description || schema.naked().description || schema?._def.description || '' diff --git a/packages/llmz/src/tool.ts b/packages/llmz/src/tool.ts index bb59af09a96..ee100d0b0a8 100644 --- a/packages/llmz/src/tool.ts +++ b/packages/llmz/src/tool.ts @@ -1,7 +1,7 @@ import { TypeOf, z, transforms, ZodObject, ZodType } from '@bpinternal/zui' import { JSONSchema7 } from 'json-schema' import { isEmpty, uniq } from 'lodash-es' -import { Serializable, ZuiType } from './types.js' +import { Serializable } from './types.js' import { getTypings as generateTypings } from './typings.js' import { convertObjectToZuiLiterals, isJsonSchema, isValidIdentifier, isZuiSchema } from './utils.js' @@ -65,7 +65,7 @@ export namespace Tool { metadata: Record input?: JSONSchema7 output?: JSONSchema7 - staticInputValues?: SmartPartial> + staticInputValues?: SmartPartial> maxRetries: number } } @@ -211,7 +211,7 @@ export namespace Tool { * - **Type coercion**: Basic type coercion where possible * */ -export class Tool implements Serializable { +export class Tool implements Serializable { private _staticInputValues?: unknown public name: string @@ -273,13 +273,13 @@ export class Tool impl const input = this.input ? transforms.fromJSONSchemaLegacy(this.input) : z.any() - if (input instanceof z.ZodObject && typeof values !== 'object') { + if (z.is.zuiObject(input) && typeof values !== 'object') { throw new Error( `Invalid static input values for tool ${this.name}. Expected an object, but got type "${typeof values}"` ) } - if (input instanceof z.ZodArray && !Array.isArray(values)) { + if (z.is.zuiArray(input) && !Array.isArray(values)) { throw new Error( `Invalid static input values for tool ${this.name}. Expected an array, but got type "${typeof values}"` ) @@ -299,7 +299,7 @@ export class Tool impl * @internal */ public get zInput() { - let input: ZuiType + let input: z.ZodType if (this.input) { try { input = transforms.fromJSONSchema(this.input) @@ -312,10 +312,10 @@ export class Tool impl if (!isEmpty(this._staticInputValues)) { const inputExtensions = convertObjectToZuiLiterals(this._staticInputValues) - if (input instanceof z.ZodObject) { + if (z.is.zuiObject(input)) { input = input.extend(inputExtensions) as typeof input - } else if (input instanceof z.ZodArray) { - input = z.array(input.element.extend(inputExtensions)) + } else if (z.is.zuiArray(input)) { + input = z.array((input.element as z.ZodObject).extend(inputExtensions)) } else { // if input is z.string() or z.number() etc input = inputExtensions as typeof input @@ -429,7 +429,7 @@ export class Tool impl * }) * ``` */ - public clone( + public clone( props: Partial<{ name: string aliases?: string[] @@ -469,13 +469,13 @@ export class Tool impl input: typeof props.input === 'function' ? props.input?.(zInput) - : props.input instanceof ZodType + : z.is.zuiType(props.input) ? props.input : (zInput as unknown as IX), output: typeof props.output === 'function' ? props.output?.(zOutput) - : props.output instanceof ZodType + : z.is.zuiType(props.output) ? props.output : (zOutput as unknown as OX), handler: (props.handler ?? this._handler) as (args: TypeOf, ctx: ToolCallContext) => Promise>, @@ -720,7 +720,7 @@ export class Tool impl */ public async getTypings(): Promise { // Try newer fromJSONSchema first, fallback to legacy if it fails - let input: ZuiType | undefined + let input: z.ZodType | undefined if (this.input) { try { input = transforms.fromJSONSchema(this.input) @@ -731,7 +731,7 @@ export class Tool impl // Handle void output specially - when z.void() is converted to JSON Schema ({}), // it becomes z.any() when converted back. Check if the JSON Schema is empty. - let output: ZuiType + let output: z.ZodType if (!this.output || Object.keys(this.output).length === 0) { output = z.void() } else { @@ -743,7 +743,8 @@ export class Tool impl } if ( - (input as any)?.naked() instanceof ZodObject && + input && + z.is.zuiObject(input.naked()) && typeof this._staticInputValues === 'object' && !isEmpty(this._staticInputValues) ) { diff --git a/packages/llmz/src/typings.ts b/packages/llmz/src/typings.ts index ce5b49e3749..eba6f98c5fc 100644 --- a/packages/llmz/src/typings.ts +++ b/packages/llmz/src/typings.ts @@ -63,7 +63,7 @@ export async function getTypings(schema: z.Schema, options?: Options): Promise { const newOptions = { @@ -102,7 +102,7 @@ async function sUnwrapZod( const isLargeDeclaration = typings.split('\n').length >= LARGE_DECLARATION_LINES const closingTag = isLargeDeclaration ? `// end of ${schema.identifier}` : '' - if (schema.schema instanceof z.ZodFunction) { + if (z.is.zuiFunction(schema.schema)) { return stripSpaces(`${description} declare function ${schema.identifier}${typings};${closingTag}`) } @@ -112,9 +112,9 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) } if (schema instanceof KeyValue) { - if (schema.value instanceof z.ZodOptional || schema.value instanceof z.ZodDefault) { + if (z.is.zuiOptional(schema.value) || z.is.zuiDefault(schema.value)) { let innerType = schema.value._def.innerType as z.Schema - if (innerType instanceof z.Schema && !innerType.description && schema.value.description) { + if (z.is.zuiType(innerType) && !innerType.description && schema.value.description) { innerType = innerType?.describe(schema.value.description) } const optionalToken = schema.key.endsWith('?') ? '' : '?' @@ -129,18 +129,18 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) } if (schema instanceof FnParameters) { - if (schema.schema instanceof z.ZodTuple) { + if (z.is.zuiTuple(schema.schema)) { let args = '' for (let i = 0; i < schema.schema.items.length; i++) { - const argName = schema.schema.items[i]?.ui?.title ?? `arg${i}` - const item = schema.schema.items[i] + const argName = (schema.schema.items[i]?.ui?.title as string) ?? `arg${i}` + const item = schema.schema.items[i]! args += `${await sUnwrapZodRecursive(new KeyValue(toPropertyKey(argName), item), newOptions)}, ` } return args } - const isLiteral = schema.schema.naked() instanceof z.ZodLiteral + const isLiteral = z.is.zuiLiteral(schema.schema.naked()) const typings = (await sUnwrapZodRecursive(schema.schema, newOptions)).trim() const startsWithPairs = @@ -159,34 +159,40 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) } if (schema instanceof FnReturn) { - if (schema.schema instanceof z.ZodOptional) { + if (z.is.zuiOptional(schema.schema)) { return `${await sUnwrapZodRecursive(schema.schema.unwrap(), newOptions)} | undefined` } return sUnwrapZodRecursive(schema.schema, newOptions) } - if (schema instanceof z.ZodDefault) { + if (schema === null) { + return 'unknown' + } + + schema satisfies z.ZodType + + if (z.is.zuiDefault(schema)) { return sUnwrapZodRecursive(schema._def.innerType, options) } - if (schema instanceof z.ZodVoid) { + if (z.is.zuiVoid(schema)) { return 'void' } - if (schema instanceof z.ZodUnknown) { + if (z.is.zuiUnknown(schema)) { return 'unknown' } - if (schema instanceof z.ZodAny) { + if (z.is.zuiAny(schema)) { return 'any' } - if (schema instanceof z.ZodPromise) { + if (z.is.zuiPromise(schema)) { return `Promise<${await sUnwrapZodRecursive(schema.unwrap(), newOptions)}>` } - if (schema instanceof z.ZodFunction) { + if (z.is.zuiFunction(schema)) { const description = getMultilineComment(schema._def.description) const input = await sUnwrapZodRecursive(new FnParameters(schema._def.args), newOptions) const output = await sUnwrapZodRecursive(new FnReturn(schema._def.returns), newOptions) @@ -200,7 +206,7 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) (${input}) => ${output}` } - if (schema instanceof z.ZodArray) { + if (z.is.zuiArray(schema)) { const item = await sUnwrapZodRecursive(schema._def.type, newOptions) if (isPrimitive(item)) { @@ -210,12 +216,12 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) return `Array<${item}>` } - if (schema instanceof z.ZodEnum) { + if (z.is.zuiEnum(schema)) { const values = schema._def.values.map(escapeString) return values.join(' | ') } - if (schema instanceof z.ZodTuple) { + if (z.is.zuiTuple(schema)) { if (schema.items.length === 0) { return '[]' } @@ -224,12 +230,12 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) return `[${items.join(', ')}]` } - if (schema instanceof z.ZodNullable) { + if (z.is.zuiNullable(schema)) { return `${await sUnwrapZodRecursive(schema.unwrap(), options)} | null` } - if (schema instanceof z.ZodOptional) { - if (options?.declaration || options?.parent instanceof z.ZodRecord) { + if (z.is.zuiOptional(schema)) { + if (options?.declaration || (z.is.zuiType(options?.parent) && options.parent.typeName === 'ZodRecord')) { return `${await sUnwrapZodRecursive(schema._def.innerType, newOptions)} | undefined` } const optionalToken = options.parent instanceof KeyValue ? '| undefined' : '' @@ -237,10 +243,10 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) return val } - if (schema instanceof z.ZodObject) { + if (z.is.zuiObject(schema)) { const props = await Promise.all( Object.entries(schema.shape).map(async ([key, value]) => { - if (value instanceof z.Schema) { + if (z.is.zuiType(value)) { return sUnwrapZodRecursive(new KeyValue(toPropertyKey(key), value), newOptions) } return `${key}: unknown` @@ -250,16 +256,16 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) return `{ ${props.join('; ')} }` } - if (schema instanceof z.ZodString) { + if (z.is.zuiString(schema)) { const description = getMultilineComment(schema._def.description) return `${description} string`.trim() } - if (schema instanceof z.ZodUnion) { + if (z.is.zuiUnion(schema)) { const description = getMultilineComment(schema._def.description) const options = await Promise.all( - (schema.options as z.ZodSchema[]).map(async (option) => { + (schema.options as readonly z.ZodSchema[]).map(async (option) => { return sUnwrapZodRecursive(option, newOptions) }) ) @@ -267,31 +273,31 @@ declare const ${schema.identifier}: ${typings};${closingTag}`) ${options.join(' | ')}` } - if (schema instanceof z.ZodLiteral) { + if (z.is.zuiLiteral(schema)) { const description = getMultilineComment(schema._def.description) return `${description} -${typeof schema.value === 'string' ? escapeString(schema.value) : schema.value}`.trim() +${typeof schema.value === 'string' ? escapeString(schema.value) : String(schema.value)}`.trim() } - if (schema instanceof z.ZodNumber) { + if (z.is.zuiNumber(schema)) { const description = getMultilineComment(schema._def.description) return `${description} number`.trim() } - if (schema instanceof z.ZodBoolean) { + if (z.is.zuiBoolean(schema)) { const description = getMultilineComment(schema._def.description) return `${description} boolean`.trim() } - if (schema instanceof z.ZodCatch) { + if (z.is.zuiCatch(schema)) { return sUnwrapZodRecursive(schema.removeCatch(), newOptions) } - if (schema instanceof z.ZodLazy) { + if (z.is.zuiLazy(schema)) { return sUnwrapZodRecursive(schema._def.getter(), newOptions) } - if (schema instanceof z.ZodRecord) { + if (z.is.zuiRecord(schema)) { const description = getMultilineComment(schema._def.description) const keyType = await sUnwrapZodRecursive(schema._def.keyType, newOptions) const valueType = await sUnwrapZodRecursive(schema._def.valueType, newOptions) diff --git a/packages/sdk/src/zui.ts b/packages/sdk/src/zui.ts index f03287cffdc..d95315acea7 100644 --- a/packages/sdk/src/zui.ts +++ b/packages/sdk/src/zui.ts @@ -14,12 +14,12 @@ export const mergeObjectSchemas = (a: ZuiObjectSchema, b: ZuiObjectSchema): ZuiO const aDef = a._def const bDef = b._def - if (aDef.typeName === z.ZodFirstPartyTypeKind.ZodObject && bDef.typeName === z.ZodFirstPartyTypeKind.ZodObject) { + if (aDef.typeName === 'ZodObject' && bDef.typeName === 'ZodObject') { const aShape = aDef.shape() const bShape = bDef.shape() return z.object({ ...aShape, ...bShape }) } - if (aDef.typeName === z.ZodFirstPartyTypeKind.ZodRecord && bDef.typeName === z.ZodFirstPartyTypeKind.ZodRecord) { + if (aDef.typeName === 'ZodRecord' && bDef.typeName === 'ZodRecord') { return z.record(z.intersection(aDef.valueType, bDef.valueType)) } // TODO: adress this case diff --git a/packages/zai/src/operations/errors.ts b/packages/zai/src/operations/errors.ts index 6df196fd6a2..2fde6818a19 100644 --- a/packages/zai/src/operations/errors.ts +++ b/packages/zai/src/operations/errors.ts @@ -1,4 +1,4 @@ -import { ZodError } from '@bpinternal/zui' +import { z, ZodError } from '@bpinternal/zui' export class JsonParsingError extends Error { public constructor( @@ -13,7 +13,7 @@ export class JsonParsingError extends Error { let errorMessage = 'Error parsing JSON:\n\n' errorMessage += `---JSON---\n${json}\n\n` - if (error instanceof ZodError) { + if (z.is.zuiError(error)) { errorMessage += '---Validation Errors---\n\n' errorMessage += JsonParsingError._formatZodError(error) } else { diff --git a/packages/zui/src/z/z.ts b/packages/zui/src/z/z.ts index 3238dcdc898..69c91aabe51 100644 --- a/packages/zui/src/z/z.ts +++ b/packages/zui/src/z/z.ts @@ -23,6 +23,7 @@ export type { IZodType as ZodType, ZodTypeAny, ZodSchema, + Schema, // any ZodAnyDef, diff --git a/plugins/conversation-insights/plugin.definition.ts b/plugins/conversation-insights/plugin.definition.ts index 52b418525ad..0c0cecc854e 100644 --- a/plugins/conversation-insights/plugin.definition.ts +++ b/plugins/conversation-insights/plugin.definition.ts @@ -2,7 +2,7 @@ import { PluginDefinition, z } from '@botpress/sdk' export default new PluginDefinition({ name: 'conversation-insights', - version: '0.5.0', + version: '0.5.1', configuration: { schema: z.object({ aiEnabled: z.boolean().default(true).describe('Set to true to enable title, summary and sentiment ai generation'), diff --git a/plugins/conversation-insights/src/prompt/parse-content.test.ts b/plugins/conversation-insights/src/prompt/parse-content.test.ts index 084fa87c19e..de1e941a1bc 100644 --- a/plugins/conversation-insights/src/prompt/parse-content.test.ts +++ b/plugins/conversation-insights/src/prompt/parse-content.test.ts @@ -32,9 +32,15 @@ describe('parseLLMOutput', () => { it('invalid json parsing throws an error', () => { const output = COGNITIVE_OUTPUT(`not a json`) - expect(() => { + let thrown: unknown | undefined = undefined + try { parseLLMOutput({ schema: CONTENT_PARSE_SCHEMA, ...output }) - }).toThrowError(sdk.ZodError) + } catch (e) { + thrown = e + } + + expect(thrown).toBeDefined() + expect(z.is.zuiError(thrown)).toBe(true) }) it('empty choices parsing throws an error', () => { diff --git a/plugins/file-synchronizer/plugin.definition.ts b/plugins/file-synchronizer/plugin.definition.ts index f406a1a895e..9084cf7b249 100644 --- a/plugins/file-synchronizer/plugin.definition.ts +++ b/plugins/file-synchronizer/plugin.definition.ts @@ -59,7 +59,7 @@ const FILE_FILTER_PROPS = sdk.z.object({ export default new sdk.PluginDefinition({ name: 'file-synchronizer', - version: '1.1.1', + version: '1.1.2', title: 'File Synchronizer', description: 'Synchronize files from external services to Botpress', icon: 'icon.svg', diff --git a/plugins/file-synchronizer/src/utils/json-lines/parser.test.ts b/plugins/file-synchronizer/src/utils/json-lines/parser.test.ts index 974b051ae2a..97cbfb0d972 100644 --- a/plugins/file-synchronizer/src/utils/json-lines/parser.test.ts +++ b/plugins/file-synchronizer/src/utils/json-lines/parser.test.ts @@ -108,7 +108,10 @@ describe.concurrent('parseJsonLines', () => { // Assert expect(result).toMatchObject([ - { rawLine: '{"id": 1, "name": "John", "email": "invalid-email"}', error: expect.any(sdk.z.ZodError) }, + { + rawLine: '{"id": 1, "name": "John", "email": "invalid-email"}', + error: expect.objectContaining({ __type__: 'ZuiError' }), + }, ]) }) @@ -123,7 +126,7 @@ describe.concurrent('parseJsonLines', () => { expect(result).toStrictEqual([ { rawLine: '1', value: 1 }, { rawLine: '2', value: 2 }, - { rawLine: '"not a number"', error: expect.any(sdk.z.ZodError) }, + { rawLine: '"not a number"', error: expect.objectContaining({ __type__: 'ZuiError' }) }, { rawLine: '4', value: 4 }, ]) }) From 8ffb54d584753dca3ecd95405bc77ecac44424a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 4 Mar 2026 11:28:45 -0500 Subject: [PATCH 30/50] chore(z): all exports are now under the z namespace (#14987) --- packages/zai/src/operations/errors.ts | 2 +- packages/zui/src/circle.ts | 23 ++ packages/zui/src/exports.ts | 8 + packages/zui/src/index.ts | 23 +- .../src/transforms/common/eval-zui-string.ts | 4 +- .../zui/src/transforms/common/json-schema.ts | 4 +- .../src/{z => transforms/common}/native.ts | 8 +- packages/zui/src/transforms/index.ts | 2 +- .../src/transforms/transform-pipeline.test.ts | 2 +- .../zui-from-json-schema-legacy/index.ts | 8 +- .../json-schema-to-zui.test.ts | 6 +- .../zui-from-json-schema/index.test.ts | 2 +- .../transforms/zui-from-json-schema/index.ts | 2 +- .../zui-from-json-schema/iterables/array.ts | 2 +- .../zui-from-json-schema/primitives/index.ts | 2 +- .../zui-from-json-schema/primitives/number.ts | 2 +- .../zui-from-json-schema/primitives/string.ts | 4 +- .../src/transforms/zui-from-object/index.ts | 6 +- .../zui-to-json-schema-legacy/parseDef.ts | 3 +- .../parsers/array.ts | 3 +- .../parsers/object.ts | 20 +- .../parsers/record.ts | 3 +- .../test/allParsers.test.ts | 2 +- .../test/issues.test.ts | 4 +- .../test/meta.test.ts | 4 +- .../test/openApiMode.test.ts | 4 +- .../test/parseDef.test.ts | 3 +- .../test/parsers/array.test.ts | 4 +- .../test/parsers/bigint.test.ts | 2 +- .../test/parsers/branded.test.ts | 4 +- .../test/parsers/date.test.ts | 2 +- .../test/parsers/default.test.ts | 4 +- .../test/parsers/effects.test.ts | 4 +- .../test/parsers/intersection.test.ts | 4 +- .../test/parsers/map.test.ts | 4 +- .../test/parsers/nativeEnum.test.ts | 2 +- .../test/parsers/nullable.test.ts | 4 +- .../test/parsers/number.test.ts | 2 +- .../test/parsers/object.test.ts | 4 +- .../test/parsers/optional.test.ts | 4 +- .../test/parsers/pipe.test.ts | 4 +- .../test/parsers/promise.test.ts | 4 +- .../test/parsers/record.test.ts | 4 +- .../test/parsers/set.test.ts | 4 +- .../test/parsers/string.test.ts | 2 +- .../test/parsers/tuple.test.ts | 4 +- .../test/parsers/union.test.ts | 4 +- .../test/readme.test.ts | 4 +- .../test/references.test.ts | 4 +- .../test/zodToJsonSchema.test.ts | 4 +- .../zui-extension.test.ts | 4 +- .../zui-extension.ts | 2 +- .../zui-to-json-schema/index.test.ts | 2 +- .../transforms/zui-to-json-schema/index.ts | 4 +- .../type-processors/array.ts | 4 +- .../type-processors/number.ts | 4 +- .../zui-to-json-schema/type-processors/set.ts | 4 +- .../type-processors/string.ts | 6 +- .../type-processors/tuple.ts | 4 +- .../zui-to-typescript-schema/index.test.ts | 4 +- .../zui-to-typescript-schema/index.ts | 6 +- .../zui-to-typescript-type/index.test.ts | 4 +- .../zui-to-typescript-type/index.ts | 4 +- .../zui-to-typescript-type/primitives.test.ts | 2 +- .../zui/src/{z => }/utils/assert-utils.ts | 0 .../{z => }/utils/datestring-utils.test.ts | 0 .../zui/src/{z => }/utils/datestring-utils.ts | 0 .../zui/src/{z => }/utils/ds-utils.test.ts | 0 packages/zui/src/{z => }/utils/ds-utils.ts | 0 packages/zui/src/{z => }/utils/error-utils.ts | 0 .../zui/src/{z => }/utils/fn-utils.test.ts | 0 packages/zui/src/{z => }/utils/fn-utils.ts | 0 packages/zui/src/{z => }/utils/index.ts | 0 packages/zui/src/{z => }/utils/other-utils.ts | 0 packages/zui/src/{z => }/utils/type-utils.ts | 0 .../zui/src/z/__tests__/async-parsing.test.ts | 2 +- .../src/z/__tests__/async-refinements.test.ts | 2 +- packages/zui/src/z/__tests__/base.test.ts | 2 +- packages/zui/src/z/__tests__/clone.test.ts | 2 +- packages/zui/src/z/__tests__/coerce.test.ts | 2 +- packages/zui/src/z/__tests__/crazySchema.ts | 2 +- .../zui/src/z/__tests__/deepmasking.test.ts | 2 +- packages/zui/src/z/__tests__/deref.test.ts | 2 +- .../zui/src/z/__tests__/description.test.ts | 2 +- packages/zui/src/z/__tests__/generics.test.ts | 2 +- .../zui/src/z/__tests__/instanceof.test.ts | 2 +- packages/zui/src/z/__tests__/is-equal.test.ts | 2 +- .../src/z/__tests__/language-server.source.ts | 2 +- .../zui/src/z/__tests__/mandatory.test.ts | 2 +- packages/zui/src/z/__tests__/masking.test.ts | 2 +- packages/zui/src/z/__tests__/naked.test.ts | 2 +- .../z/__tests__/object-augmentation.test.ts | 2 +- packages/zui/src/z/__tests__/parser.test.ts | 2 +- packages/zui/src/z/__tests__/partials.test.ts | 2 +- packages/zui/src/z/__tests__/pickomit.test.ts | 2 +- .../zui/src/z/__tests__/preprocess.test.ts | 2 +- .../zui/src/z/__tests__/primitive.test.ts | 2 +- .../zui/src/z/__tests__/recursive.test.ts | 2 +- packages/zui/src/z/__tests__/refine.test.ts | 2 +- .../zui/src/z/__tests__/safeparse.test.ts | 2 +- packages/zui/src/z/__tests__/zui.test.ts | 2 +- packages/zui/src/z/error/index.ts | 2 +- packages/zui/src/z/error/locales/en.ts | 2 +- packages/zui/src/z/index.ts | 247 +++++++++++++++++- packages/zui/src/z/types/array/index.ts | 2 +- packages/zui/src/z/types/basetype/index.ts | 7 +- packages/zui/src/z/types/bigint/index.ts | 2 +- packages/zui/src/z/types/catch/index.ts | 2 +- packages/zui/src/z/types/date/index.ts | 2 +- .../zui/src/z/types/default/default.test.ts | 2 +- packages/zui/src/z/types/default/index.ts | 2 +- .../src/z/types/discriminatedUnion/index.ts | 2 +- packages/zui/src/z/types/enum/index.ts | 2 +- packages/zui/src/z/types/function/index.ts | 3 +- .../zui/src/z/types/intersection/index.ts | 2 +- packages/zui/src/z/types/map/index.ts | 2 +- packages/zui/src/z/types/nativeEnum/index.ts | 2 +- packages/zui/src/z/types/number/index.ts | 2 +- packages/zui/src/z/types/object/index.ts | 2 +- packages/zui/src/z/types/pipeline/index.ts | 2 +- packages/zui/src/z/types/record/index.ts | 2 +- packages/zui/src/z/types/set/index.ts | 2 +- packages/zui/src/z/types/string/index.ts | 2 +- packages/zui/src/z/types/transformer/index.ts | 2 +- packages/zui/src/z/types/tuple/index.ts | 2 +- packages/zui/src/z/types/union/index.ts | 2 +- packages/zui/src/z/typings.ts | 13 +- packages/zui/src/z/z.ts | 245 ----------------- 128 files changed, 490 insertions(+), 413 deletions(-) create mode 100644 packages/zui/src/circle.ts create mode 100644 packages/zui/src/exports.ts rename packages/zui/src/{z => transforms/common}/native.ts (87%) rename packages/zui/src/{z => }/utils/assert-utils.ts (100%) rename packages/zui/src/{z => }/utils/datestring-utils.test.ts (100%) rename packages/zui/src/{z => }/utils/datestring-utils.ts (100%) rename packages/zui/src/{z => }/utils/ds-utils.test.ts (100%) rename packages/zui/src/{z => }/utils/ds-utils.ts (100%) rename packages/zui/src/{z => }/utils/error-utils.ts (100%) rename packages/zui/src/{z => }/utils/fn-utils.test.ts (100%) rename packages/zui/src/{z => }/utils/fn-utils.ts (100%) rename packages/zui/src/{z => }/utils/index.ts (100%) rename packages/zui/src/{z => }/utils/other-utils.ts (100%) rename packages/zui/src/{z => }/utils/type-utils.ts (100%) delete mode 100644 packages/zui/src/z/z.ts diff --git a/packages/zai/src/operations/errors.ts b/packages/zai/src/operations/errors.ts index 2fde6818a19..4dcb09ee708 100644 --- a/packages/zai/src/operations/errors.ts +++ b/packages/zai/src/operations/errors.ts @@ -1,4 +1,4 @@ -import { z, ZodError } from '@bpinternal/zui' +import z, { ZodError } from '@bpinternal/zui' export class JsonParsingError extends Error { public constructor( diff --git a/packages/zui/src/circle.ts b/packages/zui/src/circle.ts new file mode 100644 index 00000000000..3de5e5d704b --- /dev/null +++ b/packages/zui/src/circle.ts @@ -0,0 +1,23 @@ +import * as transforms from './transforms' +import { ZodBaseTypeImpl } from './z/types' + +/** + * This module prevents circular dependencies between the Zod types and the transforms. + * The Zod types need to reference the transforms to implement the toJSONSchema and toTypescriptType methods, + * but the transforms also need to reference the Zod types to perform the transformations. + * + * By defining the methods on the prototype of ZodBaseTypeImpl here, we can break the circular dependency. + * The Zod types can import this module to get the method implementations without importing the transforms directly. + */ + +ZodBaseTypeImpl.prototype.toJSONSchema = function () { + return transforms.toJSONSchema(this) +} + +ZodBaseTypeImpl.prototype.toTypescriptType = function (opts) { + return transforms.toTypescriptType(this, opts) +} + +ZodBaseTypeImpl.prototype.toTypescriptSchema = function () { + return transforms.toTypescriptSchema(this) +} diff --git a/packages/zui/src/exports.ts b/packages/zui/src/exports.ts new file mode 100644 index 00000000000..8e504de309c --- /dev/null +++ b/packages/zui/src/exports.ts @@ -0,0 +1,8 @@ +import './circle' + +export type { JSONSchema7 } from 'json-schema' +export * as json from './transforms/common/json-schema' +export * as transforms from './transforms' + +export * from './z' +export { default } from './z' // for the bundler not to be confused with the default export diff --git a/packages/zui/src/index.ts b/packages/zui/src/index.ts index 3b52d24902a..1a3b1e071d1 100644 --- a/packages/zui/src/index.ts +++ b/packages/zui/src/index.ts @@ -1,19 +1,4 @@ -import * as transforms from './transforms' -import { ZodBaseTypeImpl } from './z/types' - -export type { JSONSchema7 } from 'json-schema' -export * as json from './transforms/common/json-schema' -export * as transforms from './transforms' -export * from './z' - -ZodBaseTypeImpl.prototype.toJSONSchema = function () { - return transforms.toJSONSchema(this) -} - -ZodBaseTypeImpl.prototype.toTypescriptType = function (opts) { - return transforms.toTypescriptType(this, opts) -} - -ZodBaseTypeImpl.prototype.toTypescriptSchema = function () { - return transforms.toTypescriptSchema(this) -} +import * as z from './exports' +export * from './exports' +export { z } +export default z diff --git a/packages/zui/src/transforms/common/eval-zui-string.ts b/packages/zui/src/transforms/common/eval-zui-string.ts index 5e607a65f9f..9b91c6cb209 100644 --- a/packages/zui/src/transforms/common/eval-zui-string.ts +++ b/packages/zui/src/transforms/common/eval-zui-string.ts @@ -1,9 +1,9 @@ -import z, { ZodTypeAny } from '../../z' +import * as z from '../../z' export type EvalZuiStringResult = | { sucess: true - value: ZodTypeAny + value: z.ZodTypeAny } | { sucess: false diff --git a/packages/zui/src/transforms/common/json-schema.ts b/packages/zui/src/transforms/common/json-schema.ts index 7cf4f7a5fcd..2556793b5dc 100644 --- a/packages/zui/src/transforms/common/json-schema.ts +++ b/packages/zui/src/transforms/common/json-schema.ts @@ -1,6 +1,6 @@ import { JSONSchema7 } from 'json-schema' -import z from '../../z' -import * as utils from '../../z/utils/type-utils' +import * as utils from '../../utils/type-utils' +import * as z from '../../z' /** * Definitions: diff --git a/packages/zui/src/z/native.ts b/packages/zui/src/transforms/common/native.ts similarity index 87% rename from packages/zui/src/z/native.ts rename to packages/zui/src/transforms/common/native.ts index ae3395edf02..cb586c483ee 100644 --- a/packages/zui/src/z/native.ts +++ b/packages/zui/src/transforms/common/native.ts @@ -1,12 +1,6 @@ -import { ZodNativeTypeName } from './typings' +import { ZodNativeTypeName } from '../../z' -/** - * @deprecated - use ZodNativeTypeName instead - */ export type ZodFirstPartyTypeKind = ZodNativeTypeName -/** - * @deprecated - use ZodNativeTypeName instead - */ export const ZodFirstPartyTypeKind = { ZodString: 'ZodString', ZodNumber: 'ZodNumber', diff --git a/packages/zui/src/transforms/index.ts b/packages/zui/src/transforms/index.ts index 760c2e4c259..2e76eedcb5d 100644 --- a/packages/zui/src/transforms/index.ts +++ b/packages/zui/src/transforms/index.ts @@ -7,5 +7,5 @@ export { toJSONSchema } from './zui-to-json-schema' export { toTypescriptType, type TypescriptGenerationOptions } from './zui-to-typescript-type' export { toTypescriptSchema } from './zui-to-typescript-schema' -export type { Schema as ZuiJSONSchema } from './common/json-schema' +export * as json from './common/json-schema' export * as errors from './common/errors' diff --git a/packages/zui/src/transforms/transform-pipeline.test.ts b/packages/zui/src/transforms/transform-pipeline.test.ts index a306c664184..d230dcf68c2 100644 --- a/packages/zui/src/transforms/transform-pipeline.test.ts +++ b/packages/zui/src/transforms/transform-pipeline.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import z from '../z' +import * as z from '../z' import { toJSONSchema } from './zui-to-json-schema' import { fromJSONSchema } from './zui-from-json-schema' import * as errors from './common/errors' diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts index 4c9582adc34..3c795b125dc 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/index.ts @@ -4,7 +4,6 @@ import { type ZodAnyDef, type ZodArrayDef, type ZodBooleanDef, - ZodFirstPartyTypeKind, type ZodLazyDef, type ZodNullDef, type ZodObjectDef, @@ -19,10 +18,11 @@ import { ZodNumberDef, ZodEnumDef, ZodDefaultDef, - z, + ZodNativeTypeDef, } from '../../z' import * as errors from '../common/errors' import { evalZuiString } from '../common/eval-zui-string' +import { ZodFirstPartyTypeKind } from '../common/native' import { JsonSchema7Type } from '../zui-to-json-schema-legacy/parseDef' import { parseSchema } from './parsers/parseSchema' import { JSONSchemaExtended } from './types' @@ -78,9 +78,9 @@ const applyZuiPropsRecursively = (zodField: ZodTypeAny, jsonSchemaField: any) => } } else if (Array.isArray(items)) { items.forEach((item, index) => { - const def: z.ZodNativeTypeDef = zodField._def + const def: ZodNativeTypeDef = zodField._def - if (def.typeName === z.ZodFirstPartyTypeKind.ZodTuple) { + if (def.typeName === ZodFirstPartyTypeKind.ZodTuple) { applyZuiPropsRecursively(def.items[index]!, item) } }) diff --git a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts index ae96d26c68e..4fcddfdf336 100644 --- a/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema-legacy/json-schema-to-zui.test.ts @@ -1,11 +1,13 @@ import { describe, expect, test, it } from 'vitest' -import { z, ZodType, zuiKey } from '../../z' +import * as z from '../../z' import { jsonSchemaToZodStr, fromJSONSchemaLegacy, traverseZodDefinitions } from '.' import { toJSONSchemaLegacy } from '../zui-to-json-schema-legacy/zui-extension' import { JSONSchema7 } from 'json-schema' import * as assert from '../../assertions.utils.test' -const testZuiConversion = (zuiObject: ZodType) => { +const { zuiKey } = z + +const testZuiConversion = (zuiObject: z.ZodType) => { const jsonSchema = toJSONSchemaLegacy(zuiObject) const asZui = fromJSONSchemaLegacy(jsonSchema) const convertedJsonSchema = toJSONSchemaLegacy(asZui) diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts index 8baa86718fd..1dc57a53635 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.test.ts @@ -1,4 +1,4 @@ -import z from '../../z' +import * as z from '../../z' import { describe, test, expect } from 'vitest' import { fromJSONSchema } from './index' import { JSONSchema7 } from 'json-schema' diff --git a/packages/zui/src/transforms/zui-from-json-schema/index.ts b/packages/zui/src/transforms/zui-from-json-schema/index.ts index f3944b1236e..452021123ae 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/index.ts @@ -1,5 +1,5 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema' -import z from '../../z' +import * as z from '../../z' import * as errors from '../common/errors' import { ArraySchema, SetSchema, TupleSchema } from '../common/json-schema' import * as guards from './guards' diff --git a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts index 1b369752228..6ef2c4b6eb0 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts @@ -1,5 +1,5 @@ import { JSONSchema7Definition } from 'json-schema' -import z from '../../../z' +import * as z from '../../../z' import { ArraySchema, SetSchema, TupleSchema } from '../../common/json-schema' export const arrayJSONSchemaToZuiArray = ( diff --git a/packages/zui/src/transforms/zui-from-json-schema/primitives/index.ts b/packages/zui/src/transforms/zui-from-json-schema/primitives/index.ts index 13098ba4842..0702f0b32f9 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/primitives/index.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/primitives/index.ts @@ -1,5 +1,5 @@ import { JSONSchema7, JSONSchema7Type } from 'json-schema' -import z from '../../../z' +import * as z from '../../../z' import * as errs from '../../common/errors' import { numberJSONSchemaToZuiNumber } from './number' import { stringJSONSchemaToZuiString } from './string' diff --git a/packages/zui/src/transforms/zui-from-json-schema/primitives/number.ts b/packages/zui/src/transforms/zui-from-json-schema/primitives/number.ts index a1b9d0da02c..002f53218a9 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/primitives/number.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/primitives/number.ts @@ -1,5 +1,5 @@ import { JSONSchema7 } from 'json-schema' -import z from '../../../z' +import * as z from '../../../z' export const numberJSONSchemaToZuiNumber = ({ type, diff --git a/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts b/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts index ebb8d54e3a4..b243cff3c14 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/primitives/string.ts @@ -1,6 +1,6 @@ import { JSONSchema7 } from 'json-schema' -import z from '../../../z' -import * as datetime from '../../../z/utils/datestring-utils' +import * as datetime from '../../../utils/datestring-utils' +import * as z from '../../../z' import { zodPatterns } from '../../zui-to-json-schema-legacy/parsers/string' export const stringJSONSchemaToZuiString = ({ diff --git a/packages/zui/src/transforms/zui-from-object/index.ts b/packages/zui/src/transforms/zui-from-object/index.ts index fd44756f71f..be546490335 100644 --- a/packages/zui/src/transforms/zui-from-object/index.ts +++ b/packages/zui/src/transforms/zui-from-object/index.ts @@ -1,4 +1,4 @@ -import { z, ZodObject, ZodType } from '../../z' +import * as z from '../../z' import * as errors from '../common/errors' // Using a basic regex do determine if it's a date or not to avoid using another lib for that @@ -14,7 +14,7 @@ export type ObjectToZuiOptions = { optional?: boolean; nullable?: boolean; passt * @param opts - Options to customize the Zod schema: * @returns A Zod schema representing the object. */ -export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true): ZodType => { +export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true): z.ZodType => { if (typeof obj !== 'object') { throw new errors.ObjectToZuiError('Input must be an object') } @@ -65,7 +65,7 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true } } return acc - }, {} as ZodObject) + }, {} as z.ZodObject) const hasProperties = Object.keys(schema).length > 0 if (opts?.passtrough || (!isRoot && !hasProperties)) { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts index 9f5a5546ef9..7693a086584 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parseDef.ts @@ -1,4 +1,5 @@ -import { ZodNativeTypeDef, zuiKey, ZodFirstPartyTypeKind } from '../../z' +import { ZodNativeTypeDef, zuiKey } from '../../z' +import { ZodFirstPartyTypeKind } from '../common/native' import { JsonSchema7AnyType, parseAnyDef } from './parsers/any' import { JsonSchema7ArrayType, parseArrayDef } from './parsers/array' import { JsonSchema7BigintType, parseBigintDef } from './parsers/bigint' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts index 927569ab5fc..e0c1accf3a8 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/array.ts @@ -1,4 +1,5 @@ -import { zuiKey, ZuiExtensionObject, ZodArrayDef, ZodFirstPartyTypeKind, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodArrayDef, ZodTypeAny } from '../../../z' +import { ZodFirstPartyTypeKind } from '../../common/native' import { ErrorMessages, setResponseValueAndErrors } from '../errorMessages' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts index af8ecce3a89..93c1f3ba861 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/object.ts @@ -1,19 +1,21 @@ -import z, { zuiKey, ZuiExtensionObject, ZodObjectDef, ZodTypeAny } from '../../../z' +import * as z from '../../../z' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' +const { zuiKey } = z + export type JsonSchema7ObjectType = { type: 'object' properties: Record additionalProperties: boolean | JsonSchema7Type required?: string[] - [zuiKey]?: ZuiExtensionObject + [zuiKey]?: z.ZuiExtensionObject } -const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonSchema7Type => { +const getAdditionalProperties = (def: z.ZodObjectDef, refs: Refs): boolean | JsonSchema7Type => { if (z.is.zuiType(def.unknownKeys)) { return ( - parseDef((def.unknownKeys as ZodTypeAny)._def, { + parseDef((def.unknownKeys as z.ZodTypeAny)._def, { ...refs, currentPath: [...refs.currentPath, 'additionalProperties'], }) ?? true @@ -25,10 +27,10 @@ const getAdditionalProperties = (def: ZodObjectDef, refs: Refs): boolean | JsonS return false } -export function parseObjectDefX(def: ZodObjectDef, refs: Refs) { +export function parseObjectDefX(def: z.ZodObjectDef, refs: Refs) { Object.keys(def.shape()).reduce( (schema: JsonSchema7ObjectType, key) => { - let prop = def.shape()[key] as ZodTypeAny + let prop = def.shape()[key] as z.ZodTypeAny if (typeof prop === 'undefined' || typeof prop._def === 'undefined') { return schema } @@ -74,7 +76,7 @@ export function parseObjectDefX(def: ZodObjectDef, refs: Refs) { properties: Record required: string[] }, - [propName, propDef]: [string, ZodTypeAny] + [propName, propDef]: [string, z.ZodTypeAny] ) => { if (propDef === undefined || propDef._def === undefined) return acc const parsedDef = parseDef(propDef._def, { @@ -96,7 +98,7 @@ export function parseObjectDefX(def: ZodObjectDef, refs: Refs) { return result } -export function parseObjectDef(def: ZodObjectDef, refs: Refs) { +export function parseObjectDef(def: z.ZodObjectDef, refs: Refs) { const result: JsonSchema7ObjectType = { type: 'object', ...Object.entries(def.shape()).reduce( @@ -105,7 +107,7 @@ export function parseObjectDef(def: ZodObjectDef, refs: Refs) { properties: Record required: string[] }, - [propName, propDef]: [string, ZodTypeAny] + [propName, propDef]: [string, z.ZodTypeAny] ) => { if (propDef === undefined || propDef._def === undefined) return acc const parsedDef = parseDef(propDef._def, { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts index 7e5379a6b46..6a50ce92b9c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/parsers/record.ts @@ -1,4 +1,5 @@ -import { zuiKey, ZuiExtensionObject, ZodFirstPartyTypeKind, ZodMapDef, ZodRecordDef, ZodTypeAny } from '../../../z' +import { zuiKey, ZuiExtensionObject, ZodMapDef, ZodRecordDef, ZodTypeAny } from '../../../z' +import { ZodFirstPartyTypeKind } from '../../common/native' import { JsonSchema7Type, parseDef } from '../parseDef' import { Refs } from '../Refs' import { JsonSchema7EnumType } from './enum' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts index 221ce990241..ec2d6c6fa8d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/allParsers.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { zodToJsonSchema } from '../zodToJsonSchema' -import { z } from '../../../z' +import * as z from '../../../z' enum nativeEnum { 'a', diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts index e322f7fdc06..d69e65edb54 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/issues.test.ts @@ -1,7 +1,9 @@ import { describe, test, expect } from 'vitest' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' +const { zuiKey } = z + describe('Issue tests', () => { test('@94', () => { const topicSchema = z.object({ diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts index 25117c7aa1b..e86ae1dda5c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/meta.test.ts @@ -1,7 +1,9 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' +const { zuiKey } = z + describe('Meta data', () => { it('should be possible to use description', () => { const $z = z.string().describe('My neat string') diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts index dbeb7c176d7..14fadbd8ae7 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/openApiMode.test.ts @@ -1,7 +1,9 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' +const { zuiKey } = z + describe('Open API target', () => { it('should use nullable boolean property and not use $schema property', () => { const editCompanySchema = z.object({ diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts index c24377b76cc..015ef230489 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parseDef.test.ts @@ -1,10 +1,11 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { parseDef } from '../parseDef' import Ajv from 'ajv' import { getRefs } from '../Refs' +const { zuiKey } = z const ajv = new Ajv() describe('Basic parsing', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts index 91c2e5d0c04..9335bf604f5 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/array.test.ts @@ -1,11 +1,13 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseArrayDef } from '../../parsers/array' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' import deref from 'local-ref-resolver' +const { zuiKey } = z + describe('Arrays and array validations', () => { it('should be possible to describe a simple array', () => { const parsedSchema = parseArrayDef(z.array(z.string())._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts index 195b3bbae2e..8672182fd5c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/bigint.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' import { parseBigintDef } from '../../parsers/bigint' -import { z } from '../../../../z' +import * as z from '../../../../z' import { getRefs } from '../../Refs' describe('bigint', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts index 6ce3343c869..b56f8ecf92b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/branded.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseBrandedDef } from '../../parsers/branded' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('objects', () => { it('should be possible to use branded string', () => { const schema = z.string().brand<'x'>() diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts index a7e115aa73a..2ad7bd51d28 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/date.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z' +import * as z from '../../../../z' import { parseDateDef } from '../../parsers/date' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts index 83625cc5e83..c161f64a2fa 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/default.test.ts @@ -1,9 +1,11 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseDefaultDef } from '../../parsers/default' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('promise', () => { it('should be possible to use default on objects', () => { const parsedSchema = parseDefaultDef(z.object({ foo: z.boolean() }).default({ foo: true })._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts index 368b8400998..cc343548fda 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/effects.test.ts @@ -1,9 +1,11 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseEffectsDef } from '../../parsers/effects' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('effects', () => { it('should be possible to use refine', () => { const parsedSchema = parseEffectsDef(z.number().refine((x) => x + 1)._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts index cdda74d2429..3e0d94e9867 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/intersection.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseIntersectionDef } from '../../parsers/intersection' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('intersections', () => { it('should be possible to use intersections', () => { const intersection = z.intersection(z.string().min(1), z.string().max(3)) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts index bb3842c1782..31d9b7c655d 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/map.test.ts @@ -1,10 +1,12 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseMapDef } from '../../parsers/map' import Ajv from 'ajv' import { getRefs } from '../../Refs' +const { zuiKey } = z + const ajv = new Ajv({ strict: false }) describe('map', () => { it('should be possible to use Map', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts index 3ad84e4597a..c58e54d0026 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nativeEnum.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z' +import * as z from '../../../../z' import { parseNativeEnumDef } from '../../parsers/nativeEnum' describe('Native enums', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts index 2ffa6e108f2..3e07b0efefd 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/nullable.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseObjectDef } from '../../parsers/object' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('nullable', () => { it('should be possible to properly reference nested nullable primitives', () => { const nullablePrimitive = z.string().nullable() diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts index fb6d05ae0bb..f7e4bd4c15b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/number.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z' +import * as z from '../../../../z' import { parseNumberDef } from '../../parsers/number' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts index af6c8b6ff1a..a6aa5d529ab 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/object.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseObjectDef } from '../../parsers/object' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('objects', () => { it('should be possible to describe catchAll schema', () => { const schema = z.object({ normalProperty: z.string() }).catchall(z.boolean()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts index 26327a0a148..4468d3fd681 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/optional.test.ts @@ -1,9 +1,11 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseDef } from '../../parseDef' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('Standalone optionals', () => { it('should work as unions with undefined', () => { const parsedSchema = parseDef(z.string().optional()._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts index 5fc2981c64e..72fdd275ac3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/pipe.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parsePipelineDef } from '../../parsers/pipeline' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('pipe', () => { it('Should create an allOf schema with all its inner schemas represented', () => { const schema = z.number().pipe(z.number().int()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts index 5133a1c3641..8b59d8b15d2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/promise.test.ts @@ -1,9 +1,11 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parsePromiseDef } from '../../parsers/promise' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('promise', () => { it('should be possible to use promise', () => { const parsedSchema = parsePromiseDef(z.promise(z.string())._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts index d759050f1ee..72c9dc3b1ab 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/record.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseRecordDef } from '../../parsers/record' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('records', () => { it('should be possible to describe a simple record', () => { const schema = z.record(z.number()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts index 23ac436612d..eaf7adbac4b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/set.test.ts @@ -1,10 +1,12 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseSetDef } from '../../parsers/set' import { getRefs } from '../../Refs' import { errorReferences } from './errorReferences' +const { zuiKey } = z + describe('set', () => { it("should include min and max size error messages if they're passed.", () => { const minSizeError = 'Set must have at least 5 elements' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts index 8216cb8feb8..df90aa0ee6e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/string.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z } from '../../../../z' +import * as z from '../../../../z' import { JsonSchema7Type } from '../../parseDef' import { JsonSchema7StringType, zodPatterns, parseStringDef } from '../../parsers/string' import Ajv from 'ajv' diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts index a47662cc589..cada220b3bc 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/tuple.test.ts @@ -1,8 +1,10 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseTupleDef } from '../../parsers/tuple' import { getRefs } from '../../Refs' +const { zuiKey } = z + describe('objects', () => { it('should be possible to describe a simple tuple schema', () => { const schema = z.tuple([z.string(), z.number()]) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts index d7e48545d5a..4efd23391e3 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/parsers/union.test.ts @@ -1,10 +1,12 @@ import { describe, it, expect } from 'vitest' import { JSONSchema7Type } from 'json-schema' -import { z, zuiKey } from '../../../../z' +import * as z from '../../../../z' import { parseUnionDef } from '../../parsers/union' import { getRefs } from '../../Refs' import deref from 'local-ref-resolver' +const { zuiKey } = z + describe('Unions', () => { it('Should be possible to get a simple type array from a union of only unvalidated primitives', () => { const parsedSchema = parseUnionDef(z.union([z.string(), z.number(), z.boolean(), z.null()])._def, getRefs()) diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts index 92bc64a7581..12cc361e345 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/readme.test.ts @@ -1,7 +1,9 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' +const { zuiKey } = z + describe('The readme example', () => { it('should be valid', () => { const mySchema = z diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts index 65875cac73d..38a9b4a5154 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/references.test.ts @@ -1,10 +1,12 @@ import { describe, test, expect } from 'vitest' import Ajv from 'ajv' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' const ajv = new Ajv() import deref from 'local-ref-resolver' +const { zuiKey } = z + describe('Pathing', () => { test('should handle recurring properties with paths', () => { const addressSchema = z.object({ diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts index f35ff9c8cb2..abfd8f96637 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/test/zodToJsonSchema.test.ts @@ -1,7 +1,9 @@ import { describe, it, expect } from 'vitest' -import { z, zuiKey } from '../../../z' +import * as z from '../../../z' import { zodToJsonSchema } from '../zodToJsonSchema' +const { zuiKey } = z + describe('Root schema result after parsing', () => { it('should return the schema directly in the root if no name is passed', () => { expect(zodToJsonSchema(z.any())).toEqual({ diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts index bf2c4b981b2..3d8077edc0e 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.test.ts @@ -1,6 +1,8 @@ import { describe, test, expect, it } from 'vitest' import { toJSONSchemaLegacy } from './zui-extension' -import { z, zuiKey } from '../../z' +import * as z from '../../z' + +const { zuiKey } = z describe('zuiToJsonSchema', () => { test('should work', () => { diff --git a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts index ba48db0b241..4547dcd7222 100644 --- a/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts +++ b/packages/zui/src/transforms/zui-to-json-schema-legacy/zui-extension.ts @@ -1,5 +1,5 @@ import { JSONSchema7 } from 'json-schema' -import { z } from '../../z' +import * as z from '../../z' import { Options } from './Options' import { zodToJsonSchema } from './zodToJsonSchema' diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.test.ts b/packages/zui/src/transforms/zui-to-json-schema/index.test.ts index 79112e4890b..33b3b2ecbc2 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.test.ts @@ -1,5 +1,5 @@ import * as errs from '../common/errors' -import z from '../../z' +import * as z from '../../z' import { describe, test, expect } from 'vitest' import { toJSONSchema } from './index' diff --git a/packages/zui/src/transforms/zui-to-json-schema/index.ts b/packages/zui/src/transforms/zui-to-json-schema/index.ts index 9624095685c..75820c19b0b 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/index.ts @@ -1,5 +1,5 @@ -import z from '../../z' -import * as utils from '../../z/utils' +import * as utils from '../../utils' +import * as z from '../../z' import * as err from '../common/errors' import * as json from '../common/json-schema' import { zodArrayToJsonArray } from './type-processors/array' diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts index 420f11765c3..0b7ba488d16 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/array.ts @@ -1,6 +1,8 @@ -import z, { zuiKey } from '../../../z' +import * as z from '../../../z' import * as json from '../../common/json-schema' +const { zuiKey } = z + export const zodArrayToJsonArray = ( zodArray: z.ZodArray, toSchema: (x: z.ZodType) => json.Schema diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts index 41c789a397a..72e0af1542c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/number.ts @@ -1,6 +1,8 @@ -import z, { zuiKey } from '../../../z' +import * as z from '../../../z' import * as json from '../../common/json-schema' +const { zuiKey } = z + export const zodNumberToJsonNumber = (zodNumber: z.ZodNumber): json.NumberSchema => { const schema: json.NumberSchema = { type: 'number', diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts index 68acc1108ef..91d5cbfe10c 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/set.ts @@ -1,6 +1,8 @@ -import z, { zuiKey } from '../../../z' +import * as z from '../../../z' import * as json from '../../common/json-schema' +const { zuiKey } = z + export const zodSetToJsonSet = (zodSet: z.ZodSet, toSchema: (x: z.ZodType) => json.Schema): json.SetSchema => { const schema: json.SetSchema = { type: 'array', diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts index c7e98f5f3c3..d73e15ae3fa 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/string.ts @@ -1,10 +1,12 @@ -import z, { zuiKey } from '../../../z' -import { generateDatetimeRegex } from '../../../z/utils/datestring-utils' +import { generateDatetimeRegex } from '../../../utils/datestring-utils' +import * as z from '../../../z' import { regexUtils } from '../../common' import * as errors from '../../common/errors' import * as json from '../../common/json-schema' import { zodPatterns } from '../../zui-to-json-schema-legacy/parsers/string' +const { zuiKey } = z + export const zodStringToJsonString = (zodString: z.ZodString): json.StringSchema => { const schema: json.StringSchema = { type: 'string', diff --git a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts index 361a6b2e6f7..c819463fdb7 100644 --- a/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts +++ b/packages/zui/src/transforms/zui-to-json-schema/type-processors/tuple.ts @@ -1,6 +1,8 @@ -import z, { zuiKey } from '../../../z' +import * as z from '../../../z' import * as json from '../../common/json-schema' +const { zuiKey } = z + export const zodTupleToJsonTuple = ( zodTuple: z.ZodTuple, toSchema: (x: z.ZodType) => json.Schema diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts index e4dc5b2d8eb..fce50835cb6 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test, it } from 'vitest' import { toTypescriptSchema as toTypescript } from '.' import { evalZuiString } from '../common/eval-zui-string' import * as errors from '../common/errors' -import z, { ZodLiteral } from '../../z' +import * as z from '../../z' import { UIComponentDefinitions } from '../../z/typings' const evalZui = (source: string): z.ZodType => { @@ -462,7 +462,7 @@ describe.concurrent('toTypescriptSchema', () => { }) test('literal symbol', () => { const source = z.literal(Symbol('banana')) - const dest = evalZui(toTypescript(source)) as ZodLiteral + const dest = evalZui(toTypescript(source)) as z.ZodLiteral expect(dest.typeName === 'ZodLiteral').toBe(true) const value = dest.value as symbol diff --git a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts index d69bca437c4..747102179e0 100644 --- a/packages/zui/src/transforms/zui-to-typescript-schema/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-schema/index.ts @@ -1,7 +1,7 @@ import { mapValues, isEqual } from 'lodash-es' -import z, { zuiKey } from '../../z' -import * as utils from '../../z/utils' +import * as utils from '../../utils' +import * as z from '../../z' import * as errors from '../common/errors' import { primitiveToTypescriptValue, @@ -15,6 +15,8 @@ import { generateNumberChecks } from './number-checks' import { generateSetChecks } from './set-checks' import { generateStringChecks } from './string-checks' +const { zuiKey } = z + /** * * @param schema zui schema diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts index b60968091f0..bbfc73a8583 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts @@ -1,10 +1,10 @@ import { describe, it, expect } from 'vitest' import { toTypescriptType as toTs } from '.' -import z, { ZodType } from '../../z' +import * as z from '../../z' import * as errors from '../common/errors' import * as assert from '../../assertions.utils.test' -const toTypescript = (schema: ZodType): string => { +const toTypescript = (schema: z.ZodType): string => { const hasTitle = 'title' in schema.ui if (!hasTitle) { schema = schema.title('x') diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index e8062226746..62ed82929af 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -1,5 +1,5 @@ -import z from '../../z' -import * as utils from '../../z/utils' +import * as utils from '../../utils' +import * as z from '../../z' import * as errors from '../common/errors' import { primitiveToTypescriptValue, diff --git a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts index 489a58e6a60..fc8c0b2489f 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/primitives.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest' import { toTypescriptType as toTs } from '.' -import z from '../../z' +import * as z from '../../z' import * as assert from '../../assertions.utils.test' const toTypescriptType = (schema: z.ZodType) => toTs(schema, { declaration: 'variable' }) diff --git a/packages/zui/src/z/utils/assert-utils.ts b/packages/zui/src/utils/assert-utils.ts similarity index 100% rename from packages/zui/src/z/utils/assert-utils.ts rename to packages/zui/src/utils/assert-utils.ts diff --git a/packages/zui/src/z/utils/datestring-utils.test.ts b/packages/zui/src/utils/datestring-utils.test.ts similarity index 100% rename from packages/zui/src/z/utils/datestring-utils.test.ts rename to packages/zui/src/utils/datestring-utils.test.ts diff --git a/packages/zui/src/z/utils/datestring-utils.ts b/packages/zui/src/utils/datestring-utils.ts similarity index 100% rename from packages/zui/src/z/utils/datestring-utils.ts rename to packages/zui/src/utils/datestring-utils.ts diff --git a/packages/zui/src/z/utils/ds-utils.test.ts b/packages/zui/src/utils/ds-utils.test.ts similarity index 100% rename from packages/zui/src/z/utils/ds-utils.test.ts rename to packages/zui/src/utils/ds-utils.test.ts diff --git a/packages/zui/src/z/utils/ds-utils.ts b/packages/zui/src/utils/ds-utils.ts similarity index 100% rename from packages/zui/src/z/utils/ds-utils.ts rename to packages/zui/src/utils/ds-utils.ts diff --git a/packages/zui/src/z/utils/error-utils.ts b/packages/zui/src/utils/error-utils.ts similarity index 100% rename from packages/zui/src/z/utils/error-utils.ts rename to packages/zui/src/utils/error-utils.ts diff --git a/packages/zui/src/z/utils/fn-utils.test.ts b/packages/zui/src/utils/fn-utils.test.ts similarity index 100% rename from packages/zui/src/z/utils/fn-utils.test.ts rename to packages/zui/src/utils/fn-utils.test.ts diff --git a/packages/zui/src/z/utils/fn-utils.ts b/packages/zui/src/utils/fn-utils.ts similarity index 100% rename from packages/zui/src/z/utils/fn-utils.ts rename to packages/zui/src/utils/fn-utils.ts diff --git a/packages/zui/src/z/utils/index.ts b/packages/zui/src/utils/index.ts similarity index 100% rename from packages/zui/src/z/utils/index.ts rename to packages/zui/src/utils/index.ts diff --git a/packages/zui/src/z/utils/other-utils.ts b/packages/zui/src/utils/other-utils.ts similarity index 100% rename from packages/zui/src/z/utils/other-utils.ts rename to packages/zui/src/utils/other-utils.ts diff --git a/packages/zui/src/z/utils/type-utils.ts b/packages/zui/src/utils/type-utils.ts similarity index 100% rename from packages/zui/src/z/utils/type-utils.ts rename to packages/zui/src/utils/type-utils.ts diff --git a/packages/zui/src/z/__tests__/async-parsing.test.ts b/packages/zui/src/z/__tests__/async-parsing.test.ts index 63814b65fa3..463c6bd5d25 100644 --- a/packages/zui/src/z/__tests__/async-parsing.test.ts +++ b/packages/zui/src/z/__tests__/async-parsing.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' import { ZodError } from '../error' /// string diff --git a/packages/zui/src/z/__tests__/async-refinements.test.ts b/packages/zui/src/z/__tests__/async-refinements.test.ts index 1d537be68cf..f9e0ed8a275 100644 --- a/packages/zui/src/z/__tests__/async-refinements.test.ts +++ b/packages/zui/src/z/__tests__/async-refinements.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' test('parse async test', async () => { const schema1 = z.string().refine(async (_val) => false) diff --git a/packages/zui/src/z/__tests__/base.test.ts b/packages/zui/src/z/__tests__/base.test.ts index 541c211000f..0420bde5452 100644 --- a/packages/zui/src/z/__tests__/base.test.ts +++ b/packages/zui/src/z/__tests__/base.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' import * as assert from '../../assertions.utils.test' test('type guard', () => { diff --git a/packages/zui/src/z/__tests__/clone.test.ts b/packages/zui/src/z/__tests__/clone.test.ts index a3adf6045cc..b7b94bfefeb 100644 --- a/packages/zui/src/z/__tests__/clone.test.ts +++ b/packages/zui/src/z/__tests__/clone.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { z } from '../index' +import * as z from '../index' import * as transforms from '../../transforms' const expectZui = (actual: z.ZodType) => ({ diff --git a/packages/zui/src/z/__tests__/coerce.test.ts b/packages/zui/src/z/__tests__/coerce.test.ts index b35314740ac..14d709d1671 100644 --- a/packages/zui/src/z/__tests__/coerce.test.ts +++ b/packages/zui/src/z/__tests__/coerce.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' test('string coercion', () => { const schema = z.coerce.string() diff --git a/packages/zui/src/z/__tests__/crazySchema.ts b/packages/zui/src/z/__tests__/crazySchema.ts index 9400d6ccc04..d553389de40 100644 --- a/packages/zui/src/z/__tests__/crazySchema.ts +++ b/packages/zui/src/z/__tests__/crazySchema.ts @@ -1,4 +1,4 @@ -import z from '../index' +import * as z from '../index' export const crazySchema = z.object({ tuple: z.tuple([ diff --git a/packages/zui/src/z/__tests__/deepmasking.test.ts b/packages/zui/src/z/__tests__/deepmasking.test.ts index 72c7127d816..2ab8793c963 100644 --- a/packages/zui/src/z/__tests__/deepmasking.test.ts +++ b/packages/zui/src/z/__tests__/deepmasking.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import z from '../index' +import * as z from '../index' test('test', () => { z diff --git a/packages/zui/src/z/__tests__/deref.test.ts b/packages/zui/src/z/__tests__/deref.test.ts index f791c5ce35a..080dee56d2b 100644 --- a/packages/zui/src/z/__tests__/deref.test.ts +++ b/packages/zui/src/z/__tests__/deref.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest' -import { z } from '../index' +import * as z from '../index' const foo = z.ref('foo') const bar = z.ref('bar') diff --git a/packages/zui/src/z/__tests__/description.test.ts b/packages/zui/src/z/__tests__/description.test.ts index b7763864161..c61dca4554a 100644 --- a/packages/zui/src/z/__tests__/description.test.ts +++ b/packages/zui/src/z/__tests__/description.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' const description = 'a description' diff --git a/packages/zui/src/z/__tests__/generics.test.ts b/packages/zui/src/z/__tests__/generics.test.ts index 88fcca993bd..a179aead9da 100644 --- a/packages/zui/src/z/__tests__/generics.test.ts +++ b/packages/zui/src/z/__tests__/generics.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import z from '../index' +import * as z from '../index' import * as assert from '../../assertions.utils.test' test('generics', () => { diff --git a/packages/zui/src/z/__tests__/instanceof.test.ts b/packages/zui/src/z/__tests__/instanceof.test.ts index 49997f7ffa6..3b7cd3eed16 100644 --- a/packages/zui/src/z/__tests__/instanceof.test.ts +++ b/packages/zui/src/z/__tests__/instanceof.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' -import z from '../index' +import * as z from '../index' test('instanceof', async () => { class Test {} diff --git a/packages/zui/src/z/__tests__/is-equal.test.ts b/packages/zui/src/z/__tests__/is-equal.test.ts index 9dfac715517..ac3f5b8670a 100644 --- a/packages/zui/src/z/__tests__/is-equal.test.ts +++ b/packages/zui/src/z/__tests__/is-equal.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest' -import { z } from '../index' +import * as z from '../index' const expectZui = (actual: z.ZodType) => ({ not: { diff --git a/packages/zui/src/z/__tests__/language-server.source.ts b/packages/zui/src/z/__tests__/language-server.source.ts index 4f50e552f62..5c9b180ba23 100644 --- a/packages/zui/src/z/__tests__/language-server.source.ts +++ b/packages/zui/src/z/__tests__/language-server.source.ts @@ -1,4 +1,4 @@ -import z from '../index' +import * as z from '../index' export const filePath = __filename diff --git a/packages/zui/src/z/__tests__/mandatory.test.ts b/packages/zui/src/z/__tests__/mandatory.test.ts index 34eb38b1631..faf89af60fe 100644 --- a/packages/zui/src/z/__tests__/mandatory.test.ts +++ b/packages/zui/src/z/__tests__/mandatory.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest' -import { z } from '../index' +import * as z from '../index' import * as transforms from '../../transforms' const expectZui = (actual: z.ZodType) => ({ diff --git a/packages/zui/src/z/__tests__/masking.test.ts b/packages/zui/src/z/__tests__/masking.test.ts index dbfd8b347a3..ae206c3a4e0 100644 --- a/packages/zui/src/z/__tests__/masking.test.ts +++ b/packages/zui/src/z/__tests__/masking.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import z from '../index' +import * as z from '../index' test('masking test', () => {}) diff --git a/packages/zui/src/z/__tests__/naked.test.ts b/packages/zui/src/z/__tests__/naked.test.ts index e7e55ae70e6..f39ae3a9ef7 100644 --- a/packages/zui/src/z/__tests__/naked.test.ts +++ b/packages/zui/src/z/__tests__/naked.test.ts @@ -1,5 +1,5 @@ import { test, assert } from 'vitest' -import z from '../index' +import * as z from '../index' test('naked object', () => { assert.equal(z.object({ name: z.string() }).naked().typeName, 'ZodObject') diff --git a/packages/zui/src/z/__tests__/object-augmentation.test.ts b/packages/zui/src/z/__tests__/object-augmentation.test.ts index d8a9f532df4..42c9e817451 100644 --- a/packages/zui/src/z/__tests__/object-augmentation.test.ts +++ b/packages/zui/src/z/__tests__/object-augmentation.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' test('object augmentation', () => { const Animal = z diff --git a/packages/zui/src/z/__tests__/parser.test.ts b/packages/zui/src/z/__tests__/parser.test.ts index ed9f7138842..113741fdaba 100644 --- a/packages/zui/src/z/__tests__/parser.test.ts +++ b/packages/zui/src/z/__tests__/parser.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' test('parse strict object with unknown keys', () => { expect(() => diff --git a/packages/zui/src/z/__tests__/partials.test.ts b/packages/zui/src/z/__tests__/partials.test.ts index 31e57db91b1..0f9756c480f 100644 --- a/packages/zui/src/z/__tests__/partials.test.ts +++ b/packages/zui/src/z/__tests__/partials.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' -import z from '../index' +import * as z from '../index' const nested = z.object({ name: z.string(), diff --git a/packages/zui/src/z/__tests__/pickomit.test.ts b/packages/zui/src/z/__tests__/pickomit.test.ts index 81aa9baaa5b..d133c338a62 100644 --- a/packages/zui/src/z/__tests__/pickomit.test.ts +++ b/packages/zui/src/z/__tests__/pickomit.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' -import z from '../index' +import * as z from '../index' const fish = z.object({ name: z.string(), diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index d18af374888..0dd8bff733d 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' -import z from '../index' +import * as z from '../index' import { NEVER } from '../types/basetype' import { ZodError } from '../error' diff --git a/packages/zui/src/z/__tests__/primitive.test.ts b/packages/zui/src/z/__tests__/primitive.test.ts index 6e1146f6f57..043c4bd844d 100644 --- a/packages/zui/src/z/__tests__/primitive.test.ts +++ b/packages/zui/src/z/__tests__/primitive.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' import * as assert from '../../assertions.utils.test' import { Mocker } from './Mocker' diff --git a/packages/zui/src/z/__tests__/recursive.test.ts b/packages/zui/src/z/__tests__/recursive.test.ts index 4cd1312ff67..3c61bf303cc 100644 --- a/packages/zui/src/z/__tests__/recursive.test.ts +++ b/packages/zui/src/z/__tests__/recursive.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import { z } from '../index' +import * as z from '../index' interface Category { name: string diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index de581dba400..77e41d28b1a 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' -import z from '../index' +import * as z from '../index' test('refinement', () => { const obj1 = z.object({ diff --git a/packages/zui/src/z/__tests__/safeparse.test.ts b/packages/zui/src/z/__tests__/safeparse.test.ts index 0b239d9bdc8..a31e165bb78 100644 --- a/packages/zui/src/z/__tests__/safeparse.test.ts +++ b/packages/zui/src/z/__tests__/safeparse.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import z from '../index' +import * as z from '../index' import { ZodError } from '../error' const stringSchema = z.string() diff --git a/packages/zui/src/z/__tests__/zui.test.ts b/packages/zui/src/z/__tests__/zui.test.ts index d838e6355cd..2c52e2a199b 100644 --- a/packages/zui/src/z/__tests__/zui.test.ts +++ b/packages/zui/src/z/__tests__/zui.test.ts @@ -1,5 +1,5 @@ import { test } from 'vitest' -import * as zui from '../z' +import * as zui from '../../z' type ExampleSchema = { schema: zui.ZodObject diff --git a/packages/zui/src/z/error/index.ts b/packages/zui/src/z/error/index.ts index 24ead0601a3..7a196f5714a 100644 --- a/packages/zui/src/z/error/index.ts +++ b/packages/zui/src/z/error/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../utils' import type { ZodIssue, ZodFormattedError, ZodErrorMap, IZodError } from '../typings' -import * as utils from '../utils' import { errorMap as defaultErrorMap } from './locales/en' export class ZodError extends Error implements IZodError { diff --git a/packages/zui/src/z/error/locales/en.ts b/packages/zui/src/z/error/locales/en.ts index 68d26c66a0d..42bf2210f18 100644 --- a/packages/zui/src/z/error/locales/en.ts +++ b/packages/zui/src/z/error/locales/en.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import { ZodErrorMap } from '../../typings' -import * as utils from '../../utils' export const errorMap: ZodErrorMap = (issue, _ctx) => { let message: string diff --git a/packages/zui/src/z/index.ts b/packages/zui/src/z/index.ts index f38dd7595e9..a7fd20ae897 100644 --- a/packages/zui/src/z/index.ts +++ b/packages/zui/src/z/index.ts @@ -1,4 +1,243 @@ -import * as z from './z' -export * from './z' -export { z } -export default z +export { zuiKey } from './consts' +export { is } from './guards' + +export type { + // ui + ZuiMetadata, + ZuiExtensionObject, + UIComponentDefinitions, + + // error + IZodError as ZodError, + ZodIssue, + + // base type + SafeParseSuccess, + SafeParseError, + SafeParseReturnType, + infer, + input, + output, + TypeOf, + ZodTypeDef as ZodTypeDef, + IZodType as ZodType, + ZodTypeAny, + ZodSchema, + Schema, + + // any + ZodAnyDef, + IZodAny as ZodAny, + + // array + ZodArrayDef, + IZodArray as ZodArray, + + // bigInt + ZodBigIntDef, + IZodBigInt as ZodBigInt, + ZodBigIntCheck, + + // boolean + ZodBooleanDef, + IZodBoolean as ZodBoolean, + + // branded + ZodBrandedDef, + IZodBranded as ZodBranded, + + // catch + ZodCatchDef, + IZodCatch as ZodCatch, + + // date + ZodDateDef, + IZodDate as ZodDate, + ZodDateCheck, + + // default + ZodDefaultDef, + IZodDefault as ZodDefault, + + // enum + ZodEnumDef, + IZodEnum as ZodEnum, + EnumValues, + EnumValuesMap, + + // never + ZodNeverDef, + IZodNever as ZodNever, + + // nullable + ZodNullableDef, + IZodNullable as ZodNullable, + + // optional + ZodOptionalDef, + IZodOptional as ZodOptional, + + // tuple + ZodTupleDef, + IZodTuple as ZodTuple, + ZodTupleItems, + + // object + ZodObjectDef, + IZodObject as ZodObject, + ZodRawShape, + UnknownKeysParam, + AnyZodObject, + SomeZodObject, + + // discriminatedUnion + ZodDiscriminatedUnionDef, + IZodDiscriminatedUnion as ZodDiscriminatedUnion, + ZodDiscriminatedUnionOption, + + // unknown + ZodUnknownDef, + IZodUnknown as ZodUnknown, + + // function + ZodFunctionDef, + IZodFunction as ZodFunction, + + // intersection + ZodIntersectionDef, + IZodIntersection as ZodIntersection, + + // lazy + ZodLazyDef, + IZodLazy as ZodLazy, + + // literal + ZodLiteralDef, + IZodLiteral as ZodLiteral, + + // map + ZodMapDef, + IZodMap as ZodMap, + + // naN + ZodNaNDef, + IZodNaN as ZodNaN, + + // nativeEnum + ZodNativeEnumDef, + IZodNativeEnum as ZodNativeEnum, + + // null + ZodNullDef, + IZodNull as ZodNull, + + // number + ZodNumberDef, + IZodNumber as ZodNumber, + ZodNumberCheck, + + // pipeline + ZodPipelineDef, + IZodPipeline as ZodPipeline, + + // promise + ZodPromiseDef, + IZodPromise as ZodPromise, + + // readonly + ZodReadonlyDef, + IZodReadonly as ZodReadonly, + + // string + ZodStringDef, + IZodString as ZodString, + ZodStringCheck, + + // record + ZodRecordDef, + IZodRecord as ZodRecord, + + // ref + ZodRefDef, + IZodRef as ZodRef, + + // set + ZodSetDef, + IZodSet as ZodSet, + + // symbol + ZodSymbolDef, + IZodSymbol as ZodSymbol, + + // effects + ZodEffectsDef, + IZodEffects as ZodEffects, + RefinementEffect, + TransformEffect, + PreprocessEffect, + Effect, + + // undefined + ZodUndefinedDef, + IZodUndefined as ZodUndefined, + + // union + ZodUnionDef, + IZodUnion as ZodUnion, + + // void + ZodVoidDef, + IZodVoid as ZodVoid, + + // native + ZodNativeType, + ZodNativeTypeDef, + ZodNativeTypeName, + ZodFirstPartySchemaTypes, +} from './typings' + +export { + coerce, + anyType as any, + arrayType as array, + bigIntType as bigint, + booleanType as boolean, + brandedType as branded, + catchType as catch, + customType as custom, + dateType as date, + defaultType as default, + discriminatedUnionType as discriminatedUnion, + effectsType as effects, + enumType as enum, + functionType as function, + instanceOfType as instanceof, + intersectionType as intersection, + lazyType as lazy, + literalType as literal, + mapType as map, + nanType as nan, + nativeEnumType as nativeEnum, + neverType as never, + nullType as null, + nullableType as nullable, + numberType as number, + objectType as object, + optionalType as optional, + pipelineType as pipeline, + preprocessType as preprocess, + promiseType as promise, + recordType as record, + refType as ref, + readonlyType as readonly, + setType as set, + strictObjectType as strictObject, + stringType as string, + symbolType as symbol, + effectsType as transformer, + tupleType as tuple, + undefinedType as undefined, + unionType as union, + unknownType as unknown, + voidType as void, +} from './builders' diff --git a/packages/zui/src/z/types/array/index.ts b/packages/zui/src/z/types/array/index.ts index 5068f84c012..659092ec656 100644 --- a/packages/zui/src/z/types/array/index.ts +++ b/packages/zui/src/z/types/array/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' +import * as utils from '../../../utils' import type { ArrayCardinality, ArrayOutputType, IZodArray, IZodType, ZodArrayDef } from '../../typings' -import * as utils from '../../utils' import { ParseInputLazyPath, ZodBaseTypeImpl, diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 66f53ce051b..17279ed2efd 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -1,4 +1,5 @@ import type * as transforms from '../../../transforms' +import * as utils from '../../../utils' import { zuiKey } from '../../consts' import { ZodError } from '../../error' import { builders } from '../../internal-builders' @@ -30,7 +31,6 @@ import type { CustomErrorParams, IssueData, } from '../../typings' -import * as utils from '../../utils' // TODO(circle): get rid of circular dependency between zui core and transforms @@ -501,14 +501,16 @@ export abstract class ZodBaseTypeImpl diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index ddcd0dc1532..a620620ef2c 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import { type IZodDate, ZodDateCheck, ZodDateDef } from '../../typings' -import * as utils from '../../utils' import { addIssueToContext, INVALID, diff --git a/packages/zui/src/z/types/default/default.test.ts b/packages/zui/src/z/types/default/default.test.ts index 8a8f2b9eea2..3912502a070 100644 --- a/packages/zui/src/z/types/default/default.test.ts +++ b/packages/zui/src/z/types/default/default.test.ts @@ -1,5 +1,5 @@ import { test, expect } from 'vitest' -import { z } from '../../..' +import { z } from '../../../index' import * as assert from '../../../assertions.utils.test' test('basic defaults', () => { diff --git a/packages/zui/src/z/types/default/index.ts b/packages/zui/src/z/types/default/index.ts index 13d10c0d74b..adf0aa2a1bf 100644 --- a/packages/zui/src/z/types/default/index.ts +++ b/packages/zui/src/z/types/default/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' +import * as utils from '../../../utils' import type { IZodType, IZodDefault, ZodDefaultDef } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, ParseInput, ParseReturnType } from '../basetype' export class ZodDefaultImpl diff --git a/packages/zui/src/z/types/discriminatedUnion/index.ts b/packages/zui/src/z/types/discriminatedUnion/index.ts index ca64ce7c92d..93252dc4349 100644 --- a/packages/zui/src/z/types/discriminatedUnion/index.ts +++ b/packages/zui/src/z/types/discriminatedUnion/index.ts @@ -1,3 +1,4 @@ +import * as utils from '../../../utils' import type { IZodType, IZodDiscriminatedUnion, @@ -9,7 +10,6 @@ import type { Primitive, ZodNativeType, } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, INVALID, ParseInput, ParseReturnType } from '../basetype' const getDiscriminator = (_type: IZodType | undefined): Primitive[] => { diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index 034148ef0cf..6045824347d 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -1,6 +1,6 @@ +import * as utils from '../../../utils' import { builders } from '../../internal-builders' import type { FilterEnum, IZodEnum, EnumValuesMap, NeverCast, ZodEnumDef, EnumValues } from '../../typings' -import * as utils from '../../utils' import { RawCreateParams, ZodBaseTypeImpl, diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index 9e70f9e38a4..4bdd6c39978 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -1,3 +1,4 @@ +import * as utils from '../../../utils' import { defaultErrorMap, getErrorMap, ZodError } from '../../error' import { is } from '../../guards' import { builders } from '../../internal-builders' @@ -14,8 +15,6 @@ import type { IZodPromise, } from '../../typings' -import * as utils from '../../utils' - import { ZodBaseTypeImpl, addIssueToContext, INVALID, makeIssue, OK, ParseInput, ParseReturnType } from '../basetype' export class ZodFunctionImpl = IZodTuple, Returns extends IZodType = IZodType> diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 1ae759fe5d8..e95fda72256 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodIntersection, IZodType, ZodIntersectionDef } from '../../typings' -import * as utils from '../../utils' import { getParsedType, addIssueToContext, diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index 1b9c9e2cf32..17a6d79970e 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodMap, IZodType, ZodMapDef } from '../../typings' -import * as utils from '../../utils' import { ParseInputLazyPath, ZodBaseTypeImpl, diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index 3a604a14116..b8bc2f5af00 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' +import * as utils from '../../../utils' import type { EnumLike, IZodNativeEnum, ZodNativeEnumDef } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' export class ZodNativeEnumImpl diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index 56abc86e8c8..c6b7887e61a 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import { type IZodNumber, ZodNumberCheck, ZodNumberDef } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 76a2101352b..ac6fa4d4f96 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -1,3 +1,4 @@ +import * as utils from '../../../utils' import { is } from '../../guards' import { builders } from '../../internal-builders' import type { @@ -14,7 +15,6 @@ import type { IZodOptional, IZodEnum, } from '../../typings' -import * as utils from '../../utils' import { addIssueToContext, INVALID, diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index ae7b2291d49..64549d3fbb2 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodPipeline, IZodType, ZodPipelineDef } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, DIRTY, INVALID, ParseInput, ParseReturnType } from '../basetype' export type { ZodPipelineDef } diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 8195c81d25b..be0cecd2a3b 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodRecord, IZodString, IZodType, KeySchema, RecordType, ZodRecordDef } from '../../typings' -import * as utils from '../../utils' import { ParseInputLazyPath, ZodBaseTypeImpl, diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index c71020cbf45..3fcb2511d3f 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodSet, IZodType, ZodSetDef } from '../../typings' -import * as utils from '../../utils' import { ParseInputLazyPath, ZodBaseTypeImpl, diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index d25201e8918..94cc6e8b7c2 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,6 +1,6 @@ +import * as utils from '../../../utils' import { zuiKey } from '../../consts' import { type IZodString, ZodStringCheck, ZodStringDef } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 07caab9a570..139c6b167be 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodEffects, IZodType, ZodEffectsDef, input, output, RefinementCtx, IssueData } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, DIRTY, INVALID, isValid, ParseInput, ParseReturnType } from '../basetype' export class ZodEffectsImpl, Input = input> diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 11b220d3ce8..7de74fd5077 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -1,5 +1,5 @@ +import * as utils from '../../../utils' import type { IZodTuple, IZodType, ZodTupleDef } from '../../typings' -import * as utils from '../../utils' import { ParseInputLazyPath, addIssueToContext, diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index 7d0b18e24bb..f4a2c5c5694 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -1,8 +1,8 @@ +import * as utils from '../../../utils' import { ZodError } from '../../error' import { is } from '../../guards' import { builders } from '../../internal-builders' import type { DefaultZodUnionOptions, IZodUnion, IZodType, ZodUnionDef, ZodUnionOptions, ZodIssue } from '../../typings' -import * as utils from '../../utils' import { ZodBaseTypeImpl, addIssueToContext, diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 96480028ee5..2cadb919781 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -9,7 +9,7 @@ import { Writeable, AddQuestionMarks, ExtendShape, -} from './utils/type-utils' +} from '../utils/type-utils' //* ─────────────────────────── UI & Metadata ─────────────────────────────── @@ -506,12 +506,13 @@ export interface IZodType Date: Wed, 4 Mar 2026 15:22:36 -0500 Subject: [PATCH 31/50] feat(sdk): zui is only exported under the z namespace (#14990) --- .../browser/src/actions/discover-urls.ts | 4 +-- integrations/github/integration.definition.ts | 2 +- integrations/github/src/definitions/events.ts | 4 +-- integrations/github/src/definitions/index.ts | 4 +-- integrations/mailchimp/src/utils.ts | 4 +-- .../todoist/integration.definition.ts | 2 +- .../todoist/src/todoist-api/sync-client.ts | 14 ++++---- interfaces/hitl/interface.definition.ts | 6 ++-- .../cli/src/code-generation/generators.ts | 2 +- packages/cli/src/tables/tables-publisher.ts | 6 ++-- packages/cli/src/utils/schema-utils.ts | 10 +++--- packages/sdk/src/bot/definition.ts | 30 ++++++++-------- .../sdk/src/integration/definition/generic.ts | 14 ++++---- .../sdk/src/integration/definition/index.ts | 26 +++++++++++--- .../sdk/src/integration/definition/types.ts | 4 +-- packages/sdk/src/interface/definition.ts | 22 ++++++------ packages/sdk/src/interface/resolve.ts | 4 +-- packages/sdk/src/plugin/definition.ts | 30 ++++++++-------- packages/sdk/src/schema.ts | 2 +- packages/sdk/src/zui.ts | 34 ++++++------------- packages/zui/src/exports.ts | 2 -- .../src/prompt/parse-content.ts | 4 +-- .../conversation-insights/src/tagsUpdater.ts | 2 +- .../src/utils/json-lines/parser.ts | 2 +- 24 files changed, 117 insertions(+), 117 deletions(-) diff --git a/integrations/browser/src/actions/discover-urls.ts b/integrations/browser/src/actions/discover-urls.ts index a44d4710e09..e6246556b88 100644 --- a/integrations/browser/src/actions/discover-urls.ts +++ b/integrations/browser/src/actions/discover-urls.ts @@ -1,5 +1,5 @@ import { RuntimeError } from '@botpress/client' -import { IntegrationLogger, z, ZodIssue } from '@botpress/sdk' +import { IntegrationLogger, z } from '@botpress/sdk' import Firecrawl, { SdkError } from '@mendable/firecrawl-js' import { trackEvent } from '../tracking' import { isValidGlob, matchGlob } from '../utils/globs' @@ -11,7 +11,7 @@ const COST_PER_FIRECRAWL_MAP = 0.001 type StopReason = Awaited>['stopReason'] -type ZodIssueCode = ZodIssue['code'] +type ZodIssueCode = z.ZodIssue['code'] export const urlSchema = z.string().transform((url, ctx) => { url = url.trim() diff --git a/integrations/github/integration.definition.ts b/integrations/github/integration.definition.ts index eb31449fb5e..09d39ec6b5f 100644 --- a/integrations/github/integration.definition.ts +++ b/integrations/github/integration.definition.ts @@ -7,7 +7,7 @@ import { actions, events, configuration, configurations, channels, user, secrets export default new sdk.IntegrationDefinition({ name: INTEGRATION_NAME, title: 'GitHub', - version: '1.1.7', + version: '1.1.9', icon: 'icon.svg', readme: 'hub.md', description: 'Manage GitHub issues, pull requests, and repositories.', diff --git a/integrations/github/src/definitions/events.ts b/integrations/github/src/definitions/events.ts index 4b9fa4dd815..4f227d08973 100644 --- a/integrations/github/src/definitions/events.ts +++ b/integrations/github/src/definitions/events.ts @@ -1,4 +1,4 @@ -import { z, ZodTypeAny } from '@botpress/sdk' +import { z } from '@botpress/sdk' import * as sdk from '@botpress/sdk' import { Issue, PullRequest, User, PullRequestReview } from './entities' @@ -6,7 +6,7 @@ const COMMON_EVENT_FIELDS = { sender: { eventSender: User.title('Sender').describe('The user who triggered the event'), }, -} as const satisfies Record> +} as const satisfies Record> const pullRequestOpened = { title: 'Pull Request opened', diff --git a/integrations/github/src/definitions/index.ts b/integrations/github/src/definitions/index.ts index ae2fd323b95..7ca806956fd 100644 --- a/integrations/github/src/definitions/index.ts +++ b/integrations/github/src/definitions/index.ts @@ -1,4 +1,4 @@ -import { z, ZodRawShape } from '@botpress/sdk' +import { z } from '@botpress/sdk' import * as sdk from '@botpress/sdk' export { actions } from './actions' @@ -23,7 +23,7 @@ const webhookSecret = { .describe( 'A high-entropy string that only you and Botpress know. Must be set to the same value as in the GitHub organization settings.' ), -} as const satisfies ZodRawShape +} as const satisfies z.ZodRawShape export const configurations = { manualApp: { diff --git a/integrations/mailchimp/src/utils.ts b/integrations/mailchimp/src/utils.ts index 69ac148a2de..ef96e2b685e 100644 --- a/integrations/mailchimp/src/utils.ts +++ b/integrations/mailchimp/src/utils.ts @@ -1,4 +1,4 @@ -import { ZodError, RuntimeError, z } from '@botpress/sdk' +import { RuntimeError, z } from '@botpress/sdk' import { MailchimpApi } from './client' import { Customer, MailchimpAPIError } from './misc/custom-types' import { Logger } from './misc/types' @@ -27,7 +27,7 @@ export const isMailchimpError = (error: any): error is MailchimpAPIError => { return 'status' in error && 'response' in error && 'body' in error.response } -export const isZodError = (error: any): error is ZodError => { +export const isZodError = (error: any): error is z.ZodError => { return error && typeof error === 'object' && z.is.zuiError(error) && 'errors' in error } diff --git a/integrations/todoist/integration.definition.ts b/integrations/todoist/integration.definition.ts index e76a032978a..76b86fd9528 100644 --- a/integrations/todoist/integration.definition.ts +++ b/integrations/todoist/integration.definition.ts @@ -16,7 +16,7 @@ export default new sdk.IntegrationDefinition({ name: 'todoist', title: 'Todoist', description: 'Create and modify tasks, post comments and more.', - version: '1.0.2', + version: '1.0.4', readme: 'hub.md', icon: 'icon.svg', actions, diff --git a/integrations/todoist/src/todoist-api/sync-client.ts b/integrations/todoist/src/todoist-api/sync-client.ts index 57fcf750d9f..1f477818c03 100644 --- a/integrations/todoist/src/todoist-api/sync-client.ts +++ b/integrations/todoist/src/todoist-api/sync-client.ts @@ -1,4 +1,4 @@ -import { z, ZodRawShape, ZodObject } from '@botpress/sdk' +import { z } from '@botpress/sdk' export class TodoistSyncClient { private readonly _fetch: typeof fetch @@ -28,7 +28,7 @@ export class TodoistSyncClient { } } - private async _post({ + private async _post({ endpoint, params, responseSchema, @@ -36,7 +36,7 @@ export class TodoistSyncClient { endpoint: string responseSchema: T params?: Record - }): Promise>> { + }): Promise>> { return this._sendRequest({ endpoint, init: { @@ -48,13 +48,13 @@ export class TodoistSyncClient { }) } - private async _get({ + private async _get({ endpoint, responseSchema, }: { endpoint: string responseSchema: T - }): Promise>> { + }): Promise>> { return this._sendRequest({ endpoint, init: { @@ -64,7 +64,7 @@ export class TodoistSyncClient { }) } - private async _sendRequest({ + private async _sendRequest({ endpoint, init, responseSchema, @@ -72,7 +72,7 @@ export class TodoistSyncClient { endpoint: string init: RequestInit responseSchema: T - }): Promise>> { + }): Promise>> { const response = await this._fetch(`https://api.todoist.com/sync/v9/${endpoint}`, init) if (!response.ok) { diff --git a/interfaces/hitl/interface.definition.ts b/interfaces/hitl/interface.definition.ts index ddf7aafd89f..1ad8c6a6316 100644 --- a/interfaces/hitl/interface.definition.ts +++ b/interfaces/hitl/interface.definition.ts @@ -18,10 +18,10 @@ const allMessages = { ...sdk.messages.defaults, markdown: sdk.messages.markdown, bloc: sdk.messages.markdownBloc, -} satisfies Record +} satisfies Record type Tuple = [T, T, ...T[]] -const messagePayloadSchemas: sdk.AnyZodObject[] = Object.entries(allMessages).map(([k, v]) => +const messagePayloadSchemas: sdk.z.AnyZodObject[] = Object.entries(allMessages).map(([k, v]) => sdk.z.object({ source: messageSourceSchema, type: sdk.z.literal(k), @@ -29,7 +29,7 @@ const messagePayloadSchemas: sdk.AnyZodObject[] = Object.entries(allMessages).ma }) ) -const messageSchema = sdk.z.union(messagePayloadSchemas as Tuple) +const messageSchema = sdk.z.union(messagePayloadSchemas as Tuple) export default new sdk.InterfaceDefinition({ name: 'hitl', diff --git a/packages/cli/src/code-generation/generators.ts b/packages/cli/src/code-generation/generators.ts index d866e9f5021..eae42120c41 100644 --- a/packages/cli/src/code-generation/generators.ts +++ b/packages/cli/src/code-generation/generators.ts @@ -24,7 +24,7 @@ export const jsonSchemaToTypescriptZuiSchema = async ( extraProps: Record = {} ): Promise => { schema = await utils.schema.dereferenceSchema(schema) - const zuiSchema = sdk.transforms.fromJSONSchemaLegacy(schema) + const zuiSchema = sdk.z.transforms.fromJSONSchemaLegacy(schema) const allProps = { ...extraProps, diff --git a/packages/cli/src/tables/tables-publisher.ts b/packages/cli/src/tables/tables-publisher.ts index d2c3b703d4c..28f09826930 100644 --- a/packages/cli/src/tables/tables-publisher.ts +++ b/packages/cli/src/tables/tables-publisher.ts @@ -114,7 +114,7 @@ export class TablesPublisher { await api.client.updateTable({ table: existingTable.name, - schema: sdk.transforms.toJSONSchemaLegacy(updatedTableDef.schema), + schema: sdk.z.transforms.toJSONSchemaLegacy(updatedTableDef.schema), frozen: updatedTableDef.frozen, tags: updatedTableDef.tags, isComputeEnabled: updatedTableDef.isComputeEnabled, @@ -130,7 +130,7 @@ export class TablesPublisher { tableName: string tableDef: sdk.BotTableDefinition }): Promise>> { - const columns = sdk.transforms.toJSONSchemaLegacy(tableDef.schema).properties! + const columns = sdk.z.transforms.toJSONSchemaLegacy(tableDef.schema).properties! const validColumns = await Promise.all( Object.entries(columns).map(async ([columnName, columnSchema]) => { @@ -172,7 +172,7 @@ export class TablesPublisher { }) { await api.client.createTable({ name: tableName, - schema: sdk.transforms.toJSONSchemaLegacy(tableDef.schema), + schema: sdk.z.transforms.toJSONSchemaLegacy(tableDef.schema), frozen: tableDef.frozen, tags: tableDef.tags, factor: tableDef.factor, diff --git a/packages/cli/src/utils/schema-utils.ts b/packages/cli/src/utils/schema-utils.ts index 61eb9b26fcc..f1ee0d96ab2 100644 --- a/packages/cli/src/utils/schema-utils.ts +++ b/packages/cli/src/utils/schema-utils.ts @@ -2,7 +2,7 @@ import { dereference } from '@apidevtools/json-schema-ref-parser' import * as sdk from '@botpress/sdk' import { JSONSchema7 } from 'json-schema' -type ZuiToJsonSchema = typeof sdk.transforms.toJSONSchemaLegacy +type ZuiToJsonSchema = typeof sdk.z.transforms.toJSONSchemaLegacy type JsonSchema = ReturnType type SchemaOptions = { @@ -11,7 +11,7 @@ type SchemaOptions = { } type SchemaDefinition = { - schema: sdk.ZuiObjectOrRefSchema + schema: sdk.z.ZuiObjectOrRefSchema ui?: Record } @@ -24,12 +24,12 @@ const isObjectSchema = (schema: JsonSchema): boolean => schema.type === 'object' export async function mapZodToJsonSchema( definition: SchemaDefinition, options: MapSchemaOptions -): Promise> { +): Promise> { let schema: JSONSchema7 if (options.useLegacyZuiTransformer) { - schema = sdk.transforms.toJSONSchemaLegacy(definition.schema, { target: 'jsonSchema7' }) + schema = sdk.z.transforms.toJSONSchemaLegacy(definition.schema, { target: 'jsonSchema7' }) } else { - schema = sdk.transforms.toJSONSchema(definition.schema) + schema = sdk.z.transforms.toJSONSchema(definition.schema) } schema = (await dereferenceSchema(schema)) as typeof schema diff --git a/packages/sdk/src/bot/definition.ts b/packages/sdk/src/bot/definition.ts index d0c24638c01..a29303f27fe 100644 --- a/packages/sdk/src/bot/definition.ts +++ b/packages/sdk/src/bot/definition.ts @@ -6,14 +6,14 @@ import { SchemaDefinition } from '../schema' import * as utils from '../utils' import { ValueOf, Writable, Merge, StringKeys } from '../utils/type-utils' import { SDK_VERSION } from '../version' -import z, { ZuiObjectSchema, ZuiObjectOrRefSchema } from '../zui' +import { z } from '../zui' -type BaseConfig = ZuiObjectSchema -type BaseStates = Record -type BaseEvents = Record -type BaseActions = Record -type BaseTables = Record -type BaseWorkflows = Record +type BaseConfig = z.ZuiObjectSchema +type BaseStates = Record +type BaseEvents = Record +type BaseActions = Record +type BaseTables = Record +type BaseWorkflows = Record export type TagDefinition = { title?: string @@ -57,7 +57,7 @@ export type ActionDefinition - output: SchemaDefinition // cannot infer both input and output types (typescript limitation) + output: SchemaDefinition // cannot infer both input and output types (typescript limitation) attributes?: Record } @@ -65,7 +65,7 @@ export type WorkflowDefinition - output: SchemaDefinition // cannot infer both input and output types (typescript limitation) + output: SchemaDefinition // cannot infer both input and output types (typescript limitation) tags?: Record } @@ -585,13 +585,13 @@ export class BotDefinition< } private _dereferenceZuiSchema( - schema: ZuiObjectOrRefSchema, + schema: z.ZuiObjectOrRefSchema, zuiReferenceMap: Record - ): ZuiObjectSchema { - return schema.dereference(zuiReferenceMap) as ZuiObjectSchema + ): z.ZuiObjectSchema { + return schema.dereference(zuiReferenceMap) as z.ZuiObjectSchema } - private _dereferenceDefinitionSchemas>( + private _dereferenceDefinitionSchemas>( definitions: TDefinitionRecord | undefined, zuiReferenceMap: Record ): TDefinitionRecord { @@ -603,7 +603,7 @@ export class BotDefinition< ) as TDefinitionRecord } - private _dereferenceDefinitionSchema( + private _dereferenceDefinitionSchema( definition: TDefinition, zuiReferenceMap: Record ): TDefinition { @@ -615,7 +615,7 @@ export class BotDefinition< private _dereferenceActionDefinitionSchemas< TDefinitionRecord extends Record< string, - { input: { schema: ZuiObjectOrRefSchema }; output: { schema: ZuiObjectOrRefSchema } } + { input: { schema: z.ZuiObjectOrRefSchema }; output: { schema: z.ZuiObjectOrRefSchema } } >, >(definitions: TDefinitionRecord | undefined, zuiReferenceMap: Record): TDefinitionRecord { return Object.fromEntries( diff --git a/packages/sdk/src/integration/definition/generic.ts b/packages/sdk/src/integration/definition/generic.ts index 1e04b82b5f8..5be625c1f2a 100644 --- a/packages/sdk/src/integration/definition/generic.ts +++ b/packages/sdk/src/integration/definition/generic.ts @@ -1,10 +1,10 @@ -import { ZuiObjectSchema } from '../../zui' +import { z } from '../../zui' -export type BaseConfig = ZuiObjectSchema +export type BaseConfig = z.ZuiObjectSchema export type BaseConfigs = Record -export type BaseEvents = Record -export type BaseActions = Record -export type BaseMessages = Record +export type BaseEvents = Record +export type BaseActions = Record +export type BaseMessages = Record export type BaseChannels = Record -export type BaseStates = Record -export type BaseEntities = Record +export type BaseStates = Record +export type BaseEntities = Record diff --git a/packages/sdk/src/integration/definition/index.ts b/packages/sdk/src/integration/definition/index.ts index 5facc526f8a..5f285a81da9 100644 --- a/packages/sdk/src/integration/definition/index.ts +++ b/packages/sdk/src/integration/definition/index.ts @@ -3,7 +3,7 @@ import { resolveInterface } from '../../interface/resolve' import { InterfacePackage } from '../../package' import * as utils from '../../utils' import { SDK_VERSION } from '../../version' -import { mergeObjectSchemas, z } from '../../zui' +import { z } from '../../zui' import { SchemaStore, BrandedSchema, createStore, isBranded, getName } from './branded-schema' import { BaseConfig, BaseEvents, BaseActions, BaseChannels, BaseStates, BaseEntities, BaseConfigs } from './generic' import { @@ -337,10 +337,10 @@ export class IntegrationDefinition< ...a, ...b, input: { - schema: mergeObjectSchemas(a.input.schema, b.input.schema), + schema: this._mergeObjectSchemas(a.input.schema, b.input.schema), }, output: { - schema: mergeObjectSchemas(a.output.schema, b.output.schema), + schema: this._mergeObjectSchemas(a.output.schema, b.output.schema), }, } } @@ -349,7 +349,7 @@ export class IntegrationDefinition< return { ...a, ...b, - schema: mergeObjectSchemas(a.schema, b.schema), + schema: this._mergeObjectSchemas(a.schema, b.schema), } } @@ -387,7 +387,23 @@ export class IntegrationDefinition< private _mergeMessage = (a: MessageDefinition, b: MessageDefinition): MessageDefinition => { return { - schema: mergeObjectSchemas(a.schema, b.schema), + schema: this._mergeObjectSchemas(a.schema, b.schema), } } + + private _mergeObjectSchemas = (a: z.ZuiObjectSchema, b: z.ZuiObjectSchema): z.ZuiObjectSchema => { + const aDef = a._def + const bDef = b._def + + if (aDef.typeName === 'ZodObject' && bDef.typeName === 'ZodObject') { + const aShape = aDef.shape() + const bShape = bDef.shape() + return z.object({ ...aShape, ...bShape }) + } + if (aDef.typeName === 'ZodRecord' && bDef.typeName === 'ZodRecord') { + return z.record(z.intersection(aDef.valueType, bDef.valueType)) + } + // TODO: adress this case + throw new Error('Cannot merge object schemas with record schemas') + } } diff --git a/packages/sdk/src/integration/definition/types.ts b/packages/sdk/src/integration/definition/types.ts index bec97280590..76d746baf7e 100644 --- a/packages/sdk/src/integration/definition/types.ts +++ b/packages/sdk/src/integration/definition/types.ts @@ -1,5 +1,5 @@ import { SchemaDefinition } from '../../schema' -import { ZuiObjectSchema } from '../../zui' +import { z } from '../../zui' import { BaseConfig, BaseEvents, @@ -62,7 +62,7 @@ export type ActionDefinition - output: SchemaDefinition // cannot infer both input and output types (typescript limitation) + output: SchemaDefinition // cannot infer both input and output types (typescript limitation) billable?: boolean cacheable?: boolean attributes?: Record diff --git a/packages/sdk/src/interface/definition.ts b/packages/sdk/src/interface/definition.ts index dfc537e9b2e..d171f3a4ef5 100644 --- a/packages/sdk/src/interface/definition.ts +++ b/packages/sdk/src/interface/definition.ts @@ -1,20 +1,20 @@ import { ActionDefinition, ChannelDefinition, EntityDefinition, EventDefinition } from '../integration/definition' import * as utils from '../utils' import { SDK_VERSION } from '../version' -import z, { ZuiObjectSchema, GenericZuiSchema, ZodRef } from '../zui' +import { z } from '../zui' -type BaseEvents = Record -type BaseActions = Record -type BaseMessages = Record +type BaseEvents = Record +type BaseActions = Record +type BaseMessages = Record type BaseChannels = Record -type BaseEntities = Record +type BaseEntities = Record type EntityReferences = { - [K in keyof TEntities]: ZodRef + [K in keyof TEntities]: z.ZodRef } type GenericEventDefinition = { - schema: GenericZuiSchema, TEvent> + schema: z.GenericZuiSchema, TEvent> attributes?: Record } @@ -24,7 +24,7 @@ type GenericChannelDefinition< > = { messages: { [K in keyof TChannel]: { - schema: GenericZuiSchema, TChannel[K]> + schema: z.GenericZuiSchema, TChannel[K]> } } } @@ -37,8 +37,8 @@ type GenericActionDefinition< description?: string billable?: boolean cacheable?: boolean - input: { schema: GenericZuiSchema, TAction> } - output: { schema: GenericZuiSchema, ZuiObjectSchema> } + input: { schema: z.GenericZuiSchema, TAction> } + output: { schema: z.GenericZuiSchema, z.ZuiObjectSchema> } attributes?: Record } @@ -171,7 +171,7 @@ export class InterfaceDefinition< } private _getEntityReference = (entities: Record): EntityReferences => { - const entityReferences: Record = {} as EntityReferences + const entityReferences: Record = {} as EntityReferences for (const [entityName, entityDef] of Object.entries(entities)) { const title = entityDef.schema._def['x-zui']?.title const description = entityDef.schema._def.description diff --git a/packages/sdk/src/interface/resolve.ts b/packages/sdk/src/interface/resolve.ts index 1b0d24a1c27..967a3015190 100644 --- a/packages/sdk/src/interface/resolve.ts +++ b/packages/sdk/src/interface/resolve.ts @@ -7,10 +7,10 @@ import { } from '../integration' import { InterfacePackage } from '../package' import * as utils from '../utils' -import z, { ZuiObjectSchema } from '../zui' +import { z } from '../zui' type ResolveInterfaceInput = InterfacePackage & { - entities: Record + entities: Record actions: Record events: Record channels: Record diff --git a/packages/sdk/src/plugin/definition.ts b/packages/sdk/src/plugin/definition.ts index 32f7b9b2d5c..5c35ec8c3d0 100644 --- a/packages/sdk/src/plugin/definition.ts +++ b/packages/sdk/src/plugin/definition.ts @@ -12,18 +12,18 @@ import { import { IntegrationPackage, InterfacePackage } from '../package' import * as typeUtils from '../utils/type-utils' import { SDK_VERSION } from '../version' -import { ZuiObjectSchema, ZuiObjectOrRefSchema, z } from '../zui' +import { z } from '../zui' export { UserDefinition, ConversationDefinition, MessageDefinition, WorkflowDefinition } from '../bot/definition' -type BaseConfig = ZuiObjectOrRefSchema -type BaseStates = Record -type BaseEvents = Record -type BaseActions = Record +type BaseConfig = z.ZuiObjectOrRefSchema +type BaseStates = Record +type BaseEvents = Record +type BaseActions = Record type BaseInterfaces = Record type BaseIntegrations = Record -type BaseTables = Record -type BaseWorkflows = Record +type BaseTables = Record +type BaseWorkflows = Record export type TableDefinition = typeUtils.Merge< BotTableDefinition, @@ -57,7 +57,7 @@ export type ActionDefinition @@ -73,7 +73,7 @@ export type RecurringEventDefinition = export type ZuiSchemaWithEntityReferences< TInterfaces extends BaseInterfaces, - TReturnType extends ZuiObjectOrRefSchema, + TReturnType extends z.ZuiObjectOrRefSchema, > = | ((props: { entities: { @@ -86,7 +86,7 @@ export type ZuiSchemaWithEntityReferences< type GenericDefinition< TInterfaces extends BaseInterfaces, - TDefinition extends { schema: ZuiObjectOrRefSchema }, + TDefinition extends { schema: z.ZuiObjectOrRefSchema }, > = typeUtils.Merge< TDefinition, { @@ -386,13 +386,13 @@ export class PluginDefinition< } private _dereferenceZuiSchema( - schema: ZuiObjectOrRefSchema, + schema: z.ZuiObjectOrRefSchema, zuiReferenceMap: Record - ): ZuiObjectSchema { - return schema.dereference(zuiReferenceMap) as ZuiObjectSchema + ): z.ZuiObjectSchema { + return schema.dereference(zuiReferenceMap) as z.ZuiObjectSchema } - private _dereferenceDefinitionSchemas>( + private _dereferenceDefinitionSchemas>( definitions: TDefinitionRecord | undefined, zuiReferenceMap: Record ): TDefinitionRecord { @@ -407,7 +407,7 @@ export class PluginDefinition< private _dereferenceActionDefinitionSchemas< TDefinitionRecord extends Record< string, - { input: { schema: ZuiObjectOrRefSchema }; output: { schema: ZuiObjectOrRefSchema } } + { input: { schema: z.ZuiObjectOrRefSchema }; output: { schema: z.ZuiObjectOrRefSchema } } >, >(definitions: TDefinitionRecord | undefined, zuiReferenceMap: Record): TDefinitionRecord { return Object.fromEntries( diff --git a/packages/sdk/src/schema.ts b/packages/sdk/src/schema.ts index 638187b156d..423adac7d1b 100644 --- a/packages/sdk/src/schema.ts +++ b/packages/sdk/src/schema.ts @@ -1,4 +1,4 @@ -import * as z from './zui' +import { z } from './zui' type SchemaOptions = { title: string diff --git a/packages/sdk/src/zui.ts b/packages/sdk/src/zui.ts index d95315acea7..41e0dbd154a 100644 --- a/packages/sdk/src/zui.ts +++ b/packages/sdk/src/zui.ts @@ -1,29 +1,15 @@ -import { z } from '@bpinternal/zui' +import '@bpinternal/zui' -export * from '@bpinternal/zui' +declare module '@bpinternal/zui' { + export namespace z { + export type GenericZuiSchema< + A extends Record = Record, + R extends z.ZodType = z.ZodType, + > = (typeArguments: A) => R -export type GenericZuiSchema< - A extends Record = Record, - R extends z.ZodTypeAny = z.ZodTypeAny, -> = (typeArguments: A) => R - -export type ZuiObjectSchema = z.ZodObject | z.ZodRecord -export type ZuiObjectOrRefSchema = ZuiObjectSchema | z.ZodRef - -export const mergeObjectSchemas = (a: ZuiObjectSchema, b: ZuiObjectSchema): ZuiObjectSchema => { - const aDef = a._def - const bDef = b._def - - if (aDef.typeName === 'ZodObject' && bDef.typeName === 'ZodObject') { - const aShape = aDef.shape() - const bShape = bDef.shape() - return z.object({ ...aShape, ...bShape }) - } - if (aDef.typeName === 'ZodRecord' && bDef.typeName === 'ZodRecord') { - return z.record(z.intersection(aDef.valueType, bDef.valueType)) + export type ZuiObjectSchema = z.ZodObject | z.ZodRecord + export type ZuiObjectOrRefSchema = ZuiObjectSchema | z.ZodRef } - // TODO: adress this case - throw new Error('Cannot merge object schemas with record schemas') } -export default z +export { z } from '@bpinternal/zui' diff --git a/packages/zui/src/exports.ts b/packages/zui/src/exports.ts index 8e504de309c..9ba08c5db42 100644 --- a/packages/zui/src/exports.ts +++ b/packages/zui/src/exports.ts @@ -1,8 +1,6 @@ import './circle' export type { JSONSchema7 } from 'json-schema' -export * as json from './transforms/common/json-schema' export * as transforms from './transforms' - export * from './z' export { default } from './z' // for the bundler not to be confused with the default export diff --git a/plugins/conversation-insights/src/prompt/parse-content.ts b/plugins/conversation-insights/src/prompt/parse-content.ts index 39651c55f9a..bc0b21d5909 100644 --- a/plugins/conversation-insights/src/prompt/parse-content.ts +++ b/plugins/conversation-insights/src/prompt/parse-content.ts @@ -11,13 +11,13 @@ export type PredictResponse = { json: T } -const parseJson = (expectedSchema: sdk.ZodSchema, str: string): T => { +const parseJson = (expectedSchema: sdk.z.ZodSchema, str: string): T => { const repaired = jsonrepair(str) const parsed = JSON.parse(repaired) return expectedSchema.parse(parsed) } -type ParseLLMOutputProps = cognitive.GenerateContentOutput & { schema: sdk.ZodSchema } +type ParseLLMOutputProps = cognitive.GenerateContentOutput & { schema: sdk.z.ZodSchema } export const parseLLMOutput = (props: ParseLLMOutputProps): PredictResponse => { const mappedChoices: LLMChoice['content'][] = props.choices.map((choice) => choice.content) if (!mappedChoices[0]) throw new sdk.RuntimeError('Could not parse LLM output') diff --git a/plugins/conversation-insights/src/tagsUpdater.ts b/plugins/conversation-insights/src/tagsUpdater.ts index f00bcd81ac2..c72081f601b 100644 --- a/plugins/conversation-insights/src/tagsUpdater.ts +++ b/plugins/conversation-insights/src/tagsUpdater.ts @@ -57,7 +57,7 @@ type ParsePromptProps = { logger: UpdateTitleAndSummaryProps['logger'] prompt: gen.LLMInput client: cognitive.BotpressClientLike - schema: sdk.ZodSchema + schema: sdk.z.ZodSchema } const _generateContentWithRetries = async (props: ParsePromptProps): Promise> => { let attemptCount = 0 diff --git a/plugins/file-synchronizer/src/utils/json-lines/parser.ts b/plugins/file-synchronizer/src/utils/json-lines/parser.ts index 9357936f1de..6d41056ac93 100644 --- a/plugins/file-synchronizer/src/utils/json-lines/parser.ts +++ b/plugins/file-synchronizer/src/utils/json-lines/parser.ts @@ -2,7 +2,7 @@ import * as sdk from '@botpress/sdk' type _JsonParseResult = { rawLine: string } & ({ value: T } | { error: Error }) -export function* parseJsonLines( +export function* parseJsonLines( rawJsonLines: string, zodSchema: TLineSchema ): Generator<_JsonParseResult>, void, undefined> { From a3f2667b5226d71f847f3be2ba15ad924ef467ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Wed, 4 Mar 2026 17:31:13 -0500 Subject: [PATCH 32/50] chore(zui): cleanup some incorrect usages of zod any + commented code (#14991) --- .../src/transforms/common/eval-zui-string.ts | 2 +- .../zui-from-json-schema/iterables/array.ts | 2 +- .../zui-to-typescript-type/index.test.ts | 2 +- .../zui-to-typescript-type/index.ts | 2 +- packages/zui/src/utils/fn-utils.ts | 19 +- packages/zui/src/utils/other-utils.ts | 4 +- .../zui/src/z/__tests__/deepmasking.test.ts | 184 ------------------ packages/zui/src/z/__tests__/parser.test.ts | 19 +- packages/zui/src/z/__tests__/pickomit.test.ts | 24 +-- .../zui/src/z/__tests__/preprocess.test.ts | 1 + .../zui/src/z/__tests__/recursive.test.ts | 117 ----------- packages/zui/src/z/__tests__/refine.test.ts | 1 + packages/zui/src/z/builders.ts | 2 +- packages/zui/src/z/types/basetype/index.ts | 12 +- .../zui/src/z/types/basetype/parseUtil.ts | 2 +- packages/zui/src/z/types/enum/index.ts | 16 +- packages/zui/src/z/types/function/index.ts | 23 +-- .../zui/src/z/types/intersection/index.ts | 7 +- packages/zui/src/z/types/object/index.ts | 67 +------ .../zui/src/z/types/pipeline/pipeline.test.ts | 4 +- .../zui/src/z/types/record/record.test.ts | 6 +- packages/zui/src/z/types/string/index.ts | 2 - packages/zui/src/z/types/transformer/index.ts | 6 +- packages/zui/src/z/types/tuple/tuple.test.ts | 2 +- packages/zui/src/z/typings.ts | 4 +- 25 files changed, 85 insertions(+), 445 deletions(-) delete mode 100644 packages/zui/src/z/__tests__/deepmasking.test.ts diff --git a/packages/zui/src/transforms/common/eval-zui-string.ts b/packages/zui/src/transforms/common/eval-zui-string.ts index 9b91c6cb209..85fe819277f 100644 --- a/packages/zui/src/transforms/common/eval-zui-string.ts +++ b/packages/zui/src/transforms/common/eval-zui-string.ts @@ -11,7 +11,7 @@ export type EvalZuiStringResult = } export const evalZuiString = (zuiString: string): EvalZuiStringResult => { - let result: any + let result: unknown try { result = new Function('z', `return ${zuiString}`)(z) diff --git a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts index 6ef2c4b6eb0..03a7e606e41 100644 --- a/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts +++ b/packages/zui/src/transforms/zui-from-json-schema/iterables/array.ts @@ -22,7 +22,7 @@ const _handleTuple = ( toZui: (x: JSONSchema7Definition) => z.ZodType ): z.ZodTuple => { const itemSchemas = items.map(toZui) as [] | [z.ZodType, ...z.ZodType[]] - let zodTuple: z.ZodTuple = z.tuple(itemSchemas) + let zodTuple: z.ZodTuple = z.tuple(itemSchemas) if (additionalItems !== undefined) { zodTuple = zodTuple.rest(toZui(additionalItems)) diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts index bbfc73a8583..a4e8c08d052 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts @@ -824,7 +824,7 @@ describe.concurrent('objects', () => { .object({ Date: z.optional(z.string().optional().optional()), }) - .required({ Date: false } as any) + .required({ Date: false } as any) // TODO(any): type properly const typings = toTypescript(obj) await assert.expectTypescript(typings).toMatchWithoutFormatting(`declare const x: { Date?: string }`) diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.ts index 62ed82929af..751585af016 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.ts @@ -266,7 +266,7 @@ ${opts.join(' | ')}` return '[]' } - const items = s._def.items.map((i: any) => sUnwrapZod(i, newConfig)) + const items = s._def.items.map((i) => sUnwrapZod(i, newConfig)) return `[${items.join(', ')}]` case 'ZodRecord': diff --git a/packages/zui/src/utils/fn-utils.ts b/packages/zui/src/utils/fn-utils.ts index 294c64566a7..e0fb7b8a299 100644 --- a/packages/zui/src/utils/fn-utils.ts +++ b/packages/zui/src/utils/fn-utils.ts @@ -2,27 +2,28 @@ import * as lodash from 'lodash-es' /** Sadly, this type is not exported by lodash, so we must redefine it */ type IsEqualCustomizer = ( - value: any, - other: any, + value: unknown, + other: unknown, indexOrKey: PropertyKey | undefined, - parent: any, - otherParent: any, - stack: any + parent: unknown, + otherParent: unknown, + stack: unknown ) => boolean | undefined -export const isEqual = (a: any, b: any): boolean => { +export const isEqual = (a: unknown, b: unknown): boolean => { return _isEqualWithVisitedTracking(a, b, new WeakSet()) } -const _isEqualWithVisitedTracking = (a: any, b: any, visited: WeakSet): boolean => +// TODO(any): type properly +const _isEqualWithVisitedTracking = (a: unknown, b: unknown, visited: WeakSet): boolean => lodash.isEqualWith(a, b, _customizerWithVisitedTracking(visited)) const _customizerWithVisitedTracking = (visited: WeakSet): IsEqualCustomizer => (a, b) => { if (lodash.isPlainObject(a) && !visited.has(a) && lodash.isPlainObject(b) && !visited.has(b)) { - const cleanedA = lodash.omitBy(a, lodash.isUndefined) - const cleanedB = lodash.omitBy(b, lodash.isUndefined) + const cleanedA = lodash.omitBy(a as object, lodash.isUndefined) + const cleanedB = lodash.omitBy(b as object, lodash.isUndefined) // Prevent infinite recursion: mark objects as already checked: visited.add(cleanedA).add(cleanedB).add(a).add(b) diff --git a/packages/zui/src/utils/other-utils.ts b/packages/zui/src/utils/other-utils.ts index b6824a672a3..ec024a2c875 100644 --- a/packages/zui/src/utils/other-utils.ts +++ b/packages/zui/src/utils/other-utils.ts @@ -1,8 +1,8 @@ -export function joinValues(array: T, separator = ' | '): string { +export function joinValues(array: T, separator = ' | '): string { return array.map((val) => (typeof val === 'string' ? `'${val}'` : val)).join(separator) } -export const jsonStringifyReplacer = (_: string, value: any): any => { +export const jsonStringifyReplacer = (_: string, value: unknown): unknown => { if (typeof value === 'bigint') { return value.toString() } diff --git a/packages/zui/src/z/__tests__/deepmasking.test.ts b/packages/zui/src/z/__tests__/deepmasking.test.ts deleted file mode 100644 index 2ab8793c963..00000000000 --- a/packages/zui/src/z/__tests__/deepmasking.test.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { test } from 'vitest' -import * as z from '../index' - -test('test', () => { - z -}) - -// const fish = z.object({ -// name: z.string(), -// props: z.object({ -// color: z.string(), -// numScales: z.number(), -// }), -// }); - -// const nonStrict = z -// .object({ -// name: z.string(), -// color: z.string(), -// }) -// .nonstrict(); - -// test('object pick type', () => { -// const modNonStrictFish = nonStrict.omit({ name: true }); -// modNonStrictFish.parse({ color: 'asdf' }); - -// const bad1 = () => fish.pick({ props: { unknown: true } } as any); -// const bad2 = () => fish.omit({ name: true, props: { unknown: true } } as any); - -// expect(bad1).toThrow(); -// expect(bad2).toThrow(); -// }); - -// test('f1', () => { -// const f1 = fish.pick(true); -// f1.parse({ name: 'a', props: { color: 'b', numScales: 3 } }); -// }); -// test('f2', () => { -// const f2 = fish.pick({ props: true }); -// f2.parse({ props: { color: 'asdf', numScales: 1 } }); -// const badcheck2 = () => f2.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); -// expect(badcheck2).toThrow(); -// }); -// test('f3', () => { -// const f3 = fish.pick({ props: { color: true } }); -// f3.parse({ props: { color: 'b' } }); -// const badcheck3 = () => f3.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); -// expect(badcheck3).toThrow(); -// }); -// test('f4', () => { -// const badcheck4 = () => fish.pick({ props: { color: true, unknown: true } }); -// expect(badcheck4).toThrow(); -// }); -// test('f6', () => { -// const f6 = fish.omit({ props: true }); -// const badcheck6 = () => f6.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); -// f6.parse({ name: 'adsf' }); -// expect(badcheck6).toThrow(); -// }); -// test('f7', () => { -// const f7 = fish.omit({ props: { color: true } }); -// f7.parse({ name: 'a', props: { numScales: 3 } }); -// const badcheck7 = () => f7.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any); -// expect(badcheck7).toThrow(); -// }); -// test('f8', () => { -// const badcheck8 = () => fish.omit({ props: { color: true, unknown: true } }); -// expect(badcheck8).toThrow(); -// }); -// test('f9', () => { -// const f9 = nonStrict.pick(true); -// f9.parse({ name: 'a', color: 'asdf' }); -// }); -// test('f10', () => { -// const f10 = nonStrict.pick({ name: true }); -// f10.parse({ name: 'a' }); -// const val = f10.parse({ name: 'a', color: 'b' }); -// expect(val).toEqual({ name: 'a' }); -// }); -// test('f12', () => { -// const badfcheck12 = () => nonStrict.omit({ color: true, asdf: true }); -// expect(badfcheck12).toThrow(); -// }); - -// test('array masking', () => { -// const fishArray = z.array(fish); -// const modFishArray = fishArray.pick({ -// name: true, -// props: { -// numScales: true, -// }, -// }); - -// modFishArray.parse([{ name: 'fish', props: { numScales: 12 } }]); -// const bad1 = () => modFishArray.parse([{ name: 'fish', props: { numScales: 12, color: 'asdf' } }] as any); -// expect(bad1).toThrow(); -// }); - -// test('array masking', () => { -// const fishArray = z.array(fish); -// const fail = () => -// fishArray.pick({ -// name: true, -// props: { -// whatever: true, -// }, -// } as any); -// expect(fail).toThrow(); -// }); - -// test('array masking', () => { -// const fishArray = z.array(fish); -// const fail = () => -// fishArray.omit({ -// whateve: true, -// } as any); -// expect(fail).toThrow(); -// }); - -// test('array masking', () => { -// const fishArray = z.array(fish); -// const modFishList = fishArray.omit({ -// name: true, -// props: { -// color: true, -// }, -// }); - -// modFishList.parse([{ props: { numScales: 12 } }]); -// const fail = () => modFishList.parse([{ name: 'hello', props: { numScales: 12 } }] as any); -// expect(fail).toThrow(); -// }); - -// test('primitive array masking', () => { -// const fishArray = z.array(z.number()); -// const fail = () => fishArray.pick({} as any); -// expect(fail).toThrow(); -// }); - -// test('other array masking', () => { -// const fishArray = z.array(z.array(z.number())); -// const fail = () => fishArray.pick({} as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #1', () => { -// const fail = () => fish.pick(1 as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #2', () => { -// const fail = () => fish.pick([] as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #3', () => { -// const fail = () => fish.pick(false as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #4', () => { -// const fail = () => fish.pick('asdf' as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #5', () => { -// const fail = () => fish.omit(1 as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #6', () => { -// const fail = () => fish.omit([] as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #7', () => { -// const fail = () => fish.omit(false as any); -// expect(fail).toThrow(); -// }); - -// test('invalid mask #8', () => { -// const fail = () => fish.omit('asdf' as any); -// expect(fail).toThrow(); -// }); diff --git a/packages/zui/src/z/__tests__/parser.test.ts b/packages/zui/src/z/__tests__/parser.test.ts index 113741fdaba..2f50d24571d 100644 --- a/packages/zui/src/z/__tests__/parser.test.ts +++ b/packages/zui/src/z/__tests__/parser.test.ts @@ -2,12 +2,7 @@ import { test, expect } from 'vitest' import * as z from '../index' test('parse strict object with unknown keys', () => { - expect(() => - z - .object({ name: z.string() }) - .strict() - .parse({ name: 'bill', unknownKey: 12 } as any) - ).toThrow() + expect(() => z.object({ name: z.string() }).strict().parse({ name: 'bill', unknownKey: 12 })).toThrow() }) test('parse nonstrict object with unknown keys', () => { @@ -15,25 +10,25 @@ test('parse nonstrict object with unknown keys', () => { }) test('invalid left side of intersection', () => { - expect(() => z.intersection(z.string(), z.number()).parse(12 as any)).toThrow() + expect(() => z.intersection(z.string(), z.number()).parse(12)).toThrow() }) test('invalid right side of intersection', () => { - expect(() => z.intersection(z.string(), z.number()).parse('12' as any)).toThrow() + expect(() => z.intersection(z.string(), z.number()).parse('12')).toThrow() }) test('parsing non-array in tuple schema', () => { - expect(() => z.tuple([]).parse('12' as any)).toThrow() + expect(() => z.tuple([]).parse('12')).toThrow() }) test('incorrect num elements in tuple', () => { - expect(() => z.tuple([]).parse(['asdf'] as any)).toThrow() + expect(() => z.tuple([]).parse(['asdf'])).toThrow() }) test('invalid enum value', () => { - expect(() => z.enum(['Blue']).parse('Red' as any)).toThrow() + expect(() => z.enum(['Blue']).parse('Red')).toThrow() }) test('parsing unknown', () => { - z.string().parse('Red' as unknown) + z.string().parse('Red') }) diff --git a/packages/zui/src/z/__tests__/pickomit.test.ts b/packages/zui/src/z/__tests__/pickomit.test.ts index d133c338a62..92e6b16727f 100644 --- a/packages/zui/src/z/__tests__/pickomit.test.ts +++ b/packages/zui/src/z/__tests__/pickomit.test.ts @@ -24,18 +24,18 @@ test('pick parse - success', () => { }) test('pick parse - fail', () => { - fish.pick({ name: true }).parse({ name: '12' } as any) - fish.pick({ name: true }).parse({ name: 'bob', age: 12 } as any) - fish.pick({ age: true }).parse({ age: 12 } as any) + fish.pick({ name: true }).parse({ name: '12' }) + fish.pick({ name: true }).parse({ name: 'bob', age: 12 }) + fish.pick({ age: true }).parse({ age: 12 }) const nameonlyFish = fish.pick({ name: true }).strict() - const bad1 = () => nameonlyFish.parse({ name: 12 } as any) - const bad2 = () => nameonlyFish.parse({ name: 'bob', age: 12 } as any) - const bad3 = () => nameonlyFish.parse({ age: 12 } as any) + const bad1 = () => nameonlyFish.parse({ name: 12 }) + const bad2 = () => nameonlyFish.parse({ name: 'bob', age: 12 }) + const bad3 = () => nameonlyFish.parse({ age: 12 }) // @ts-expect-error checking runtime picks `name` only. const anotherNameonlyFish = fish.pick({ name: true, age: false }).strict() - const bad4 = () => anotherNameonlyFish.parse({ name: 'bob', age: 12 } as any) + const bad4 = () => anotherNameonlyFish.parse({ name: 'bob', age: 12 }) expect(bad1).toThrow() expect(bad2).toThrow() @@ -60,13 +60,13 @@ test('omit parse - success', () => { test('omit parse - fail', () => { const nonameFish = fish.omit({ name: true }) - const bad1 = () => nonameFish.parse({ name: 12 } as any) - const bad2 = () => nonameFish.parse({ age: 12 } as any) - const bad3 = () => nonameFish.parse({} as any) + const bad1 = () => nonameFish.parse({ name: 12 }) + const bad2 = () => nonameFish.parse({ age: 12 }) + const bad3 = () => nonameFish.parse({}) // @ts-expect-error checking runtime omits `name` only. const anotherNonameFish = fish.omit({ name: true, age: false }) - const bad4 = () => anotherNonameFish.parse({ nested: {} } as any) + const bad4 = () => anotherNonameFish.parse({ nested: {} }) expect(bad1).toThrow() expect(bad2).toThrow() @@ -88,6 +88,6 @@ test('nonstrict parsing - pass', () => { test('nonstrict parsing - fail', () => { const laxfish = fish.passthrough().pick({ name: true }) - const bad = () => laxfish.parse({ whatever: 'asdf' } as any) + const bad = () => laxfish.parse({ whatever: 'asdf' }) expect(bad).toThrow() }) diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 0dd8bff733d..a57d8ef863d 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -163,6 +163,7 @@ test('preprocess validates with sibling errors', () => { z.object({ // Must be first missing: z.string().refine(() => false), + // TODO(any): type properly preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)), }).parse({ preprocess: ' asdf' }) }).toThrow( diff --git a/packages/zui/src/z/__tests__/recursive.test.ts b/packages/zui/src/z/__tests__/recursive.test.ts index 3c61bf303cc..befcc3ca51c 100644 --- a/packages/zui/src/z/__tests__/recursive.test.ts +++ b/packages/zui/src/z/__tests__/recursive.test.ts @@ -78,120 +78,3 @@ test('recursion involving union type', () => { ) LinkedListSchema.parse(linkedListExample) }) - -// interface A { -// val: number; -// b: B; -// } - -// interface B { -// val: number; -// a: A; -// } - -// const A: z.ZodType = z.late.object(() => ({ -// val: z.number(), -// b: B, -// })); - -// const B: z.ZodType = z.late.object(() => ({ -// val: z.number(), -// a: A, -// })); - -// const Alazy: z.ZodType = z.lazy(() => z.object({ -// val: z.number(), -// b: B, -// })); - -// const Blazy: z.ZodType = z.lazy(() => z.object({ -// val: z.number(), -// a: A, -// })); - -// const a: any = { val: 1 }; -// const b: any = { val: 2 }; -// a.b = b; -// b.a = a; - -// test('valid check', () => { -// A.parse(a); -// B.parse(b); -// }); - -// test("valid check lazy", () => { -// A.parse({val:1, b:}); -// B.parse(b); -// }); - -// test('masking check', () => { -// const FragmentOnA = z -// .object({ -// val: z.number(), -// b: z -// .object({ -// val: z.number(), -// a: z -// .object({ -// val: z.number(), -// }) -// .nonstrict(), -// }) -// .nonstrict(), -// }) -// .nonstrict(); - -// const fragment = FragmentOnA.parse(a); -// fragment; -// }); - -// test('invalid check', () => { -// expect(() => A.parse({} as any)).toThrow(); -// }); - -// test('schema getter', () => { -// (A as z.ZodLazy).schema; -// }); - -// test("self recursion with cyclical data", () => { -// interface Category { -// name: string; -// subcategories: Category[]; -// } - -// const Category: z.ZodType = z.late.object(() => ({ -// name: z.string(), -// subcategories: z.array(Category), -// })); - -// const untypedCategory: any = { -// name: "Category A", -// }; -// // creating a cycle -// untypedCategory.subcategories = [untypedCategory]; -// Category.parse(untypedCategory); -// }); - -// test("self recursion with base type", () => { -// const BaseCategory = z.object({ -// name: z.string(), -// }); -// type BaseCategory = z.infer; - -// type Category = BaseCategory & { subcategories: Category[] }; - -// const Category: z.ZodType = z.late -// .object(() => ({ -// subcategories: z.array(Category), -// })) -// .extend({ -// name: z.string(), -// }); - -// const untypedCategory: any = { -// name: "Category A", -// }; -// // creating a cycle -// untypedCategory.subcategories = [untypedCategory]; -// Category.parse(untypedCategory); // parses successfully -// }); diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index 77e41d28b1a..7d9394a5e16 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -11,6 +11,7 @@ test('refinement', () => { const obj3 = obj2.refine((data) => data.first || data.second, 'Either first or second should be filled in.') + // TODO(any): type properly expect(obj1 === (obj2 as any)).toEqual(false) expect(obj2 === (obj3 as any)).toEqual(false) diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index 1aea3a14e5e..5135760737b 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -71,7 +71,7 @@ const _processCreateParams = ( description, supportsExtensions, [zuiKey]: zuiExtensions, - } = params as any + } = params if (errorMap && (invalid_type_error || required_error)) { throw new Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.') diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 17279ed2efd..7e8e8b213cd 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -460,9 +460,7 @@ export abstract class ZodBaseTypeImpl @@ -30,18 +37,18 @@ export class ZodPipelineImpl { const { status, ctx } = this._processInputParams(input) if (ctx.common.async) { - const handleAsync = async () => { - const inResult = await ZodBaseTypeImpl.fromInterface(this._def.in)._parseAsync({ + const handleAsync = async (): AsyncParseReturnType => { + const inResult = await this._def.in._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }) - if (inResult.status === 'aborted') return INVALID + if (inResult.status === 'aborted') return { status: 'aborted' } if (inResult.status === 'dirty') { status.dirty() - return DIRTY(inResult.value) + return { status: 'dirty', value: inResult.value } } else { - return ZodBaseTypeImpl.fromInterface(this._def.out)._parseAsync({ + return this._def.out._parseAsync({ data: inResult.value, path: ctx.path, parent: ctx, @@ -50,12 +57,12 @@ export class ZodPipelineImpl @@ -36,19 +36,20 @@ export class ZodPromiseImpl expected: 'promise', received: ctx.parsedType, }) - return INVALID + return { status: 'aborted' } } const promisified = ctx.parsedType === 'promise' ? ctx.data : Promise.resolve(ctx.data) - return OK( - promisified.then((data: any) => { + return { + status: 'valid', + value: promisified.then((data: any) => { return this._def.type.parseAsync(data, { path: ctx.path, errorMap: ctx.common.contextualErrorMap, }) - }) - ) + }), + } } isEqual(schema: IZodType): boolean { diff --git a/packages/zui/src/z/types/readonly/index.ts b/packages/zui/src/z/types/readonly/index.ts index aba699bd779..bc0a8e307e2 100644 --- a/packages/zui/src/z/types/readonly/index.ts +++ b/packages/zui/src/z/types/readonly/index.ts @@ -1,5 +1,5 @@ -import type { IZodReadonly, IZodType, MakeReadonly, ZodReadonlyDef } from '../../typings' -import { ZodBaseTypeImpl, isValid, ParseInput, ParseReturnType } from '../basetype' +import type { IZodReadonly, IZodType, MakeReadonly, ZodReadonlyDef, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl, isValid } from '../basetype' export class ZodReadonlyImpl extends ZodBaseTypeImpl, ZodReadonlyDef, MakeReadonly> @@ -24,7 +24,7 @@ export class ZodReadonlyImpl } _parse(input: ParseInput): ParseReturnType { - const result = ZodBaseTypeImpl.fromInterface(this._def.innerType)._parse(input) + const result = this._def.innerType._parse(input) if (isValid(result)) { result.value = Object.freeze(result.value) } diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index be0cecd2a3b..788e08ba3ff 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,15 +1,15 @@ import * as utils from '../../../utils' -import type { IZodRecord, IZodString, IZodType, KeySchema, RecordType, ZodRecordDef } from '../../typings' -import { - ParseInputLazyPath, - ZodBaseTypeImpl, - addIssueToContext, - INVALID, +import type { + IZodRecord, + IZodString, + IZodType, + KeySchema, + RecordType, + ZodRecordDef, ParseInput, ParseReturnType, - ParseStatus, - type MergeObjectPair, -} from '../basetype' +} from '../../typings' +import { ParseInputLazyPath, ZodBaseTypeImpl, addIssueToContext, ParseStatus, type MergeObjectPair } from '../basetype' export class ZodRecordImpl extends ZodBaseTypeImpl< @@ -56,7 +56,7 @@ export class ZodRecordImpl, ZodRefDef> addIssueToContext(ctx, { code: 'unresolved_reference', }) - return INVALID + return { status: 'aborted' } } public override isOptional(): boolean { diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 3fcb2511d3f..8f2f406f0f5 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -1,14 +1,6 @@ import * as utils from '../../../utils' -import type { IZodSet, IZodType, ZodSetDef } from '../../typings' -import { - ParseInputLazyPath, - ZodBaseTypeImpl, - addIssueToContext, - INVALID, - ParseInput, - ParseReturnType, - SyncParseReturnType, -} from '../basetype' +import type { IZodSet, IZodType, ZodSetDef, ParseInput, ParseReturnType, SyncParseReturnType } from '../../typings' +import { ParseInputLazyPath, ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodSetImpl extends ZodBaseTypeImpl, ZodSetDef, Set> @@ -40,7 +32,7 @@ export class ZodSetImpl expected: 'set', received: ctx.parsedType, }) - return INVALID + return { status: 'aborted' } } const def = this._def @@ -75,10 +67,10 @@ export class ZodSetImpl const valueType = this._def.valueType - function finalizeSet(elements: SyncParseReturnType[]) { + function finalizeSet(elements: SyncParseReturnType[]): SyncParseReturnType { const parsedSet = new Set() for (const element of elements) { - if (element.status === 'aborted') return INVALID + if (element.status === 'aborted') return { status: 'aborted' } if (element.status === 'dirty') status.dirty() parsedSet.add(element.value) } @@ -86,7 +78,7 @@ export class ZodSetImpl } const elements = [...(ctx.data as Set).values()].map((item, i) => - ZodBaseTypeImpl.fromInterface(valueType)._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) + valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) ) if (ctx.common.async) { diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 10a67d36e1f..6af984638c0 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,15 +1,7 @@ import * as utils from '../../../utils' import { zuiKey } from '../../consts' -import { type IZodString, ZodStringCheck, ZodStringDef } from '../../typings' -import { - ZodBaseTypeImpl, - addIssueToContext, - INVALID, - ParseContext, - ParseInput, - ParseReturnType, - ParseStatus, -} from '../basetype' +import { type IZodString, ZodStringCheck, ZodStringDef, ParseContext, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, ParseStatus } from '../basetype' export type { ZodStringCheck, ZodStringDef } export type IpVersion = NonNullable['version']> @@ -61,7 +53,7 @@ export class ZodStringImpl extends ZodBaseTypeImpl impleme } // ) - return INVALID + return { status: 'aborted' } } const status = new ParseStatus() diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index 7c658adf70a..f239552e17e 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,5 +1,5 @@ -import type { IZodSymbol, ZodSymbolDef } from '../../typings' -import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' +import type { IZodSymbol, ZodSymbolDef, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodSymbolImpl extends ZodBaseTypeImpl implements IZodSymbol { _parse(input: ParseInput): ParseReturnType { @@ -11,10 +11,10 @@ export class ZodSymbolImpl extends ZodBaseTypeImpl impleme expected: 'symbol', received: ctx.parsedType, }) - return INVALID + return { status: 'aborted' } } - return OK(input.data) + return { status: 'valid', value: input.data } } isEqual(schema: ZodBaseTypeImpl): boolean { diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 940d1474747..3eda16afbe5 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -1,7 +1,17 @@ import * as utils from '../../../utils' import { is } from '../../guards' -import type { IZodEffects, IZodType, ZodEffectsDef, input, output, RefinementCtx, IssueData } from '../../typings' -import { ZodBaseTypeImpl, addIssueToContext, DIRTY, INVALID, isValid, ParseInput, ParseReturnType } from '../basetype' +import type { + IZodEffects, + IZodType, + ZodEffectsDef, + input, + output, + RefinementCtx, + IssueData, + ParseInput, + ParseReturnType, +} from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext, isValid } from '../basetype' export class ZodEffectsImpl, Input = input> extends ZodBaseTypeImpl, Input> @@ -64,28 +74,28 @@ export class ZodEffectsImpl, I if (ctx.common.async) { return Promise.resolve(processed).then(async (processed) => { - if (status.value === 'aborted') return INVALID + if (status.value === 'aborted') return { status: 'aborted' } - const result = await ZodEffectsImpl.fromInterface(this._def.schema)._parseAsync({ + const result = await this._def.schema._parseAsync({ data: processed, path: ctx.path, parent: ctx, }) - if (result.status === 'aborted') return INVALID - if (result.status === 'dirty') return DIRTY(result.value) - if (status.value === 'dirty') return DIRTY(result.value) + if (result.status === 'aborted') return { status: 'aborted' } + if (result.status === 'dirty') return { status: 'dirty', value: result.value } + if (status.value === 'dirty') return { status: 'dirty', value: result.value } return result }) } else { - if (status.value === 'aborted') return INVALID - const result = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ + if (status.value === 'aborted') return { status: 'aborted' } + const result = this._def.schema._parseSync({ data: processed, path: ctx.path, parent: ctx, }) - if (result.status === 'aborted') return INVALID - if (result.status === 'dirty') return DIRTY(result.value) - if (status.value === 'dirty') return DIRTY(result.value) + if (result.status === 'aborted') return { status: 'aborted' } + if (result.status === 'dirty') return { status: 'dirty', value: result.value } + if (status.value === 'dirty') return { status: 'dirty', value: result.value } return result } } @@ -103,34 +113,32 @@ export class ZodEffectsImpl, I } if (ctx.common.async === false) { - const inner = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ + const inner = this._def.schema._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }) - if (inner.status === 'aborted') return INVALID + if (inner.status === 'aborted') return { status: 'aborted' } if (inner.status === 'dirty') status.dirty() // return value is ignored executeRefinement(inner.value) return { status: status.value, value: inner.value } } else { - return ZodEffectsImpl.fromInterface(this._def.schema) - ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) - .then((inner) => { - if (inner.status === 'aborted') return INVALID - if (inner.status === 'dirty') status.dirty() - - return executeRefinement(inner.value).then(() => { - return { status: status.value, value: inner.value } - }) + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => { + if (inner.status === 'aborted') return { status: 'aborted' } + if (inner.status === 'dirty') status.dirty() + + return executeRefinement(inner.value).then(() => { + return { status: status.value, value: inner.value } }) + }) } } if (effect.type === 'transform') { if (ctx.common.async === false) { - const base = ZodEffectsImpl.fromInterface(this._def.schema)._parseSync({ + const base = this._def.schema._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, @@ -147,16 +155,14 @@ export class ZodEffectsImpl, I return { status: status.value, value: result } } else { - return ZodEffectsImpl.fromInterface(this._def.schema) - ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) - .then((base) => { - if (!isValid(base)) return base - - return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ - status: status.value, - value: result, - })) - }) + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => { + if (!isValid(base)) return base + + return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ + status: status.value, + value: result, + })) + }) } } diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index 48b63177384..2829fa5b284 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -1,7 +1,6 @@ import { test, expect } from 'vitest' import * as z from '../../index' import * as assert from '../../../assertions.utils.test' -import { NEVER } from '..' const stringToNumber = z.string().transform((arg) => parseFloat(arg)) // const numberToString = z @@ -73,14 +72,14 @@ test('transform ctx.addIssue with parseAsync', async () => { }) }) -test('z.NEVER in transform', () => { +test('return invalid parse result in transform', () => { const foo = z .number() .optional() .transform((val, ctx) => { if (!val) { ctx.addIssue({ code: 'custom', message: 'bad' }) - return NEVER + return { status: 'aborted' } as never } return val }) diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 0a6ee38e1f0..299b72a3c37 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -5,17 +5,11 @@ import type { ZodTupleDef, OutputTypeOfTupleWithRest, InputTypeOfTupleWithRest, -} from '../../typings' -import { - ParseInputLazyPath, - addIssueToContext, - INVALID, ParseInput, ParseReturnType, - ParseStatus, SyncParseReturnType, - ZodBaseTypeImpl, -} from '../basetype' +} from '../../typings' +import { ParseInputLazyPath, addIssueToContext, ParseStatus, ZodBaseTypeImpl } from '../basetype' export class ZodTupleImpl< T extends [IZodType, ...IZodType[]] | [] = [IZodType, ...IZodType[]], @@ -59,7 +53,7 @@ export class ZodTupleImpl< expected: 'array', received: ctx.parsedType, }) - return INVALID + return { status: 'aborted' } } if (ctx.data.length < this._def.items.length) { @@ -71,7 +65,7 @@ export class ZodTupleImpl< type: 'array', }) - return INVALID + return { status: 'aborted' } } const rest = this._def.rest @@ -91,7 +85,7 @@ export class ZodTupleImpl< .map((item, itemIndex) => { const schema = this._def.items[itemIndex] || this._def.rest if (!schema) return null - return ZodBaseTypeImpl.fromInterface(schema)._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)) + return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)) }) .filter((x) => !!x) // filter nulls diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index ed22ac2915c..8adf7b2d751 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,6 +1,6 @@ import { builders } from '../../internal-builders' -import type { IZodNever, IZodUndefined, ZodUndefinedDef } from '../../typings' -import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' +import type { IZodNever, IZodUndefined, ZodUndefinedDef, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodUndefinedImpl extends ZodBaseTypeImpl implements IZodUndefined { _parse(input: ParseInput): ParseReturnType { @@ -12,9 +12,9 @@ export class ZodUndefinedImpl extends ZodBaseTypeImpl extends ZodBaseTypeImpl, T[number]['_input']> @@ -46,7 +50,9 @@ export class ZodUnionImpl const { ctx } = this._processInputParams(input) const options = this._def.options - function handleResults(results: { ctx: ParseContext; result: SyncParseReturnType }[]) { + function handleResults( + results: { ctx: ParseContext; result: SyncParseReturnType }[] + ): SyncParseReturnType { // return first issue-free validation if it exists for (const result of results) { if (result.result.status === 'valid') { @@ -69,7 +75,7 @@ export class ZodUnionImpl code: 'invalid_union', unionErrors, }) - return INVALID + return { status: 'aborted' } } if (ctx.common.async) { @@ -84,7 +90,7 @@ export class ZodUnionImpl parent: null, } return { - result: await ZodBaseTypeImpl.fromInterface(option)._parseAsync({ + result: await option._parseAsync({ data: ctx.data, path: ctx.path, parent: childCtx, @@ -94,7 +100,7 @@ export class ZodUnionImpl }) ).then(handleResults) } else { - let dirty: undefined | { result: DIRTY; ctx: ParseContext } = undefined + let dirty: undefined | { result: DirtyParseReturnType; ctx: ParseContext } = undefined const issues: ZodIssue[][] = [] for (const option of options) { const childCtx: ParseContext = { @@ -105,7 +111,7 @@ export class ZodUnionImpl }, parent: null, } - const result = ZodBaseTypeImpl.fromInterface(option)._parseSync({ + const result = option._parseSync({ data: ctx.data, path: ctx.path, parent: childCtx, @@ -133,7 +139,7 @@ export class ZodUnionImpl unionErrors, }) - return INVALID + return { status: 'aborted' } satisfies InvalidParseReturnType } } diff --git a/packages/zui/src/z/types/unknown/index.ts b/packages/zui/src/z/types/unknown/index.ts index 7784ee1c588..de300b43596 100644 --- a/packages/zui/src/z/types/unknown/index.ts +++ b/packages/zui/src/z/types/unknown/index.ts @@ -1,11 +1,11 @@ -import type { IZodUnknown, ZodUnknownDef } from '../../typings' -import { ZodBaseTypeImpl, OK, ParseInput, ParseReturnType } from '../basetype' +import type { IZodUnknown, ZodUnknownDef, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl } from '../basetype' export class ZodUnknownImpl extends ZodBaseTypeImpl implements IZodUnknown { // required _unknown = true as const _parse(input: ParseInput): ParseReturnType { - return OK(input.data) + return { status: 'valid', value: input.data } } isEqual(schema: ZodBaseTypeImpl): boolean { diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index 0b87294d5d3..8758bd6580e 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,5 +1,5 @@ -import type { IZodVoid, ZodVoidDef } from '../../typings' -import { ZodBaseTypeImpl, addIssueToContext, INVALID, OK, ParseInput, ParseReturnType } from '../basetype' +import type { IZodVoid, ZodVoidDef, ParseInput, ParseReturnType } from '../../typings' +import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodVoidImpl extends ZodBaseTypeImpl implements IZodVoid { _parse(input: ParseInput): ParseReturnType { @@ -11,9 +11,9 @@ export class ZodVoidImpl extends ZodBaseTypeImpl implements IZ expected: 'void', received: ctx.parsedType, }) - return INVALID + return { status: 'aborted' } } - return OK(input.data) + return { status: 'valid', value: input.data } } isEqual(schema: ZodBaseTypeImpl): boolean { diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 3abfa7905bb..7af8ddb47f2 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -302,6 +302,34 @@ export type ZodParsedType = | 'map' | 'set' +export type ParseContext = { + common: { + issues: ZodIssue[] + contextualErrorMap?: ZodErrorMap + async: boolean + } + schemaErrorMap?: ZodErrorMap + parsedType: ZodParsedType + + data: any + path: (string | number)[] + parent: ParseContext | null +} + +export type ParseInput = { + data: any + path: (string | number)[] + parent: ParseContext +} + +export type InvalidParseReturnType = { status: 'aborted' } +export type DirtyParseReturnType = { status: 'dirty'; value: T } +export type ValidParseReturnType = { status: 'valid'; value: T } + +export type SyncParseReturnType = ValidParseReturnType | DirtyParseReturnType | InvalidParseReturnType +export type AsyncParseReturnType = Promise> +export type ParseReturnType = SyncParseReturnType | AsyncParseReturnType + export type SafeParseSuccess = { success: true data: Output @@ -316,7 +344,7 @@ export type SafeParseError = { export type SafeParseReturnType = SafeParseSuccess | SafeParseError -type _ParseParams = { +export type ParseParams = { path: (string | number)[] errorMap: ZodErrorMap async: boolean @@ -376,6 +404,11 @@ export interface IZodType + _parseAsync(input: ParseInput): AsyncParseReturnType + _parseSync(input: ParseInput): SyncParseReturnType + description: string | undefined typeName: Def['typeName'] /** deeply replace all references in the schema */ @@ -383,12 +416,12 @@ export interface IZodType - parse(data: unknown, params?: Partial<_ParseParams>): Output - safeParse(data: unknown, params?: Partial<_ParseParams>): SafeParseReturnType - parseAsync(data: unknown, params?: Partial<_ParseParams>): Promise - safeParseAsync(data: unknown, params?: Partial<_ParseParams>): Promise> + parse(data: unknown, params?: Partial): Output + safeParse(data: unknown, params?: Partial): SafeParseReturnType + parseAsync(data: unknown, params?: Partial): Promise + safeParseAsync(data: unknown, params?: Partial): Promise> /** Alias of safeParseAsync */ - spa: (data: unknown, params?: Partial<_ParseParams>) => Promise> + spa: (data: unknown, params?: Partial) => Promise> refine( check: (arg: Output) => arg is RefinedOutput, message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) From 7683d5d3bcc41be5fb4f21fd3368d2221a998e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 9 Mar 2026 17:20:26 -0400 Subject: [PATCH 35/50] chore(zui): rm bunch of any types (#14997) --- .../src/transforms/zui-from-object/index.ts | 34 ++++++++--- .../zui-from-object/object-to-zui.test.ts | 4 +- .../zui-to-typescript-type/index.test.ts | 3 +- packages/zui/src/utils/ds-utils.ts | 2 +- packages/zui/src/utils/fn-utils.ts | 9 +-- .../zui/src/z/__tests__/preprocess.test.ts | 3 +- packages/zui/src/z/__tests__/refine.test.ts | 7 ++- packages/zui/src/z/builders.ts | 6 +- packages/zui/src/z/types/basetype/index.ts | 5 +- .../zui/src/z/types/basetype/parseUtil.ts | 33 +++++++---- packages/zui/src/z/types/branded/index.ts | 2 +- packages/zui/src/z/types/function/index.ts | 6 +- .../zui/src/z/types/intersection/index.ts | 8 ++- packages/zui/src/z/types/map/index.ts | 4 +- packages/zui/src/z/types/nan/index.ts | 2 +- packages/zui/src/z/types/nativeEnum/index.ts | 4 +- packages/zui/src/z/types/object/index.ts | 59 ++++++++++--------- packages/zui/src/z/types/pipeline/index.ts | 4 +- packages/zui/src/z/types/promise/index.ts | 2 +- packages/zui/src/z/types/record/index.ts | 7 +-- packages/zui/src/z/types/set/index.ts | 4 +- packages/zui/src/z/types/transformer/index.ts | 5 +- packages/zui/src/z/types/tuple/index.ts | 2 +- packages/zui/src/z/types/union/index.ts | 6 +- packages/zui/src/z/typings.ts | 24 ++++---- 25 files changed, 137 insertions(+), 108 deletions(-) diff --git a/packages/zui/src/transforms/zui-from-object/index.ts b/packages/zui/src/transforms/zui-from-object/index.ts index be546490335..861f5836c93 100644 --- a/packages/zui/src/transforms/zui-from-object/index.ts +++ b/packages/zui/src/transforms/zui-from-object/index.ts @@ -19,7 +19,7 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true throw new errors.ObjectToZuiError('Input must be an object') } - const applyOptions = (zodType: any) => { + const applyOptions = (zodType: z.ZodType) => { let newType = zodType if (opts?.nullable) { newType = newType.nullable() @@ -27,13 +27,13 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true if (opts?.optional) { newType = newType.optional() } - if (opts?.passtrough && typeof newType.passthrough === 'function') { + if (opts?.passtrough && z.is.zuiObject(newType)) { newType = newType.passthrough() } return newType } - const schema = Object.entries(obj).reduce((acc: any, [key, value]) => { + const schema: z.ZodRawShape = Object.entries(obj).reduce((acc: z.ZodRawShape, [key, value]: [string, unknown]) => { if (value === null) { acc[key] = applyOptions(z.null()) } else { @@ -49,12 +49,14 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true break case 'object': if (Array.isArray(value)) { - if (value.length === 0) { + const [first] = value as unknown[] + if (first === undefined || first === null) { acc[key] = applyOptions(z.array(z.unknown())) - } else if (typeof value[0] === 'object') { - acc[key] = applyOptions(z.array(fromObject(value[0], opts, false))) - } else if (['string', 'number', 'boolean'].includes(typeof value[0])) { - acc[key] = applyOptions(z.array((z as any)[typeof value[0] as any]())) + } else if (typeof first === 'object') { + acc[key] = applyOptions(z.array(fromObject(first, opts, false))) + } else if (typeof first === 'string' || typeof first === 'number' || typeof first === 'boolean') { + const inner = _getInnerType(first) + acc[key] = applyOptions(z.array(inner)) } } else { acc[key] = applyOptions(fromObject(value, opts, false)) @@ -65,7 +67,7 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true } } return acc - }, {} as z.ZodObject) + }, {} as z.ZodRawShape) const hasProperties = Object.keys(schema).length > 0 if (opts?.passtrough || (!isRoot && !hasProperties)) { @@ -74,3 +76,17 @@ export const fromObject = (obj: object, opts?: ObjectToZuiOptions, isRoot = true return z.object(schema) } + +const _getInnerType = (first: string | number | boolean): z.ZodType => { + if (typeof first === 'string') { + return z.string() + } + if (typeof first === 'number') { + return z.number() + } + if (typeof first === 'boolean') { + return z.boolean() + } + first satisfies never + return z.unknown() +} diff --git a/packages/zui/src/transforms/zui-from-object/object-to-zui.test.ts b/packages/zui/src/transforms/zui-from-object/object-to-zui.test.ts index d3f5f97ce79..03bac6309fd 100644 --- a/packages/zui/src/transforms/zui-from-object/object-to-zui.test.ts +++ b/packages/zui/src/transforms/zui-from-object/object-to-zui.test.ts @@ -151,10 +151,10 @@ describe('object-to-zui', () => { } expect(Array.isArray(tagsSchema?.items)).toBe(false) expect(tagsSchema?.type).toBe('array') - expect((tagsSchema?.items as any)?.type).toBe('string') + expect((tagsSchema?.items as JSONSchema7)?.type).toBe('string') expect(scoresSchema?.type).toBe('array') expect(Array.isArray(scoresSchema?.items)).toBe(false) - expect((scoresSchema?.items as any)?.type).toBe('number') + expect((scoresSchema?.items as JSONSchema7)?.type).toBe('number') }) test('should handle empty objects correctly', () => { diff --git a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts index a4e8c08d052..37b26a94b23 100644 --- a/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts +++ b/packages/zui/src/transforms/zui-to-typescript-type/index.test.ts @@ -820,11 +820,12 @@ describe.concurrent('objects', () => { }) it('double optional', async () => { + const false_: boolean = false const obj = z .object({ Date: z.optional(z.string().optional().optional()), }) - .required({ Date: false } as any) // TODO(any): type properly + .required({ Date: false_ as true }) const typings = toTypescript(obj) await assert.expectTypescript(typings).toMatchWithoutFormatting(`declare const x: { Date?: string }`) diff --git a/packages/zui/src/utils/ds-utils.ts b/packages/zui/src/utils/ds-utils.ts index 040e72541e0..e3ed8edf347 100644 --- a/packages/zui/src/utils/ds-utils.ts +++ b/packages/zui/src/utils/ds-utils.ts @@ -4,7 +4,7 @@ export type CustomSetOptions = { compare: (a: T, b: T) => boolean } -const DEFAULT_OPTIONS: CustomSetOptions = { +const DEFAULT_OPTIONS: CustomSetOptions = { compare: isEqual, } diff --git a/packages/zui/src/utils/fn-utils.ts b/packages/zui/src/utils/fn-utils.ts index e0fb7b8a299..c1c8d28ff3f 100644 --- a/packages/zui/src/utils/fn-utils.ts +++ b/packages/zui/src/utils/fn-utils.ts @@ -14,14 +14,15 @@ export const isEqual = (a: unknown, b: unknown): boolean => { return _isEqualWithVisitedTracking(a, b, new WeakSet()) } -// TODO(any): type properly -const _isEqualWithVisitedTracking = (a: unknown, b: unknown, visited: WeakSet): boolean => +const _isPlainObject = (x: unknown): x is object => lodash.isPlainObject(x) + +const _isEqualWithVisitedTracking = (a: unknown, b: unknown, visited: WeakSet): boolean => lodash.isEqualWith(a, b, _customizerWithVisitedTracking(visited)) const _customizerWithVisitedTracking = - (visited: WeakSet): IsEqualCustomizer => + (visited: WeakSet): IsEqualCustomizer => (a, b) => { - if (lodash.isPlainObject(a) && !visited.has(a) && lodash.isPlainObject(b) && !visited.has(b)) { + if (_isPlainObject(a) && !visited.has(a) && _isPlainObject(b) && !visited.has(b)) { const cleanedA = lodash.omitBy(a as object, lodash.isUndefined) const cleanedB = lodash.omitBy(b as object, lodash.isUndefined) diff --git a/packages/zui/src/z/__tests__/preprocess.test.ts b/packages/zui/src/z/__tests__/preprocess.test.ts index 0bf1c380a56..8909216398b 100644 --- a/packages/zui/src/z/__tests__/preprocess.test.ts +++ b/packages/zui/src/z/__tests__/preprocess.test.ts @@ -162,8 +162,7 @@ test('preprocess validates with sibling errors', () => { z.object({ // Must be first missing: z.string().refine(() => false), - // TODO(any): type properly - preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)), + preprocess: z.preprocess((data) => (data as string)?.trim(), z.string().regex(/ asdf/)), }).parse({ preprocess: ' asdf' }) }).toThrow( JSON.stringify( diff --git a/packages/zui/src/z/__tests__/refine.test.ts b/packages/zui/src/z/__tests__/refine.test.ts index 7d9394a5e16..37578414180 100644 --- a/packages/zui/src/z/__tests__/refine.test.ts +++ b/packages/zui/src/z/__tests__/refine.test.ts @@ -2,6 +2,8 @@ import { test, expect } from 'vitest' import * as assert from '../../assertions.utils.test' import * as z from '../index' +const _strictEqual = (a: unknown, b: unknown) => a === b + test('refinement', () => { const obj1 = z.object({ first: z.string(), @@ -11,9 +13,8 @@ test('refinement', () => { const obj3 = obj2.refine((data) => data.first || data.second, 'Either first or second should be filled in.') - // TODO(any): type properly - expect(obj1 === (obj2 as any)).toEqual(false) - expect(obj2 === (obj3 as any)).toEqual(false) + expect(_strictEqual(obj1, obj2)).toEqual(false) + expect(_strictEqual(obj2, obj3)).toEqual(false) expect(() => obj1.parse({})).toThrow() expect(() => obj2.parse({ third: 'adsf' })).toThrow() diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index 5135760737b..a8701cd2f9f 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -247,15 +247,15 @@ export const recordType: ZodBuilders['record'] = ( ): IZodRecord => { if (second instanceof ZodBaseTypeImpl) { return new ZodRecordImpl({ - keyType: first, - valueType: second, + keyType: first as KeySchema, + valueType: second as IZodType, typeName: 'ZodRecord', ..._processCreateParams(third), }) } return new ZodRecordImpl({ keyType: stringType(), - valueType: first, + valueType: first as IZodType, typeName: 'ZodRecord', ..._processCreateParams(second), }) diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 107175832c1..961fdba4a0a 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -356,7 +356,7 @@ export abstract class ZodBaseTypeImpl): IZodDefault default(def: () => utils.types.NoUndefined): IZodDefault - default(def: any) { + default(def: utils.types.NoUndefined | (() => utils.types.NoUndefined)) { const defaultValueFunc = typeof def === 'function' ? def : () => def return builders.default(this, defaultValueFunc) } @@ -525,7 +525,7 @@ export abstract class ZodBaseTypeImpl( + private _handleResult = ( ctx: ParseContext, result: SyncParseReturnType ): { success: true; data: Output } | { success: false; error: ZodError } => { @@ -539,6 +539,7 @@ export abstract class ZodBaseTypeImpl - value: SyncParseReturnType + key: SyncParseReturnType + value: SyncParseReturnType alwaysSet?: boolean } @@ -68,8 +68,8 @@ export function addIssueToContext(ctx: ParseContext, issueData: IssueData): void } export type ObjectPair = { - key: SyncParseReturnType - value: SyncParseReturnType + key: SyncParseReturnType + value: SyncParseReturnType } export class ParseStatus { value: 'aborted' | 'dirty' | 'valid' = 'valid' @@ -80,7 +80,7 @@ export class ParseStatus { if (this.value !== 'aborted') this.value = 'aborted' } - static mergeArray(status: ParseStatus, results: SyncParseReturnType[]): SyncParseReturnType { + static mergeArray(status: ParseStatus, results: SyncParseReturnType[]): SyncParseReturnType { const arrayValue: any[] = [] for (const s of results) { if (s.status === 'aborted') return { status: 'aborted' } @@ -93,8 +93,8 @@ export class ParseStatus { static async mergeObjectAsync( status: ParseStatus, - pairs: { key: ParseReturnType; value: ParseReturnType }[] - ): Promise> { + pairs: { key: ParseReturnType; value: ParseReturnType }[] + ): Promise { const syncPairs: ObjectPair[] = [] for (const pair of pairs) { syncPairs.push({ @@ -123,7 +123,7 @@ export class ParseStatus { } } -export const isAborted = (x: ParseReturnType): x is InvalidParseReturnType => +export const isAborted = (x: ParseReturnType): x is InvalidParseReturnType => (x as SyncParseReturnType).status === 'aborted' export const isDirty = (x: ParseReturnType): x is ValidParseReturnType | DirtyParseReturnType => (x as SyncParseReturnType).status === 'dirty' @@ -132,10 +132,8 @@ export const isValid = (x: ParseReturnType): x is ValidParseReturnType export const isAsync = (x: ParseReturnType): x is AsyncParseReturnType => typeof Promise !== 'undefined' && x instanceof Promise -export const getParsedType = (data: any): ZodParsedType => { - const t = typeof data - - switch (t) { +export const getParsedType = (data: unknown): ZodParsedType => { + switch (typeof data) { case 'undefined': return 'undefined' @@ -164,7 +162,16 @@ export const getParsedType = (data: any): ZodParsedType => { if (data === null) { return 'null' } - if (data.then && typeof data.then === 'function' && data.catch && typeof data.catch === 'function') { + if (typeof Promise !== 'undefined' && data instanceof Promise) { + return 'promise' + } + if ( + // for fake promises + (data as Promise).then && + typeof (data as Promise).then === 'function' && + (data as Promise).catch && + typeof (data as Promise).catch === 'function' + ) { return 'promise' } if (typeof Map !== 'undefined' && data instanceof Map) { diff --git a/packages/zui/src/z/types/branded/index.ts b/packages/zui/src/z/types/branded/index.ts index 4f3a0751263..c998d0e8aca 100644 --- a/packages/zui/src/z/types/branded/index.ts +++ b/packages/zui/src/z/types/branded/index.ts @@ -25,7 +25,7 @@ export class ZodBrandedImpl }) } - _parse(input: ParseInput): ParseReturnType { + _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) const data = ctx.data return this._def.type._parse({ diff --git a/packages/zui/src/z/types/function/index.ts b/packages/zui/src/z/types/function/index.ts index eda21eb6b49..106b0452e1a 100644 --- a/packages/zui/src/z/types/function/index.ts +++ b/packages/zui/src/z/types/function/index.ts @@ -48,7 +48,7 @@ export class ZodFunctionImpl = IZodTuple, Retur }) } - _parse(input: ParseInput): ParseReturnType { + _parse(input: ParseInput): ParseReturnType { const { ctx } = this._processInputParams(input) if (ctx.parsedType !== 'function') { addIssueToContext(ctx, { @@ -59,7 +59,7 @@ export class ZodFunctionImpl = IZodTuple, Retur return { status: 'aborted' } } - function makeArgsIssue(args: any, error: ZodError): ZodIssue { + function makeArgsIssue(args: unknown, error: ZodError): ZodIssue { return makeIssue({ data: args, path: ctx.path, @@ -73,7 +73,7 @@ export class ZodFunctionImpl = IZodTuple, Retur }) } - function makeReturnsIssue(returns: any, error: ZodError): ZodIssue { + function makeReturnsIssue(returns: unknown, error: ZodError): ZodIssue { return makeIssue({ data: returns, path: ctx.path, diff --git a/packages/zui/src/z/types/intersection/index.ts b/packages/zui/src/z/types/intersection/index.ts index 361455cc881..192d0a82a02 100644 --- a/packages/zui/src/z/types/intersection/index.ts +++ b/packages/zui/src/z/types/intersection/index.ts @@ -99,8 +99,10 @@ export class ZodIntersectionImpl bKeys.indexOf(key) !== -1) - const newObj: any = { ...a, ...b } + const newObj: T['_output'] & U['_output'] = { ...a, ...b } for (const key of sharedKeys) { const sharedValue = this._mergeValues(a[key], b[key]) if (!sharedValue.valid) { diff --git a/packages/zui/src/z/types/map/index.ts b/packages/zui/src/z/types/map/index.ts index edc5b1f02a7..6406b3bd537 100644 --- a/packages/zui/src/z/types/map/index.ts +++ b/packages/zui/src/z/types/map/index.ts @@ -80,8 +80,8 @@ export class ZodMapImpl - const value = pair.value as SyncParseReturnType + const key = pair.key as SyncParseReturnType + const value = pair.value as SyncParseReturnType if (key.status === 'aborted' || value.status === 'aborted') { return { status: 'aborted' } } diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index af46305d080..87f0b1d2d1a 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -2,7 +2,7 @@ import type { IZodNaN, ZodNaNDef, ParseInput, ParseReturnType } from '../../typi import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodNaNImpl extends ZodBaseTypeImpl implements IZodNaN { - _parse(input: ParseInput): ParseReturnType { + _parse(input: ParseInput): ParseReturnType { const parsedType = this._getType(input) if (parsedType !== 'nan') { const ctx = this._getOrReturnCtx(input) diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index b91a343d2c1..39c20b10f58 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -22,7 +22,7 @@ export class ZodNativeEnumImpl } if (nativeEnumValues.indexOf(input.data) === -1) { - const expectedValues: any[] = Object.values(nativeEnumValues) + const expectedValues: (string | number)[] = Object.values(nativeEnumValues) addIssueToContext(ctx, { received: ctx.data, @@ -44,7 +44,7 @@ export class ZodNativeEnumImpl } private _getValidEnumValues = (obj: EnumLike) => { - const validKeys = Object.keys(obj).filter((k: any) => typeof obj[obj[k]!] !== 'number') + const validKeys = Object.keys(obj).filter((k) => typeof obj[obj[k]!] !== 'number') const filtered: EnumLike = {} for (const k of validKeys) { filtered[k] = obj[k]! diff --git a/packages/zui/src/z/types/object/index.ts b/packages/zui/src/z/types/object/index.ts index 81372cbdb65..daf6e832d91 100644 --- a/packages/zui/src/z/types/object/index.ts +++ b/packages/zui/src/z/types/object/index.ts @@ -16,6 +16,7 @@ import type { IZodEnum, ParseInput, ParseReturnType, + SyncParseReturnType, } from '../../typings' import { addIssueToContext, ParseStatus, ParseInputLazyPath, ZodBaseTypeImpl, type MergeObjectPair } from '../basetype' @@ -100,8 +101,8 @@ export class ZodObjectImpl< } const pairs: { - key: ParseReturnType - value: ParseReturnType + key: ParseReturnType + value: ParseReturnType alwaysSet?: boolean }[] = [] for (const key of shapeKeys) { @@ -148,7 +149,11 @@ export class ZodObjectImpl< if (ctx.common.async) { return Promise.resolve() .then(async () => { - const syncPairs: any[] = [] + const syncPairs: { + key: SyncParseReturnType + value: SyncParseReturnType + alwaysSet?: boolean + }[] = [] for (const pair of pairs) { const key = await pair.key syncPairs.push({ @@ -304,16 +309,16 @@ export class ZodObjectImpl< merge, Augmentation extends Incoming['shape']>( merging: Incoming ): IZodObject, Incoming['_def']['unknownKeys']> { - // TODO(any): type properly - const merged: any = new ZodObjectImpl({ - unknownKeys: merging._def.unknownKeys, - shape: () => ({ - ...this._def.shape(), - ...merging._def.shape(), - }), + const merged = new ZodObjectImpl({ + unknownKeys: merging._def.unknownKeys as Incoming['_def']['unknownKeys'], + shape: () => + ({ + ...this._def.shape(), + ...merging._def.shape(), + }) as utils.types.ExtendShape, typeName: 'ZodObject', }) - return merged + return merged as IZodObject, Incoming['_def']['unknownKeys']> } setKey( @@ -325,8 +330,7 @@ export class ZodObjectImpl< }, UnknownKeys > { - // TODO(any): type properly - return this.augment({ [key]: schema }) as unknown as IZodObject< + return this.augment({ [key]: schema }) as IZodObject< T & { [k in Key]: Schema }, @@ -346,8 +350,7 @@ export class ZodObjectImpl< [k in keyof T]?: true }, >(mask: Mask): IZodObject>, UnknownKeys> { - // TODO(any): type properly - const shape: any = {} + const shape: Record = {} Object.keys(mask).forEach((key) => { if (mask[key] && this.shape[key]) { @@ -368,12 +371,11 @@ export class ZodObjectImpl< [k in keyof T]?: true }, >(mask: Mask): IZodObject, UnknownKeys> { - // TODO(any): type properly - const shape: any = {} + const shape: Record = {} - Object.keys(this.shape).forEach((key) => { + Object.entries(this.shape).forEach(([key, value]) => { if (!mask[key]) { - shape[key] = this.shape[key] + shape[key] = value } }) @@ -403,7 +405,9 @@ export class ZodObjectImpl< }>, UnknownKeys > - partial(mask?: any): IZodObject { + partial(mask?: { + [k in keyof T]?: true + }): IZodObject, UnknownKeys> { const newShape: Record = {} Object.keys(this.shape).forEach((key) => { @@ -442,15 +446,16 @@ export class ZodObjectImpl< }>, UnknownKeys > - required(mask?: any): IZodObject { - // TODO(any): type properly - const newShape: any = {} + required(mask?: { + [k in keyof T]?: true + }): IZodObject { + const newShape: Record = {} - Object.keys(this.shape).forEach((key) => { + Object.entries(this.shape).forEach(([key, value]) => { if (mask && !mask[key]) { - newShape[key] = this.shape[key] + newShape[key] = value } else { - const fieldSchema = this.shape[key] + const fieldSchema = value let newField = fieldSchema! while (is.zuiOptional(newField)) { @@ -464,7 +469,7 @@ export class ZodObjectImpl< return new ZodObjectImpl({ ...this._def, shape: () => newShape, - }) + }) as IZodObject } keyof(): IZodEnum> { diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index 800592a73cf..ce4f5a661ff 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -34,10 +34,10 @@ export class ZodPipelineImpl { + _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) if (ctx.common.async) { - const handleAsync = async (): AsyncParseReturnType => { + const handleAsync = async (): AsyncParseReturnType => { const inResult = await this._def.in._parseAsync({ data: ctx.data, path: ctx.path, diff --git a/packages/zui/src/z/types/promise/index.ts b/packages/zui/src/z/types/promise/index.ts index c6a89c840e0..256a2843283 100644 --- a/packages/zui/src/z/types/promise/index.ts +++ b/packages/zui/src/z/types/promise/index.ts @@ -43,7 +43,7 @@ export class ZodPromiseImpl return { status: 'valid', - value: promisified.then((data: any) => { + value: promisified.then((data: unknown) => { return this._def.type.parseAsync(data, { path: ctx.path, errorMap: ctx.common.contextualErrorMap, diff --git a/packages/zui/src/z/types/record/index.ts b/packages/zui/src/z/types/record/index.ts index 788e08ba3ff..81523f1c20c 100644 --- a/packages/zui/src/z/types/record/index.ts +++ b/packages/zui/src/z/types/record/index.ts @@ -1,7 +1,6 @@ import * as utils from '../../../utils' import type { IZodRecord, - IZodString, IZodType, KeySchema, RecordType, @@ -11,7 +10,7 @@ import type { } from '../../typings' import { ParseInputLazyPath, ZodBaseTypeImpl, addIssueToContext, ParseStatus, type MergeObjectPair } from '../basetype' -export class ZodRecordImpl +export class ZodRecordImpl extends ZodBaseTypeImpl< RecordType, ZodRecordDef, @@ -60,8 +59,8 @@ export class ZodRecordImpl - value: ParseReturnType + key: ParseReturnType + value: ParseReturnType }[] = [] const keyType = this._def.keyType diff --git a/packages/zui/src/z/types/set/index.ts b/packages/zui/src/z/types/set/index.ts index 8f2f406f0f5..25e1841a45c 100644 --- a/packages/zui/src/z/types/set/index.ts +++ b/packages/zui/src/z/types/set/index.ts @@ -67,7 +67,7 @@ export class ZodSetImpl const valueType = this._def.valueType - function finalizeSet(elements: SyncParseReturnType[]): SyncParseReturnType { + function finalizeSet(elements: SyncParseReturnType[]): SyncParseReturnType { const parsedSet = new Set() for (const element of elements) { if (element.status === 'aborted') return { status: 'aborted' } @@ -84,7 +84,7 @@ export class ZodSetImpl if (ctx.common.async) { return Promise.all(elements).then((elements) => finalizeSet(elements)) } else { - return finalizeSet(elements as SyncParseReturnType[]) + return finalizeSet(elements as SyncParseReturnType[]) } } diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 3eda16afbe5..ca6ec018ca4 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -100,8 +100,7 @@ export class ZodEffectsImpl, I } } if (effect.type === 'refinement') { - // TODO(any): type properly - const executeRefinement = (acc: unknown): any => { + const executeRefinement = (acc: unknown): unknown => { const result = effect.refinement(acc, checkCtx) if (ctx.common.async) { return Promise.resolve(result) @@ -129,7 +128,7 @@ export class ZodEffectsImpl, I if (inner.status === 'aborted') return { status: 'aborted' } if (inner.status === 'dirty') status.dirty() - return executeRefinement(inner.value).then(() => { + return (executeRefinement(inner.value) as Promise).then(() => { return { status: status.value, value: inner.value } }) }) diff --git a/packages/zui/src/z/types/tuple/index.ts b/packages/zui/src/z/types/tuple/index.ts index 299b72a3c37..43097813c2a 100644 --- a/packages/zui/src/z/types/tuple/index.ts +++ b/packages/zui/src/z/types/tuple/index.ts @@ -94,7 +94,7 @@ export class ZodTupleImpl< return ParseStatus.mergeArray(status, results) }) } else { - return ParseStatus.mergeArray(status, items as SyncParseReturnType[]) + return ParseStatus.mergeArray(status, items as SyncParseReturnType[]) } } diff --git a/packages/zui/src/z/types/union/index.ts b/packages/zui/src/z/types/union/index.ts index 36b1820a278..0cf03145614 100644 --- a/packages/zui/src/z/types/union/index.ts +++ b/packages/zui/src/z/types/union/index.ts @@ -50,9 +50,7 @@ export class ZodUnionImpl const { ctx } = this._processInputParams(input) const options = this._def.options - function handleResults( - results: { ctx: ParseContext; result: SyncParseReturnType }[] - ): SyncParseReturnType { + function handleResults(results: { ctx: ParseContext; result: SyncParseReturnType }[]): SyncParseReturnType { // return first issue-free validation if it exists for (const result of results) { if (result.result.status === 'valid') { @@ -100,7 +98,7 @@ export class ZodUnionImpl }) ).then(handleResults) } else { - let dirty: undefined | { result: DirtyParseReturnType; ctx: ParseContext } = undefined + let dirty: undefined | { result: DirtyParseReturnType; ctx: ParseContext } = undefined const issues: ZodIssue[][] = [] for (const option of options) { const childCtx: ParseContext = { diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index 7af8ddb47f2..d67521a013f 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -26,7 +26,7 @@ export type ZuiMetadata = export type ZuiExtensionObject = { tooltip?: boolean - displayAs?: [string, any] + displayAs?: [string, ZuiMetadata] title?: string disabled?: boolean | string hidden?: boolean | string @@ -198,7 +198,7 @@ export type ZodUnresolvedReferenceIssue = { export type ZodCustomIssue = { code: 'custom' params?: { - [k: string]: any + [k: string]: unknown } } & _ZodIssueBase @@ -247,7 +247,7 @@ export type ZodFormattedError = { } & _RecursiveZodFormattedError> /* oxlint-disable typescript-eslint(consistent-type-definitions) */ -export interface IZodError extends Error { +export interface IZodError extends Error { readonly __type__: 'ZuiError' issues: ZodIssue[] errors: ZodIssue[] @@ -323,12 +323,12 @@ export type ParseInput = { } export type InvalidParseReturnType = { status: 'aborted' } -export type DirtyParseReturnType = { status: 'dirty'; value: T } -export type ValidParseReturnType = { status: 'valid'; value: T } +export type DirtyParseReturnType = { status: 'dirty'; value: T } +export type ValidParseReturnType = { status: 'valid'; value: T } export type SyncParseReturnType = ValidParseReturnType | DirtyParseReturnType | InvalidParseReturnType -export type AsyncParseReturnType = Promise> -export type ParseReturnType = SyncParseReturnType | AsyncParseReturnType +export type AsyncParseReturnType = Promise> +export type ParseReturnType = SyncParseReturnType | AsyncParseReturnType export type SafeParseSuccess = { success: true @@ -1323,7 +1323,7 @@ export interface IZodPromise //* ─────────────────────────── ZodReadonly ─────────────────────────────────── -export type BuiltIn = +type _BuiltIn = | (((...args: any[]) => any) | (new (...args: any[]) => any)) | { readonly [Symbol.toStringTag]: string @@ -1343,7 +1343,7 @@ export type MakeReadonly = ? readonly [Head, ...Tail] : T extends Array ? ReadonlyArray - : T extends BuiltIn + : T extends _BuiltIn ? T : Readonly @@ -1524,7 +1524,7 @@ export type ZodRecordDef +export type KeySchema = IZodType export type RecordType = [string] extends [K] ? Record : [number] extends [K] @@ -1536,7 +1536,7 @@ export type RecordType = [string] extends : Partial> /* oxlint-disable typescript-eslint(consistent-type-definitions) */ -export interface IZodRecord +export interface IZodRecord extends IZodType< RecordType, ZodRecordDef, @@ -1795,7 +1795,7 @@ export declare function createRecord( first: KeySchema | IZodType, second?: ZodCreateParams | IZodType, third?: ZodCreateParams -): IZodRecord +): IZodRecord export declare function createMap( keyType: Key, valueType: Value, From 907d6cd44d4027db5dd2aa2eb27a206033521c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 9 Mar 2026 18:11:17 -0400 Subject: [PATCH 36/50] chore(zui): rm weird null fallback --- packages/zui/src/z/types/transformer/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index ca6ec018ca4..981f10a91f3 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -51,7 +51,7 @@ export class ZodEffectsImpl, I _parse(input: ParseInput): ParseReturnType { const { status, ctx } = this._processInputParams(input) - const effect = this._def.effect || null + const effect = this._def.effect const checkCtx: RefinementCtx = { addIssue: (arg: IssueData) => { From 70cc4635e5de6ecc608d91c9e59428a2b6f1d68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Tue, 10 Mar 2026 11:43:12 -0400 Subject: [PATCH 37/50] feat(zui): zod effects have distinct builders and are fully typed (#14998) --- packages/zui/src/z/__tests__/deref.test.ts | 10 +--- packages/zui/src/z/builders.ts | 36 ++++++++++--- packages/zui/src/z/index.ts | 8 +-- packages/zui/src/z/types/basetype/index.ts | 7 +-- packages/zui/src/z/types/bigint/index.ts | 12 ++++- packages/zui/src/z/types/boolean/index.ts | 4 +- packages/zui/src/z/types/date/index.ts | 12 ++++- packages/zui/src/z/types/enum/index.ts | 3 +- packages/zui/src/z/types/literal/index.ts | 4 +- packages/zui/src/z/types/nan/index.ts | 4 +- packages/zui/src/z/types/nativeEnum/index.ts | 4 +- packages/zui/src/z/types/never/index.ts | 4 +- packages/zui/src/z/types/null/index.ts | 4 +- packages/zui/src/z/types/number/index.ts | 12 ++++- packages/zui/src/z/types/pipeline/index.ts | 2 +- packages/zui/src/z/types/ref/index.ts | 2 +- packages/zui/src/z/types/string/index.ts | 12 ++++- packages/zui/src/z/types/symbol/index.ts | 4 +- packages/zui/src/z/types/transformer/index.ts | 16 +++--- .../z/types/transformer/transformer.test.ts | 2 + packages/zui/src/z/types/undefined/index.ts | 4 +- packages/zui/src/z/types/unknown/index.ts | 4 +- packages/zui/src/z/types/void/index.ts | 4 +- packages/zui/src/z/typings.ts | 51 ++++++++++++------- 24 files changed, 143 insertions(+), 82 deletions(-) diff --git a/packages/zui/src/z/__tests__/deref.test.ts b/packages/zui/src/z/__tests__/deref.test.ts index 080dee56d2b..2740c3ffbbe 100644 --- a/packages/zui/src/z/__tests__/deref.test.ts +++ b/packages/zui/src/z/__tests__/deref.test.ts @@ -100,10 +100,7 @@ describe('dereference', () => { expect(result.success).toBe(true) }) test('transformer', () => { - const refSchema = z.transformer(foo, { - type: 'transform', - transform: (data) => data, - }) + const refSchema = z.transformer(foo, (data) => data) const derefSchema = refSchema.dereference(deref) const result = derefSchema.safeParse('astring') expect(result.success).toBe(true) @@ -205,10 +202,7 @@ describe('getReferences', () => { expect(refs).toEqual(['foo']) }) test('transformer', () => { - const refSchema = z.transformer(foo, { - type: 'transform', - transform: (data) => data, - }) + const refSchema = z.transformer(foo, (data) => data) const refs = refSchema.getReferences() expect(refs).toEqual(['foo']) }) diff --git a/packages/zui/src/z/builders.ts b/packages/zui/src/z/builders.ts index a8701cd2f9f..ea5811f0676 100644 --- a/packages/zui/src/z/builders.ts +++ b/packages/zui/src/z/builders.ts @@ -51,6 +51,9 @@ import type { ZodErrorMap, ZuiExtensionObject, ZodBuilders, + RefinementCtx, + IZodEffects, + output, } from './typings' type _ProcessedCreateParams = { @@ -286,13 +289,34 @@ export const functionType: ZodBuilders['function'] = ( }) } -export const effectsType: ZodBuilders['effects'] = (schema, effect, params) => - new ZodEffectsImpl({ schema, typeName: 'ZodEffects', effect, ..._processCreateParams(params) }) - export const preprocessType: ZodBuilders['preprocess'] = (preprocess, schema, params) => new ZodEffectsImpl({ schema, - effect: { type: 'preprocess', transform: preprocess }, + effect: { type: 'preprocess', preprocess }, + typeName: 'ZodEffects', + ..._processCreateParams(params), + }) + +export const refineType: ZodBuilders['refine'] = ( + schema: T, + refinement: (arg: T['_output'], ctx: RefinementCtx) => unknown, + params?: ZodCreateParams +): IZodEffects => + new ZodEffectsImpl({ + schema, + effect: { type: 'refinement', refinement }, + typeName: 'ZodEffects', + ..._processCreateParams(params), + }) + +export const transformType: ZodBuilders['transformer'] = ( + schema: T, + transform: (arg: output, ctx: RefinementCtx) => O | Promise, + params?: ZodCreateParams +): IZodEffects => + new ZodEffectsImpl({ + schema, + effect: { type: 'transform', transform }, typeName: 'ZodEffects', ..._processCreateParams(params), }) @@ -343,7 +367,6 @@ setBuilders({ date: dateType, default: defaultType, discriminatedUnion: discriminatedUnionType, - effects: effectsType, enum: enumType, function: functionType, instanceof: instanceOfType, @@ -364,12 +387,13 @@ setBuilders({ promise: promiseType, record: recordType, ref: refType, + refine: refineType, readonly: readonlyType, set: setType, strictObject: strictObjectType, string: stringType, symbol: symbolType, - transformer: effectsType, + transformer: transformType, tuple: tupleType, undefined: undefinedType, union: unionType, diff --git a/packages/zui/src/z/index.ts b/packages/zui/src/z/index.ts index 32d64047918..28f70ee2dc8 100644 --- a/packages/zui/src/z/index.ts +++ b/packages/zui/src/z/index.ts @@ -173,10 +173,6 @@ export type { // effects ZodEffectsDef, IZodEffects as ZodEffects, - RefinementEffect, - TransformEffect, - PreprocessEffect, - Effect, // undefined ZodUndefinedDef, @@ -209,7 +205,6 @@ export { dateType as date, defaultType as default, discriminatedUnionType as discriminatedUnion, - effectsType as effects, enumType as enum, functionType as function, instanceOfType as instanceof, @@ -230,12 +225,13 @@ export { promiseType as promise, recordType as record, refType as ref, + refineType as refine, readonlyType as readonly, setType as set, strictObjectType as strictObject, stringType as string, symbolType as symbol, - effectsType as transformer, + transformType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 961fdba4a0a..5bc855314a3 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -262,7 +262,7 @@ export abstract class ZodBaseTypeImpl['refinement']): IZodEffects { - return builders.effects(this, { type: 'refinement', refinement }) + return builders.refine(this, refinement) } superRefine( @@ -348,10 +348,7 @@ export abstract class ZodBaseTypeImpl( transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise ): IZodEffects { - return builders.effects(this, { - type: 'transform', - transform, - }) + return builders.transformer(this, transform) } default(def: utils.types.NoUndefined): IZodDefault diff --git a/packages/zui/src/z/types/bigint/index.ts b/packages/zui/src/z/types/bigint/index.ts index 6fc491e902a..7dd94438bb4 100644 --- a/packages/zui/src/z/types/bigint/index.ts +++ b/packages/zui/src/z/types/bigint/index.ts @@ -1,5 +1,13 @@ import * as utils from '../../../utils' -import { type IZodBigInt, ZodBigIntCheck, ZodBigIntDef, ParseContext, ParseInput, ParseReturnType } from '../../typings' +import { + type IZodBigInt, + type IZodType, + ZodBigIntCheck, + ZodBigIntDef, + ParseContext, + ParseInput, + ParseReturnType, +} from '../../typings' import { addIssueToContext, ParseStatus, ZodBaseTypeImpl } from '../basetype' export class ZodBigIntImpl extends ZodBaseTypeImpl implements IZodBigInt { @@ -66,7 +74,7 @@ export class ZodBigIntImpl extends ZodBaseTypeImpl impleme return { status: status.value, value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodBigIntImpl)) { return false } diff --git a/packages/zui/src/z/types/boolean/index.ts b/packages/zui/src/z/types/boolean/index.ts index eefbc59a9e4..8f3dcf51045 100644 --- a/packages/zui/src/z/types/boolean/index.ts +++ b/packages/zui/src/z/types/boolean/index.ts @@ -1,4 +1,4 @@ -import type { IZodBoolean, ZodBooleanDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodBoolean, IZodType, ZodBooleanDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodBooleanImpl extends ZodBaseTypeImpl implements IZodBoolean { @@ -20,7 +20,7 @@ export class ZodBooleanImpl extends ZodBaseTypeImpl impl return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodBooleanImpl)) return false return this._def.coerce === schema._def.coerce } diff --git a/packages/zui/src/z/types/date/index.ts b/packages/zui/src/z/types/date/index.ts index b701969d1cb..36549fdff5c 100644 --- a/packages/zui/src/z/types/date/index.ts +++ b/packages/zui/src/z/types/date/index.ts @@ -1,5 +1,13 @@ import * as utils from '../../../utils' -import { type IZodDate, ZodDateCheck, ZodDateDef, ParseContext, ParseInput, ParseReturnType } from '../../typings' +import { + type IZodDate, + type IZodType, + ZodDateCheck, + ZodDateDef, + ParseContext, + ParseInput, + ParseReturnType, +} from '../../typings' import { addIssueToContext, ParseStatus, ZodBaseTypeImpl } from '../basetype' export class ZodDateImpl extends ZodBaseTypeImpl implements IZodDate { @@ -113,7 +121,7 @@ export class ZodDateImpl extends ZodBaseTypeImpl implements IZ return max != null ? new Date(max) : null } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodDateImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) diff --git a/packages/zui/src/z/types/enum/index.ts b/packages/zui/src/z/types/enum/index.ts index c37c1c2c465..de75eb7cb54 100644 --- a/packages/zui/src/z/types/enum/index.ts +++ b/packages/zui/src/z/types/enum/index.ts @@ -3,6 +3,7 @@ import { builders } from '../../internal-builders' import type { FilterEnum, IZodEnum, + IZodType, EnumValuesMap, NeverCast, ZodEnumDef, @@ -85,7 +86,7 @@ export class ZodEnumImpl }) as IZodEnum>, [string, ...string[]]>> } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodEnumImpl)) return false const thisValues = new utils.ds.CustomSet(this._def.values) const thatValues = new utils.ds.CustomSet(schema._def.values) diff --git a/packages/zui/src/z/types/literal/index.ts b/packages/zui/src/z/types/literal/index.ts index 4dd24376dc6..f87f75f22b9 100644 --- a/packages/zui/src/z/types/literal/index.ts +++ b/packages/zui/src/z/types/literal/index.ts @@ -1,5 +1,5 @@ import { isEqual } from 'lodash-es' -import type { IZodLiteral, Primitive, ZodLiteralDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodLiteral, IZodType, Primitive, ZodLiteralDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodLiteralImpl @@ -23,7 +23,7 @@ export class ZodLiteralImpl return this._def.value } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodLiteralImpl)) return false return isEqual(this._def.value, schema._def.value) } diff --git a/packages/zui/src/z/types/nan/index.ts b/packages/zui/src/z/types/nan/index.ts index 87f0b1d2d1a..8d65c9894d4 100644 --- a/packages/zui/src/z/types/nan/index.ts +++ b/packages/zui/src/z/types/nan/index.ts @@ -1,4 +1,4 @@ -import type { IZodNaN, ZodNaNDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodNaN, IZodType, ZodNaNDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodNaNImpl extends ZodBaseTypeImpl implements IZodNaN { @@ -17,7 +17,7 @@ export class ZodNaNImpl extends ZodBaseTypeImpl implements IZ return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodNaNImpl } } diff --git a/packages/zui/src/z/types/nativeEnum/index.ts b/packages/zui/src/z/types/nativeEnum/index.ts index 39c20b10f58..2c35e636eb6 100644 --- a/packages/zui/src/z/types/nativeEnum/index.ts +++ b/packages/zui/src/z/types/nativeEnum/index.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es' import * as utils from '../../../utils' -import type { EnumLike, IZodNativeEnum, ZodNativeEnumDef, ParseInput, ParseReturnType } from '../../typings' +import type { EnumLike, IZodNativeEnum, IZodType, ZodNativeEnumDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodNativeEnumImpl @@ -38,7 +38,7 @@ export class ZodNativeEnumImpl return this._def.values } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodNativeEnumImpl)) return false return isEqual(this._def.values, schema._def.values) } diff --git a/packages/zui/src/z/types/never/index.ts b/packages/zui/src/z/types/never/index.ts index 382a4533137..a3241dfd6be 100644 --- a/packages/zui/src/z/types/never/index.ts +++ b/packages/zui/src/z/types/never/index.ts @@ -1,4 +1,4 @@ -import type { IZodNever, ZodNeverDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodNever, IZodType, ZodNeverDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export type { ZodNeverDef } @@ -13,7 +13,7 @@ export class ZodNeverImpl extends ZodBaseTypeImpl implements }) return { status: 'aborted' } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodNeverImpl } } diff --git a/packages/zui/src/z/types/null/index.ts b/packages/zui/src/z/types/null/index.ts index 66671ec9d25..56d28f94490 100644 --- a/packages/zui/src/z/types/null/index.ts +++ b/packages/zui/src/z/types/null/index.ts @@ -1,4 +1,4 @@ -import type { IZodNull, ZodNullDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodNull, IZodType, ZodNullDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodNullImpl extends ZodBaseTypeImpl implements IZodNull { @@ -15,7 +15,7 @@ export class ZodNullImpl extends ZodBaseTypeImpl implements IZ } return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodNullImpl } } diff --git a/packages/zui/src/z/types/number/index.ts b/packages/zui/src/z/types/number/index.ts index bdceadc959c..f0d92a699f6 100644 --- a/packages/zui/src/z/types/number/index.ts +++ b/packages/zui/src/z/types/number/index.ts @@ -1,5 +1,13 @@ import * as utils from '../../../utils' -import { type IZodNumber, ZodNumberCheck, ZodNumberDef, ParseContext, ParseInput, ParseReturnType } from '../../typings' +import { + type IZodNumber, + type IZodType, + ZodNumberCheck, + ZodNumberDef, + ParseContext, + ParseInput, + ParseReturnType, +} from '../../typings' import { ZodBaseTypeImpl, addIssueToContext, ParseStatus } from '../basetype' // https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034 @@ -244,7 +252,7 @@ export class ZodNumberImpl extends ZodBaseTypeImpl impleme return Number.isFinite(min) && Number.isFinite(max) } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodNumberImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) diff --git a/packages/zui/src/z/types/pipeline/index.ts b/packages/zui/src/z/types/pipeline/index.ts index ce4f5a661ff..c2bbf4d6f6f 100644 --- a/packages/zui/src/z/types/pipeline/index.ts +++ b/packages/zui/src/z/types/pipeline/index.ts @@ -79,7 +79,7 @@ export class ZodPipelineImpl, ZodRefDef> return false } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodRefImpl)) return false return this._def.uri === schema._def.uri } diff --git a/packages/zui/src/z/types/string/index.ts b/packages/zui/src/z/types/string/index.ts index 6af984638c0..118fff53f2b 100644 --- a/packages/zui/src/z/types/string/index.ts +++ b/packages/zui/src/z/types/string/index.ts @@ -1,6 +1,14 @@ import * as utils from '../../../utils' import { zuiKey } from '../../consts' -import { type IZodString, ZodStringCheck, ZodStringDef, ParseContext, ParseInput, ParseReturnType } from '../../typings' +import { + type IZodString, + type IZodType, + ZodStringCheck, + ZodStringDef, + ParseContext, + ParseInput, + ParseReturnType, +} from '../../typings' import { ZodBaseTypeImpl, addIssueToContext, ParseStatus } from '../basetype' export type { ZodStringCheck, ZodStringDef } @@ -462,7 +470,7 @@ export class ZodStringImpl extends ZodBaseTypeImpl impleme return max } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { if (!(schema instanceof ZodStringImpl)) return false const thisChecks = new utils.ds.CustomSet(this._def.checks) const thatChecks = new utils.ds.CustomSet(schema._def.checks) diff --git a/packages/zui/src/z/types/symbol/index.ts b/packages/zui/src/z/types/symbol/index.ts index f239552e17e..5bad4eb0eda 100644 --- a/packages/zui/src/z/types/symbol/index.ts +++ b/packages/zui/src/z/types/symbol/index.ts @@ -1,4 +1,4 @@ -import type { IZodSymbol, ZodSymbolDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodSymbol, IZodType, ZodSymbolDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodSymbolImpl extends ZodBaseTypeImpl implements IZodSymbol { @@ -17,7 +17,7 @@ export class ZodSymbolImpl extends ZodBaseTypeImpl impleme return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodSymbolImpl } } diff --git a/packages/zui/src/z/types/transformer/index.ts b/packages/zui/src/z/types/transformer/index.ts index 981f10a91f3..53ca730f6b8 100644 --- a/packages/zui/src/z/types/transformer/index.ts +++ b/packages/zui/src/z/types/transformer/index.ts @@ -30,11 +30,11 @@ export class ZodEffectsImpl, I : (this._def.schema as T) } - dereference(defs: Record): IZodType { + dereference(defs: Record): IZodEffects { return new ZodEffectsImpl({ ...this._def, schema: this._def.schema.dereference(defs), - }) + }) as IZodEffects } getReferences(): string[] { @@ -45,7 +45,7 @@ export class ZodEffectsImpl, I return new ZodEffectsImpl({ ...this._def, schema: this._def.schema.clone() as T, - }) + }) as IZodEffects } _parse(input: ParseInput): ParseReturnType { @@ -70,7 +70,7 @@ export class ZodEffectsImpl, I checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx) if (effect.type === 'preprocess') { - const processed = effect.transform(ctx.data, checkCtx) + const processed = effect.preprocess(ctx.data, checkCtx) if (ctx.common.async) { return Promise.resolve(processed).then(async (processed) => { @@ -152,7 +152,7 @@ export class ZodEffectsImpl, I ) } - return { status: status.value, value: result } + return { status: status.value, value: result } as ParseReturnType } else { return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => { if (!isValid(base)) return base @@ -161,7 +161,7 @@ export class ZodEffectsImpl, I status: status.value, value: result, })) - }) + }) as ParseReturnType } } @@ -184,7 +184,7 @@ export class ZodEffectsImpl, I if (this._def.effect.type === 'preprocess') { if (schema._def.effect.type !== 'preprocess') return false - return utils.others.compareFunctions(this._def.effect.transform, schema._def.effect.transform) + return utils.others.compareFunctions(this._def.effect.preprocess, schema._def.effect.preprocess) } this._def.effect satisfies never @@ -199,6 +199,6 @@ export class ZodEffectsImpl, I return new ZodEffectsImpl({ ...this._def, schema: this._def.schema.mandatory(), - }) + }) as IZodEffects } } diff --git a/packages/zui/src/z/types/transformer/transformer.test.ts b/packages/zui/src/z/types/transformer/transformer.test.ts index 2829fa5b284..3b2eb2d0de5 100644 --- a/packages/zui/src/z/types/transformer/transformer.test.ts +++ b/packages/zui/src/z/types/transformer/transformer.test.ts @@ -96,6 +96,8 @@ test('basic transformations', () => { .string() .transform((data) => data.length) .parse('asdf') + + assert.assertEqual(true) expect(r1).toEqual(4) }) diff --git a/packages/zui/src/z/types/undefined/index.ts b/packages/zui/src/z/types/undefined/index.ts index 8adf7b2d751..67112a8d635 100644 --- a/packages/zui/src/z/types/undefined/index.ts +++ b/packages/zui/src/z/types/undefined/index.ts @@ -1,5 +1,5 @@ import { builders } from '../../internal-builders' -import type { IZodNever, IZodUndefined, ZodUndefinedDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodNever, IZodType, IZodUndefined, ZodUndefinedDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodUndefinedImpl extends ZodBaseTypeImpl implements IZodUndefined { @@ -17,7 +17,7 @@ export class ZodUndefinedImpl extends ZodBaseTypeImpl implements IZodUnknown { @@ -8,7 +8,7 @@ export class ZodUnknownImpl extends ZodBaseTypeImpl impl return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodUnknownImpl } } diff --git a/packages/zui/src/z/types/void/index.ts b/packages/zui/src/z/types/void/index.ts index 8758bd6580e..eb26a9b2e45 100644 --- a/packages/zui/src/z/types/void/index.ts +++ b/packages/zui/src/z/types/void/index.ts @@ -1,4 +1,4 @@ -import type { IZodVoid, ZodVoidDef, ParseInput, ParseReturnType } from '../../typings' +import type { IZodVoid, IZodType, ZodVoidDef, ParseInput, ParseReturnType } from '../../typings' import { ZodBaseTypeImpl, addIssueToContext } from '../basetype' export class ZodVoidImpl extends ZodBaseTypeImpl implements IZodVoid { @@ -16,7 +16,7 @@ export class ZodVoidImpl extends ZodBaseTypeImpl implements IZ return { status: 'valid', value: input.data } } - isEqual(schema: ZodBaseTypeImpl): boolean { + isEqual(schema: IZodType): boolean { return schema instanceof ZodVoidImpl } } diff --git a/packages/zui/src/z/typings.ts b/packages/zui/src/z/typings.ts index d67521a013f..07427635121 100644 --- a/packages/zui/src/z/typings.ts +++ b/packages/zui/src/z/typings.ts @@ -1593,26 +1593,28 @@ export interface IZodSymbol extends IZodType {} //* ─────────────────────────── ZodEffects ─────────────────────────────────── -export type RefinementEffect = { +export type RefinementEffect = { type: 'refinement' - refinement: (arg: T, ctx: RefinementCtx) => any + refinement: (arg: I, ctx: RefinementCtx) => O } -export type TransformEffect = { +export type TransformEffect = { type: 'transform' - transform: (arg: T, ctx: RefinementCtx) => any + transform: (arg: I, ctx: RefinementCtx) => O } -export type PreprocessEffect = { +export type PreprocessEffect = { type: 'preprocess' - transform: (arg: T, ctx: RefinementCtx) => any + preprocess: (arg: I, ctx: RefinementCtx) => O } -export type Effect = RefinementEffect | TransformEffect | PreprocessEffect +export type Effect = RefinementEffect | TransformEffect | PreprocessEffect export type ZodEffectsDef = { schema: T typeName: 'ZodEffects' - effect: Effect + + // We don't care about the specific type here as this is a storage type. Type inference is done at the builder level. + effect: Effect } & ZodTypeDef /* oxlint-disable typescript-eslint(consistent-type-definitions) */ @@ -1822,16 +1824,29 @@ export declare function createFunction( params?: ZodCreateParams ): IZodFunction -export declare function createEffects( - schema: I, - effect: Effect, +export declare function createRefine( + schema: T, + refinement: (arg: output, ctx: RefinementCtx) => arg is O, + params?: ZodCreateParams +): IZodEffects +export declare function createRefine( + schema: T, + refinement: (arg: output, ctx: RefinementCtx) => unknown | Promise, + params?: ZodCreateParams +): IZodEffects + +export declare function createTransform( + schema: T, + transform: (arg: output, ctx: RefinementCtx) => O | Promise, params?: ZodCreateParams -): IZodEffects -export declare function createPreprocess( - preprocess: (arg: unknown, ctx: RefinementCtx) => unknown, - schema: I, +): IZodEffects + +export declare function createPreprocess, O>( + preprocess: (arg: unknown, ctx: RefinementCtx) => unknown | Promise, + schema: T, params?: ZodCreateParams -): IZodEffects +): IZodEffects, unknown> + export declare function createOptional(type: T, params?: ZodCreateParams): IZodOptional export declare function createNullable(type: T, params?: ZodCreateParams): IZodNullable export declare function createReadonly(type: T, params?: ZodCreateParams): IZodReadonly @@ -1859,7 +1874,6 @@ export type ZodBuilders = { date: typeof createDate default: typeof createDefault discriminatedUnion: typeof createDiscriminatedUnion - effects: typeof createEffects enum: typeof createEnum function: typeof createFunction instanceof: typeof createInstanceOf @@ -1880,12 +1894,13 @@ export type ZodBuilders = { promise: typeof createPromise record: typeof createRecord ref: typeof createRef + refine: typeof createRefine readonly: typeof createReadonly set: typeof createSet strictObject: typeof createStrictObject string: typeof createString symbol: typeof createSymbol - transformer: typeof createEffects + transformer: typeof createTransform tuple: typeof createTuple undefined: typeof createUndefined union: typeof createUnion From 2a51dadf29c9ee6be73ce6b496b549ede52ccbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Tue, 10 Mar 2026 11:51:14 -0400 Subject: [PATCH 38/50] chore(zui): cleanup basetype implementation --- packages/zui/src/z/types/basetype/index.ts | 90 +------------------ .../zui/src/z/types/basetype/parseUtil.ts | 21 ++--- 2 files changed, 12 insertions(+), 99 deletions(-) diff --git a/packages/zui/src/z/types/basetype/index.ts b/packages/zui/src/z/types/basetype/index.ts index 5bc855314a3..12a26e7d662 100644 --- a/packages/zui/src/z/types/basetype/index.ts +++ b/packages/zui/src/z/types/basetype/index.ts @@ -43,9 +43,9 @@ import { getParsedType, isAsync, isValid, ParseStatus } from './parseUtil' export * from './parseUtil' class _CircularDependencyError extends Error { - public constructor(private _propName: keyof IZodType) { + public constructor(propName: keyof IZodType) { super( - `Cannot access property ${_propName} before initialization. You're probably importing ZUI incorrectly. If not, reach out to the maintainers.` + `Cannot access property ${propName} before initialization. You're probably importing ZUI incorrectly. If not, reach out to the maintainers.` ) } } @@ -69,12 +69,10 @@ export abstract class ZodBaseTypeImpl - /** deeply replace all references in the schema */ dereference(_defs: Record): IZodType { return this } - /** deeply scans the schema to check if it contains references */ getReferences(): string[] { return [] } @@ -86,7 +84,6 @@ export abstract class ZodBaseTypeImpl( - check: (arg: Output) => arg is RefinedOutput, - message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) - ): IZodEffects - refine( - check: (arg: Output) => unknown | Promise, - message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) - ): IZodEffects refine( check: (arg: Output) => unknown, message?: string | CustomErrorParams | ((arg: Output) => CustomErrorParams) @@ -239,14 +227,6 @@ export abstract class ZodBaseTypeImpl( - check: (arg: Output) => arg is RefinedOutput, - refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) - ): IZodEffects - refinement( - check: (arg: Output) => boolean, - refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) - ): IZodEffects refinement( check: (arg: Output) => unknown, refinementData: IssueData | ((arg: Output, ctx: RefinementCtx) => IssueData) @@ -265,11 +245,6 @@ export abstract class ZodBaseTypeImpl( - refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput - ): IZodEffects - superRefine(refinement: (arg: Output, ctx: RefinementCtx) => void): IZodEffects - superRefine(refinement: (arg: Output, ctx: RefinementCtx) => Promise): IZodEffects superRefine( refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise ): IZodEffects { @@ -319,20 +294,7 @@ export abstract class ZodBaseTypeImpl { return builders.promise(this, this._def) // TODO(why): find out why def is passed as second argument } - /** - * # \#\#\# Experimental \#\#\# - * - * @experimental This function is experimental and is subject to breaking changes in the future. - * - * Would have been named `required` but a method with that name already exists in ZodObject. - * Makes the schema required; i.e. not optional or undefined. If the schema is already required than it returns itself. - * Null is not considered optional and remains unchanged. - * - * @example z.string().optional().mandatory() // z.string() - * @example z.string().nullable().mandatory() // z.string().nullable() - * @example z.string().or(z.undefined()).mandatory() // z.string() - * @example z.union([z.string(), z.number(), z.undefined()]).mandatory() // z.union([z.string(), z.number()]) - */ + mandatory(): IZodType { return this } @@ -351,8 +313,6 @@ export abstract class ZodBaseTypeImpl): IZodDefault - default(def: () => utils.types.NoUndefined): IZodDefault default(def: utils.types.NoUndefined | (() => utils.types.NoUndefined)) { const defaultValueFunc = typeof def === 'function' ? def : () => def return builders.default(this, defaultValueFunc) @@ -388,9 +348,6 @@ export abstract class ZodBaseTypeImpl): this { const clone = this.clone() as this const root = clone._metadataRoot @@ -404,20 +361,14 @@ export abstract class ZodBaseTypeImpl { return { ...this._metadataRoot._def[zuiKey] } } - /** set metadata of the schema */ setMetadata(data: Record): void { this._metadataRoot._def[zuiKey] = { ...data } } - /** - * get metadata of the schema - * @deprecated use `getMetadata()` instead - */ get ui(): Record { return { ...this._metadataRoot._def[zuiKey] } } @@ -439,17 +390,10 @@ export abstract class ZodBaseTypeImpl