utils.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import {
  2. Partition,
  3. SerdeDescription,
  4. TopicSerdeSuggestion,
  5. } from 'generated-sources';
  6. import jsf from 'json-schema-faker';
  7. import { compact } from 'lodash';
  8. import Ajv, { DefinedError } from 'ajv/dist/2020';
  9. import addFormats from 'ajv-formats';
  10. import upperFirst from 'lodash/upperFirst';
  11. jsf.option('fillProperties', false);
  12. jsf.option('alwaysFakeOptionals', true);
  13. jsf.option('failOnInvalidFormat', false);
  14. const generateValueFromSchema = (preferred?: SerdeDescription) => {
  15. if (!preferred?.schema) {
  16. return undefined;
  17. }
  18. const parsedSchema = JSON.parse(preferred.schema);
  19. const value = jsf.generate(parsedSchema);
  20. return JSON.stringify(value);
  21. };
  22. export const getPreferredDescription = (serdes: SerdeDescription[]) =>
  23. serdes.find((s) => s.preferred);
  24. export const getDefaultValues = (serdes: TopicSerdeSuggestion) => {
  25. const keySerde = getPreferredDescription(serdes.key || []);
  26. const valueSerde = getPreferredDescription(serdes.value || []);
  27. return {
  28. key: generateValueFromSchema(keySerde),
  29. content: generateValueFromSchema(valueSerde),
  30. headers: undefined,
  31. partition: undefined,
  32. keySerde: keySerde?.name,
  33. valueSerde: valueSerde?.name,
  34. };
  35. };
  36. export const getPartitionOptions = (partitions: Partition[]) =>
  37. partitions.map(({ partition }) => ({
  38. label: `Partition #${partition}`,
  39. value: partition,
  40. }));
  41. export const getSerdeOptions = (items: SerdeDescription[]) => {
  42. const options = items.map(({ name }) => {
  43. if (!name) return undefined;
  44. return { label: name, value: name };
  45. });
  46. return compact(options);
  47. };
  48. export const validateBySchema = (
  49. value: string,
  50. schema: string | undefined,
  51. type: 'key' | 'content'
  52. ) => {
  53. let errors: string[] = [];
  54. if (!value || !schema) {
  55. return errors;
  56. }
  57. let parsedSchema;
  58. let parsedValue;
  59. try {
  60. parsedSchema = JSON.parse(schema);
  61. } catch (e) {
  62. return [`Error in parsing the "${type}" field schema`];
  63. }
  64. if (parsedSchema.type === 'string') {
  65. return [];
  66. }
  67. try {
  68. parsedValue = JSON.parse(value);
  69. } catch (e) {
  70. return [`Error in parsing the "${type}" field value`];
  71. }
  72. try {
  73. const ajv = new Ajv();
  74. addFormats(ajv);
  75. const validate = ajv.compile(parsedSchema);
  76. validate(parsedValue);
  77. if (validate.errors) {
  78. errors = validate.errors.map(
  79. ({ schemaPath, message }) =>
  80. `${schemaPath.replace('#', upperFirst(type))} - ${message}`
  81. );
  82. }
  83. } catch (e) {
  84. const err = e as DefinedError;
  85. return [`${upperFirst(type)} ${err.message}`];
  86. }
  87. return errors;
  88. };