From 23769512a393445391f020b676ee5941ffbedcd6 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Fri, 23 Apr 2021 15:03:30 +0200 Subject: [PATCH 1/2] Support anyOf schemas in the scaffolder template Signed-off-by: Dominik Henneke --- .changeset/tough-planes-jump.md | 5 + .../MultistepJsonForm/schema.test.ts | 120 ++++++++++++++++++ .../components/MultistepJsonForm/schema.ts | 35 +++-- 3 files changed, 146 insertions(+), 14 deletions(-) create mode 100644 .changeset/tough-planes-jump.md diff --git a/.changeset/tough-planes-jump.md b/.changeset/tough-planes-jump.md new file mode 100644 index 0000000000..a30315e9e4 --- /dev/null +++ b/.changeset/tough-planes-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Support anyOf schemas in the scaffolder template diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts index b83725c2bb..edfde0ea90 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts @@ -70,4 +70,124 @@ 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, + }, + }, + }, + ], + 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, + }, + }, + }, + ], + }, + 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', + }, + }, + }, + ], + properties: { + field1: { + type: 'object', + anyOf: [ + { + properties: { + field3: { + type: 'string', + default: 'Value 1', + }, + }, + }, + { + properties: { + field3: { + type: 'string', + default: 'Value 2', + }, + }, + }, + ], + }, + field2: { + type: 'string', + }, + }, + }; + const expectedUiSchema = { + field3: { + 'ui:readonly': true, + }, + field1: { + field3: { + 'ui:readonly': true, + }, + }, + field2: { + 'ui:derp': 'xerp', + }, + }; + + expect(transformSchemaToProps(inputSchema)).toEqual({ + schema: expectedSchema, + uiSchema: expectedUiSchema, + }); + }); }); diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts index e591589bd8..c189bbf1a7 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts @@ -26,7 +26,7 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { return; } - const { properties } = schema; + const { properties, anyOf } = schema; for (const propName in schema) { if (!schema.hasOwnProperty(propName)) { @@ -39,22 +39,29 @@ 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; - } - const innerUiSchema = {}; - uiSchema[propName] = innerUiSchema; - extractUiSchema(schemaNode, innerUiSchema); } } From 08e32cf91327ac57628499c61524fc4e2dff3c46 Mon Sep 17 00:00:00 2001 From: Dominik Henneke Date: Thu, 29 Apr 2021 10:36:53 +0200 Subject: [PATCH 2/2] Add support for oneOf and allOf Signed-off-by: Dominik Henneke --- .changeset/tough-planes-jump.md | 2 +- .../MultistepJsonForm/schema.test.ts | 96 +++++++++++++++++++ .../components/MultistepJsonForm/schema.ts | 20 +++- 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/.changeset/tough-planes-jump.md b/.changeset/tough-planes-jump.md index a30315e9e4..ebbec65159 100644 --- a/.changeset/tough-planes-jump.md +++ b/.changeset/tough-planes-jump.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Support anyOf schemas in the scaffolder template +Support `anyOf`, `oneOf` and `allOf` schemas in the scaffolder template. diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts index edfde0ea90..64dd705952 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.test.ts @@ -94,6 +94,28 @@ describe('transformSchemaToProps', () => { }, }, ], + 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', @@ -117,6 +139,28 @@ describe('transformSchemaToProps', () => { }, }, ], + 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', @@ -144,6 +188,26 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], properties: { field1: { type: 'object', @@ -165,6 +229,26 @@ describe('transformSchemaToProps', () => { }, }, ], + oneOf: [ + { + properties: { + field4: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], + allOf: [ + { + properties: { + field5: { + type: 'string', + default: 'Value 1', + }, + }, + }, + ], }, field2: { type: 'string', @@ -175,10 +259,22 @@ describe('transformSchemaToProps', () => { 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', diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts index c189bbf1a7..b4aa3e309d 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts +++ b/plugins/scaffolder/src/components/MultistepJsonForm/schema.ts @@ -26,7 +26,7 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { return; } - const { properties, anyOf } = schema; + const { properties, anyOf, oneOf, allOf } = schema; for (const propName in schema) { if (!schema.hasOwnProperty(propName)) { @@ -63,6 +63,24 @@ function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { extractUiSchema(schemaNode, uiSchema); } } + + 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); + } + } } export function transformSchemaToProps(