@veloxts/validation 0.6.102 → 0.6.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @veloxts/validation
2
2
 
3
+ ## 0.6.104
4
+
5
+ ### Patch Changes
6
+
7
+ - feat(client): smart convention-based route inference, eliminate routes.ts
8
+ - Updated dependencies
9
+ - @veloxts/core@0.6.104
10
+
11
+ ## 0.6.103
12
+
13
+ ### Patch Changes
14
+
15
+ - chore(deps): upgrade Zod from v3 to v4
16
+ - Updated dependencies
17
+ - @veloxts/core@0.6.103
18
+
3
19
  ## 0.6.102
4
20
 
5
21
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  *
23
23
  * @module @veloxts/validation
24
24
  */
25
- export { ZodError, type ZodType, type ZodTypeDef, z } from 'zod';
25
+ export { ZodError, type ZodType, z } from 'zod';
26
26
  /** Validation package version */
27
27
  export declare const VALIDATION_VERSION: string;
28
28
  export type { AnySchema, AnyZodSchema, InferInput, InferOutput, NoInput, ResolveInput, ResolveOutput, SafeParseError, SafeParseResult, SafeParseSuccess, Schema, SchemaLike, UnknownOutput, ValidationIssue, } from './types.js';
@@ -7,7 +7,7 @@
7
7
  * @module middleware
8
8
  */
9
9
  import { ValidationError } from '@veloxts/core';
10
- import { ZodError, type ZodType, type ZodTypeDef } from 'zod';
10
+ import { ZodError, type ZodType } from 'zod';
11
11
  import type { AnySchema, AnyZodSchema, SafeParseResult } from './types.js';
12
12
  /**
13
13
  * Transforms Zod validation issues into a field-error map
@@ -47,7 +47,9 @@ export declare function zodErrorToValidationError(error: ZodError, customMessage
47
47
  * // user is typed as { name: string; email: string }
48
48
  * ```
49
49
  */
50
- export declare function parse<T>(schema: ZodType<T, ZodTypeDef, unknown> | AnySchema, data: unknown, errorMessage?: string): T;
50
+ export declare function parse<T>(schema: (ZodType & {
51
+ parse: (data: unknown) => T;
52
+ }) | AnySchema, data: unknown, errorMessage?: string): T;
51
53
  /**
52
54
  * Safely parses data without throwing
53
55
  *
@@ -68,7 +70,9 @@ export declare function parse<T>(schema: ZodType<T, ZodTypeDef, unknown> | AnySc
68
70
  * }
69
71
  * ```
70
72
  */
71
- export declare function safeParse<T>(schema: ZodType<T, ZodTypeDef, unknown> | AnySchema, data: unknown): SafeParseResult<T>;
73
+ export declare function safeParse<T>(schema: (ZodType & {
74
+ parse: (data: unknown) => T;
75
+ }) | AnySchema, data: unknown): SafeParseResult<T>;
72
76
  /**
73
77
  * Creates a reusable validator function from a schema
74
78
  *
@@ -85,7 +89,9 @@ export declare function safeParse<T>(schema: ZodType<T, ZodTypeDef, unknown> | A
85
89
  * const user = userValidator.parse(request.body);
86
90
  * ```
87
91
  */
88
- export declare function createValidator<TOutput, TInput = unknown>(schema: ZodType<TOutput, ZodTypeDef, TInput>): Validator<TOutput>;
92
+ export declare function createValidator<TOutput>(schema: ZodType & {
93
+ parse: (data: unknown) => TOutput;
94
+ }): Validator<TOutput>;
89
95
  /**
90
96
  * Validator interface for type-safe validation
91
97
  */
@@ -116,7 +122,9 @@ export interface Validator<T> {
116
122
  * ```
117
123
  */
118
124
  export declare function parseAll<T extends Record<string, [AnyZodSchema, unknown]>>(validations: T): {
119
- [K in keyof T]: T[K][0] extends ZodType<infer O, ZodTypeDef, unknown> ? O : never;
125
+ [K in keyof T]: T[K][0] extends {
126
+ parse: (data: unknown) => infer O;
127
+ } ? O : never;
120
128
  };
121
129
  /**
122
130
  * Creates a type guard from a Zod schema
@@ -135,7 +143,9 @@ export declare function parseAll<T extends Record<string, [AnyZodSchema, unknown
135
143
  * }
136
144
  * ```
137
145
  */
138
- export declare function createTypeGuard<T>(schema: ZodType<T, ZodTypeDef, unknown>): (value: unknown) => value is T;
146
+ export declare function createTypeGuard<T>(schema: ZodType & {
147
+ parse: (data: unknown) => T;
148
+ }): (value: unknown) => value is T;
139
149
  /**
140
150
  * Asserts that a value matches a schema, narrowing the type
141
151
  *
@@ -154,4 +164,6 @@ export declare function createTypeGuard<T>(schema: ZodType<T, ZodTypeDef, unknow
154
164
  * }
155
165
  * ```
156
166
  */
157
- export declare function assertSchema<T>(schema: ZodType<T, ZodTypeDef, unknown>, value: unknown, errorMessage?: string): asserts value is T;
167
+ export declare function assertSchema<T>(schema: ZodType & {
168
+ parse: (data: unknown) => T;
169
+ }, value: unknown, errorMessage?: string): asserts value is T;
@@ -37,7 +37,10 @@ export function formatZodErrors(issues) {
37
37
  * @returns ValidationError with field-specific errors
38
38
  */
39
39
  export function zodErrorToValidationError(error, customMessage) {
40
- const fields = formatZodErrors(error.issues);
40
+ const fields = formatZodErrors(error.issues.map((i) => ({
41
+ path: i.path.filter((p) => typeof p !== 'symbol'),
42
+ message: i.message,
43
+ })));
41
44
  const message = customMessage ?? 'Validation failed';
42
45
  return new ValidationError(message, fields);
43
46
  }
@@ -121,7 +124,7 @@ export function safeParse(schema, data) {
121
124
  return {
122
125
  success: false,
123
126
  error: result.error.issues.map((issue) => ({
124
- path: issue.path,
127
+ path: issue.path.filter((p) => typeof p !== 'symbol'),
125
128
  message: issue.message,
126
129
  code: issue.code,
127
130
  })),
@@ -38,11 +38,7 @@ export declare const datetimeSchema: z.ZodString;
38
38
  */
39
39
  export declare const idParamSchema: z.ZodObject<{
40
40
  id: z.ZodString;
41
- }, "strip", z.ZodTypeAny, {
42
- id: string;
43
- }, {
44
- id: string;
45
- }>;
41
+ }, z.core.$strip>;
46
42
  /**
47
43
  * Type for id parameter objects
48
44
  */
@@ -53,20 +49,14 @@ export type IdParam = z.infer<typeof idParamSchema>;
53
49
  * @param type - Type of ID to accept ('uuid' | 'integer' | 'string')
54
50
  * @returns Zod schema for the specified ID type
55
51
  */
56
- export declare function createIdSchema<T extends 'uuid' | 'integer' | 'string'>(type: T): T extends 'uuid' ? typeof uuidSchema : T extends 'integer' ? z.ZodPipeline<z.ZodEffects<z.ZodString, number, string>, z.ZodNumber> : z.ZodString;
52
+ export declare function createIdSchema<T extends 'uuid' | 'integer' | 'string'>(type: T): T extends 'uuid' ? typeof uuidSchema : T extends 'integer' ? z.ZodType<number, unknown> : z.ZodString;
57
53
  /**
58
54
  * Timestamp fields commonly added to database records
59
55
  */
60
56
  export declare const timestampFieldsSchema: z.ZodObject<{
61
- createdAt: z.ZodDate;
62
- updatedAt: z.ZodDate;
63
- }, "strip", z.ZodTypeAny, {
64
- createdAt: Date;
65
- updatedAt: Date;
66
- }, {
67
- createdAt: Date;
68
- updatedAt: Date;
69
- }>;
57
+ createdAt: z.ZodCoercedDate<unknown>;
58
+ updatedAt: z.ZodCoercedDate<unknown>;
59
+ }, z.core.$strip>;
70
60
  /**
71
61
  * Type for timestamp fields
72
62
  */
@@ -76,17 +66,9 @@ export type TimestampFields = z.infer<typeof timestampFieldsSchema>;
76
66
  */
77
67
  export declare const baseEntitySchema: z.ZodObject<{
78
68
  id: z.ZodString;
79
- createdAt: z.ZodDate;
80
- updatedAt: z.ZodDate;
81
- }, "strip", z.ZodTypeAny, {
82
- id: string;
83
- createdAt: Date;
84
- updatedAt: Date;
85
- }, {
86
- id: string;
87
- createdAt: Date;
88
- updatedAt: Date;
89
- }>;
69
+ createdAt: z.ZodCoercedDate<unknown>;
70
+ updatedAt: z.ZodCoercedDate<unknown>;
71
+ }, z.core.$strip>;
90
72
  /**
91
73
  * Type for base entity
92
74
  */
@@ -154,14 +136,14 @@ export declare function pickFields<T extends z.ZodRawShape, K extends keyof T &
154
136
  * String that coerces to boolean
155
137
  * Accepts 'true', '1', 'yes' as true; 'false', '0', 'no' as false
156
138
  */
157
- export declare const booleanStringSchema: z.ZodPipeline<z.ZodEffects<z.ZodString, boolean | undefined, string>, z.ZodBoolean>;
139
+ export declare const booleanStringSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<boolean | undefined, string>>, z.ZodBoolean>;
158
140
  /**
159
141
  * String that coerces to number
160
142
  * Useful for query parameters
161
143
  */
162
- export declare const numberStringSchema: z.ZodPipeline<z.ZodEffects<z.ZodString, number, string>, z.ZodNumber>;
144
+ export declare const numberStringSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>;
163
145
  /**
164
146
  * String that coerces to integer
165
147
  * Useful for pagination parameters
166
148
  */
167
- export declare const integerStringSchema: z.ZodPipeline<z.ZodEffects<z.ZodString, number, string>, z.ZodNumber>;
149
+ export declare const integerStringSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>;
@@ -85,6 +85,20 @@ export const baseEntitySchema = z.object({
85
85
  // ============================================================================
86
86
  // Schema Composition Utilities
87
87
  // ============================================================================
88
+ /**
89
+ * Builds a `{ key: true }` mask from an array of string keys.
90
+ *
91
+ * Zod 4's `.partial()`, `.omit()`, and `.pick()` accept a mask object whose
92
+ * exact type is derived from the schema's shape. We build a plain
93
+ * `Record<string, true>` at runtime and cast it to the schema-specific mask
94
+ * type at each call-site via `Parameters<typeof schema.method>[0]`.
95
+ */
96
+ function buildMask(keys) {
97
+ const mask = {};
98
+ for (const key of keys)
99
+ mask[key] = true;
100
+ return mask;
101
+ }
88
102
  /**
89
103
  * Makes all fields in a schema optional
90
104
  *
@@ -114,18 +128,8 @@ export function makePartial(schema) {
114
128
  * ```
115
129
  */
116
130
  export function partialExcept(schema, keys) {
117
- const shape = schema.shape;
118
- const requiredKeys = new Set(keys);
119
- const newShape = {};
120
- for (const key in shape) {
121
- if (requiredKeys.has(key)) {
122
- newShape[key] = shape[key];
123
- }
124
- else {
125
- newShape[key] = shape[key].optional();
126
- }
127
- }
128
- return z.object(newShape);
131
+ const keysToOptional = Object.keys(schema.shape).filter((k) => !keys.includes(k));
132
+ return schema.partial(buildMask(keysToOptional));
129
133
  }
130
134
  /**
131
135
  * Omits specified fields from a schema
@@ -140,16 +144,7 @@ export function partialExcept(schema, keys) {
140
144
  * ```
141
145
  */
142
146
  export function omitFields(schema, keys) {
143
- // Build the omit mask manually to avoid Zod's strict typing
144
- const shape = schema.shape;
145
- const keysToOmit = new Set(keys);
146
- const newShape = {};
147
- for (const key in shape) {
148
- if (!keysToOmit.has(key)) {
149
- newShape[key] = shape[key];
150
- }
151
- }
152
- return z.object(newShape);
147
+ return schema.omit(buildMask(keys));
153
148
  }
154
149
  /**
155
150
  * Picks specified fields from a schema
@@ -164,15 +159,7 @@ export function omitFields(schema, keys) {
164
159
  * ```
165
160
  */
166
161
  export function pickFields(schema, keys) {
167
- // Build the pick mask manually to avoid Zod's strict typing
168
- const shape = schema.shape;
169
- const newShape = {};
170
- for (const key of keys) {
171
- if (key in shape) {
172
- newShape[key] = shape[key];
173
- }
174
- }
175
- return z.object(newShape);
162
+ return schema.pick(buildMask(keys));
176
163
  }
177
164
  // ============================================================================
178
165
  // Coercion Utilities
@@ -40,34 +40,18 @@ export declare function createPaginationSchema(options?: {
40
40
  defaultLimit?: number;
41
41
  maxLimit?: number;
42
42
  }): z.ZodObject<{
43
- /** Current page number (1-indexed) */
44
- page: z.ZodDefault<z.ZodNumber>;
45
- /** Number of items per page */
46
- limit: z.ZodDefault<z.ZodNumber>;
47
- }, "strip", z.ZodTypeAny, {
48
- page: number;
49
- limit: number;
50
- }, {
51
- page?: number | undefined;
52
- limit?: number | undefined;
53
- }>;
43
+ page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
44
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
45
+ }, z.core.$strip>;
54
46
  /**
55
47
  * Default pagination input schema
56
48
  *
57
49
  * Accepts page (default 1) and limit (default 20, max 100)
58
50
  */
59
51
  export declare const paginationInputSchema: z.ZodObject<{
60
- /** Current page number (1-indexed) */
61
- page: z.ZodDefault<z.ZodNumber>;
62
- /** Number of items per page */
63
- limit: z.ZodDefault<z.ZodNumber>;
64
- }, "strip", z.ZodTypeAny, {
65
- page: number;
66
- limit: number;
67
- }, {
68
- page?: number | undefined;
69
- limit?: number | undefined;
70
- }>;
52
+ page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
53
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
54
+ }, z.core.$strip>;
71
55
  /**
72
56
  * Type for pagination input
73
57
  */
@@ -78,21 +62,13 @@ export type PaginationInput = z.infer<typeof paginationInputSchema>;
78
62
  * For more efficient pagination of large datasets
79
63
  */
80
64
  export declare const cursorPaginationSchema: z.ZodObject<{
81
- /** Cursor for the current position */
82
65
  cursor: z.ZodOptional<z.ZodString>;
83
- /** Number of items to fetch */
84
- limit: z.ZodDefault<z.ZodNumber>;
85
- /** Direction to fetch (forward/backward from cursor) */
86
- direction: z.ZodDefault<z.ZodEnum<["forward", "backward"]>>;
87
- }, "strip", z.ZodTypeAny, {
88
- limit: number;
89
- direction: "forward" | "backward";
90
- cursor?: string | undefined;
91
- }, {
92
- limit?: number | undefined;
93
- cursor?: string | undefined;
94
- direction?: "forward" | "backward" | undefined;
95
- }>;
66
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
67
+ direction: z.ZodDefault<z.ZodEnum<{
68
+ forward: "forward";
69
+ backward: "backward";
70
+ }>>;
71
+ }, z.core.$strip>;
96
72
  /**
97
73
  * Type for cursor-based pagination input
98
74
  */
@@ -112,53 +88,16 @@ export type CursorPaginationInput = z.infer<typeof cursorPaginationSchema>;
112
88
  * // { data: User[]; meta: { page, limit, total, totalPages, hasMore } }
113
89
  * ```
114
90
  */
115
- export declare function createPaginatedResponseSchema<T extends z.ZodTypeAny>(itemSchema: T): z.ZodObject<{
116
- /** Array of items for the current page */
117
- data: z.ZodArray<T, "many">;
118
- /** Pagination metadata */
91
+ export declare function createPaginatedResponseSchema<T extends z.ZodType>(itemSchema: T): z.ZodObject<{
92
+ data: z.ZodArray<T>;
119
93
  meta: z.ZodObject<{
120
- /** Current page number */
121
94
  page: z.ZodNumber;
122
- /** Items per page */
123
95
  limit: z.ZodNumber;
124
- /** Total number of items across all pages */
125
96
  total: z.ZodNumber;
126
- /** Total number of pages */
127
97
  totalPages: z.ZodNumber;
128
- /** Whether there are more pages after this one */
129
98
  hasMore: z.ZodBoolean;
130
- }, "strip", z.ZodTypeAny, {
131
- page: number;
132
- limit: number;
133
- total: number;
134
- totalPages: number;
135
- hasMore: boolean;
136
- }, {
137
- page: number;
138
- limit: number;
139
- total: number;
140
- totalPages: number;
141
- hasMore: boolean;
142
- }>;
143
- }, "strip", z.ZodTypeAny, {
144
- data: T["_output"][];
145
- meta: {
146
- page: number;
147
- limit: number;
148
- total: number;
149
- totalPages: number;
150
- hasMore: boolean;
151
- };
152
- }, {
153
- data: T["_input"][];
154
- meta: {
155
- page: number;
156
- limit: number;
157
- total: number;
158
- totalPages: number;
159
- hasMore: boolean;
160
- };
161
- }>;
99
+ }, z.core.$strip>;
100
+ }, z.core.$strip>;
162
101
  /**
163
102
  * Type helper to infer paginated response type from item schema
164
103
  */
@@ -182,41 +121,14 @@ export interface PaginationMeta {
182
121
  * @param itemSchema - Zod schema for individual items
183
122
  * @returns Zod schema for cursor-paginated response
184
123
  */
185
- export declare function createCursorPaginatedResponseSchema<T extends z.ZodTypeAny>(itemSchema: T): z.ZodObject<{
186
- /** Array of items */
187
- data: z.ZodArray<T, "many">;
188
- /** Cursor pagination metadata */
124
+ export declare function createCursorPaginatedResponseSchema<T extends z.ZodType>(itemSchema: T): z.ZodObject<{
125
+ data: z.ZodArray<T>;
189
126
  meta: z.ZodObject<{
190
- /** Cursor for the next page (null if no more) */
191
127
  nextCursor: z.ZodNullable<z.ZodString>;
192
- /** Cursor for the previous page (null if at start) */
193
128
  prevCursor: z.ZodNullable<z.ZodString>;
194
- /** Whether there are more items after this page */
195
129
  hasMore: z.ZodBoolean;
196
- }, "strip", z.ZodTypeAny, {
197
- hasMore: boolean;
198
- nextCursor: string | null;
199
- prevCursor: string | null;
200
- }, {
201
- hasMore: boolean;
202
- nextCursor: string | null;
203
- prevCursor: string | null;
204
- }>;
205
- }, "strip", z.ZodTypeAny, {
206
- data: T["_output"][];
207
- meta: {
208
- hasMore: boolean;
209
- nextCursor: string | null;
210
- prevCursor: string | null;
211
- };
212
- }, {
213
- data: T["_input"][];
214
- meta: {
215
- hasMore: boolean;
216
- nextCursor: string | null;
217
- prevCursor: string | null;
218
- };
219
- }>;
130
+ }, z.core.$strip>;
131
+ }, z.core.$strip>;
220
132
  /**
221
133
  * Type for cursor-paginated response
222
134
  */
@@ -29,8 +29,8 @@ import { z } from 'zod';
29
29
  * }))
30
30
  * ```
31
31
  */
32
- export declare function queryNumber(): z.ZodNumber;
33
- export declare function queryNumber(defaultValue: number): z.ZodDefault<z.ZodNumber>;
32
+ export declare function queryNumber(): z.ZodType<number>;
33
+ export declare function queryNumber(defaultValue: number): z.ZodType<number>;
34
34
  /**
35
35
  * Creates an integer schema that coerces from query string
36
36
  *
@@ -45,8 +45,8 @@ export declare function queryNumber(defaultValue: number): z.ZodDefault<z.ZodNum
45
45
  * }))
46
46
  * ```
47
47
  */
48
- export declare function queryInt(): z.ZodNumber;
49
- export declare function queryInt(defaultValue: number): z.ZodDefault<z.ZodNumber>;
48
+ export declare function queryInt(): z.ZodType<number>;
49
+ export declare function queryInt(defaultValue: number): z.ZodType<number>;
50
50
  /**
51
51
  * Creates a boolean schema that coerces from query string
52
52
  *
@@ -117,7 +117,7 @@ export declare function queryArray(options?: {
117
117
  max?: number;
118
118
  /** Separator character (default: ',') */
119
119
  separator?: string;
120
- }): z.ZodType<string[], z.ZodTypeDef, string>;
120
+ }): z.ZodType;
121
121
  /**
122
122
  * Creates an enum schema that validates against allowed values
123
123
  *
@@ -136,8 +136,12 @@ export declare function queryArray(options?: {
136
136
  * // Result: { sort: 'desc', status: 'active' }
137
137
  * ```
138
138
  */
139
- export declare function queryEnum<T extends readonly [string, ...string[]]>(values: T): z.ZodEnum<[T[number], ...T[number][]]>;
140
- export declare function queryEnum<T extends readonly [string, ...string[]]>(values: T, defaultValue: T[number]): z.ZodDefault<z.ZodEnum<[T[number], ...T[number][]]>>;
139
+ export declare function queryEnum<const T extends readonly [string, ...string[]]>(values: T): z.ZodEnum<{
140
+ [K in T[number]]: K;
141
+ }>;
142
+ export declare function queryEnum<const T extends readonly [string, ...string[]]>(values: T, defaultValue: T[number]): z.ZodDefault<z.ZodEnum<{
143
+ [K in T[number]]: K;
144
+ }>>;
141
145
  /**
142
146
  * Pre-built pagination schema for common use cases
143
147
  *
@@ -174,12 +178,6 @@ export declare function pagination(options?: {
174
178
  /** Maximum allowed items per page (default: 100) */
175
179
  maxLimit?: number;
176
180
  }): z.ZodObject<{
177
- page: z.ZodDefault<z.ZodNumber>;
178
- limit: z.ZodDefault<z.ZodNumber>;
179
- }, "strip", z.ZodTypeAny, {
180
- page: number;
181
- limit: number;
182
- }, {
183
- page?: number | undefined;
184
- limit?: number | undefined;
185
- }>;
181
+ page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
182
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
183
+ }, z.core.$strip>;
@@ -105,10 +105,8 @@ export function queryArray(options = {}) {
105
105
  return baseSchema;
106
106
  }
107
107
  export function queryEnum(values, defaultValue) {
108
- // Cast to mutable tuple type that Zod expects
109
- const mutableValues = [...values];
110
- const base = z.enum(mutableValues);
111
- return defaultValue !== undefined ? base.default(defaultValue) : base;
108
+ const base = z.enum(values);
109
+ return (defaultValue !== undefined ? base.default(defaultValue) : base);
112
110
  }
113
111
  // ============================================================================
114
112
  // Pagination Shorthand
@@ -50,19 +50,19 @@ export type OmitTimestamps<T> = Omit<T, 'createdAt' | 'updatedAt' | 'deletedAt'>
50
50
  * });
51
51
  * ```
52
52
  */
53
- export declare function prismaDecimal(): z.ZodEffects<z.ZodAny, number, any>;
53
+ export declare function prismaDecimal(): z.ZodPipe<z.ZodUnknown, z.ZodTransform<number, unknown>>;
54
54
  /**
55
55
  * Nullable version of prismaDecimal
56
56
  *
57
57
  * Returns null for null/undefined inputs, otherwise converts to number.
58
58
  */
59
- export declare function prismaDecimalNullable(): z.ZodEffects<z.ZodAny, number | null, any>;
59
+ export declare function prismaDecimalNullable(): z.ZodPipe<z.ZodUnknown, z.ZodTransform<number | null, unknown>>;
60
60
  /**
61
61
  * Optional version of prismaDecimal
62
62
  *
63
63
  * Returns undefined for null/undefined inputs, otherwise converts to number.
64
64
  */
65
- export declare function prismaDecimalOptional(): z.ZodEffects<z.ZodAny, number | undefined, any>;
65
+ export declare function prismaDecimalOptional(): z.ZodPipe<z.ZodUnknown, z.ZodTransform<number | undefined, unknown>>;
66
66
  /**
67
67
  * Creates a date field that serializes to ISO string
68
68
  *
@@ -78,15 +78,15 @@ export declare function prismaDecimalOptional(): z.ZodEffects<z.ZodAny, number |
78
78
  * });
79
79
  * ```
80
80
  */
81
- export declare function dateToISOString(): z.ZodEffects<z.ZodDate, string, Date>;
81
+ export declare function dateToISOString(): z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
82
82
  /**
83
83
  * Creates a nullable date field that serializes to ISO string or null
84
84
  */
85
- export declare function dateToISOStringNullable(): z.ZodEffects<z.ZodNullable<z.ZodDate>, string | null, Date | null>;
85
+ export declare function dateToISOStringNullable(): z.ZodPipe<z.ZodNullable<z.ZodCoercedDate<unknown>>, z.ZodTransform<string | null, Date | null>>;
86
86
  /**
87
87
  * Creates an optional date field that serializes to ISO string or undefined
88
88
  */
89
- export declare function dateToISOStringOptional(): z.ZodEffects<z.ZodOptional<z.ZodDate>, string | undefined, Date | undefined>;
89
+ export declare function dateToISOStringOptional(): z.ZodPipe<z.ZodOptional<z.ZodCoercedDate<unknown>>, z.ZodTransform<string | undefined, Date | undefined>>;
90
90
  /**
91
91
  * Alias for dateToISOString for naming consistency
92
92
  * @alias dateToISOString
@@ -110,35 +110,21 @@ export declare const dateToIsoOptional: typeof dateToISOStringOptional;
110
110
  * const UserSchema = z.object({
111
111
  * id: z.string().uuid(),
112
112
  * name: z.string(),
113
- * }).merge(timestamps);
113
+ * }).extend(timestamps.shape);
114
114
  * ```
115
115
  */
116
116
  export declare const timestamps: ZodObject<{
117
- createdAt: z.ZodEffects<z.ZodDate, string, Date>;
118
- updatedAt: z.ZodEffects<z.ZodDate, string, Date>;
119
- }, "strip", z.ZodTypeAny, {
120
- createdAt: string;
121
- updatedAt: string;
122
- }, {
123
- createdAt: Date;
124
- updatedAt: Date;
125
- }>;
117
+ createdAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
118
+ updatedAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
119
+ }, z.core.$strip>;
126
120
  /**
127
121
  * Timestamp fields with soft delete support
128
122
  */
129
123
  export declare const timestampsWithSoftDelete: ZodObject<{
130
- createdAt: z.ZodEffects<z.ZodDate, string, Date>;
131
- updatedAt: z.ZodEffects<z.ZodDate, string, Date>;
132
- deletedAt: z.ZodEffects<z.ZodNullable<z.ZodDate>, string | null, Date | null>;
133
- }, "strip", z.ZodTypeAny, {
134
- createdAt: string;
135
- updatedAt: string;
136
- deletedAt: string | null;
137
- }, {
138
- createdAt: Date;
139
- updatedAt: Date;
140
- deletedAt: Date | null;
141
- }>;
124
+ createdAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
125
+ updatedAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
126
+ deletedAt: z.ZodPipe<z.ZodNullable<z.ZodCoercedDate<unknown>>, z.ZodTransform<string | null, Date | null>>;
127
+ }, z.core.$strip>;
142
128
  /**
143
129
  * Configuration for withTimestamps
144
130
  */
@@ -177,8 +163,8 @@ interface TimestampConfig {
177
163
  */
178
164
  export declare function withTimestamps<T extends ZodRawShape>(schema: ZodObject<T>, config?: TimestampConfig): ZodObject<T & typeof timestampShape>;
179
165
  declare const timestampShape: {
180
- createdAt: z.ZodEffects<z.ZodDate, string, Date>;
181
- updatedAt: z.ZodEffects<z.ZodDate, string, Date>;
166
+ createdAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
167
+ updatedAt: z.ZodPipe<z.ZodCoercedDate<unknown>, z.ZodTransform<string, Date>>;
182
168
  };
183
169
  /**
184
170
  * Type helper to infer the output type of a schema with timestamps
@@ -26,7 +26,7 @@ import { z } from 'zod';
26
26
  * ```
27
27
  */
28
28
  export function prismaDecimal() {
29
- return z.any().transform((val) => {
29
+ return z.unknown().transform((val) => {
30
30
  if (val === null || val === undefined) {
31
31
  throw new Error('Expected Decimal, got null/undefined');
32
32
  }
@@ -55,7 +55,7 @@ export function prismaDecimal() {
55
55
  * Returns null for null/undefined inputs, otherwise converts to number.
56
56
  */
57
57
  export function prismaDecimalNullable() {
58
- return z.any().transform((val) => {
58
+ return z.unknown().transform((val) => {
59
59
  if (val === null || val === undefined) {
60
60
  return null;
61
61
  }
@@ -81,7 +81,7 @@ export function prismaDecimalNullable() {
81
81
  * Returns undefined for null/undefined inputs, otherwise converts to number.
82
82
  */
83
83
  export function prismaDecimalOptional() {
84
- return z.any().transform((val) => {
84
+ return z.unknown().transform((val) => {
85
85
  if (val === null || val === undefined) {
86
86
  return undefined;
87
87
  }
@@ -166,7 +166,7 @@ export const dateToIsoOptional = dateToISOStringOptional;
166
166
  * const UserSchema = z.object({
167
167
  * id: z.string().uuid(),
168
168
  * name: z.string(),
169
- * }).merge(timestamps);
169
+ * }).extend(timestamps.shape);
170
170
  * ```
171
171
  */
172
172
  export const timestamps = z.object({
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @module types
8
8
  */
9
- import type { ZodType, ZodTypeDef } from 'zod';
9
+ import type { ZodType } from 'zod';
10
10
  /**
11
11
  * Type-safe validator interface that wraps Zod schemas
12
12
  *
@@ -77,7 +77,9 @@ export interface ValidationIssue {
77
77
  * // User = { id: string; name: string }
78
78
  * ```
79
79
  */
80
- export type InferOutput<T> = T extends Schema<infer O, infer _I> ? O : T extends ZodType<infer O, ZodTypeDef, infer _I> ? O : never;
80
+ export type InferOutput<T> = T extends Schema<infer O, infer _I> ? O : T extends {
81
+ parse: (data: unknown) => infer O;
82
+ } ? O : never;
81
83
  /**
82
84
  * Infers the input type from a Schema or ZodType
83
85
  *
@@ -92,13 +94,17 @@ export type InferOutput<T> = T extends Schema<infer O, infer _I> ? O : T extends
92
94
  * // DateInput = string (not Date)
93
95
  * ```
94
96
  */
95
- export type InferInput<T> = T extends Schema<infer _O, infer I> ? I : T extends ZodType<infer _O, ZodTypeDef, infer I> ? I : never;
97
+ export type InferInput<T> = T extends Schema<infer _O, infer I> ? I : T extends {
98
+ _input: infer I;
99
+ } ? I : T extends {
100
+ '~input': infer I;
101
+ } ? I : never;
96
102
  /**
97
103
  * Type constraint for any Zod schema
98
104
  *
99
105
  * Used in generic constraints to accept any valid Zod schema.
100
106
  */
101
- export type AnyZodSchema = ZodType<unknown, ZodTypeDef, unknown>;
107
+ export type AnyZodSchema = ZodType;
102
108
  /**
103
109
  * Type constraint for any Schema wrapper
104
110
  */
@@ -137,7 +143,9 @@ export declare function isZodSchema(value: unknown): value is AnyZodSchema;
137
143
  * }));
138
144
  * ```
139
145
  */
140
- export declare function wrapSchema<TOutput, TInput = TOutput>(zodSchema: ZodType<TOutput, ZodTypeDef, TInput>): Schema<TOutput, TInput>;
146
+ export declare function wrapSchema<TOutput, TInput = TOutput>(zodSchema: ZodType & {
147
+ parse: (input: unknown) => TOutput;
148
+ }): Schema<TOutput, TInput>;
141
149
  /**
142
150
  * Represents no input (undefined) for procedures without input schemas
143
151
  */
package/dist/types.js CHANGED
@@ -23,7 +23,7 @@ export function isZodSchema(value) {
23
23
  value !== null &&
24
24
  'parse' in value &&
25
25
  'safeParse' in value &&
26
- '_def' in value);
26
+ ('_zod' in value || '_def' in value));
27
27
  }
28
28
  // ============================================================================
29
29
  // Schema Wrapper Factory
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veloxts/validation",
3
- "version": "0.6.102",
3
+ "version": "0.6.104",
4
4
  "description": "Zod integration and validation middleware for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,8 +22,8 @@
22
22
  }
23
23
  },
24
24
  "dependencies": {
25
- "zod": "3.25.76",
26
- "@veloxts/core": "0.6.102"
25
+ "zod": "4.3.6",
26
+ "@veloxts/core": "0.6.104"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@vitest/coverage-v8": "4.0.18",
@@ -31,7 +31,7 @@
31
31
  "vitest": "4.0.18"
32
32
  },
33
33
  "peerDependencies": {
34
- "zod": "^3.25.0"
34
+ "zod": "^4.3.0"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "zod": {