function expandSchema()

in experimental/generation/generator/packages/library/src/dialogGenerator.ts [796:864]


function expandSchema(schema: any, scope: any, path: string, inProperties: boolean, missingIsError: boolean, feedback: Feedback): any {
    let newSchema = schema
    const isTopLevel = inProperties && !scope.propertySchema
    if (Array.isArray(schema)) {
        newSchema = []
        let isExpanded = false
        for (const val of schema) {
            const isExpr = typeof val === 'string' && val.startsWith('${')
            const newVal = expandSchema(val, scope, path, false, missingIsError, feedback)
            isExpanded = isExpanded || (isExpr && (typeof newVal !== 'string' || !val.startsWith('${')))
            if (newVal !== null) {
                if (Array.isArray(newVal)) {
                    newSchema = [...newSchema, ...newVal]
                } else {
                    newSchema.push(newVal)
                }
            }
        }
        if (isExpanded && newSchema.length > 0 && !path.includes('.')) {
            // Assume top-level arrays are merged across schemas
            newSchema = Array.from(new Set(newSchema.flat(1)))
            if (typeof newSchema[0] === 'object') {
                // Merge into single object
                let obj = {}
                for (const elt of newSchema) {
                    obj = {...obj, ...elt}
                }
                newSchema = obj
            }
        }
    } else if (typeof schema === 'object') {
        newSchema = {}
        for (const [key, val] of Object.entries(schema)) {
            let newPath = path
            if (inProperties) {
                newPath += newPath === '' ? key : '.' + key
            }
            if (key === '$parameters') {
                newSchema[key] = val
            } else {
                if (isTopLevel) {
                    // Bind property schema to use when expanding
                    scope.propertySchema = val
                }
                const newVal = expandSchema(val, {...scope, property: newPath}, newPath, key === 'properties', missingIsError, feedback)
                newSchema[key] = newVal
                if (isTopLevel) {
                    delete scope.propertySchema
                }
            }
        }
    } else if (typeof schema === 'string' && schema.startsWith('${')) {
        try {
            const value = generatorTemplate.evaluateText(schema, scope)
            if (value && value !== 'null') {
                newSchema = value
            } else {
                if (missingIsError) {
                    feedback(FeedbackType.error, `Could not evaluate ${schema} in schema`)
                }
            }
        } catch (e) {
            if (missingIsError) {
                feedback(FeedbackType.error, (e as Error).message)
            }
        }
    }
    return newSchema
}