@caipira/tamandua 0.0.1

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 (295) hide show
  1. package/.editorconfig +12 -0
  2. package/.prettierrc +5 -0
  3. package/.storybook/main.ts +25 -0
  4. package/.storybook/preview-body.html +3 -0
  5. package/.storybook/preview.ts +24 -0
  6. package/App.vue +1 -0
  7. package/Dockerfile +21 -0
  8. package/LICENSE +674 -0
  9. package/README.md +11 -0
  10. package/assets/icons/account.svg +1 -0
  11. package/assets/icons/alert-octagon-outline.svg +1 -0
  12. package/assets/icons/alert-octagon.svg +1 -0
  13. package/assets/icons/archive-outline.svg +1 -0
  14. package/assets/icons/archive.svg +1 -0
  15. package/assets/icons/arrow-left.svg +1 -0
  16. package/assets/icons/arrow-right.svg +1 -0
  17. package/assets/icons/bank-outline.svg +1 -0
  18. package/assets/icons/bank.svg +1 -0
  19. package/assets/icons/camera.svg +1 -0
  20. package/assets/icons/cards-outline.svg +1 -0
  21. package/assets/icons/cards-variant.svg +1 -0
  22. package/assets/icons/cart-outline.svg +1 -0
  23. package/assets/icons/chart-box-outline.svg +1 -0
  24. package/assets/icons/chart-box.svg +1 -0
  25. package/assets/icons/check-circle-outline.svg +1 -0
  26. package/assets/icons/check-circle.svg +1 -0
  27. package/assets/icons/check.svg +1 -0
  28. package/assets/icons/checkbox-dark.svg +1 -0
  29. package/assets/icons/checkbox-indeterminate-dark.svg +1 -0
  30. package/assets/icons/checkbox-indeterminate.svg +1 -0
  31. package/assets/icons/checkbox.svg +1 -0
  32. package/assets/icons/chevron-down.svg +1 -0
  33. package/assets/icons/chevron-left.svg +1 -0
  34. package/assets/icons/chevron-right.svg +1 -0
  35. package/assets/icons/chevron-up.svg +1 -0
  36. package/assets/icons/circle.svg +1 -0
  37. package/assets/icons/clock.svg +1 -0
  38. package/assets/icons/close-circle-outline.svg +1 -0
  39. package/assets/icons/close-circle.svg +1 -0
  40. package/assets/icons/close.svg +1 -0
  41. package/assets/icons/cog.svg +1 -0
  42. package/assets/icons/color-fill.svg +1 -0
  43. package/assets/icons/copy.svg +1 -0
  44. package/assets/icons/credit-card-plus.svg +1 -0
  45. package/assets/icons/credit-card.svg +1 -0
  46. package/assets/icons/currency.svg +1 -0
  47. package/assets/icons/database.svg +1 -0
  48. package/assets/icons/dots-grid.svg +1 -0
  49. package/assets/icons/dots-vertical.svg +1 -0
  50. package/assets/icons/email-open-outline.svg +1 -0
  51. package/assets/icons/email-outline.svg +1 -0
  52. package/assets/icons/eye-off.svg +1 -0
  53. package/assets/icons/eye.svg +1 -0
  54. package/assets/icons/file-document-plus-outline.svg +1 -0
  55. package/assets/icons/filmstrip.svg +1 -0
  56. package/assets/icons/filter.svg +1 -0
  57. package/assets/icons/fullscreen-exit.svg +1 -0
  58. package/assets/icons/fullscreen.svg +1 -0
  59. package/assets/icons/group.svg +1 -0
  60. package/assets/icons/image-album-outline.svg +1 -0
  61. package/assets/icons/image-album.svg +1 -0
  62. package/assets/icons/image-outline.svg +1 -0
  63. package/assets/icons/image.svg +1 -0
  64. package/assets/icons/info-outline.svg +1 -0
  65. package/assets/icons/key-chain.svg +1 -0
  66. package/assets/icons/key-variant.svg +1 -0
  67. package/assets/icons/key.svg +1 -0
  68. package/assets/icons/listbox-outline.svg +1 -0
  69. package/assets/icons/loading.svg +1 -0
  70. package/assets/icons/lock-outline.svg +1 -0
  71. package/assets/icons/lock.svg +1 -0
  72. package/assets/icons/logout.svg +1 -0
  73. package/assets/icons/menu-down.svg +1 -0
  74. package/assets/icons/menu-left.svg +1 -0
  75. package/assets/icons/menu-right.svg +1 -0
  76. package/assets/icons/menu.svg +1 -0
  77. package/assets/icons/minus-circle-outline.svg +1 -0
  78. package/assets/icons/minus-circle.svg +1 -0
  79. package/assets/icons/minus.svg +1 -0
  80. package/assets/icons/moon.svg +1 -0
  81. package/assets/icons/open-in-new.svg +1 -0
  82. package/assets/icons/pencil.svg +1 -0
  83. package/assets/icons/people.svg +1 -0
  84. package/assets/icons/piggy-bank-outline.svg +1 -0
  85. package/assets/icons/plus-circle-outline.svg +1 -0
  86. package/assets/icons/plus-circle.svg +1 -0
  87. package/assets/icons/plus.svg +1 -0
  88. package/assets/icons/qrcode-scan.svg +1 -0
  89. package/assets/icons/radio-dark.svg +1 -0
  90. package/assets/icons/radio.svg +1 -0
  91. package/assets/icons/refresh.svg +1 -0
  92. package/assets/icons/save.svg +1 -0
  93. package/assets/icons/search.svg +1 -0
  94. package/assets/icons/spotlight.svg +1 -0
  95. package/assets/icons/store-outline.svg +1 -0
  96. package/assets/icons/sun.svg +1 -0
  97. package/assets/icons/swap-horizontal.svg +1 -0
  98. package/assets/icons/swap-left.svg +1 -0
  99. package/assets/icons/swap-right.svg +1 -0
  100. package/assets/icons/swap.svg +1 -0
  101. package/assets/icons/system-theme.svg +1 -0
  102. package/assets/icons/tag-outline.svg +1 -0
  103. package/assets/icons/trash-can-outline.svg +1 -0
  104. package/assets/icons/trash-can.svg +1 -0
  105. package/assets/icons/upload.svg +1 -0
  106. package/assets/icons/user-circle.svg +1 -0
  107. package/assets/icons/zip-box.svg +1 -0
  108. package/assets/images/fs/apk.svg +11 -0
  109. package/assets/images/fs/bmp.svg +7 -0
  110. package/assets/images/fs/css.svg +8 -0
  111. package/assets/images/fs/doc.svg +9 -0
  112. package/assets/images/fs/docx.svg +9 -0
  113. package/assets/images/fs/folder-adwaita.svg +8 -0
  114. package/assets/images/fs/folder-black.svg +8 -0
  115. package/assets/images/fs/folder-brown.svg +8 -0
  116. package/assets/images/fs/folder-grey.svg +8 -0
  117. package/assets/images/fs/folder-nordic.svg +8 -0
  118. package/assets/images/fs/folder-orange.svg +8 -0
  119. package/assets/images/fs/folder-palebrown.svg +8 -0
  120. package/assets/images/fs/folder-paleorange.svg +8 -0
  121. package/assets/images/fs/folder-teal.svg +8 -0
  122. package/assets/images/fs/folder-white.svg +8 -0
  123. package/assets/images/fs/folder-yellow.svg +8 -0
  124. package/assets/images/fs/gif.svg +7 -0
  125. package/assets/images/fs/go.svg +9 -0
  126. package/assets/images/fs/ics.svg +24 -0
  127. package/assets/images/fs/iso.svg +10 -0
  128. package/assets/images/fs/jpeg.svg +7 -0
  129. package/assets/images/fs/jpg.svg +7 -0
  130. package/assets/images/fs/js.svg +9 -0
  131. package/assets/images/fs/json.svg +9 -0
  132. package/assets/images/fs/lua.svg +9 -0
  133. package/assets/images/fs/m4v.svg +7 -0
  134. package/assets/images/fs/md.svg +10 -0
  135. package/assets/images/fs/mov.svg +7 -0
  136. package/assets/images/fs/mp3.svg +9 -0
  137. package/assets/images/fs/mp4.svg +7 -0
  138. package/assets/images/fs/pdf.svg +9 -0
  139. package/assets/images/fs/pgp.svg +8 -0
  140. package/assets/images/fs/php.svg +9 -0
  141. package/assets/images/fs/png.svg +7 -0
  142. package/assets/images/fs/ppt.svg +9 -0
  143. package/assets/images/fs/py.svg +9 -0
  144. package/assets/images/fs/rar.svg +20 -0
  145. package/assets/images/fs/rpm.svg +7 -0
  146. package/assets/images/fs/rs.svg +9 -0
  147. package/assets/images/fs/sh.svg +9 -0
  148. package/assets/images/fs/tar.svg +20 -0
  149. package/assets/images/fs/txt.svg +8 -0
  150. package/assets/images/fs/unknown.svg +8 -0
  151. package/assets/images/fs/xls.svg +9 -0
  152. package/assets/images/fs/xlsx.svg +9 -0
  153. package/assets/images/fs/xml.svg +8 -0
  154. package/assets/images/fs/yaml.svg +9 -0
  155. package/assets/images/fs/zip.svg +20 -0
  156. package/components/Avatar/Avatar.story.ts +55 -0
  157. package/components/Avatar/Avatar.vue +82 -0
  158. package/components/Avatar/index.ts +12 -0
  159. package/components/Backdrop/Backdrop.vue +27 -0
  160. package/components/Backdrop/index.ts +12 -0
  161. package/components/Button/Button.story.ts +74 -0
  162. package/components/Button/Button.vue +230 -0
  163. package/components/Button/index.ts +12 -0
  164. package/components/ButtonCopy/ButtonCopy.vue +61 -0
  165. package/components/ButtonCopy/index.ts +12 -0
  166. package/components/Drawer/Drawer.vue +102 -0
  167. package/components/Drawer/index.ts +12 -0
  168. package/components/Dropdown/Dropdown.vue +258 -0
  169. package/components/Dropdown/index.ts +12 -0
  170. package/components/EventListener/EventListener.vue +12 -0
  171. package/components/FileDrop/FileDrop.vue +116 -0
  172. package/components/FileDrop/index.ts +12 -0
  173. package/components/Form/Form.spec.ts +72 -0
  174. package/components/Form/Form.vue +134 -0
  175. package/components/Form/index.ts +12 -0
  176. package/components/FormItem/FormItem.vue +85 -0
  177. package/components/FormItem/index.ts +12 -0
  178. package/components/GraphyEmpty/GraphyEmpty.vue +16 -0
  179. package/components/GraphyEmpty/index.ts +12 -0
  180. package/components/GraphyLabel/GraphyLabel.vue +34 -0
  181. package/components/GraphyLabel/index.ts +12 -0
  182. package/components/GraphyPrice/GraphyPrice.story.ts +37 -0
  183. package/components/GraphyPrice/GraphyPrice.vue +65 -0
  184. package/components/GraphyPrice/index.ts +12 -0
  185. package/components/GraphySubtitle/GraphySubtitle.vue +22 -0
  186. package/components/GraphySubtitle/index.ts +12 -0
  187. package/components/GraphyTitle/GraphyTitle.vue +13 -0
  188. package/components/GraphyTitle/index.ts +12 -0
  189. package/components/Icon/Icon.vue +84 -0
  190. package/components/Icon/index.ts +12 -0
  191. package/components/IconButton/IconButton.vue +168 -0
  192. package/components/IconButton/index.ts +12 -0
  193. package/components/InputAvatar/InputAvatar.vue +63 -0
  194. package/components/InputAvatar/index.ts +12 -0
  195. package/components/InputCheckbox/InputCheckbox.vue +77 -0
  196. package/components/InputCheckbox/index.ts +12 -0
  197. package/components/InputColor/InputColor.vue +54 -0
  198. package/components/InputColor/index.ts +12 -0
  199. package/components/InputDate/InputDate.story.ts +15 -0
  200. package/components/InputDate/InputDate.vue +368 -0
  201. package/components/InputDate/index.ts +12 -0
  202. package/components/InputMultiplier/InputMultiplier.vue +144 -0
  203. package/components/InputMultiplier/index.ts +12 -0
  204. package/components/InputPassword/InputPassword.vue +168 -0
  205. package/components/InputPassword/index.ts +12 -0
  206. package/components/InputPhone/InputPhone.vue +125 -0
  207. package/components/InputPhone/index.ts +12 -0
  208. package/components/InputPrice/InputPrice.vue +96 -0
  209. package/components/InputPrice/index.ts +12 -0
  210. package/components/InputRadio/InputRadio.vue +41 -0
  211. package/components/InputRadio/InputRadioGroup.story.ts +24 -0
  212. package/components/InputRadio/InputRadioGroup.vue +48 -0
  213. package/components/InputRadio/index.ts +14 -0
  214. package/components/InputSelect/InputSelect.story.ts +87 -0
  215. package/components/InputSelect/InputSelect.vue +507 -0
  216. package/components/InputSelect/index.ts +12 -0
  217. package/components/InputSwitch/InputSwitch.story.ts +34 -0
  218. package/components/InputSwitch/InputSwitch.vue +82 -0
  219. package/components/InputSwitch/index.ts +12 -0
  220. package/components/InputText/InputText.vue +62 -0
  221. package/components/InputText/index.ts +12 -0
  222. package/components/InputTextarea/InputTextarea.vue +64 -0
  223. package/components/InputTextarea/index.ts +12 -0
  224. package/components/LineChart/LineChart.vue +14 -0
  225. package/components/LineChart/index.ts +12 -0
  226. package/components/Modal/Modal.vue +106 -0
  227. package/components/Modal/index.ts +12 -0
  228. package/components/ModalForm/ModalForm.vue +141 -0
  229. package/components/ModalForm/index.ts +12 -0
  230. package/components/Pagination/Pagination.story.ts +15 -0
  231. package/components/Pagination/Pagination.vue +138 -0
  232. package/components/Pagination/index.ts +12 -0
  233. package/components/PieChart/PieChart.vue +14 -0
  234. package/components/PieChart/index.ts +12 -0
  235. package/components/Popconfirm/Popconfirm.vue +80 -0
  236. package/components/Popconfirm/index.ts +12 -0
  237. package/components/Popover/Popover.vue +133 -0
  238. package/components/Popover/index.ts +12 -0
  239. package/components/ProgressCircle/ProgressCircle.story.ts +31 -0
  240. package/components/ProgressCircle/ProgressCircle.vue +82 -0
  241. package/components/ProgressCircle/index.ts +12 -0
  242. package/components/ProgressLine/ProgressLine.story.ts +27 -0
  243. package/components/ProgressLine/ProgressLine.vue +104 -0
  244. package/components/ProgressLine/index.ts +12 -0
  245. package/components/SensitiveInfo/SensitiveInfo.vue +18 -0
  246. package/components/SensitiveInfo/index.ts +12 -0
  247. package/components/Tab/Tab.vue +58 -0
  248. package/components/Tab/index.ts +12 -0
  249. package/components/Table/Table.story.ts +32 -0
  250. package/components/Table/Table.vue +318 -0
  251. package/components/Table/index.ts +12 -0
  252. package/components/Tag/Tag.vue +73 -0
  253. package/components/Tag/index.ts +12 -0
  254. package/components/Toast/Toast.vue +75 -0
  255. package/components/Toast/index.ts +12 -0
  256. package/components/index.ts +43 -0
  257. package/components/plugins.ts +89 -0
  258. package/composables/index.ts +2 -0
  259. package/composables/useBreakpoints.ts +30 -0
  260. package/composables/useRender.ts +29 -0
  261. package/entrypoint.sh +19 -0
  262. package/enums/app.ts +5 -0
  263. package/enums/form.ts +25 -0
  264. package/enums/ui.ts +160 -0
  265. package/env.d.ts +8 -0
  266. package/i18n.ts +20 -0
  267. package/index.css +383 -0
  268. package/index.html +22 -0
  269. package/index.ts +14 -0
  270. package/main.ts +31 -0
  271. package/package.json +70 -0
  272. package/plugins/register-component.ts +5 -0
  273. package/postcss.config.js +6 -0
  274. package/services/clipboard.ts +5 -0
  275. package/services/date.ts +27 -0
  276. package/services/form/crud.ts +109 -0
  277. package/services/form/form-data-transformers.ts +148 -0
  278. package/services/form/form-json-transformers.ts +91 -0
  279. package/services/form/form-transformer.ts +54 -0
  280. package/services/form/form-value-transformers.ts +35 -0
  281. package/services/form/form.test.ts +98 -0
  282. package/services/form/form.ts +80 -0
  283. package/services/password.ts +309 -0
  284. package/services/ui.ts +43 -0
  285. package/tailwind.config.js +16 -0
  286. package/tsconfig.json +23 -0
  287. package/types/address.ts +44 -0
  288. package/types/api.ts +28 -0
  289. package/types/common.ts +5 -0
  290. package/types/form.ts +144 -0
  291. package/types/index.ts +5 -0
  292. package/types/ui.ts +55 -0
  293. package/types/website.ts +16 -0
  294. package/vite.config.mts +38 -0
  295. package/vitest.setup.ts +21 -0
@@ -0,0 +1,148 @@
1
+ import { FormDataTypes, FormSubmissionFormat } from "@/enums/form";
2
+ import {
3
+ formValueDateTransformer,
4
+ formValuePriceTransformer,
5
+ formValueCountryTransformer,
6
+ formValuePasswordTransformer,
7
+ } from "@/services/form/form-value-transformers";
8
+ import {
9
+ FormDataForm,
10
+ TransformedForm,
11
+ FormSchemaValueMap,
12
+ AcceptedFormDataValues,
13
+ } from "@/types/form";
14
+ ``;
15
+ const sanitizeValue = (value: string | number): AcceptedFormDataValues => {
16
+ if (value === null || value === undefined) {
17
+ value = "";
18
+ } else if (typeof value === "object") {
19
+ value = JSON.stringify(value);
20
+ } else if (typeof value === "number") {
21
+ value = value.toString();
22
+ } else if (typeof value === "boolean") {
23
+ value = value ? "1" : "0";
24
+ }
25
+
26
+ return value;
27
+ };
28
+
29
+ const transformers = {
30
+ default: (
31
+ value:
32
+ | FormSchemaValueMap[FormDataTypes.String]
33
+ | FormSchemaValueMap[FormDataTypes.Number],
34
+ form: FormDataForm,
35
+ key: string
36
+ ) => {
37
+ value = sanitizeValue(value);
38
+
39
+ if (value) {
40
+ form.append(key, value);
41
+ }
42
+
43
+ return form;
44
+ },
45
+ price: (
46
+ price: FormSchemaValueMap[FormDataTypes.Price],
47
+ form: FormDataForm,
48
+ key: string,
49
+ suffixes: string[] = ["Currency", "Value"]
50
+ ): FormDataForm => {
51
+ const [iso, value] = formValuePriceTransformer(price);
52
+
53
+ form.append(`${key}${suffixes[0]}`, sanitizeValue(iso));
54
+ form.append(`${key}${suffixes[1]}`, sanitizeValue(value));
55
+
56
+ return form;
57
+ },
58
+ address: (
59
+ address: FormSchemaValueMap[FormDataTypes.Address],
60
+ form: FormDataForm,
61
+ key: string
62
+ ): FormDataForm => {
63
+ form.append(
64
+ key,
65
+ JSON.stringify({
66
+ ...address,
67
+ country: formValueCountryTransformer(address?.country),
68
+ })
69
+ );
70
+
71
+ return form;
72
+ },
73
+ documents: (
74
+ files: FormSchemaValueMap[FormDataTypes.Documents],
75
+ form: FormDataForm,
76
+ key: string
77
+ ): FormDataForm => {
78
+ if (!key.endsWith("[]")) {
79
+ key = `${key}[]`;
80
+ }
81
+
82
+ Array.from(files).forEach((file: File) => form.append(key, file));
83
+
84
+ return form;
85
+ },
86
+ document: (
87
+ file: FormSchemaValueMap[FormDataTypes.Document],
88
+ form: FormDataForm,
89
+ key: string
90
+ ): FormDataForm => {
91
+ form.append(key, file);
92
+
93
+ return form;
94
+ },
95
+ stringArray: (
96
+ value: FormSchemaValueMap[FormDataTypes.StringArray],
97
+ form: FormDataForm,
98
+ key: string
99
+ ) => {
100
+ if (!key.endsWith("[]")) {
101
+ key = `${key}[]`;
102
+ }
103
+
104
+ value.forEach((item: string) => form.append(key, sanitizeValue(item)));
105
+
106
+ return form;
107
+ },
108
+ };
109
+
110
+ export const formValueToFormDataValue = async (
111
+ schema: FormDataTypes,
112
+ form: TransformedForm<FormSubmissionFormat.FormData>,
113
+ value: FormFieldValue<typeof schema>,
114
+ key: string
115
+ ): Promise<FormDataForm> => {
116
+ switch (schema) {
117
+ case FormDataTypes.Country:
118
+ return transformers.default(
119
+ formValueCountryTransformer(value),
120
+ form,
121
+ key
122
+ );
123
+ case FormDataTypes.Document:
124
+ return transformers.document(value, form, key);
125
+ case FormDataTypes.Documents:
126
+ return transformers.documents(value, form, key);
127
+ case FormDataTypes.Date:
128
+ return transformers.default(
129
+ formValueDateTransformer(value),
130
+ form,
131
+ key
132
+ );
133
+ case FormDataTypes.Address:
134
+ return transformers.address(value, form, key);
135
+ case FormDataTypes.Price:
136
+ return transformers.price(value, form, key);
137
+ case FormDataTypes.Password:
138
+ return transformers.default(
139
+ await formValuePasswordTransformer(value),
140
+ form,
141
+ key
142
+ );
143
+ case FormDataTypes.StringArray:
144
+ return transformers.stringArray(value, form, key);
145
+ default:
146
+ return transformers.default(value, form, key);
147
+ }
148
+ };
@@ -0,0 +1,91 @@
1
+ import { FormDataTypes, FormSubmissionFormat } from "@/enums/form";
2
+ import {
3
+ JSONForm,
4
+ FormSchema,
5
+ TransformedForm,
6
+ FormSchemaValueMap,
7
+ } from "@/types/form";
8
+
9
+ import {
10
+ formValueDateTransformer,
11
+ formValuePriceTransformer,
12
+ formValueCountryTransformer,
13
+ formValuePasswordTransformer,
14
+ } from "@/services/form/form-value-transformers";
15
+
16
+ const transformers = {
17
+ default: (
18
+ value: FormSchemaValueMap[FormDataTypes.String],
19
+ form: JSONForm,
20
+ key: string
21
+ ) => {
22
+ form[key] = value;
23
+
24
+ return form;
25
+ },
26
+ price: (
27
+ date: FormSchemaValueMap[FormDataTypes.Price],
28
+ form: JSONForm,
29
+ key: string,
30
+ suffixes: string[] = ["Currency", "Value"]
31
+ ): JSONForm => {
32
+ const [currency, value] = formValuePriceTransformer(date);
33
+
34
+ form[`${key}${suffixes[0]}`] = currency;
35
+ form[`${key}${suffixes[1]}`] = value;
36
+
37
+ return form;
38
+ },
39
+ password: async (
40
+ value: FormSchemaValueMap[FormDataTypes.Password],
41
+ form: JSONForm,
42
+ key: string
43
+ ): Promise<JSONForm> => {
44
+ form[key] = await formValuePasswordTransformer(value);
45
+
46
+ return form;
47
+ },
48
+ stringArray: (
49
+ value: FormSchemaValueMap[FormDataTypes.StringArray],
50
+ form: JSONForm,
51
+ key: string
52
+ ) => {
53
+ form[key] = value;
54
+
55
+ return form;
56
+ },
57
+ };
58
+
59
+ export const formValueToJSONFormValue = async <T extends FormDataTypes>(
60
+ schema: FormSchema[T],
61
+ form: TransformedForm<FormSubmissionFormat.JSON>,
62
+ value: any,
63
+ key: string
64
+ ): Promise<JSONForm> => {
65
+ switch (schema) {
66
+ case FormDataTypes.Country:
67
+ return transformers.default(
68
+ formValueCountryTransformer(value),
69
+ form,
70
+ key
71
+ );
72
+ case FormDataTypes.Documents:
73
+ return transformers.default(value, form, key);
74
+ case FormDataTypes.Date:
75
+ return transformers.default(
76
+ formValueDateTransformer(value),
77
+ form,
78
+ key
79
+ );
80
+ case FormDataTypes.Address:
81
+ return transformers.default(value, form, key);
82
+ case FormDataTypes.Price:
83
+ return transformers.price(value, form, key);
84
+ case FormDataTypes.Password:
85
+ return await transformers.password(value, form, key);
86
+ case FormDataTypes.StringArray:
87
+ return transformers.stringArray(value, form, key);
88
+ default:
89
+ return transformers.default(value, form, key);
90
+ }
91
+ };
@@ -0,0 +1,54 @@
1
+ import { FormSubmissionFormat } from "@/enums/form";
2
+ import {
3
+ FormSchema,
4
+ FormInstance,
5
+ FormSubmissionFormatMap,
6
+ TransformedForm,
7
+ } from "@/types/form";
8
+
9
+ import { formValueToJSONFormValue } from "@/services/form/form-json-transformers";
10
+ import { formValueToFormDataValue } from "@/services/form/form-data-transformers";
11
+
12
+ /**
13
+ * Transforms the form values to a format that conforms to the submission format
14
+ */
15
+ export const transformForm = async <
16
+ F extends FormSubmissionFormat,
17
+ S extends FormSchema,
18
+ >(
19
+ form: FormInstance<S>,
20
+ schema: FormSchema,
21
+ submissionFormat: F,
22
+ ): Promise<FormSubmissionFormatMap[F]> => {
23
+ switch (submissionFormat) {
24
+ case FormSubmissionFormat.JSON:
25
+ let json: TransformedForm<FormSubmissionFormat.JSON> = {};
26
+
27
+ for (const key in form) {
28
+ json = await formValueToJSONFormValue(
29
+ schema[key],
30
+ json,
31
+ form[key],
32
+ key,
33
+ );
34
+ }
35
+
36
+ return json as FormSubmissionFormatMap[F];
37
+
38
+ case FormSubmissionFormat.FormData:
39
+ default:
40
+ let formData: TransformedForm<FormSubmissionFormat.FormData> =
41
+ new FormData();
42
+
43
+ for (const key in form) {
44
+ formData = await formValueToFormDataValue(
45
+ schema[key],
46
+ formData,
47
+ form[key],
48
+ key,
49
+ );
50
+ }
51
+
52
+ return formData as FormSubmissionFormatMap[F];
53
+ }
54
+ };
@@ -0,0 +1,35 @@
1
+ import { Country } from "@/types/address";
2
+ import { InputPriceModel, InputPasswordModel } from "@/types/form";
3
+
4
+ // import useVault from "@/composables/useVault";
5
+ import dateService from "@/services/date";
6
+
7
+ // const vault = useVault();
8
+
9
+ const formValueDateTransformer = (date: Date): string => {
10
+ return date ? dateService.format(date, "yyyy-MM-dd") : "";
11
+ };
12
+
13
+ const formValuePriceTransformer = (price: InputPriceModel): string[] => {
14
+ return [`${price?.iso}`, `${price?.value}`];
15
+ };
16
+
17
+ const formValueCountryTransformer = (country?: Country): string => {
18
+ return country?.iso2 ?? "";
19
+ };
20
+
21
+ const formValuePasswordTransformer = async (
22
+ password?: InputPasswordModel,
23
+ ): Promise<string> => {
24
+ const pass = password?.value ?? "";
25
+
26
+ // return password?.encrypt ? await vault.encrypt(pass) : pass;
27
+ return pass;
28
+ };
29
+
30
+ export {
31
+ formValueDateTransformer,
32
+ formValuePriceTransformer,
33
+ formValueCountryTransformer,
34
+ formValuePasswordTransformer,
35
+ };
@@ -0,0 +1,98 @@
1
+ import { FormInstance } from "@/types/form";
2
+ import { FormDataTypes, FormSubmissionFormat } from "@/enums/form";
3
+
4
+ import { expect, test } from "vitest";
5
+ import { transformForm } from "@/services/form/form-transformer";
6
+
7
+ test("Form is transformed into FormData", async () => {
8
+ const schema = {
9
+ name: FormDataTypes.String as const,
10
+ age: FormDataTypes.Number as const,
11
+ hobbies: FormDataTypes.StringArray as const,
12
+ birthDate: FormDataTypes.Date as const,
13
+ password: FormDataTypes.Password as const,
14
+ price: FormDataTypes.Price as const,
15
+ };
16
+
17
+ const form: FormInstance<typeof schema> = {
18
+ name: "Theone",
19
+ age: 27,
20
+ hobbies: ["Reading", "Coding"],
21
+ birthDate: new Date("1996-10-06"),
22
+ password: {
23
+ value: "123",
24
+ strength: 100,
25
+ encrypt: false,
26
+ updatedAt: new Date(),
27
+ },
28
+ price: {
29
+ iso: "USD",
30
+ value: 100,
31
+ },
32
+ };
33
+
34
+ const transformedForm = await transformForm(
35
+ form,
36
+ schema,
37
+ FormSubmissionFormat.FormData,
38
+ );
39
+
40
+ expect(transformedForm instanceof FormData).toBeTruthy();
41
+
42
+ // Only the password is extracted from the object
43
+ expect(transformedForm.get("password")).toBe("123");
44
+
45
+ // The price is split into the currency and value
46
+ expect(transformedForm.get("priceCurrency")).toBe("USD");
47
+ expect(transformedForm.get("priceValue")).toBe("100");
48
+
49
+ expect(transformedForm.get("name")).toBe("Theone");
50
+ expect(transformedForm.get("age")).toBe("27");
51
+ expect(transformedForm.getAll("hobbies[]")).toEqual(["Reading", "Coding"]);
52
+ expect(transformedForm.get("birthDate")).toBe("1996-10-06");
53
+ });
54
+
55
+ test("Form is transformed into JSON", async () => {
56
+ const schema = {
57
+ name: FormDataTypes.String as const,
58
+ age: FormDataTypes.Number as const,
59
+ hobbies: FormDataTypes.StringArray as const,
60
+ birthDate: FormDataTypes.Date as const,
61
+ password: FormDataTypes.Password as const,
62
+ price: FormDataTypes.Price as const,
63
+ };
64
+
65
+ const form: FormInstance<typeof schema> = {
66
+ name: "Theone",
67
+ age: 27,
68
+ hobbies: ["Reading", "Coding"],
69
+ birthDate: new Date("1996-10-06"),
70
+ password: {
71
+ value: "123",
72
+ strength: 100,
73
+ encrypt: false,
74
+ updatedAt: new Date(),
75
+ },
76
+ price: {
77
+ iso: "USD",
78
+ value: 100,
79
+ },
80
+ };
81
+
82
+ const transformedForm = await transformForm(
83
+ form,
84
+ schema,
85
+ FormSubmissionFormat.JSON,
86
+ );
87
+
88
+ expect(transformedForm instanceof Object).toBeTruthy();
89
+ expect(transformedForm).toEqual({
90
+ name: "Theone",
91
+ age: 27,
92
+ hobbies: ["Reading", "Coding"],
93
+ birthDate: "1996-10-06",
94
+ password: "123",
95
+ priceCurrency: "USD",
96
+ priceValue: "100",
97
+ });
98
+ });
@@ -0,0 +1,80 @@
1
+ import { APISearchFilters } from "@/types/api";
2
+
3
+ const jsonToFormData = (json: any) => {
4
+ const formData = new FormData();
5
+
6
+ if (json) {
7
+ for (const key in json) {
8
+ if (json[key] !== null && json[key] !== undefined) {
9
+ if (Array.isArray(json[key])) {
10
+ json[key].forEach((item: any) => {
11
+ formData.append(`${key}[]`, item);
12
+ });
13
+ } else {
14
+ formData.append(key, json[key]);
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ return formData;
21
+ };
22
+
23
+ const formDataToJson = (formData: FormData) => {
24
+ const json: any = {};
25
+
26
+ formData.forEach((value, key) => {
27
+ json[key] = value;
28
+ });
29
+
30
+ return json;
31
+ };
32
+
33
+ const hitSearchCache = (
34
+ filters: APISearchFilters | undefined,
35
+ store: any,
36
+ key: string
37
+ ) => {
38
+ if (!store) {
39
+ return;
40
+ }
41
+
42
+ if (filters?.i) {
43
+ const item = store[
44
+ filters?.r && filters?.r === "option" ? `${key}Options` : key
45
+ ]?.find((item: { uuid: string }) => item.uuid === filters.i);
46
+
47
+ if (item) {
48
+ return {
49
+ items: [item],
50
+ pagination: {
51
+ page: 1,
52
+ pages: 1,
53
+ perPage: 12,
54
+ items: 1,
55
+ totalItems: 1,
56
+ skip: 0,
57
+ },
58
+ };
59
+ }
60
+ }
61
+ };
62
+
63
+ const refreshSearchCache = (
64
+ filters: APISearchFilters | undefined,
65
+ store: any,
66
+ key: string,
67
+ data: any[]
68
+ ) => {
69
+ if (!store) {
70
+ return;
71
+ }
72
+
73
+ if (filters?.r && filters?.r === "option") {
74
+ store[`${key}Options`] = data;
75
+ } else {
76
+ store[key] = data;
77
+ }
78
+ };
79
+
80
+ export { jsonToFormData, formDataToJson, hitSearchCache, refreshSearchCache };