Validation.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { MetricType, METRIC_TYPES_VALUES } from '../consts/Milvus';
  2. export type ValidType =
  3. | 'email'
  4. | 'require'
  5. | 'confirm'
  6. | 'range'
  7. | 'password'
  8. | 'clusterName'
  9. | 'CIDRorIP'
  10. | 'integer'
  11. | 'positiveNumber'
  12. | 'collectionName'
  13. | 'dimension'
  14. | 'multiple'
  15. | 'partitionName';
  16. export interface ICheckMapParam {
  17. value: string;
  18. extraParam?: IExtraParam;
  19. rule: ValidType;
  20. }
  21. export interface IExtraParam {
  22. // used for confirm type
  23. compareValue?: string;
  24. // used for length type
  25. min?: number;
  26. max?: number;
  27. type?: 'string' | 'number';
  28. // used for dimension
  29. metricType?: MetricType;
  30. multipleNumber?: number;
  31. }
  32. export type CheckMap = {
  33. [key in ValidType]: boolean;
  34. };
  35. export const checkEmptyValid = (value: string): boolean => {
  36. return value.trim() !== '';
  37. };
  38. export const checkEmail = (value: string): boolean => {
  39. const re = /\S+@\S+\.\S+/;
  40. return re.test(value);
  41. };
  42. /* password rules:
  43. * 1. at least one uppercase letter
  44. * 2. at least one lowercase letter
  45. * 3. at least one number
  46. * 4. at least one nonalphanumeric character: ! @ # $ % ^ & * ( ) _ + - = [ ] { } | '
  47. */
  48. export const checkPasswordStrength = (value: string): boolean => {
  49. const re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*([^A-Za-z0-9]))/;
  50. return re.test(value);
  51. };
  52. export const checkRange = (param: {
  53. value: string;
  54. min?: number;
  55. max?: number;
  56. type?: 'string' | 'number';
  57. }): boolean => {
  58. const { value, min = 0, max = 0, type } = param;
  59. const length = type === 'number' ? Number(value) : value.length;
  60. let result = true;
  61. const conditionMap = {
  62. min: length >= min,
  63. max: length <= max,
  64. };
  65. if (min !== 0) {
  66. result = result && conditionMap.min;
  67. }
  68. if (max !== 0) {
  69. result = result && conditionMap.max;
  70. }
  71. return result;
  72. };
  73. export const checkClusterName = (value: string): boolean => {
  74. const re = new RegExp('^[A-Za-z0-9+-=._:@/ ]*$');
  75. return re.test(value);
  76. };
  77. export const checkIP = (value: string): boolean => {
  78. const re =
  79. /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  80. return re.test(value);
  81. };
  82. export const checkCIDR = (value: string): boolean => {
  83. const re =
  84. /^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([0-9]|[1-2]\d|3[0-2])$/;
  85. return re.test(value);
  86. };
  87. export const checkIpOrCIDR = (value: string): boolean => {
  88. // const re = new RegExp('^([0-9]{1,3}.){3}[0-9]{1,3}($|/(16|24)$)');
  89. // return re.test(value);
  90. return checkIP(value) || checkCIDR(value);
  91. };
  92. // collection name can only be combined with number, letter or _
  93. // name max length 255 and can't start with number
  94. export const checkCollectionName = (value: string): boolean => {
  95. const length = value.length;
  96. if (length > 254) {
  97. return false;
  98. }
  99. const start = Number(value[0]);
  100. if (!isNaN(start)) {
  101. return false;
  102. }
  103. const re = /^[0-9,a-z,A-Z$_]+$/;
  104. return re.test(value);
  105. };
  106. export const checkPartitionName = (value: string): boolean => {
  107. return value !== '_default';
  108. };
  109. export const checkMultiple = (param: {
  110. value: string;
  111. multipleNumber?: number;
  112. }): boolean => {
  113. const { value, multipleNumber = 1 } = param;
  114. return Number(value) % multipleNumber === 0;
  115. };
  116. export const checkDimension = (param: {
  117. value: string;
  118. metricType?: MetricType;
  119. multipleNumber?: number;
  120. }): boolean => {
  121. const { value, metricType, multipleNumber } = param;
  122. if (
  123. metricType === METRIC_TYPES_VALUES.IP ||
  124. metricType === METRIC_TYPES_VALUES.L2
  125. ) {
  126. return true;
  127. }
  128. return checkMultiple({ value, multipleNumber });
  129. };
  130. export const getCheckResult = (param: ICheckMapParam): boolean => {
  131. const { value, extraParam = {}, rule } = param;
  132. const numberValue = Number(value);
  133. const checkMap = {
  134. email: checkEmail(value),
  135. require: checkEmptyValid(value),
  136. confirm: value === extraParam?.compareValue,
  137. range: checkRange({
  138. value,
  139. min: extraParam?.min,
  140. max: extraParam?.max,
  141. type: extraParam?.type,
  142. }),
  143. password: checkPasswordStrength(value),
  144. clusterName: checkClusterName(value),
  145. CIDRorIP: checkIpOrCIDR(value),
  146. integer: !isNaN(numberValue) && Number.isInteger(numberValue),
  147. positiveNumber: !isNaN(numberValue) && numberValue > 0,
  148. collectionName: checkCollectionName(value),
  149. dimension: checkDimension({
  150. value,
  151. metricType: extraParam?.metricType,
  152. multipleNumber: extraParam?.multipleNumber,
  153. }),
  154. multiple: checkMultiple({
  155. value,
  156. multipleNumber: extraParam?.multipleNumber,
  157. }),
  158. partitionName: checkPartitionName(value),
  159. };
  160. return checkMap[rule];
  161. };