@@ -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