Merge pull request #5451 from SDA-SE/feat/scaffolder-anyof

Support anyOf schemas in the scaffolder template
This commit is contained in:
Dominik Henneke
2021-04-29 12:50:28 +02:00
committed by GitHub
3 changed files with 258 additions and 12 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Support `anyOf`, `oneOf` and `allOf` schemas in the scaffolder template.
@@ -70,4 +70,220 @@ describe('transformSchemaToProps', () => {
uiSchema: expectedUiSchema,
});
});
it('transforms schema with anyOf fields', () => {
const inputSchema = {
type: 'object',
anyOf: [
{
properties: {
field3: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
{
properties: {
field3: {
type: 'string',
default: 'Value 2',
'ui:readonly': true,
},
},
},
],
oneOf: [
{
properties: {
field4: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
],
allOf: [
{
properties: {
field5: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
],
properties: {
field1: {
type: 'object',
anyOf: [
{
properties: {
field3: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
{
properties: {
field3: {
type: 'string',
default: 'Value 2',
'ui:readonly': true,
},
},
},
],
oneOf: [
{
properties: {
field4: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
],
allOf: [
{
properties: {
field5: {
type: 'string',
default: 'Value 1',
'ui:readonly': true,
},
},
},
],
},
field2: {
type: 'string',
'ui:derp': 'xerp',
},
},
};
const expectedSchema = {
type: 'object',
anyOf: [
{
properties: {
field3: {
type: 'string',
default: 'Value 1',
},
},
},
{
properties: {
field3: {
type: 'string',
default: 'Value 2',
},
},
},
],
oneOf: [
{
properties: {
field4: {
type: 'string',
default: 'Value 1',
},
},
},
],
allOf: [
{
properties: {
field5: {
type: 'string',
default: 'Value 1',
},
},
},
],
properties: {
field1: {
type: 'object',
anyOf: [
{
properties: {
field3: {
type: 'string',
default: 'Value 1',
},
},
},
{
properties: {
field3: {
type: 'string',
default: 'Value 2',
},
},
},
],
oneOf: [
{
properties: {
field4: {
type: 'string',
default: 'Value 1',
},
},
},
],
allOf: [
{
properties: {
field5: {
type: 'string',
default: 'Value 1',
},
},
},
],
},
field2: {
type: 'string',
},
},
};
const expectedUiSchema = {
field3: {
'ui:readonly': true,
},
field4: {
'ui:readonly': true,
},
field5: {
'ui:readonly': true,
},
field1: {
field3: {
'ui:readonly': true,
},
field4: {
'ui:readonly': true,
},
field5: {
'ui:readonly': true,
},
},
field2: {
'ui:derp': 'xerp',
},
};
expect(transformSchemaToProps(inputSchema)).toEqual({
schema: expectedSchema,
uiSchema: expectedUiSchema,
});
});
});
@@ -26,7 +26,7 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) {
return;
}
const { properties } = schema;
const { properties, anyOf, oneOf, allOf } = schema;
for (const propName in schema) {
if (!schema.hasOwnProperty(propName)) {
@@ -39,22 +39,47 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) {
}
}
if (!isObject(properties)) {
return;
if (isObject(properties)) {
for (const propName in properties) {
if (!properties.hasOwnProperty(propName)) {
continue;
}
const schemaNode = properties[propName];
if (!isObject(schemaNode)) {
continue;
}
const innerUiSchema = {};
uiSchema[propName] = innerUiSchema;
extractUiSchema(schemaNode, innerUiSchema);
}
}
for (const propName in properties) {
if (!properties.hasOwnProperty(propName)) {
continue;
if (Array.isArray(anyOf)) {
for (const schemaNode of anyOf) {
if (!isObject(schemaNode)) {
continue;
}
extractUiSchema(schemaNode, uiSchema);
}
}
const schemaNode = properties[propName];
if (!isObject(schemaNode)) {
continue;
if (Array.isArray(oneOf)) {
for (const schemaNode of oneOf) {
if (!isObject(schemaNode)) {
continue;
}
extractUiSchema(schemaNode, uiSchema);
}
}
if (Array.isArray(allOf)) {
for (const schemaNode of allOf) {
if (!isObject(schemaNode)) {
continue;
}
extractUiSchema(schemaNode, uiSchema);
}
const innerUiSchema = {};
uiSchema[propName] = innerUiSchema;
extractUiSchema(schemaNode, innerUiSchema);
}
}