From be99a4ddd60cf6dc99d28659967d4e01a9f7cc1e Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 21 Feb 2023 12:31:25 +0100 Subject: [PATCH 1/3] feat: added the ability to grab the schema for the field definition in the validator Signed-off-by: blam --- .../Stepper/createAsyncValidators.test.ts | 73 +++++++++++++++++++ .../Stepper/createAsyncValidators.ts | 21 +++++- .../src/next/extensions/types.ts | 6 +- 3 files changed, 96 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts index 3c4442afea..196bae0255 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts @@ -56,6 +56,79 @@ describe('createAsyncValidators', () => { expect(validators.AddressField).toHaveBeenCalled(); }); + it('should call the validator function with the correct schema in the context', async () => { + const schema: JsonObject = { + type: 'object', + properties: { + name: { + type: 'string', + 'ui:options': { + bob: true, + }, + pattern: 'lols', + 'ui:field': 'NameField', + }, + address: { + type: 'object', + 'ui:field': 'AddressField', + properties: { + street: { + type: 'string', + }, + postcode: { + type: 'string', + }, + }, + }, + }, + }; + + const validators = { NameField: jest.fn(), AddressField: jest.fn() }; + + const validate = createAsyncValidators(schema, validators, { + apiHolder: { get: jest.fn() }, + }); + + await validate({ + name: 'asd', + address: { street: 'street', postcode: 'postcode' }, + }); + + expect(validators.NameField).toHaveBeenCalledWith( + 'asd', + expect.anything(), + expect.objectContaining({ + schema: { + type: 'string', + 'ui:options': { + bob: true, + }, + pattern: 'lols', + 'ui:field': 'NameField', + }, + }), + ); + + expect(validators.AddressField).toHaveBeenCalledWith( + { street: 'street', postcode: 'postcode' }, + expect.anything(), + expect.objectContaining({ + schema: { + type: 'object', + 'ui:field': 'AddressField', + properties: { + street: { + type: 'string', + }, + postcode: { + type: 'string', + }, + }, + }, + }), + ); + }); + it('should return the correct errors to the frontend', async () => { const schema: JsonObject = { type: 'object', diff --git a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts index b524944719..111f3a0f1f 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts @@ -48,12 +48,17 @@ export const createAsyncValidators = ( validatorName: string, key: string, value: JsonValue | undefined, + schema: JsonObject, ) => { const validator = validators[validatorName]; if (validator) { const fieldValidation = createFieldValidation(); try { - await validator(value, fieldValidation, { ...context, formData }); + await validator(value, fieldValidation, { + ...context, + formData, + schema, + }); } catch (ex) { fieldValidation.addError(ex.message); } @@ -67,7 +72,12 @@ export const createAsyncValidators = ( if (definitionInSchema && 'ui:field' in definitionInSchema) { if ('ui:field' in definitionInSchema) { - await validateForm(definitionInSchema['ui:field'], key, value); + await validateForm( + definitionInSchema['ui:field'], + key, + value, + definitionInSchema, + ); } } else if ( definitionInSchema && @@ -75,7 +85,12 @@ export const createAsyncValidators = ( 'ui:field' in definitionInSchema.items ) { if ('ui:field' in definitionInSchema.items) { - await validateForm(definitionInSchema.items['ui:field'], key, value); + await validateForm( + definitionInSchema.items['ui:field'], + key, + value, + definitionInSchema.items, + ); } } else if (isObject(value)) { formValidation[key] = await validate(formData, path, value); diff --git a/plugins/scaffolder-react/src/next/extensions/types.ts b/plugins/scaffolder-react/src/next/extensions/types.ts index 27778b0420..d8ed2817d3 100644 --- a/plugins/scaffolder-react/src/next/extensions/types.ts +++ b/plugins/scaffolder-react/src/next/extensions/types.ts @@ -46,7 +46,11 @@ export interface NextFieldExtensionComponentProps< export type NextCustomFieldValidator = ( data: TFieldReturnValue, field: FieldValidationV5, - context: { apiHolder: ApiHolder; formData: JsonObject }, + context: { + apiHolder: ApiHolder; + formData: JsonObject; + schema?: JsonObject; + }, ) => void | Promise; /** From cc418d652a7517b3031ce9aa277438db09bf339b Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 21 Feb 2023 12:33:07 +0100 Subject: [PATCH 2/3] chore: added changeset Signed-off-by: blam --- .changeset/six-melons-rhyme.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-melons-rhyme.md diff --git a/.changeset/six-melons-rhyme.md b/.changeset/six-melons-rhyme.md new file mode 100644 index 0000000000..dbb878fc89 --- /dev/null +++ b/.changeset/six-melons-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +scaffolder/next: Added the ability to get the fields definition in the schema in the validation function From 8fbcbd34b61a3bab56d6c4863f2fcc4271784c26 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 21 Feb 2023 12:39:37 +0100 Subject: [PATCH 3/3] chore: this is always going to be present Signed-off-by: blam --- plugins/scaffolder-react/api-report.md | 1 + plugins/scaffolder-react/src/next/extensions/types.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index 33246d8bea..69bffbf724 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -176,6 +176,7 @@ export type NextCustomFieldValidator = ( context: { apiHolder: ApiHolder; formData: JsonObject; + schema: JsonObject; }, ) => void | Promise; diff --git a/plugins/scaffolder-react/src/next/extensions/types.ts b/plugins/scaffolder-react/src/next/extensions/types.ts index d8ed2817d3..1e4c671511 100644 --- a/plugins/scaffolder-react/src/next/extensions/types.ts +++ b/plugins/scaffolder-react/src/next/extensions/types.ts @@ -49,7 +49,7 @@ export type NextCustomFieldValidator = ( context: { apiHolder: ApiHolder; formData: JsonObject; - schema?: JsonObject; + schema: JsonObject; }, ) => void | Promise;