@arkyn/server 3.0.1-beta.76 → 3.0.1-beta.78

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.
@@ -1,6 +1,7 @@
1
1
  import { ZodType, z } from "zod";
2
2
  import { ServerError } from "../http/badResponses/serverError";
3
3
  import { UnprocessableEntity } from "../http/badResponses/unprocessableEntity";
4
+ import { formAsyncParse } from "./formAsyncParse";
4
5
  import { formParse } from "./formParse";
5
6
  import { getCaller } from "./getCaller";
6
7
  function formatErrorMessage(error) {
@@ -8,22 +9,116 @@ function formatErrorMessage(error) {
8
9
  const lines = error.issues.map(({ path, message }) => `-> ${path.join(".")}: ${message}`);
9
10
  return [title, ...lines].join("\n");
10
11
  }
12
+ /**
13
+ * A schema validator class that provides multiple validation methods for Zod schemas.
14
+ *
15
+ * @template T - A type that extends ZodType.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { z } from "zod";
20
+ *
21
+ * const userSchema = z.object({
22
+ * name: z.string().min(1, "Name is required"),
23
+ * email: z.string().email("Invalid email"),
24
+ * age: z.number().min(18, "Must be at least 18")
25
+ * });
26
+ *
27
+ * const validator = new SchemaValidator(userSchema);
28
+ *
29
+ * // Check if data is valid without throwing
30
+ * const isValid = validator.isValid({ name: "John", email: "john@example.com", age: 25 });
31
+ *
32
+ * // Validate and throw ServerError on failure
33
+ * try {
34
+ * const validData = validator.validate({ name: "John", email: "john@example.com", age: 25 });
35
+ * } catch (error) {
36
+ * console.error(error.message);
37
+ * }
38
+ *
39
+ * // Form validation with UnprocessableEntity error
40
+ * try {
41
+ * const formData = validator.formValidate(requestBody);
42
+ * } catch (error) {
43
+ * // Returns structured error with fieldErrors for forms
44
+ * }
45
+ * ```
46
+ */
11
47
  class SchemaValidator {
12
48
  schema;
13
49
  functionName;
14
50
  callerInfo;
51
+ /**
52
+ * Creates a new SchemaValidator instance.
53
+ *
54
+ * @param {T} schema - The Zod schema to use for validation.
55
+ */
15
56
  constructor(schema) {
16
57
  this.schema = schema;
17
58
  const { callerInfo, functionName } = getCaller();
18
59
  this.callerInfo = callerInfo;
19
60
  this.functionName = functionName;
20
61
  }
62
+ /**
63
+ * Checks if the provided data is valid according to the schema without throwing errors.
64
+ *
65
+ * @param {any} data - The data to validate.
66
+ *
67
+ * @returns {boolean} True if the data is valid, false otherwise.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const validator = new SchemaValidator(userSchema);
72
+ * const isValid = validator.isValid({ name: "John", email: "invalid-email" });
73
+ * console.log(isValid); // false
74
+ * ```
75
+ */
21
76
  isValid(data) {
22
77
  return this.schema.safeParse(data).success;
23
78
  }
79
+ /**
80
+ * Safely validates data and returns the complete parse result without throwing errors.
81
+ *
82
+ * @param {any} data - The data to validate.
83
+ *
84
+ * @returns {z.ZodSafeParseResult<z.infer<T>>} The Zod safe parse result containing success status and data or error.
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const validator = new SchemaValidator(userSchema);
89
+ * const result = validator.safeValidate({ name: "", email: "john@example.com" });
90
+ *
91
+ * if (result.success) {
92
+ * console.log(result.data); // Validated data
93
+ * } else {
94
+ * console.log(result.error.issues); // Validation errors
95
+ * }
96
+ * ```
97
+ */
24
98
  safeValidate(data) {
25
99
  return this.schema.safeParse(data);
26
100
  }
101
+ /**
102
+ * Validates data and returns the parsed result, throwing a ServerError on validation failure.
103
+ *
104
+ * @param {any} data - The data to validate.
105
+ *
106
+ * @returns {z.infer<T>} The validated and parsed data.
107
+ *
108
+ * @throws {ServerError} When validation fails, with a formatted error message.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const validator = new SchemaValidator(userSchema);
113
+ *
114
+ * try {
115
+ * const validUser = validator.validate({ name: "John", email: "john@example.com", age: 25 });
116
+ * console.log(validUser); // { name: "John", email: "john@example.com", age: 25 }
117
+ * } catch (error) {
118
+ * console.error(error.message); // "Error validating:\n-> name: String must contain at least 1 character(s)"
119
+ * }
120
+ * ```
121
+ */
27
122
  validate(data) {
28
123
  try {
29
124
  return this.schema.parse(data);
@@ -32,6 +127,31 @@ class SchemaValidator {
32
127
  throw new ServerError(formatErrorMessage(error));
33
128
  }
34
129
  }
130
+ /**
131
+ * Validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
132
+ * This method is specifically designed for form validation in web applications.
133
+ *
134
+ * @param {any} data - The form data to validate.
135
+ * @param {string} [message] - Optional custom error message.
136
+ *
137
+ * @returns {z.infer<T>} The validated and parsed form data.
138
+ *
139
+ * @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const validator = new SchemaValidator(userSchema);
144
+ *
145
+ * try {
146
+ * const validFormData = validator.formValidate(requestBody, "User data is invalid");
147
+ * console.log(validFormData);
148
+ * } catch (error) {
149
+ * // UnprocessableEntity with fieldErrors, fields, and scrollTo data
150
+ * console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
151
+ * console.log(error.data.scrollTo); // "name" (first error field)
152
+ * }
153
+ * ```
154
+ */
35
155
  formValidate(data, message) {
36
156
  const formParsed = formParse([data, this.schema]);
37
157
  if (!formParsed.success) {
@@ -45,5 +165,43 @@ class SchemaValidator {
45
165
  }
46
166
  return formParsed.data;
47
167
  }
168
+ /**
169
+ * Asynchronously validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
170
+ * This method is the async version of formValidate, designed for form validation with async schemas.
171
+ *
172
+ * @param {any} data - The form data to validate.
173
+ * @param {string} [message] - Optional custom error message.
174
+ *
175
+ * @returns {Promise<z.infer<T>>} A promise that resolves to the validated and parsed form data.
176
+ *
177
+ * @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * const validator = new SchemaValidator(userSchemaWithAsyncValidation);
182
+ *
183
+ * try {
184
+ * const validFormData = await validator.formAsyncValidate(requestBody, "User data is invalid");
185
+ * console.log(validFormData);
186
+ * } catch (error) {
187
+ * // UnprocessableEntity with fieldErrors, fields, and scrollTo data
188
+ * console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
189
+ * console.log(error.data.scrollTo); // "name" (first error field)
190
+ * }
191
+ * ```
192
+ */
193
+ async formAsyncValidate(data, message) {
194
+ const formParsed = await formAsyncParse([data, this.schema]);
195
+ if (!formParsed.success) {
196
+ const firstErrorKey = Object.keys(formParsed.fieldErrors)[0];
197
+ throw new UnprocessableEntity({
198
+ fields: formParsed.fields,
199
+ fieldErrors: formParsed.fieldErrors,
200
+ data: { scrollTo: firstErrorKey },
201
+ message,
202
+ });
203
+ }
204
+ return formParsed.data;
205
+ }
48
206
  }
49
207
  export { SchemaValidator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkyn/server",
3
- "version": "3.0.1-beta.76",
3
+ "version": "3.0.1-beta.78",
4
4
  "author": "Arkyn | Lucas Gonçalves",
5
5
  "main": "./dist/bundle.js",
6
6
  "module": "./dist/bundle.js",