in packages/dialog/src/library/schemaMerger.ts [1948:2041]
private verifySchema(schema: any): void {
this.log('Verifying schema')
this.validateSchema(schema)
for (const entry of schema.oneOf) {
this.currentKind = entry.$ref.substring(entry.$ref.lastIndexOf('/') + 1)
const definition = schema.definitions[this.currentKind]
const verifyProperty = (val, path) => {
if (val.$ref) {
const ref: any = ptr.get(schema, val.$ref)
if (!ref) {
this.mergingError(`${path} $ref ${val.$ref} does not exist`)
} else {
// Expand $ref to check locally
val = clone(val)
for (const prop in ref) {
if (!val[prop]) {
val[prop] = ref[prop]
}
}
delete val.$ref
}
}
if (!val.$schema) {
// Assume $schema is an external reference and ignore error checking
if (val.$kind) {
const kind = schema.definitions[val.$kind]
if (this.roles(kind, 'interface').length > 0) {
const implementations = kind.oneOf
let hasImplementation = false
if (kind.oneOf) {
for (const implementation of implementations) {
if (implementation.$ref) {
hasImplementation = true
break
}
}
}
if (!hasImplementation) {
this.mergingError(`${path} has no implementations of ${val.$kind}`)
}
}
}
if (typeof val === 'object') {
if (!val.title) {
this.mergingWarning(`${path} has no title`)
}
if (!val.description) {
this.mergingWarning(`${path} has no description`)
}
}
}
}
walkJSON(definition, (val, _, path) => {
if (val.$schema && path) {
// Embedded non-component schema
return true
}
if (val.properties && (!path || !path.endsWith('properties'))) {
for (const propName in val.properties) {
verifyProperty(val.properties[propName], pathName(path, propName))
}
}
if (val.items) {
if (Array.isArray(val.items)) {
for (const idx in val.items) {
verifyProperty(val.items[idx], pathName(path, `items/${idx}`))
}
} else {
verifyProperty(val.items, pathName(path, 'item'))
}
}
if (val.oneOf) {
for (const idx in val.oneOf) {
verifyProperty(val.oneOf[idx], pathName(path, `oneOf/${idx}`))
}
}
if (val.anyOf) {
for (const idx in val.anyOf) {
verifyProperty(val.anyOf[idx], pathName(path, `anyOf/${idx}`))
}
}
if (typeof val.additionalProperties === 'object') {
verifyProperty(val.additionalProperties, pathName(path, 'additionalProperties'))
}
if (val.patternProperties) {
for (const pattern in val.patternProperties) {
verifyProperty(val.patternProperties[pattern], pathName(path, `patternProperties/${pattern}`))
}
}
return false
})
}
this.currentKind = ''
}