mobx-formkit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/AGENTS.md +761 -0
  2. package/LICENSE +21 -0
  3. package/README.md +214 -0
  4. package/lib/ArrayMap.d.ts +50 -0
  5. package/lib/ArrayMap.d.ts.map +1 -0
  6. package/lib/ArrayMap.js +151 -0
  7. package/lib/ArrayMap.js.map +1 -0
  8. package/lib/Base.d.ts +237 -0
  9. package/lib/Base.d.ts.map +1 -0
  10. package/lib/Base.js +872 -0
  11. package/lib/Base.js.map +1 -0
  12. package/lib/Bindings.d.ts +28 -0
  13. package/lib/Bindings.d.ts.map +1 -0
  14. package/lib/Bindings.js +73 -0
  15. package/lib/Bindings.js.map +1 -0
  16. package/lib/Field.d.ts +195 -0
  17. package/lib/Field.d.ts.map +1 -0
  18. package/lib/Field.js +734 -0
  19. package/lib/Field.js.map +1 -0
  20. package/lib/Form.d.ts +75 -0
  21. package/lib/Form.d.ts.map +1 -0
  22. package/lib/Form.js +199 -0
  23. package/lib/Form.js.map +1 -0
  24. package/lib/Options.d.ts +9 -0
  25. package/lib/Options.d.ts.map +1 -0
  26. package/lib/Options.js +85 -0
  27. package/lib/Options.js.map +1 -0
  28. package/lib/State.d.ts +43 -0
  29. package/lib/State.d.ts.map +1 -0
  30. package/lib/State.js +147 -0
  31. package/lib/State.js.map +1 -0
  32. package/lib/Validator.d.ts +25 -0
  33. package/lib/Validator.d.ts.map +1 -0
  34. package/lib/Validator.js +143 -0
  35. package/lib/Validator.js.map +1 -0
  36. package/lib/compat.d.ts +29 -0
  37. package/lib/compat.d.ts.map +1 -0
  38. package/lib/compat.js +117 -0
  39. package/lib/compat.js.map +1 -0
  40. package/lib/composer.d.ts +26 -0
  41. package/lib/composer.d.ts.map +1 -0
  42. package/lib/composer.js +65 -0
  43. package/lib/composer.js.map +1 -0
  44. package/lib/esm/ArrayMap.js +146 -0
  45. package/lib/esm/ArrayMap.js.map +1 -0
  46. package/lib/esm/Base.js +868 -0
  47. package/lib/esm/Base.js.map +1 -0
  48. package/lib/esm/Bindings.js +69 -0
  49. package/lib/esm/Bindings.js.map +1 -0
  50. package/lib/esm/Field.js +730 -0
  51. package/lib/esm/Field.js.map +1 -0
  52. package/lib/esm/Form.js +195 -0
  53. package/lib/esm/Form.js.map +1 -0
  54. package/lib/esm/Options.js +81 -0
  55. package/lib/esm/Options.js.map +1 -0
  56. package/lib/esm/State.js +143 -0
  57. package/lib/esm/State.js.map +1 -0
  58. package/lib/esm/Validator.js +139 -0
  59. package/lib/esm/Validator.js.map +1 -0
  60. package/lib/esm/compat.js +96 -0
  61. package/lib/esm/compat.js.map +1 -0
  62. package/lib/esm/composer.js +63 -0
  63. package/lib/esm/composer.js.map +1 -0
  64. package/lib/esm/index.js +8 -0
  65. package/lib/esm/index.js.map +1 -0
  66. package/lib/esm/models/FieldProps.js +116 -0
  67. package/lib/esm/models/FieldProps.js.map +1 -0
  68. package/lib/esm/models/OptionsModel.js +51 -0
  69. package/lib/esm/models/OptionsModel.js.map +1 -0
  70. package/lib/esm/models/StateInterface.js +9 -0
  71. package/lib/esm/models/StateInterface.js.map +1 -0
  72. package/lib/esm/models/ValidatorInterface.js +8 -0
  73. package/lib/esm/models/ValidatorInterface.js.map +1 -0
  74. package/lib/esm/parser.js +235 -0
  75. package/lib/esm/parser.js.map +1 -0
  76. package/lib/esm/props.js +118 -0
  77. package/lib/esm/props.js.map +1 -0
  78. package/lib/esm/utils.js +156 -0
  79. package/lib/esm/utils.js.map +1 -0
  80. package/lib/esm/validators/AJV.js +105 -0
  81. package/lib/esm/validators/AJV.js.map +1 -0
  82. package/lib/esm/validators/DVR.js +104 -0
  83. package/lib/esm/validators/DVR.js.map +1 -0
  84. package/lib/esm/validators/JOI.js +54 -0
  85. package/lib/esm/validators/JOI.js.map +1 -0
  86. package/lib/esm/validators/VALIBOT.js +50 -0
  87. package/lib/esm/validators/VALIBOT.js.map +1 -0
  88. package/lib/esm/validators/VINEJS.js +60 -0
  89. package/lib/esm/validators/VINEJS.js.map +1 -0
  90. package/lib/esm/validators/VJF.js +88 -0
  91. package/lib/esm/validators/VJF.js.map +1 -0
  92. package/lib/esm/validators/YUP.js +69 -0
  93. package/lib/esm/validators/YUP.js.map +1 -0
  94. package/lib/esm/validators/ZOD.js +43 -0
  95. package/lib/esm/validators/ZOD.js.map +1 -0
  96. package/lib/index.d.ts +7 -0
  97. package/lib/index.d.ts.map +1 -0
  98. package/lib/index.js +15 -0
  99. package/lib/index.js.map +1 -0
  100. package/lib/models/BaseInterface.d.ts +40 -0
  101. package/lib/models/BaseInterface.d.ts.map +1 -0
  102. package/lib/models/BindingsInterface.d.ts +18 -0
  103. package/lib/models/BindingsInterface.d.ts.map +1 -0
  104. package/lib/models/FieldInterface.d.ts +88 -0
  105. package/lib/models/FieldInterface.d.ts.map +1 -0
  106. package/lib/models/FieldProps.d.ts +111 -0
  107. package/lib/models/FieldProps.d.ts.map +1 -0
  108. package/lib/models/FieldProps.js +116 -0
  109. package/lib/models/FieldProps.js.map +1 -0
  110. package/lib/models/FormInterface.d.ts +184 -0
  111. package/lib/models/FormInterface.d.ts.map +1 -0
  112. package/lib/models/OptionsInterface.d.ts +8 -0
  113. package/lib/models/OptionsInterface.d.ts.map +1 -0
  114. package/lib/models/OptionsModel.d.ts +99 -0
  115. package/lib/models/OptionsModel.d.ts.map +1 -0
  116. package/lib/models/OptionsModel.js +51 -0
  117. package/lib/models/OptionsModel.js.map +1 -0
  118. package/lib/models/SharedActionsInterface.d.ts +27 -0
  119. package/lib/models/SharedActionsInterface.d.ts.map +1 -0
  120. package/lib/models/SharedEventsInterface.d.ts +8 -0
  121. package/lib/models/SharedEventsInterface.d.ts.map +1 -0
  122. package/lib/models/SharedHelpersInterface.d.ts +26 -0
  123. package/lib/models/SharedHelpersInterface.d.ts.map +1 -0
  124. package/lib/models/SharedInitializerInterface.d.ts +6 -0
  125. package/lib/models/SharedInitializerInterface.d.ts.map +1 -0
  126. package/lib/models/SharedUtilsInterface.d.ts +10 -0
  127. package/lib/models/SharedUtilsInterface.d.ts.map +1 -0
  128. package/lib/models/StateInterface.d.ts +37 -0
  129. package/lib/models/StateInterface.d.ts.map +1 -0
  130. package/lib/models/StateInterface.js +9 -0
  131. package/lib/models/StateInterface.js.map +1 -0
  132. package/lib/models/ValidatorInterface.d.ts +74 -0
  133. package/lib/models/ValidatorInterface.d.ts.map +1 -0
  134. package/lib/models/ValidatorInterface.js +8 -0
  135. package/lib/models/ValidatorInterface.js.map +1 -0
  136. package/lib/parser.d.ts +13 -0
  137. package/lib/parser.d.ts.map +1 -0
  138. package/lib/parser.js +247 -0
  139. package/lib/parser.js.map +1 -0
  140. package/lib/props.d.ts +14 -0
  141. package/lib/props.d.ts.map +1 -0
  142. package/lib/props.js +120 -0
  143. package/lib/props.js.map +1 -0
  144. package/lib/utils.d.ts +34 -0
  145. package/lib/utils.d.ts.map +1 -0
  146. package/lib/utils.js +182 -0
  147. package/lib/utils.js.map +1 -0
  148. package/lib/validators/AJV.d.ts +4 -0
  149. package/lib/validators/AJV.d.ts.map +1 -0
  150. package/lib/validators/AJV.js +109 -0
  151. package/lib/validators/AJV.js.map +1 -0
  152. package/lib/validators/DVR.d.ts +4 -0
  153. package/lib/validators/DVR.d.ts.map +1 -0
  154. package/lib/validators/DVR.js +108 -0
  155. package/lib/validators/DVR.js.map +1 -0
  156. package/lib/validators/JOI.d.ts +4 -0
  157. package/lib/validators/JOI.d.ts.map +1 -0
  158. package/lib/validators/JOI.js +58 -0
  159. package/lib/validators/JOI.js.map +1 -0
  160. package/lib/validators/VALIBOT.d.ts +4 -0
  161. package/lib/validators/VALIBOT.d.ts.map +1 -0
  162. package/lib/validators/VALIBOT.js +73 -0
  163. package/lib/validators/VALIBOT.js.map +1 -0
  164. package/lib/validators/VINEJS.d.ts +4 -0
  165. package/lib/validators/VINEJS.d.ts.map +1 -0
  166. package/lib/validators/VINEJS.js +64 -0
  167. package/lib/validators/VINEJS.js.map +1 -0
  168. package/lib/validators/VJF.d.ts +4 -0
  169. package/lib/validators/VJF.d.ts.map +1 -0
  170. package/lib/validators/VJF.js +92 -0
  171. package/lib/validators/VJF.js.map +1 -0
  172. package/lib/validators/YUP.d.ts +4 -0
  173. package/lib/validators/YUP.d.ts.map +1 -0
  174. package/lib/validators/YUP.js +73 -0
  175. package/lib/validators/YUP.js.map +1 -0
  176. package/lib/validators/ZOD.d.ts +4 -0
  177. package/lib/validators/ZOD.d.ts.map +1 -0
  178. package/lib/validators/ZOD.js +47 -0
  179. package/lib/validators/ZOD.js.map +1 -0
  180. package/package.json +183 -0
  181. package/src/ArrayMap.ts +165 -0
  182. package/src/Base.ts +1229 -0
  183. package/src/Bindings.ts +85 -0
  184. package/src/Field.ts +1034 -0
  185. package/src/Form.ts +264 -0
  186. package/src/Options.ts +91 -0
  187. package/src/State.ts +183 -0
  188. package/src/Validator.ts +177 -0
  189. package/src/compat.ts +104 -0
  190. package/src/composer.ts +82 -0
  191. package/src/index.ts +7 -0
  192. package/src/models/BaseInterface.ts +45 -0
  193. package/src/models/BindingsInterface.ts +25 -0
  194. package/src/models/FieldInterface.ts +97 -0
  195. package/src/models/FieldProps.ts +116 -0
  196. package/src/models/FormInterface.ts +203 -0
  197. package/src/models/OptionsInterface.ts +9 -0
  198. package/src/models/OptionsModel.ts +100 -0
  199. package/src/models/SharedActionsInterface.ts +30 -0
  200. package/src/models/SharedEventsInterface.ts +8 -0
  201. package/src/models/SharedHelpersInterface.ts +12 -0
  202. package/src/models/SharedInitializerInterface.ts +6 -0
  203. package/src/models/SharedUtilsInterface.ts +10 -0
  204. package/src/models/StateInterface.ts +44 -0
  205. package/src/models/ValidatorInterface.ts +88 -0
  206. package/src/parser.ts +327 -0
  207. package/src/props.ts +127 -0
  208. package/src/utils.ts +218 -0
  209. package/src/validators/AJV.ts +140 -0
  210. package/src/validators/DVR.ts +145 -0
  211. package/src/validators/JOI.ts +79 -0
  212. package/src/validators/VALIBOT.ts +70 -0
  213. package/src/validators/VINEJS.ts +83 -0
  214. package/src/validators/VJF.ts +123 -0
  215. package/src/validators/YUP.ts +90 -0
  216. package/src/validators/ZOD.ts +66 -0
  217. package/umd/MobxFormkit.umd.js +3093 -0
  218. package/umd/MobxFormkit.umd.js.map +1 -0
  219. package/umd/MobxFormkit.umd.min.js +2 -0
  220. package/umd/MobxFormkit.umd.min.js.map +1 -0
  221. package/umd/MobxFormkitComposer.umd.js +183 -0
  222. package/umd/MobxFormkitComposer.umd.js.map +1 -0
  223. package/umd/MobxFormkitComposer.umd.min.js +2 -0
  224. package/umd/MobxFormkitComposer.umd.min.js.map +1 -0
  225. package/umd/MobxFormkitValidatorAJV.umd.js +113 -0
  226. package/umd/MobxFormkitValidatorAJV.umd.js.map +1 -0
  227. package/umd/MobxFormkitValidatorAJV.umd.min.js +2 -0
  228. package/umd/MobxFormkitValidatorAJV.umd.min.js.map +1 -0
  229. package/umd/MobxFormkitValidatorDVR.umd.js +110 -0
  230. package/umd/MobxFormkitValidatorDVR.umd.js.map +1 -0
  231. package/umd/MobxFormkitValidatorDVR.umd.min.js +2 -0
  232. package/umd/MobxFormkitValidatorDVR.umd.min.js.map +1 -0
  233. package/umd/MobxFormkitValidatorJOI.umd.js +62 -0
  234. package/umd/MobxFormkitValidatorJOI.umd.js.map +1 -0
  235. package/umd/MobxFormkitValidatorJOI.umd.min.js +2 -0
  236. package/umd/MobxFormkitValidatorJOI.umd.min.js.map +1 -0
  237. package/umd/MobxFormkitValidatorVALIBOT.umd.js +8032 -0
  238. package/umd/MobxFormkitValidatorVALIBOT.umd.js.map +1 -0
  239. package/umd/MobxFormkitValidatorVALIBOT.umd.min.js +2 -0
  240. package/umd/MobxFormkitValidatorVALIBOT.umd.min.js.map +1 -0
  241. package/umd/MobxFormkitValidatorVINEJS.umd.js +11737 -0
  242. package/umd/MobxFormkitValidatorVINEJS.umd.js.map +1 -0
  243. package/umd/MobxFormkitValidatorVINEJS.umd.min.js +2 -0
  244. package/umd/MobxFormkitValidatorVINEJS.umd.min.js.map +1 -0
  245. package/umd/MobxFormkitValidatorVJF.umd.js +96 -0
  246. package/umd/MobxFormkitValidatorVJF.umd.js.map +1 -0
  247. package/umd/MobxFormkitValidatorVJF.umd.min.js +2 -0
  248. package/umd/MobxFormkitValidatorVJF.umd.min.js.map +1 -0
  249. package/umd/MobxFormkitValidatorYUP.umd.js +77 -0
  250. package/umd/MobxFormkitValidatorYUP.umd.js.map +1 -0
  251. package/umd/MobxFormkitValidatorYUP.umd.min.js +2 -0
  252. package/umd/MobxFormkitValidatorYUP.umd.min.js.map +1 -0
  253. package/umd/MobxFormkitValidatorZOD.umd.js +49 -0
  254. package/umd/MobxFormkitValidatorZOD.umd.js.map +1 -0
  255. package/umd/MobxFormkitValidatorZOD.umd.min.js +2 -0
  256. package/umd/MobxFormkitValidatorZOD.umd.min.js.map +1 -0
package/src/props.ts ADDED
@@ -0,0 +1,127 @@
1
+ import { FieldPropsEnum, FieldPropsOccurrence, SeparatedPropsMode } from "./models/FieldProps";
2
+
3
+ export interface PropsGroupsInterface {
4
+ editable: string[];
5
+ handlers: string[];
6
+ computed: string[];
7
+ functions: string[];
8
+ validation: string[];
9
+ separated: string[];
10
+ occurrences: {
11
+ [index: string]: FieldPropsOccurrence;
12
+ };
13
+ }
14
+
15
+ export const props: PropsGroupsInterface = {
16
+ editable: [
17
+ FieldPropsEnum.type,
18
+ FieldPropsEnum.value,
19
+ FieldPropsEnum.initial,
20
+ FieldPropsEnum.default,
21
+ FieldPropsEnum.label,
22
+ FieldPropsEnum.placeholder,
23
+ FieldPropsEnum.related,
24
+ FieldPropsEnum.options,
25
+ FieldPropsEnum.extra,
26
+ FieldPropsEnum.bindings,
27
+ FieldPropsEnum.hooks,
28
+ FieldPropsEnum.handlers,
29
+ FieldPropsEnum.deleted,
30
+ FieldPropsEnum.disabled,
31
+ FieldPropsEnum.autoFocus,
32
+ FieldPropsEnum.inputMode,
33
+ FieldPropsEnum.ref,
34
+ FieldPropsEnum.nullable,
35
+ FieldPropsEnum.autoComplete,
36
+ ],
37
+ handlers: [
38
+ FieldPropsEnum.onChange,
39
+ FieldPropsEnum.onToggle,
40
+ FieldPropsEnum.onFocus,
41
+ FieldPropsEnum.onBlur,
42
+ FieldPropsEnum.onDrop,
43
+ FieldPropsEnum.onSubmit,
44
+ FieldPropsEnum.onReset,
45
+ FieldPropsEnum.onClear,
46
+ FieldPropsEnum.onAdd,
47
+ FieldPropsEnum.onDel,
48
+ ],
49
+ computed: [
50
+ FieldPropsEnum.error,
51
+ FieldPropsEnum.hasError,
52
+ FieldPropsEnum.isValid,
53
+ FieldPropsEnum.isDirty,
54
+ FieldPropsEnum.isPristine,
55
+ FieldPropsEnum.isDefault,
56
+ FieldPropsEnum.isEmpty,
57
+ FieldPropsEnum.focused,
58
+ FieldPropsEnum.touched,
59
+ FieldPropsEnum.changed,
60
+ FieldPropsEnum.validating,
61
+ FieldPropsEnum.submitting,
62
+ FieldPropsEnum.resetting,
63
+ FieldPropsEnum.clearing,
64
+ FieldPropsEnum.blurred,
65
+ FieldPropsEnum.deleted,
66
+ FieldPropsEnum.disabled,
67
+ ],
68
+ separated: [
69
+ SeparatedPropsMode.computed,
70
+ SeparatedPropsMode.values,
71
+ SeparatedPropsMode.labels,
72
+ SeparatedPropsMode.placeholders,
73
+ SeparatedPropsMode.defaults,
74
+ SeparatedPropsMode.initials,
75
+ SeparatedPropsMode.disabled,
76
+ SeparatedPropsMode.deleted,
77
+ SeparatedPropsMode.types,
78
+ SeparatedPropsMode.related,
79
+ SeparatedPropsMode.rules,
80
+ SeparatedPropsMode.options,
81
+ SeparatedPropsMode.bindings,
82
+ SeparatedPropsMode.extra,
83
+ SeparatedPropsMode.hooks,
84
+ SeparatedPropsMode.handlers,
85
+ SeparatedPropsMode.validatedWith,
86
+ SeparatedPropsMode.validators,
87
+ SeparatedPropsMode.observers,
88
+ SeparatedPropsMode.interceptors,
89
+ SeparatedPropsMode.converters,
90
+ SeparatedPropsMode.input,
91
+ SeparatedPropsMode.output,
92
+ SeparatedPropsMode.autoFocus,
93
+ SeparatedPropsMode.inputMode,
94
+ SeparatedPropsMode.refs,
95
+ SeparatedPropsMode.classes,
96
+ SeparatedPropsMode.nullable,
97
+ SeparatedPropsMode.autoComplete,
98
+ ],
99
+ functions: [
100
+ FieldPropsEnum.computed,
101
+ FieldPropsEnum.observers,
102
+ FieldPropsEnum.interceptors,
103
+ FieldPropsEnum.converter,
104
+ FieldPropsEnum.input,
105
+ FieldPropsEnum.output,
106
+ ],
107
+ validation: [
108
+ FieldPropsEnum.rules,
109
+ FieldPropsEnum.validators,
110
+ FieldPropsEnum.validatedWith,
111
+ ],
112
+ occurrences: {
113
+ isDirty: FieldPropsOccurrence.some,
114
+ isPristine: FieldPropsOccurrence.every,
115
+ isDefault: FieldPropsOccurrence.every,
116
+ isValid: FieldPropsOccurrence.every,
117
+ isEmpty: FieldPropsOccurrence.every,
118
+ hasError: FieldPropsOccurrence.some,
119
+ focused: FieldPropsOccurrence.some,
120
+ blurred: FieldPropsOccurrence.some,
121
+ touched: FieldPropsOccurrence.some,
122
+ deleted: FieldPropsOccurrence.every,
123
+ disabled: FieldPropsOccurrence.every,
124
+ clearing: FieldPropsOccurrence.every,
125
+ resetting: FieldPropsOccurrence.every,
126
+ },
127
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,218 @@
1
+ import { has, isEmpty, isPlainObject } from "lodash";
2
+ import { values as mobxValues, keys as mobxKeys } from "mobx";
3
+ import { FieldInterface } from "./models/FieldInterface";
4
+ import { AllowedFieldPropsTypes, FieldPropsEnum, FieldPropsOccurrence } from "./models/FieldProps";
5
+ import { props } from "./props";
6
+
7
+ const getObservableMapValues = (fields: any):
8
+ ReadonlyArray<FieldInterface> => {
9
+ // ArrayMap duck-typing
10
+ if (fields && fields._isArrayMap) {
11
+ const result: FieldInterface[] = [];
12
+ fields.forEach((value: FieldInterface) => result.push(value));
13
+ return result;
14
+ }
15
+ return mobxValues(fields);
16
+ };
17
+
18
+ const getObservableMapKeys = (fields: any):
19
+ ReadonlyArray<any> => {
20
+ // ArrayMap duck-typing
21
+ if (fields && fields._isArrayMap) {
22
+ return Array.from(fields.keys());
23
+ }
24
+ return mobxKeys(fields);
25
+ };
26
+
27
+ const checkObserveItem =
28
+ (change: any) =>
29
+ ({ key, to, type, exec }: any) =>
30
+ change.type === type &&
31
+ change.name === key &&
32
+ change.newValue === to &&
33
+ exec.apply(change, [change]);
34
+
35
+ const checkObserve = (collection: Record<string, any>[]) => (change: any) =>
36
+ collection.map(checkObserveItem(change));
37
+
38
+ const checkPropOccurrence = ({ type, data }: any): boolean => {
39
+ let $check: any;
40
+ switch (type) {
41
+ case FieldPropsOccurrence.some: $check = ($data: object) => ($data as any[]).some(Boolean); break;
42
+ case FieldPropsOccurrence.every: $check = ($data: object) => ($data as any[]).every(Boolean); break;
43
+ default: throw new Error('Occurrence not found for specified prop');
44
+ }
45
+ return $check(data);
46
+ };
47
+
48
+ const hasProps = ($type: string, $data: any): boolean => {
49
+ let $props: string[] | null;
50
+ switch ($type) {
51
+ case AllowedFieldPropsTypes.computed:
52
+ $props = props.computed;
53
+ break;
54
+ case AllowedFieldPropsTypes.observable:
55
+ $props = [
56
+ FieldPropsEnum.fields,
57
+ ...props.computed,
58
+ ...props.editable,
59
+ ];
60
+ break;
61
+ case AllowedFieldPropsTypes.editable:
62
+ $props = [
63
+ ...props.editable,
64
+ ...props.validation,
65
+ ...props.functions,
66
+ ...props.handlers,
67
+ ];
68
+ break;
69
+ case AllowedFieldPropsTypes.all:
70
+ $props = [
71
+ FieldPropsEnum.id,
72
+ FieldPropsEnum.key,
73
+ FieldPropsEnum.name,
74
+ FieldPropsEnum.path,
75
+ ...props.computed,
76
+ ...props.editable,
77
+ ...props.validation,
78
+ ...props.functions,
79
+ ...props.handlers,
80
+ ];
81
+ break;
82
+ default:
83
+ $props = null;
84
+ }
85
+
86
+ return $data.filter((x: string) => $props!.includes(x)).length > 0;
87
+ };
88
+
89
+ /**
90
+ Check Allowed Properties
91
+ */
92
+ const allowedProps = (type: string, data: string[]): void => {
93
+ if (hasProps(type, data)) return;
94
+ const $msg = "The selected property is not allowed";
95
+ throw new Error(`${$msg} (${JSON.stringify(data)})`);
96
+ };
97
+
98
+ /**
99
+ Throw Error if undefined Fields
100
+ */
101
+ const throwError = (path: string, fields: any, msg: null | string = null): void => {
102
+ if (fields != null) return;
103
+ const $msg = msg == null ? "The selected field is not defined" : msg;
104
+ throw new Error(`${$msg} (${path})`);
105
+ };
106
+
107
+ const pathToStruct = (path: string): string => {
108
+ let struct;
109
+ struct = path.replace(/\.\d+($|\.)/g, "[].");
110
+ struct = struct.replace("..", ".");
111
+ struct = struct.replace(/^\.+|\.+$/g, "");
112
+ return struct;
113
+ };
114
+
115
+ const isArrayFromStruct = (struct: string[], structPath: string): boolean => {
116
+ if (isArrayOfStrings(struct)) return !!struct
117
+ .filter((s) => s.startsWith(structPath))
118
+ .find((s) => s.substring(structPath.length) === "[]")
119
+ || (struct?.find((e) => e === structPath)?.endsWith('[]') ?? false);
120
+ else return false;
121
+ };
122
+
123
+ const hasSome = (obj: any, keys: any): boolean =>
124
+ keys.some((key: string) => has(obj, key));
125
+
126
+ const isEmptyArray = (field: any): boolean =>
127
+ isEmpty(field) && Array.isArray(field);
128
+
129
+ const isArrayOfStrings = (struct: any): boolean =>
130
+ Array.isArray(struct) && struct.every((s: any) => typeof s === 'string');
131
+
132
+ const isArrayOfObjects = (fields: any): boolean =>
133
+ Array.isArray(fields) && fields.every((f: any) => isPlainObject(f));
134
+
135
+ const getKeys = (fields: any) =>
136
+ fields ? [...new Set(Object.values(fields).flatMap((values) => values ? Object.keys(values) : []))] : [];
137
+
138
+ const hasUnifiedProps = ({ fields }: any) =>
139
+ !isArrayOfStrings({ fields }) && hasProps(AllowedFieldPropsTypes.editable, getKeys(fields));
140
+
141
+ const hasSeparatedProps = (initial: any): boolean =>
142
+ hasSome(initial, props.separated) || hasSome(initial, props.validation);
143
+
144
+ const allowNested = (field: any, strictProps: boolean): boolean =>
145
+ field !== null && typeof field === 'object' &&
146
+ !(field instanceof Date) &&
147
+ !has(field, FieldPropsEnum.fields) &&
148
+ !has(field, FieldPropsEnum.class) &&
149
+ (!hasSome(field, [
150
+ ...props.editable,
151
+ ...props.handlers,
152
+ ...props.validation,
153
+ ...props.functions,
154
+ ]) || strictProps);
155
+
156
+ const parseIntKeys = (fields: any) =>
157
+ Array.from(getObservableMapKeys(fields)).map(Number);
158
+
159
+ const hasIntKeys = (fields: any): boolean =>
160
+ parseIntKeys(fields).every((x: any) => Number.isInteger(x));
161
+
162
+ const maxKey = (fields: any): number => {
163
+ const keys = parseIntKeys(fields);
164
+ const maxVal = keys.length ? Math.max(...keys) : undefined;
165
+ return maxVal === void 0 ? 0 : maxVal + 1;
166
+ };
167
+
168
+ let _idCounter = 0;
169
+ const _localUniqueId = (prefix: string): string => `${prefix}${++_idCounter}`;
170
+
171
+ const uniqueId = (field: any): string =>
172
+ _localUniqueId([field.path.replace(/\./g, "-"), "--"].join(""));
173
+
174
+ const isEvent = (obj: any): boolean => {
175
+ if (obj == null || typeof Event === "undefined") return false;
176
+ return obj instanceof Event || obj.target != null;
177
+ };
178
+
179
+ const hasFiles = ($: any): boolean =>
180
+ !!$?.target?.files && $.target.files.length !== 0;
181
+
182
+ const isBool = ($: any, val: any): boolean =>
183
+ typeof val === 'boolean' && typeof $.target.checked === 'boolean';
184
+
185
+ const $try = (...args: any[]) => {
186
+ for (const val of args) {
187
+ if (val !== undefined) return val;
188
+ }
189
+ return undefined;
190
+ };
191
+
192
+ export {
193
+ props,
194
+ checkObserve,
195
+ checkPropOccurrence,
196
+ hasProps,
197
+ allowedProps,
198
+ throwError,
199
+ isArrayOfStrings,
200
+ isEmptyArray,
201
+ isArrayOfObjects,
202
+ pathToStruct,
203
+ isArrayFromStruct,
204
+ hasUnifiedProps,
205
+ hasSeparatedProps,
206
+ allowNested,
207
+ parseIntKeys,
208
+ hasIntKeys,
209
+ maxKey,
210
+ uniqueId,
211
+ isEvent,
212
+ hasFiles,
213
+ isBool,
214
+ hasSome,
215
+ $try,
216
+ getObservableMapKeys,
217
+ getObservableMapValues,
218
+ };
@@ -0,0 +1,140 @@
1
+
2
+ import FieldInterface from "../models/FieldInterface";
3
+ import FormInterface from "../models/FormInterface";
4
+ import StateInterface from "../models/StateInterface";
5
+ import {
6
+ ValidationPlugin,
7
+ ValidationPluginConfig,
8
+ ValidationPluginConstructor,
9
+ ValidationPluginInterface,
10
+ } from "../models/ValidatorInterface";
11
+
12
+ function isPromise(obj: any): obj is Promise<any> {
13
+ return (
14
+ !!obj &&
15
+ typeof obj.then === "function" &&
16
+ (typeof obj === "object" || typeof obj === "function")
17
+ );
18
+ }
19
+
20
+ class AJV<TValidator = any> implements ValidationPluginInterface<TValidator> {
21
+ promises: Promise<any>[];
22
+ config: ValidationPluginConfig<TValidator>;
23
+ state: StateInterface | null;
24
+ extend?: (args: { validator: TValidator; form: FormInterface }) => void;
25
+ validator: any;
26
+ schema: any;
27
+
28
+ constructor({
29
+ config,
30
+ state = null,
31
+ promises = [],
32
+ }: ValidationPluginConstructor<TValidator>) {
33
+ this.state = state;
34
+ this.promises = promises;
35
+ this.config = config;
36
+ this.extend = config?.extend;
37
+ this.schema = config.schema;
38
+ this.initValidator();
39
+ }
40
+
41
+ extendOptions(options: any = {}) {
42
+ return {
43
+ ...options,
44
+ allErrors: true,
45
+ coerceTypes: true,
46
+ strict: false,
47
+ };
48
+ }
49
+
50
+ initValidator(): void {
51
+ const AjvPackage = this.config.package as any;
52
+ const validatorInstance = new AjvPackage(this.extendOptions(this.config.options));
53
+
54
+ if (typeof validatorInstance.addFormat === "function") {
55
+ validatorInstance.addFormat("email", (value: any) =>
56
+ typeof value === "string"
57
+ ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
58
+ : false
59
+ );
60
+ }
61
+
62
+ if (typeof this.extend === "function") {
63
+ this.extend({
64
+ form: this.state!.form,
65
+ validator: validatorInstance,
66
+ });
67
+ }
68
+
69
+ this.validator = validatorInstance.compile(this.schema);
70
+ }
71
+
72
+ validate(field: FieldInterface): void {
73
+ let result: any;
74
+ try {
75
+ result = this.validator(field.state.form.flatMapValues);
76
+ } catch (e) {
77
+ return;
78
+ }
79
+
80
+ if (isPromise(result)) {
81
+ const $p = result
82
+ .then(() => field.setValidationAsyncData(true))
83
+ .catch((err) => err && this.handleAsyncError(field, err.errors))
84
+ .then(() => this.executeAsyncValidation(field));
85
+
86
+ this.promises.push($p);
87
+ return;
88
+ }
89
+
90
+ this.handleSyncError(field, this.validator.errors);
91
+ }
92
+
93
+ handleSyncError(field: FieldInterface, errors: any[]): void {
94
+ const fieldError = this.findError(field.path ?? '', errors);
95
+ if (!fieldError) return;
96
+
97
+ const message = `${field.label} ${fieldError.message}`;
98
+ field.invalidate(message, false);
99
+ }
100
+
101
+ handleAsyncError(field: FieldInterface, errors: any[]): void {
102
+ const fieldError = this.findError(field.path ?? '', errors);
103
+ if (!fieldError) return;
104
+
105
+ const message = `${field.label} ${fieldError.message}`;
106
+ field.setValidationAsyncData(false, message);
107
+ }
108
+
109
+ normalizePath(value: any): string {
110
+ return String(value)
111
+ .replace(/^[./]+/, "")
112
+ .replace(/\]/g, "")
113
+ .replace(/\[/g, ".")
114
+ .replace(/\//g, ".");
115
+ }
116
+
117
+ findError(path: string, errors: any[]): any {
118
+ if (!errors) return;
119
+ const $path = this.normalizePath(path);
120
+ return errors.find(({ instancePath, dataPath }) => {
121
+ const $dataPath = this.normalizePath(
122
+ typeof instancePath === "string" ? instancePath : dataPath
123
+ );
124
+ return $dataPath.includes($path);
125
+ });
126
+ }
127
+
128
+ executeAsyncValidation(field: FieldInterface): void {
129
+ if (field.validationAsyncData.valid === false) {
130
+ field.invalidate(field.validationAsyncData.message ?? undefined, false, true);
131
+ }
132
+ }
133
+ }
134
+
135
+ export default <TValidator = any>(
136
+ config?: ValidationPluginConfig<TValidator>
137
+ ): ValidationPlugin<TValidator> => ({
138
+ class: AJV<TValidator>,
139
+ config,
140
+ });
@@ -0,0 +1,145 @@
1
+ import { forIn, isEmpty } from "lodash";
2
+ import FieldInterface from "../models/FieldInterface";
3
+ import FormInterface from "../models/FormInterface";
4
+ import StateInterface from "../models/StateInterface";
5
+ import {
6
+ ValidationPlugin,
7
+ ValidationPluginConfig,
8
+ ValidationPluginConstructor,
9
+ ValidationPluginInterface,
10
+ } from "../models/ValidatorInterface";
11
+
12
+ class DVR<TValidator = any>
13
+ implements ValidationPluginInterface<TValidator>
14
+ {
15
+ promises: Promise<any>[];
16
+ config: any;
17
+ state: StateInterface | null;
18
+ extend?: (args: { validator: TValidator; form: FormInterface }) => void;
19
+ validator: TValidator;
20
+ schema?: any;
21
+
22
+ constructor({
23
+ config,
24
+ state = null,
25
+ promises = [],
26
+ }: ValidationPluginConstructor<TValidator>) {
27
+ this.state = state;
28
+ this.promises = promises;
29
+ this.config = config;
30
+ this.extend = config?.extend;
31
+ this.validator = config.package!;
32
+ this.extendValidator();
33
+ }
34
+
35
+ extendValidator() {
36
+ if (typeof this.extend === "function") {
37
+ this.extend({
38
+ validator: this.validator,
39
+ form: this.state!.form,
40
+ });
41
+ }
42
+ }
43
+
44
+ validate(field: FieldInterface) {
45
+ const data = this.state!.form.flatMapValues;
46
+ this.validateFieldAsync(field, data);
47
+ this.validateFieldSync(field, data);
48
+ }
49
+
50
+ makeLabels(validation: any, field: FieldInterface) {
51
+ const labels: Record<string, any> = { [field.path ?? ""]: field.label };
52
+ forIn(validation.rules[field.path ?? ""], (rule) => {
53
+ if (
54
+ typeof rule.value === "string" &&
55
+ rule.name.match(/^(required_|same|different)/)
56
+ ) {
57
+ forIn(rule.value.split(","), (p, i: any) => {
58
+ if (!rule.name.match(/^required_(if|unless)/) || i % 2 === 0) {
59
+ const f = this.state!.form.$(p);
60
+ if (f && f.path && f.label) {
61
+ labels[f.path] = f.label;
62
+ }
63
+ }
64
+ });
65
+ } else if (
66
+ typeof rule.value === "string" &&
67
+ rule.name.match(/^(before|after)/)
68
+ ) {
69
+ const f = this.state!.form.$(rule.value);
70
+ if (f && f.path && f.label) {
71
+ labels[f.path] = f.label;
72
+ }
73
+ }
74
+ });
75
+ validation.setAttributeNames(labels);
76
+ }
77
+
78
+ validateFieldSync(field: FieldInterface, data: any) {
79
+ const $rules = this.rules(field.rules, "sync");
80
+ if (isEmpty($rules[0])) return;
81
+ const rules = { [field.path ?? ""]: $rules };
82
+ const validation = new (this.validator as any)(data, rules);
83
+ this.makeLabels(validation, field);
84
+ if (validation.passes()) return;
85
+ field.invalidate((validation.errors.get(field.path) as any[])[0], false);
86
+ }
87
+
88
+ validateFieldAsync(field: FieldInterface, data: any) {
89
+ const $rules = this.rules(field.rules, "async");
90
+ if (isEmpty($rules[0])) return;
91
+ const rules = { [field.path ?? ""]: $rules };
92
+ const validation = new (this.validator as any)(data, rules);
93
+ this.makeLabels(validation, field);
94
+
95
+ const $p = new Promise((resolve: any) =>
96
+ validation.checkAsync(
97
+ () => this.handleAsyncPasses(field, resolve),
98
+ () => this.handleAsyncFails(field, validation, resolve)
99
+ )
100
+ );
101
+
102
+ this.promises.push($p);
103
+ }
104
+
105
+ handleAsyncPasses(field: FieldInterface, resolve: () => void) {
106
+ field.setValidationAsyncData(true);
107
+ resolve();
108
+ }
109
+
110
+ handleAsyncFails(
111
+ field: FieldInterface,
112
+ validation: any,
113
+ resolve: () => void
114
+ ) {
115
+ field.setValidationAsyncData(
116
+ false,
117
+ (validation.errors.get(field.path) as any[])[0]
118
+ );
119
+ this.executeAsyncValidation(field);
120
+ resolve();
121
+ }
122
+
123
+ executeAsyncValidation(field: FieldInterface) {
124
+ if (field.validationAsyncData.valid === false) {
125
+ field.invalidate(field.validationAsyncData.message ?? undefined, false, true);
126
+ }
127
+ }
128
+
129
+ rules(rules: any, type: "sync" | "async") {
130
+ const $rules = Array.isArray(rules) ? rules : typeof rules === 'string' ? rules.split("|") : [];
131
+ const v = new (this.validator as any)();
132
+ return $rules.filter(($rule: any) =>
133
+ type === "async"
134
+ ? v.getRule($rule.split(":")[0])?.async
135
+ : !v.getRule($rule.split(":")[0])?.async
136
+ );
137
+ }
138
+ }
139
+
140
+ export default <TValidator = any>(
141
+ config?: ValidationPluginConfig<TValidator>
142
+ ): ValidationPlugin<TValidator> => ({
143
+ class: DVR<TValidator>,
144
+ config,
145
+ });
@@ -0,0 +1,79 @@
1
+ import FieldInterface from "../models/FieldInterface";
2
+ import FormInterface from "../models/FormInterface";
3
+ import StateInterface from "../models/StateInterface";
4
+ import {
5
+ ValidationPlugin,
6
+ ValidationPluginConfig,
7
+ ValidationPluginConstructor,
8
+ ValidationPluginInterface,
9
+ } from "../models/ValidatorInterface";
10
+
11
+ class JOI<TValidator = any> implements ValidationPluginInterface<TValidator> {
12
+ promises: Promise<any>[];
13
+ config: ValidationPluginConfig<TValidator>;
14
+ state: StateInterface | null;
15
+ extend?: (args: { validator: TValidator; form: FormInterface }) => void;
16
+ validator: TValidator;
17
+ schema: any;
18
+
19
+ constructor({
20
+ config,
21
+ state = null,
22
+ promises = [],
23
+ }: ValidationPluginConstructor<TValidator>) {
24
+ this.state = state;
25
+ this.promises = promises;
26
+ this.config = config;
27
+ this.extend = config?.extend;
28
+ this.validator = config.package!;
29
+ this.schema = config.schema;
30
+ this.extendValidator();
31
+ }
32
+
33
+ extendValidator(): void {
34
+ if (typeof this.extend === "function") {
35
+ this.extend({
36
+ validator: this.validator,
37
+ form: this.state!.form,
38
+ });
39
+ }
40
+ }
41
+
42
+ validate(field: FieldInterface): void {
43
+ const data = this.state!.form.flatMapValues;
44
+ const { error } = this.schema.validate(data, { abortEarly: false });
45
+
46
+ if (!error) return;
47
+
48
+ const fieldPathArray = (field.path ?? "").split(".");
49
+
50
+ const fieldErrors = error.details
51
+ .filter((detail: any) => {
52
+ const errorPathString = detail.path.join(".");
53
+ const fieldPathString = fieldPathArray.join(".");
54
+ return (
55
+ errorPathString === fieldPathString ||
56
+ errorPathString.startsWith(`${fieldPathString}.`)
57
+ );
58
+ })
59
+ .map((detail: any) => {
60
+ const label = detail.context?.label || detail.path.join(".");
61
+ const message = detail.message.replace(
62
+ `${detail.path.join(".")}`,
63
+ label
64
+ );
65
+ return message;
66
+ });
67
+
68
+ if (fieldErrors.length) {
69
+ field.validationErrorStack = fieldErrors;
70
+ }
71
+ }
72
+ }
73
+
74
+ export default <TValidator = any>(
75
+ config?: ValidationPluginConfig<TValidator>
76
+ ): ValidationPlugin<TValidator> => ({
77
+ class: JOI<TValidator>,
78
+ config,
79
+ });