index.d.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import { Ref, UnwrapRef, defineComponent, ComponentInternalInstance } from 'vue-demi';
  2. type Component = ReturnType<typeof defineComponent>;
  3. /*
  4. * Structure
  5. *
  6. * This package is mainly a validation engine. This engine requires 2
  7. * inputs: validation arguments and the state to be validated. The output
  8. * is a validation result.
  9. *
  10. * The structure of the validation object is constrained by the structure
  11. * of the validation arguments. These validation arguments also constraint
  12. * the type of the states that can be validated. And although the state does
  13. * not affect the structure of the validation result, it can narrow the
  14. * property "$model" in the validation result.
  15. *
  16. * Why do validation arguments constraint the type of the states that can
  17. * be validated? Because validation arguments make assumptions about the state.
  18. * For instance we expect a state `{ foo?: string }`, and we want to check
  19. * that `foo` is not empty, so we write `(foo?.length ?? 0) > 0`. If now we try
  20. * to validate the state `{ foo: [1] }` our validation result is meaningless.
  21. * This state would pass our test, but clearly it's not a valid object. This
  22. * situation was possible because that state violated our initial assumptions.
  23. *
  24. *
  25. * Validation Arguments
  26. * |
  27. * _____|____
  28. * / \
  29. * | |
  30. * | States to be validated
  31. * | |
  32. * | |
  33. * Validation Result
  34. *
  35. */
  36. export interface ValidatorResponse {
  37. $valid: boolean
  38. [key: string]: any
  39. }
  40. export type ValidatorFn <T = any, K = any, S = any> = (value: T, siblingState: K, vm: S) => boolean | ValidatorResponse | Promise<boolean | ValidatorResponse>;
  41. export interface ValidationRuleWithoutParams <T = any> {
  42. $validator: ValidatorFn<T>
  43. $message?: string | Ref<string> | (() => string)
  44. }
  45. export interface ValidationRuleWithParams<P extends object = object, T = any> {
  46. $validator: ValidatorFn<T>
  47. $message: (input: { $params: P }) => string
  48. $params: P
  49. }
  50. export type ValidationRule <T = any> = ValidationRuleWithParams<any, T> | ValidationRuleWithoutParams<T> | ValidatorFn<T>;
  51. export type ValidationRuleCollection <T = any> = Record<string, ValidationRule<T>>;
  52. export type ValidationArgs<T = unknown> = {
  53. [key in keyof T]: ValidationArgs<T[key]> | ValidationRuleCollection<T[key]> | ValidationRule<T[key]>
  54. }
  55. export interface RuleResultWithoutParams {
  56. readonly $message: string
  57. readonly $pending: boolean
  58. readonly $invalid: boolean
  59. readonly $response: any
  60. }
  61. export interface RuleResultWithParams <P extends object = object> extends RuleResultWithoutParams {
  62. readonly $params: P
  63. }
  64. export type RuleResult = RuleResultWithoutParams | RuleResultWithParams;
  65. type ExtractRuleResult <R extends ValidationRule> = R extends ValidationRuleWithParams<infer P> ? RuleResultWithParams<P> : RuleResultWithoutParams;
  66. type ExtractRulesResults <T, Vrules extends ValidationRuleCollection<T> | undefined> = {
  67. readonly [K in keyof Vrules]: Vrules[K] extends ValidationRule ? ExtractRuleResult<Vrules[K]> : undefined;
  68. };
  69. export interface ErrorObject {
  70. readonly $propertyPath: string
  71. readonly $property: string
  72. readonly $validator: string
  73. readonly $message: string | Ref<string>
  74. readonly $params: object
  75. readonly $pending: boolean
  76. readonly $response: any,
  77. readonly $uid: string,
  78. }
  79. export type BaseValidation <
  80. T = unknown,
  81. Vrules extends ValidationRuleCollection<T> | undefined = undefined,
  82. > = (
  83. Vrules extends ValidationRuleCollection<T>
  84. ? ExtractRulesResults<T, Vrules>
  85. : unknown) & {
  86. $model: T
  87. // const validationGetters
  88. readonly $dirty: boolean
  89. readonly $error: boolean
  90. readonly $errors: ErrorObject[]
  91. readonly $silentErrors: ErrorObject[]
  92. readonly $externalResults: ({ $validator: '$externalResults', $response: null, $pending: false, $params: {} } & ErrorObject)[]
  93. readonly $invalid: boolean
  94. readonly $anyDirty: boolean
  95. readonly $pending: boolean
  96. readonly $path: string
  97. // const validationMethods
  98. readonly $touch: () => void
  99. readonly $reset: () => void
  100. readonly $commit: () => void
  101. readonly $validate: () => Promise<boolean>
  102. // For accessing individual form properties on v$
  103. readonly [key: string]: any
  104. };
  105. export type NestedValidations <Vargs extends ValidationArgs = ValidationArgs, T = unknown> = {
  106. readonly [K in keyof Vargs]: BaseValidation<
  107. T extends Record<K, unknown> ? T[K] : unknown,
  108. Vargs[K] extends ValidationRuleCollection
  109. ? Vargs[K] : undefined
  110. > & (
  111. Vargs[K] extends Record<string, ValidationArgs>
  112. ? NestedValidations<Vargs[K], T extends Record<K, unknown> ? T[K] : unknown>
  113. : unknown
  114. )
  115. };
  116. interface ChildValidations {
  117. readonly $getResultsForChild: (key: string) => (BaseValidation & ChildValidations) | undefined
  118. readonly $clearExternalResults: () => void
  119. }
  120. export type Validation <Vargs extends ValidationArgs = ValidationArgs, T = unknown> =
  121. NestedValidations<Vargs, T> &
  122. BaseValidation<T, Vargs extends ValidationRuleCollection ? Vargs : any> &
  123. ChildValidations;
  124. export type ExtractStateLeaf <Vrules extends ValidationRuleCollection> =
  125. Vrules extends ValidationRuleCollection<infer T>
  126. ? T
  127. : unknown;
  128. export type ChildStateLeafs <Vargs extends ValidationArgs = ValidationArgs> = {
  129. [K in keyof Vargs]?: (
  130. Vargs[K] extends ValidationRuleCollection
  131. ? ExtractStateLeaf<Vargs[K]>
  132. : unknown
  133. ) & (
  134. Vargs[K] extends Record<string, ValidationArgs>
  135. ? ChildStateLeafs<Vargs[K]>
  136. : unknown
  137. )
  138. };
  139. export type ExtractState <Vargs extends ValidationArgs> = Vargs extends ValidationRuleCollection
  140. ? ExtractStateLeaf<Vargs> & ChildStateLeafs<Vargs>
  141. : ChildStateLeafs<Vargs>;
  142. type ToRefs <T> = { [K in keyof T]: Ref<T[K]> };
  143. export interface ServerErrors {
  144. [key: string]: string | string[] | ServerErrors
  145. }
  146. export interface GlobalConfig {
  147. $registerAs?: string
  148. $scope?: string | number | symbol | boolean
  149. $stopPropagation?: boolean
  150. $autoDirty?: boolean
  151. $lazy?: boolean,
  152. $externalResults?: ServerErrors | Ref<ServerErrors> | UnwrapRef<ServerErrors>,
  153. $rewardEarly?: boolean,
  154. currentVueInstance?: ComponentInternalInstance | null
  155. }
  156. export function useVuelidate(globalConfig?: GlobalConfig): Ref<Validation>;
  157. export function useVuelidate<
  158. T extends {[key in keyof Vargs]: any},
  159. Vargs extends ValidationArgs = ValidationArgs,
  160. EState extends ExtractState<Vargs> = ExtractState<Vargs>
  161. >(
  162. validationsArgs: Ref<Vargs> | Vargs,
  163. state: T | Ref<T> | ToRefs<T>,
  164. globalConfig?: GlobalConfig
  165. ): Ref<Validation<Vargs, T>>;
  166. export default useVuelidate;