Skip to content

Commit f98cb6b

Browse files
committed
fix: enhance validation for required fields and improve email format handling
1 parent acf5e04 commit f98cb6b

File tree

1 file changed

+66
-18
lines changed

1 file changed

+66
-18
lines changed

src/imports/meta/validateAndProcessValueFor.js

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,42 @@ export async function validateAndProcessValueFor({ meta, fieldName, value, actio
9797
}
9898

9999
// Validate required fields
100-
101-
if (field.isRequired === true && (value == null || (typeof value === 'string' && size(value) === 0))) {
102-
return errorReturn(`Field ${fieldName} is required`);
100+
// For list fields, also check if array is empty
101+
if (field.isRequired === true) {
102+
if (field.isList === true) {
103+
// For list fields, check if array is empty or null
104+
// If isRequired is true, minItems should be at least 1
105+
if (value == null || !isArray(value) || value.length === 0) {
106+
return errorReturn(`Field ${fieldName} is required`);
107+
}
108+
} else {
109+
// For non-list fields, check if null or empty string
110+
if (value == null || (typeof value === 'string' && size(value) === 0)) {
111+
return errorReturn(`Field ${fieldName} is required`);
112+
}
113+
}
103114
}
104115

105116
// Validate List fields
106117
if (field.isList === true) {
107-
if (field.maxElements && field.maxElements > 0) {
108-
if (!isArray(value) || value.length > field.maxElements) {
109-
return errorReturn(`Value for field ${fieldName} must be array with the maximum of ${field.maxElements} item(s)`);
118+
// Support both minItems (from JSON schema) and minElements (legacy)
119+
let minElements = field.minElements || field.minItems || 0;
120+
const maxElements = field.maxElements || field.maxItems || 0;
121+
122+
// If field is required but minItems is 0, enforce at least 1 item
123+
if (field.isRequired === true && minElements === 0) {
124+
minElements = 1;
125+
}
126+
127+
if (maxElements > 0) {
128+
if (!isArray(value) || value.length > maxElements) {
129+
return errorReturn(`Value for field ${fieldName} must be array with the maximum of ${maxElements} item(s)`);
110130
}
111131
}
112132

113-
if (field.minElements && field.minElements > 0) {
114-
if (!isArray(value) || value.length < field.minElements) {
115-
return errorReturn(`Value for field ${fieldName} must be array with the minimum of ${field.minElements} item(s)`);
133+
if (minElements > 0) {
134+
if (!isArray(value) || value.length < minElements) {
135+
return errorReturn(`Value for field ${fieldName} must be array with the minimum of ${minElements} item(s)`);
116136
}
117137
}
118138

@@ -524,22 +544,43 @@ export async function validateAndProcessValueFor({ meta, fieldName, value, actio
524544
};
525545

526546
case 'email':
527-
const emailObjectResult = mustBeObject(value);
528-
if (emailObjectResult.success === false) {
529-
return emailObjectResult;
547+
// Accept both string and object formats
548+
let emailAddress = null;
549+
let emailType = null;
550+
551+
if (isString(value)) {
552+
// If value is a string, convert to object format
553+
emailAddress = value.trim();
554+
emailType = null;
555+
} else if (isObject(value)) {
556+
// If value is already an object, use it
557+
emailAddress = value.address;
558+
emailType = value.type;
559+
} else {
560+
return {
561+
success: false,
562+
errors: [
563+
{
564+
message: `Value for field ${fieldName} must be a string or an object with 'address' property`,
565+
},
566+
],
567+
};
530568
}
531-
const addressResult = mustBeString(value.address, `${fieldName}.address`);
569+
570+
// Validate address is a string
571+
const addressResult = mustBeString(emailAddress, `${fieldName}.address`);
532572
if (addressResult.success === false) {
533573
return addressResult;
534574
}
535575

536-
const typeResult = mustBeStringOrNull(value.type, `${fieldName}.type`);
537-
576+
// Validate type if provided
577+
const typeResult = mustBeStringOrNull(emailType, `${fieldName}.type`);
538578
if (typeResult.success === false) {
539579
return typeResult;
540580
}
541581

542-
if (regexUtils.email.test(value.address) === false) {
582+
// Validate email format
583+
if (regexUtils.email.test(emailAddress) === false) {
543584
return {
544585
success: false,
545586
errors: [
@@ -550,11 +591,18 @@ export async function validateAndProcessValueFor({ meta, fieldName, value, actio
550591
};
551592
}
552593

553-
value.address = value.address.toLowerCase();
594+
// Return normalized object format
595+
const normalizedEmail = {
596+
address: emailAddress.toLowerCase(),
597+
};
598+
599+
if (emailType != null) {
600+
normalizedEmail.type = emailType;
601+
}
554602

555603
return {
556604
success: true,
557-
data: value,
605+
data: normalizedEmail,
558606
};
559607

560608
case 'url':

0 commit comments

Comments
 (0)