Incorporated feedback

Signed-off-by: bnechyporenko <bnechyporenko@bol.com>
This commit is contained in:
bnechyporenko
2023-02-10 14:29:04 +01:00
parent 8d3a8205d4
commit 5a2faa801f
3 changed files with 85 additions and 12 deletions
@@ -272,4 +272,59 @@ describe('createAsyncValidators', () => {
},
});
});
it('should call a validator for array property from a custom field extension', async () => {
const schema: JsonObject = {
type: 'object',
properties: {
tags: {
title: 'Tags',
type: 'array',
items: {
type: 'string',
'ui:field': 'TagField',
},
},
},
};
const validators = { TagField: jest.fn() };
const validate = createAsyncValidators(schema, validators, {
apiHolder: { get: jest.fn() },
});
await validate({
tags: ['tag-1', 'tag-2'],
});
expect(validators.TagField).toHaveBeenCalled();
});
it('should does not call a validator if no ui field specified', async () => {
const schema: JsonObject = {
type: 'object',
properties: {
tags: {
title: 'Tags',
type: 'array',
items: {
type: 'string',
},
},
},
};
const validators = { TagField: jest.fn() };
const validate = createAsyncValidators(schema, validators, {
apiHolder: { get: jest.fn() },
});
await validate({
tags: ['asd', 'asd$'],
});
expect(validators.TagField).not.toHaveBeenCalled();
});
});
@@ -15,7 +15,7 @@
*/
import { FieldValidation } from '@rjsf/utils';
import type { JsonObject } from '@backstage/types';
import type { JsonObject, JsonValue } from '@backstage/types';
import { ApiHolder } from '@backstage/core-plugin-api';
import { Draft07 as JSONSchema } from 'json-schema-library';
import { createFieldValidation } from '../../lib';
@@ -44,20 +44,38 @@ export const createAsyncValidators = (
const parsedSchema = new JSONSchema(rootSchema);
const formValidation: FormValidation = {};
const validateForm = async (
validatorName: string,
key: string,
value: JsonValue | undefined,
) => {
const validator = validators[validatorName];
if (validator) {
const fieldValidation = createFieldValidation();
try {
await validator(value, fieldValidation, { ...context, formData });
} catch (ex) {
fieldValidation.addError(ex.message);
}
formValidation[key] = fieldValidation;
}
};
for (const [key, value] of Object.entries(current)) {
const path = `${pathPrefix}/${key}`;
const definitionInSchema = parsedSchema.getSchema(path, formData);
if (definitionInSchema && 'ui:field' in definitionInSchema) {
const validator = validators[definitionInSchema['ui:field']];
if (validator) {
const fieldValidation = createFieldValidation();
try {
await validator(value, fieldValidation, { ...context, formData });
} catch (ex) {
fieldValidation.addError(ex.message);
}
formValidation[key] = fieldValidation;
if ('ui:field' in definitionInSchema) {
await validateForm(definitionInSchema['ui:field'], key, value);
}
} else if (
definitionInSchema &&
definitionInSchema.items &&
'ui:field' in definitionInSchema.items
) {
if ('ui:field' in definitionInSchema.items) {
await validateForm(definitionInSchema.items['ui:field'], key, value);
}
} else if (isObject(value)) {
formValidation[key] = await validate(formData, path, value);