-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathutils.ts
121 lines (107 loc) · 3.25 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import {
Partition,
SerdeDescription,
TopicSerdeSuggestion,
} from 'generated-sources';
import jsf from 'json-schema-faker';
import { compact } from 'lodash';
import Ajv, { DefinedError } from 'ajv';
import Ajv2019 from 'ajv/dist/2019';
import Ajv2020 from 'ajv/dist/2020';
import * as draft6MetaSchema from 'ajv/dist/refs/json-schema-draft-06.json';
import AjvDraft4 from 'ajv-draft-04';
import addFormats from 'ajv-formats';
import upperFirst from 'lodash/upperFirst';
jsf.option('fillProperties', false);
jsf.option('alwaysFakeOptionals', true);
jsf.option('failOnInvalidFormat', false);
const generateValueFromSchema = (preferred?: SerdeDescription) => {
if (!preferred?.schema) {
return undefined;
}
const parsedSchema = JSON.parse(preferred.schema);
const value = jsf.generate(parsedSchema);
return JSON.stringify(value);
};
export const getPreferredDescription = (serdes: SerdeDescription[]) =>
serdes.find((s) => s.preferred);
export const getDefaultValues = (serdes: TopicSerdeSuggestion) => {
const keySerde = getPreferredDescription(serdes.key || []);
const valueSerde = getPreferredDescription(serdes.value || []);
return {
key: generateValueFromSchema(keySerde),
content: generateValueFromSchema(valueSerde),
headers: undefined,
partition: undefined,
keySerde: keySerde?.name,
valueSerde: valueSerde?.name,
};
};
export const getPartitionOptions = (partitions: Partition[]) =>
partitions.map(({ partition }) => ({
label: `Partition #${partition}`,
value: partition,
}));
export const getSerdeOptions = (items: SerdeDescription[]) => {
const options = items.map(({ name }) => {
if (!name) return undefined;
return { label: name, value: name };
});
return compact(options);
};
const getAjvVersionForSchemaRef = (schemaRef: string) => {
switch (schemaRef) {
case 'https://json-schema.org/draft/2019-09/schema':
return new Ajv2019();
case 'https://json-schema.org/draft/2020-12/schema':
return new Ajv2020();
case 'http://json-schema.org/draft-06/schema#':
return new Ajv().addMetaSchema(draft6MetaSchema);
case 'http://json-schema.org/draft-04/schema#':
return new AjvDraft4();
default:
return new Ajv();
}
};
export const validateBySchema = (
value: string,
schema: string | undefined,
type: 'key' | 'content'
) => {
let errors: string[] = [];
if (!value || !schema) {
return errors;
}
let parsedSchema;
let parsedValue;
try {
parsedSchema = JSON.parse(schema);
} catch (e) {
return [`Error in parsing the "${type}" field schema`];
}
if (parsedSchema.type === 'string') {
return [];
}
try {
parsedValue = JSON.parse(value);
} catch (e) {
return [`Error in parsing the "${type}" field value`];
}
try {
const schemaRef = parsedSchema.$schema;
const ajv = getAjvVersionForSchemaRef(schemaRef);
addFormats(ajv);
const validate = ajv.compile(parsedSchema);
validate(parsedValue);
if (validate.errors) {
errors = validate.errors.map(
({ schemaPath, message }) =>
`${schemaPath.replace('#', upperFirst(type))} - ${message}`
);
}
} catch (e) {
const err = e as DefinedError;
return [`${upperFirst(type)} ${err.message}`];
}
return errors;
};