Skip to content

Instantly share code, notes, and snippets.

@distums
Created July 29, 2020 09:01
Show Gist options
  • Select an option

  • Save distums/901e555d8f9dea8d602d18311e441075 to your computer and use it in GitHub Desktop.

Select an option

Save distums/901e555d8f9dea8d602d18311e441075 to your computer and use it in GitHub Desktop.
function constructSchemaTree({ name, required, path }, schema, uiSchema = {}) {
const {
type,
required: requiredProperties = [],
properties,
oneOf,
anyOf,
allOf,
dependencies,
items,
...rest
} = schema;
const branchType = ['oneOf', 'anyOf', 'allOf'].find(
type => schema[type] != null,
);
const node = {
name,
type: getTypeOfSchema(schema),
required,
path,
schema: rest,
uiSchema: Object.keys(uiSchema)
.filter(key => key.startsWith('ui:'))
.reduce((result, key) => {
result[key] = uiSchema[key];
return result;
}, {}),
childNodes: [],
branchType: branchType,
branchNodes: [],
dependencyNodes: [],
};
if (node.type === SchemaType.object && properties) {
node.childNodes = Object.keys(properties).map(propertyName => {
const childNode = constructSchemaTree(
{
name: propertyName,
required: requiredProperties.includes(propertyName),
path: `${path}/properties/${propertyName}`,
},
properties[propertyName],
uiSchema[propertyName],
);
return childNode;
});
} else if (node.type === SchemaType.array && items) {
node.childNodes = (Array.isArray(items) ? items : [items]).map(
(item, index) => {
return constructSchemaTree(
{
name: `${index}`,
required: false,
path: `${path}/items/${index}`,
},
item,
Array.isArray(uiSchema.items)
? uiSchema.items[index]
: uiSchema.items,
);
},
);
}
if (branchType) {
node.branchNodes = schema[branchType].map((item, index) => {
return constructSchemaTree(
{
name: `${index}`,
required: false,
path: `${path}/${branchType}/${index}`,
},
{
type: node.type,
...item,
},
uiSchema,
);
});
}
if (dependencies) {
node.dependencyNodes = Object.keys(dependencies).map(name => {
return constructSchemaTree(
{ name, required: false, path: `${path}/dependencies/${name}` },
dependencies[name],
uiSchema,
);
});
}
return node;
}
function constructJsonSchema(node) {
const schema = {
type: node.type,
...node.schema,
};
const uiSchema = {
...node.uiSchema,
};
if (node.type === SchemaType.object && node.childNodes?.length > 0) {
schema.properties = {};
node.childNodes.forEach(node => {
const {
schema: childSchema,
uiSchema: childUiSchema,
} = constructJsonSchema(node);
schema.properties[node.name] = childSchema;
if (Object.getOwnPropertyNames(childUiSchema).length > 0) {
uiSchema[node.name] = childUiSchema;
}
});
schema.required = node.childNodes
.filter(node => node.required)
.map(node => node.name);
} else if (node.type === SchemaType.array && node.childNodes.length === 1) {
const {
schema: childSchema,
uiSchema: childUiSchema,
} = constructJsonSchema(node.childNodes[0]);
schema.items = childSchema;
if (Object.getOwnPropertyNames(childUiSchema).length > 0) {
uiSchema.items = childUiSchema;
}
} else if (node.type === SchemaType.array && node.childNodes.length > 1) {
schema.items = [];
uiSchema.items = [];
node.childNodes.forEach(node => {
const {
schema: childSchema,
uiSchema: childUiSchema,
} = constructJsonSchema(node);
schema.items[node.name] = childSchema;
uiSchema.items[node.name] = childUiSchema;
});
}
if (node.branchType) {
schema[node.branchType] = (node.branchNodes ?? []).map(node => {
const {
schema: childSchema,
uiSchema: childUiSchema,
} = constructJsonSchema(node);
Object.assign(uiSchema, childUiSchema);
return childSchema;
});
}
if (node.dependencyNodes && node.dependencyNodes.length > 0) {
schema.dependencies = {};
node.dependencyNodes.forEach(node => {
const {
schema: childSchema,
uiSchema: childUiSchema,
} = constructJsonSchema(node);
schema.dependencies[node.name] = childSchema;
Object.assign(uiSchema, childUiSchema);
});
}
return {
schema,
uiSchema,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment