Skip to content

Commit dfcb65e

Browse files
authored
FE: Messages: Add schema validation support for more json-schema version refs (#900)
1 parent 8146e71 commit dfcb65e

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

frontend/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"@tanstack/react-table": "8.16.0",
1515
"ace-builds": "1.33.0",
1616
"ajv": "8.8.2",
17+
"ajv-draft-04": "^1.0.0",
1718
"ajv-formats": "2.1.1",
1819
"json-schema-faker": "0.5.6",
1920
"jsonpath-plus": "10.2.0",

frontend/pnpm-lock.yaml

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/src/components/Topics/Topic/SendMessage/__test__/utils.spec.ts

+26
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,31 @@ describe('SendMessage utils', () => {
8181
'Error in parsing the "content" field value',
8282
]);
8383
});
84+
85+
it('should successfully validate when schema references json-schema version draft-07', () => {
86+
const schema = `{"type":"object","title":"A","description":"A","$id":"https://example.com/A.json",
87+
"$schema":"http://json-schema.org/draft-07/schema#","required":["a"],"properties":{"a":{"type":"number"}}}`;
88+
expect(validateBySchema('{"a": 6}', schema, 'key')).toHaveLength(0);
89+
});
90+
it('should successfully validate when schema references json-schema version draft-06', () => {
91+
const schema = `{"type":"object","title":"A","description":"A","$id":"https://example.com/A.json",
92+
"$schema":"http://json-schema.org/draft-06/schema#","required":["a"],"properties":{"a":{"type":"number"}}}`;
93+
expect(validateBySchema('{"a": 6}', schema, 'key')).toHaveLength(0);
94+
});
95+
it('should successfully validate when schema references json-schema version draft-04', () => {
96+
const schema = `{"type":"object","title":"A","description":"A","id":"https://example.com/A.json",
97+
"$schema":"http://json-schema.org/draft-04/schema#","required":["a"],"properties":{"a":{"type":"number"}}}`;
98+
expect(validateBySchema('{"a": 6}', schema, 'key')).toHaveLength(0);
99+
});
100+
it('should successfully validate when schema references json-schema version draft-2019-09', () => {
101+
const schema = `{"type":"object","title":"A","description":"A","$id":"https://example.com/A.json",
102+
"$schema":"https://json-schema.org/draft/2019-09/schema","required":["a"],"properties":{"a":{"type":"number"}}}`;
103+
expect(validateBySchema('{"a": 6}', schema, 'key')).toHaveLength(0);
104+
});
105+
it('should successfully validate when schema references json-schema version draft-2020-12', () => {
106+
const schema = `{"type":"object","title":"A","description":"A","$id":"https://example.com/A.json",
107+
"$schema":"https://json-schema.org/draft/2020-12/schema","required":["a"],"properties":{"a":{"type":"number"}}}`;
108+
expect(validateBySchema('{"a": 6}', schema, 'key')).toHaveLength(0);
109+
});
84110
});
85111
});

frontend/src/components/Topics/Topic/SendMessage/utils.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import {
44
TopicSerdeSuggestion,
55
} from 'generated-sources';
66
import jsf from 'json-schema-faker';
7-
import Ajv, { DefinedError } from 'ajv/dist/2020';
7+
import Ajv, { DefinedError } from 'ajv';
8+
import Ajv2019 from 'ajv/dist/2019';
9+
import Ajv2020 from 'ajv/dist/2020';
10+
import * as draft6MetaSchema from 'ajv/dist/refs/json-schema-draft-06.json';
11+
import AjvDraft4 from 'ajv-draft-04';
812
import addFormats from 'ajv-formats';
913

1014
jsf.option('fillProperties', false);
@@ -56,6 +60,21 @@ function upperFirst(str: string) {
5660
return str.charAt(0).toUpperCase() + str.slice(1);
5761
}
5862

63+
const getAjvVersionForSchemaRef = (schemaRef: string) => {
64+
switch (schemaRef) {
65+
case 'https://json-schema.org/draft/2019-09/schema':
66+
return new Ajv2019();
67+
case 'https://json-schema.org/draft/2020-12/schema':
68+
return new Ajv2020();
69+
case 'http://json-schema.org/draft-06/schema#':
70+
return new Ajv().addMetaSchema(draft6MetaSchema);
71+
case 'http://json-schema.org/draft-04/schema#':
72+
return new AjvDraft4();
73+
default:
74+
return new Ajv();
75+
}
76+
};
77+
5978
export const validateBySchema = (
6079
value: string,
6180
schema: string | undefined,
@@ -84,7 +103,8 @@ export const validateBySchema = (
84103
return [`Error in parsing the "${type}" field value`];
85104
}
86105
try {
87-
const ajv = new Ajv();
106+
const schemaRef = parsedSchema.$schema;
107+
const ajv = getAjvVersionForSchemaRef(schemaRef);
88108
addFormats(ajv);
89109
const validate = ajv.compile(parsedSchema);
90110
validate(parsedValue);

0 commit comments

Comments
 (0)