11import type { JsfObjectSchema , JsfSchema , JsfSchemaType , NonBooleanJsfSchema } from '../types'
22import type { Field , FieldOption , FieldType } from './type'
3- import { buildFieldArray } from './array'
4- import { buildFieldObject } from './object'
3+ import { setCustomOrder } from '../custom/order'
54
65/**
76 * Add checkbox attributes to a field
@@ -49,13 +48,8 @@ function getInputTypeFromSchema(type: JsfSchemaType, schema: NonBooleanJsfSchema
4948 return 'number'
5049 case 'object' :
5150 return 'fieldset'
52- case 'array' : {
53- const { items } = schema
54- if ( items ?. properties ) {
55- return 'group-array'
56- }
57- return 'select'
58- }
51+ case 'array' :
52+ return 'group-array'
5953 case 'boolean' :
6054 return 'checkbox'
6155 default :
@@ -68,7 +62,7 @@ function getInputTypeFromSchema(type: JsfSchemaType, schema: NonBooleanJsfSchema
6862 * @param schema - The non boolean schema of the field
6963 * @returns The input type for the field, based schema type. Default to 'text'
7064 */
71- function getInputType ( schema : NonBooleanJsfSchema , strictInputType ?: boolean ) : FieldType {
65+ export function getInputType ( schema : NonBooleanJsfSchema , strictInputType ?: boolean ) : FieldType {
7266 const presentation = schema [ 'x-jsf-presentation' ]
7367 if ( presentation ?. inputType ) {
7468 return presentation . inputType as FieldType
@@ -170,6 +164,68 @@ function getFieldOptions(schema: NonBooleanJsfSchema) {
170164 return null
171165}
172166
167+ function getObjectFields ( schema : NonBooleanJsfSchema , strictInputType ?: boolean ) : Field [ ] | null {
168+ const fields : Field [ ] = [ ]
169+
170+ for ( const key in schema . properties ) {
171+ const isRequired = schema . required ?. includes ( key ) || false
172+ const field = buildFieldSchema ( schema . properties [ key ] , key , isRequired , strictInputType )
173+ if ( field ) {
174+ fields . push ( field )
175+ }
176+ }
177+
178+ const orderedFields = setCustomOrder ( { fields, schema } )
179+
180+ return orderedFields
181+ }
182+
183+ function getArrayFields ( schema : NonBooleanJsfSchema , strictInputType ?: boolean ) : Field [ ] {
184+ const fields : Field [ ] = [ ]
185+
186+ if ( typeof schema . items !== 'object' || schema . items === null ) {
187+ return [ ]
188+ }
189+
190+ if ( schema . items ?. type === 'object' ) {
191+ const objectSchema = schema . items as JsfObjectSchema
192+
193+ for ( const key in objectSchema . properties ) {
194+ const isFieldRequired = objectSchema . required ?. includes ( key ) || false
195+ const field = buildFieldSchema ( objectSchema . properties [ key ] , key , isFieldRequired , strictInputType )
196+ if ( field ) {
197+ field . nameKey = key
198+ fields . push ( field )
199+ }
200+ }
201+ }
202+ else {
203+ const field = buildFieldSchema ( schema . items , 'item' , false , strictInputType )
204+ if ( field ) {
205+ fields . push ( field )
206+ }
207+ }
208+
209+ return fields
210+ }
211+
212+ /**
213+ * Get the fields for a schema from either `items` or `properties`
214+ * @param schema - The schema of the field
215+ * @param strictInputType - Whether to strictly enforce the input type
216+ * @returns The fields for the schema
217+ */
218+ function getFields ( schema : NonBooleanJsfSchema , strictInputType ?: boolean ) : Field [ ] | null {
219+ if ( typeof schema . items === 'object' ) {
220+ return getArrayFields ( schema , strictInputType )
221+ }
222+ else if ( schema . type === 'object' ) {
223+ return getObjectFields ( schema , strictInputType )
224+ }
225+
226+ return null
227+ }
228+
173229/**
174230 * List of schema properties that should be excluded from the final field or handled specially
175231 */
@@ -180,7 +236,7 @@ const excludedSchemaProps = [
180236 'x-jsf-presentation' , // Handled separately
181237 'oneOf' , // Transformed to 'options'
182238 'anyOf' , // Transformed to 'options'
183- 'items ' , // Handled specially for arrays
239+ 'properties ' , // Handled separately
184240]
185241
186242/**
@@ -210,16 +266,6 @@ export function buildFieldSchema(
210266 return null
211267 }
212268
213- if ( schema . type === 'object' ) {
214- const objectSchema : JsfObjectSchema = { ...schema , type : 'object' }
215- return buildFieldObject ( objectSchema , name , required )
216- }
217-
218- if ( schema . type === 'array' ) {
219- const arraySchema = schema as NonBooleanJsfSchema & { type : 'array' }
220- return buildFieldArray ( arraySchema , name , required , strictInputType )
221- }
222-
223269 const presentation = schema [ 'x-jsf-presentation' ] || { }
224270 const errorMessage = schema [ 'x-jsf-errorMessage' ]
225271
@@ -264,5 +310,11 @@ export function buildFieldSchema(
264310 field . options = options
265311 }
266312
313+ // Handle array fields
314+ const fields = getFields ( schema , strictInputType )
315+ if ( fields ) {
316+ field . fields = fields
317+ }
318+
267319 return field
268320}
0 commit comments