Skip to content

Instantly share code, notes, and snippets.

@modellking
Created October 22, 2023 22:21
Show Gist options
  • Save modellking/d44060795fcbc24a0cf1eefb824b9863 to your computer and use it in GitHub Desktop.
Save modellking/d44060795fcbc24a0cf1eefb824b9863 to your computer and use it in GitHub Desktop.
React JsonSchema Form schemaMerger
const handleObject = (node, path, cUiNode) =>
Object.fromEntries(Object.entries(node.properties).map(([prop, subschema]) => {
const fullCPath = [...path, prop]
return [prop, handleLayer(subschema, fullCPath, cUiNode[prop] ??= {})]
}))
const handleArray = (node, path, cUiNode) => handleLayer(node.items, [...path, "items", cUiNode.items ??= {}])
const handleOneOfAnyOf = (node, path, cUiNode, oneOf = node.oneOf) => {
oneOf.map(n => handleLayer(n, path, cUiNode)).forEach(o => Object.entries(o).forEach(([prop, subschema]) => cUiNode[prop] ??= subschema))
return cUiNode
}
const handleLayer = (node, path, cUiNode) => {
cUiNode ??= {}
Object.entries(node).forEach(([key, pVal]) => {
if (key.startsWith("ui:")) cUiNode[key] ??= pVal // Conflict Resolution: Keep UiSchema
})
if (node.type === "object") return handleObject(node, path, cUiNode)
else if (node.type === "array") return handleArray(node, path, cUiNode)
else if (node.oneOf) return handleOneOfAnyOf(node, path, cUiNode, node.oneOf)
else if (node.anyOf) return handleOneOfAnyOf(node, path, cUiNode, node.anyOf)
// Any other type should not recurse
return cUiNode
}
export const extendUiSchemaWithSchemaAnnotations = (schema, uiSchema = {}) => {
return handleLayer(deepCopy(schema), [], deepCopy(uiSchema))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment