yupExtended.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import * as yup from 'yup';
  2. import { TOPIC_NAME_VALIDATION_PATTERN } from './constants';
  3. declare module 'yup' {
  4. interface StringSchema<
  5. TType extends yup.Maybe<string> = string | undefined,
  6. TContext = yup.AnyObject,
  7. TDefault = undefined,
  8. TFlags extends yup.Flags = ''
  9. > extends yup.Schema<TType, TContext, TDefault, TFlags> {
  10. isJsonObject(message?: string): StringSchema<TType, TContext>;
  11. }
  12. }
  13. export const isValidJsonObject = (value?: string) => {
  14. try {
  15. if (!value) return false;
  16. const trimmedValue = value.trim();
  17. if (
  18. trimmedValue.indexOf('{') === 0 &&
  19. trimmedValue.lastIndexOf('}') === trimmedValue.length - 1
  20. ) {
  21. JSON.parse(trimmedValue);
  22. return true;
  23. }
  24. } catch {
  25. // do nothing
  26. }
  27. return false;
  28. };
  29. const isJsonObject = (message?: string) => {
  30. return yup.string().test(
  31. 'isJsonObject',
  32. // eslint-disable-next-line no-template-curly-in-string
  33. message || '${path} is not JSON object',
  34. isValidJsonObject
  35. );
  36. };
  37. /**
  38. * due to yup rerunning all the object validiation during any render,
  39. * it makes sense to cache the async results
  40. * */
  41. export function cacheTest(
  42. asyncValidate: (val?: string, ctx?: yup.AnyObject) => Promise<boolean>
  43. ) {
  44. let valid = false;
  45. let closureValue = '';
  46. return async (value?: string, ctx?: yup.AnyObject) => {
  47. if (value !== closureValue) {
  48. const response = await asyncValidate(value, ctx);
  49. closureValue = value || '';
  50. valid = response;
  51. return response;
  52. }
  53. return valid;
  54. };
  55. }
  56. yup.addMethod(yup.StringSchema, 'isJsonObject', isJsonObject);
  57. export const topicFormValidationSchema = yup.object().shape({
  58. name: yup
  59. .string()
  60. .max(249)
  61. .required()
  62. .matches(
  63. TOPIC_NAME_VALIDATION_PATTERN,
  64. 'Only alphanumeric, _, -, and . allowed'
  65. ),
  66. partitions: yup
  67. .number()
  68. .min(1)
  69. .max(2147483647)
  70. .required()
  71. .typeError('Number of partitions is required and must be a number'),
  72. replicationFactor: yup.string(),
  73. minInSyncReplicas: yup.string(),
  74. cleanupPolicy: yup.string().required(),
  75. retentionMs: yup.string(),
  76. retentionBytes: yup.number(),
  77. maxMessageBytes: yup.string(),
  78. customParams: yup.array().of(
  79. yup.object().shape({
  80. name: yup.string().required('Custom parameter is required'),
  81. value: yup.string().required('Value is required'),
  82. })
  83. ),
  84. });
  85. export default yup;