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
}