@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,309 @@
1
+ const getPasswordStrength = (pwd: string) => {
2
+ let nScore = 0;
3
+ let nLength = 0;
4
+ let nAlphaUC = 0;
5
+ let nAlphaLC = 0;
6
+ let nNumber = 0;
7
+ let nSymbol = 0;
8
+ let nMidChar = 0;
9
+ let nRequirements = 0;
10
+ let nAlphasOnly = 0;
11
+ let nNumbersOnly = 0;
12
+ let nUnqChar = 0;
13
+ let nRepChar = 0;
14
+ let nRepInc = 0;
15
+ let nConsecAlphaUC = 0;
16
+ let nConsecAlphaLC = 0;
17
+ let nConsecNumber = 0;
18
+ let nConsecSymbol = 0;
19
+ let nConsecCharType = 0;
20
+ let nSeqAlpha = 0;
21
+ let nSeqNumber = 0;
22
+ let nSeqSymbol = 0;
23
+ let nSeqChar = 0;
24
+ let nReqChar = 0;
25
+ let nMultMidChar = 2;
26
+ let nMultConsecAlphaUC = 2;
27
+ let nMultConsecAlphaLC = 2;
28
+ let nMultConsecNumber = 2;
29
+ let nMultSeqAlpha = 3;
30
+ let nMultSeqNumber = 3;
31
+ let nMultSeqSymbol = 3;
32
+ let nMultLength = 4;
33
+ let nMultNumber = 4;
34
+ let nMultSymbol = 6;
35
+ let nTmpAlphaUC = "";
36
+ let nTmpAlphaLC = "";
37
+ let nTmpNumber = "";
38
+ let nTmpSymbol = "";
39
+ let sAlphaUC = "0";
40
+ let sAlphaLC = "0";
41
+ let sNumber = "0";
42
+ let sSymbol = "0";
43
+ let sMidChar = "0";
44
+ let sRequirements = "0";
45
+ let sAlphasOnly = "0";
46
+ let sNumbersOnly = "0";
47
+ let sRepChar = "0";
48
+ let sConsecAlphaUC = "0";
49
+ let sConsecAlphaLC = "0";
50
+ let sConsecNumber = "0";
51
+ let sSeqAlpha = "0";
52
+ let sSeqNumber = "0";
53
+ let sSeqSymbol = "0";
54
+ let sComplexity = "Too Short";
55
+ const sAlphas = "abcdefghijklmnopqrstuvwxyz";
56
+ const sNumerics = "01234567890";
57
+ const sSymbols = ")!@#$%^&*()";
58
+ const nMinPwdLen = 8;
59
+ const arrPwd = pwd.replace(/\s+/g, "").split(/\s*/);
60
+ const arrPwdLen = arrPwd.length;
61
+
62
+ nScore = pwd.length * nMultLength;
63
+ nLength = pwd.length;
64
+
65
+ /* Loop through password to check for Symbol, Numeric, Lowercase and Uppercase pattern matches */
66
+ for (let a = 0; a < arrPwdLen; a++) {
67
+ if (arrPwd[a].match(/[A-Z]/g)) {
68
+ if (nTmpAlphaUC !== "") {
69
+ if (nTmpAlphaUC + 1 == a) {
70
+ nConsecAlphaUC++;
71
+ nConsecCharType++;
72
+ }
73
+ }
74
+
75
+ nTmpAlphaUC = a;
76
+ nAlphaUC++;
77
+ } else if (arrPwd[a].match(/[a-z]/g)) {
78
+ if (nTmpAlphaLC !== "") {
79
+ if (nTmpAlphaLC + 1 == a) {
80
+ nConsecAlphaLC++;
81
+ nConsecCharType++;
82
+ }
83
+ }
84
+
85
+ nTmpAlphaLC = a;
86
+ nAlphaLC++;
87
+ } else if (arrPwd[a].match(/[0-9]/g)) {
88
+ if (a > 0 && a < arrPwdLen - 1) {
89
+ nMidChar++;
90
+ }
91
+ if (nTmpNumber !== "") {
92
+ if (nTmpNumber + 1 == a) {
93
+ nConsecNumber++;
94
+ nConsecCharType++;
95
+ }
96
+ }
97
+
98
+ nTmpNumber = a;
99
+ nNumber++;
100
+ } else if (arrPwd[a].match(/[^a-zA-Z0-9_]/g)) {
101
+ if (a > 0 && a < arrPwdLen - 1) {
102
+ nMidChar++;
103
+ }
104
+
105
+ if (nTmpSymbol !== "") {
106
+ if (nTmpSymbol + 1 == a) {
107
+ nConsecSymbol++;
108
+ nConsecCharType++;
109
+ }
110
+ }
111
+
112
+ nTmpSymbol = a;
113
+ nSymbol++;
114
+ }
115
+
116
+ /* Internal loop through password to check for repeat characters */
117
+ let bCharExists = false;
118
+ for (let b = 0; b < arrPwdLen; b++) {
119
+ if (arrPwd[a] == arrPwd[b] && a != b) {
120
+ // repeat character exists
121
+ bCharExists = true;
122
+
123
+ /**
124
+ * Calculate icrement deduction based on proximity to identical characters
125
+ * Deduction is incremented each time a new match is discovered
126
+ * Deduction amount is based on total password length divided by the
127
+ * difference of distance between currently selected match
128
+ */
129
+ nRepInc += Math.abs(arrPwdLen / (b - a));
130
+ }
131
+ }
132
+
133
+ if (bCharExists) {
134
+ nRepChar++;
135
+ nUnqChar = arrPwdLen - nRepChar;
136
+ nRepInc = nUnqChar
137
+ ? Math.ceil(nRepInc / nUnqChar)
138
+ : Math.ceil(nRepInc);
139
+ }
140
+ }
141
+
142
+ /* Check for sequential alpha string patterns (forward and reverse) */
143
+ for (let s = 0; s < 23; s++) {
144
+ let sFwd = sAlphas.substring(s, parseInt(s + 3));
145
+ let sRev = sFwd.split("").reverse().join("");
146
+
147
+ if (
148
+ pwd.toLowerCase().indexOf(sFwd) != -1 ||
149
+ pwd.toLowerCase().indexOf(sRev) != -1
150
+ ) {
151
+ nSeqAlpha++;
152
+ nSeqChar++;
153
+ }
154
+ }
155
+
156
+ /* Check for sequential numeric string patterns (forward and reverse) */
157
+ for (let s = 0; s < 8; s++) {
158
+ let sFwd = sNumerics.substring(s, parseInt(s + 3));
159
+ var sRev = sFwd.split("").reverse().join("");
160
+
161
+ if (
162
+ pwd.toLowerCase().indexOf(sFwd) != -1 ||
163
+ pwd.toLowerCase().indexOf(sRev) != -1
164
+ ) {
165
+ nSeqNumber++;
166
+ nSeqChar++;
167
+ }
168
+ }
169
+
170
+ /* Check for sequential symbol string patterns (forward and reverse) */
171
+ for (let s = 0; s < 8; s++) {
172
+ let sFwd = sSymbols.substring(s, parseInt(s + 3));
173
+ let sRev = sFwd.split("").reverse().join("");
174
+
175
+ if (
176
+ pwd.toLowerCase().indexOf(sFwd) != -1 ||
177
+ pwd.toLowerCase().indexOf(sRev) != -1
178
+ ) {
179
+ nSeqSymbol++;
180
+ nSeqChar++;
181
+ }
182
+ }
183
+
184
+ /* General point assignment */
185
+ if (nAlphaUC > 0 && nAlphaUC < nLength) {
186
+ nScore = parseInt(nScore + (nLength - nAlphaUC) * 2);
187
+ sAlphaUC = "+ " + parseInt((nLength - nAlphaUC) * 2);
188
+ }
189
+
190
+ if (nAlphaLC > 0 && nAlphaLC < nLength) {
191
+ nScore = parseInt(nScore + (nLength - nAlphaLC) * 2);
192
+ sAlphaLC = "+ " + parseInt((nLength - nAlphaLC) * 2);
193
+ }
194
+
195
+ if (nNumber > 0 && nNumber < nLength) {
196
+ nScore = parseInt(nScore + nNumber * nMultNumber);
197
+ sNumber = "+ " + parseInt(nNumber * nMultNumber);
198
+ }
199
+
200
+ if (nSymbol > 0) {
201
+ nScore = parseInt(nScore + nSymbol * nMultSymbol);
202
+ sSymbol = "+ " + parseInt(nSymbol * nMultSymbol);
203
+ }
204
+
205
+ if (nMidChar > 0) {
206
+ nScore = parseInt(nScore + nMidChar * nMultMidChar);
207
+ sMidChar = "+ " + parseInt(nMidChar * nMultMidChar);
208
+ }
209
+
210
+ /* Point deductions for poor practices */
211
+ if ((nAlphaLC > 0 || nAlphaUC > 0) && nSymbol === 0 && nNumber === 0) {
212
+ // Only Letters
213
+ nScore = parseInt(nScore - nLength);
214
+ nAlphasOnly = nLength;
215
+ sAlphasOnly = "- " + nLength;
216
+ }
217
+
218
+ if (nAlphaLC === 0 && nAlphaUC === 0 && nSymbol === 0 && nNumber > 0) {
219
+ // Only Numbers
220
+ nScore = parseInt(nScore - nLength);
221
+ nNumbersOnly = nLength;
222
+ sNumbersOnly = "- " + nLength;
223
+ }
224
+
225
+ if (nRepChar > 0) {
226
+ // Same character exists more than once
227
+ nScore = parseInt(nScore - nRepInc);
228
+ sRepChar = "- " + nRepInc;
229
+ }
230
+
231
+ if (nConsecAlphaUC > 0) {
232
+ // Consecutive Uppercase Letters exist
233
+ nScore = parseInt(nScore - nConsecAlphaUC * nMultConsecAlphaUC);
234
+ sConsecAlphaUC = "- " + parseInt(nConsecAlphaUC * nMultConsecAlphaUC);
235
+ }
236
+
237
+ if (nConsecAlphaLC > 0) {
238
+ // Consecutive Lowercase Letters exist
239
+ nScore = parseInt(nScore - nConsecAlphaLC * nMultConsecAlphaLC);
240
+ sConsecAlphaLC = "- " + parseInt(nConsecAlphaLC * nMultConsecAlphaLC);
241
+ }
242
+
243
+ if (nConsecNumber > 0) {
244
+ // Consecutive Numbers exist
245
+ nScore = parseInt(nScore - nConsecNumber * nMultConsecNumber);
246
+ sConsecNumber = "- " + parseInt(nConsecNumber * nMultConsecNumber);
247
+ }
248
+
249
+ if (nSeqAlpha > 0) {
250
+ // Sequential alpha strings exist (3 characters or more)
251
+ nScore = parseInt(nScore - nSeqAlpha * nMultSeqAlpha);
252
+ sSeqAlpha = "- " + parseInt(nSeqAlpha * nMultSeqAlpha);
253
+ }
254
+
255
+ if (nSeqNumber > 0) {
256
+ // Sequential numeric strings exist (3 characters or more)
257
+ nScore = parseInt(nScore - nSeqNumber * nMultSeqNumber);
258
+ sSeqNumber = "- " + parseInt(nSeqNumber * nMultSeqNumber);
259
+ }
260
+
261
+ if (nSeqSymbol > 0) {
262
+ // Sequential symbol strings exist (3 characters or more)
263
+ nScore = parseInt(nScore - nSeqSymbol * nMultSeqSymbol);
264
+ sSeqSymbol = "- " + parseInt(nSeqSymbol * nMultSeqSymbol);
265
+ }
266
+
267
+ nRequirements = nReqChar;
268
+ let nMinReqChars = 0;
269
+
270
+ if (pwd.length >= nMinPwdLen) {
271
+ nMinReqChars = 3;
272
+ } else {
273
+ nMinReqChars = 4;
274
+ }
275
+
276
+ if (nRequirements > nMinReqChars) {
277
+ // One or more required characters exist
278
+ nScore = parseInt(nScore + nRequirements * 2);
279
+ sRequirements = "+ " + parseInt(nRequirements * 2);
280
+ }
281
+
282
+ /* Determine complexity based on overall score */
283
+ if (nScore > 100) {
284
+ nScore = 100;
285
+ } else if (nScore < 0) {
286
+ nScore = 0;
287
+ }
288
+
289
+ if (nScore >= 0 && nScore < 20) {
290
+ sComplexity = "Very Weak";
291
+ } else if (nScore >= 20 && nScore < 40) {
292
+ sComplexity = "Weak";
293
+ } else if (nScore >= 40 && nScore < 60) {
294
+ sComplexity = "Good";
295
+ } else if (nScore >= 60 && nScore < 80) {
296
+ sComplexity = "Strong";
297
+ } else if (nScore >= 80 && nScore <= 100) {
298
+ sComplexity = "Very Strong";
299
+ }
300
+
301
+ return {
302
+ score: nScore,
303
+ complexity: sComplexity,
304
+ };
305
+ };
306
+
307
+ export default {
308
+ getPasswordStrength,
309
+ };
package/services/ui.ts ADDED
@@ -0,0 +1,43 @@
1
+ import type { ComponentInternalInstance } from "vue";
2
+
3
+ export default {
4
+ popoverActivatorEvent: "popoverClick",
5
+
6
+ wasClickOutsideOfContainer(event: MouseEvent, container: HTMLElement) {
7
+ let targetElement: HTMLElement | null = event.target as HTMLElement;
8
+
9
+ if (!targetElement) {
10
+ return false;
11
+ }
12
+
13
+ do {
14
+ if (targetElement === container) {
15
+ event.stopPropagation();
16
+
17
+ return false;
18
+ }
19
+
20
+ targetElement = targetElement?.parentNode as HTMLElement | null;
21
+ } while (targetElement);
22
+
23
+ return true;
24
+ },
25
+
26
+ isPopoverActivator(instance?: ComponentInternalInstance): boolean {
27
+ if (!instance?.parent || !instance?.parent?.emitsOptions) {
28
+ return false;
29
+ }
30
+
31
+ return this.popoverActivatorEvent in instance.parent.emitsOptions;
32
+ },
33
+
34
+ onPopoverActivatorClick(event: MouseEvent, el: any): void {
35
+ if (this.isPopoverActivator(el)) {
36
+ el.parent.emit(this.popoverActivatorEvent, event);
37
+ }
38
+
39
+ // Make sure not to propagate this further, as it'll also trigger a click event
40
+ // in the parent component
41
+ event.stopPropagation();
42
+ },
43
+ };
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ content: ['./index.html', './components/**/*.vue'],
3
+ darkMode: 'class',
4
+ theme: {
5
+ extend: {
6
+ minHeight: {
7
+ 9: '2.25rem',
8
+ },
9
+ },
10
+ },
11
+ plugins: [
12
+ require('@tailwindcss/forms')({
13
+ strategy: 'class',
14
+ }),
15
+ ],
16
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "experimentalDecorators": true,
4
+ "target": "esnext",
5
+ "useDefineForClassFields": true,
6
+ "module": "esnext",
7
+ "moduleResolution": "node",
8
+ "strict": true,
9
+ "sourceMap": true,
10
+ "resolveJsonModule": true,
11
+ "noImplicitAny": false,
12
+ "allowJs": true,
13
+ "esModuleInterop": true,
14
+ "lib": ["esnext", "dom", "dom.iterable"],
15
+ "baseUrl": ".",
16
+ "types": ["node", "vite/client", "vitest/globals"],
17
+ "paths": {
18
+ "@/*": ["./*"]
19
+ }
20
+ },
21
+ "include": ["./**/*.ts", "./**/*.vue", "vite.config.mts"],
22
+ "exclude": ["node_modules"]
23
+ }
@@ -0,0 +1,44 @@
1
+ export interface Country {
2
+ name: string;
3
+ dialCode: string;
4
+ flag: string;
5
+ iso2: string;
6
+ order: string;
7
+ }
8
+
9
+ export interface CountryStateOption {
10
+ uuid: string;
11
+ name: string;
12
+ }
13
+
14
+ /* Response & Payload from/to the API */
15
+ export interface AddressResource {
16
+ city?: string;
17
+ complement?: string;
18
+ country?: string;
19
+ county?: string;
20
+ id?: string;
21
+ neighborhood?: string;
22
+ number?: string;
23
+ province?: string;
24
+ state?: string;
25
+ street?: string;
26
+ town?: string;
27
+ zipCode?: string;
28
+ }
29
+
30
+ /* Model for InputAddress */
31
+ export interface AddressModel {
32
+ city?: string;
33
+ complement?: string;
34
+ country?: Country;
35
+ county?: string;
36
+ id?: string;
37
+ neighborhood?: string;
38
+ number?: string;
39
+ province?: string;
40
+ state?: string;
41
+ street?: string;
42
+ town?: string;
43
+ zipCode?: string;
44
+ }
package/types/api.ts ADDED
@@ -0,0 +1,28 @@
1
+ export type APISearchFilters = {
2
+ /**
3
+ * ID or UUID
4
+ */
5
+ i?: string;
6
+
7
+ /**
8
+ * Resource type, either:
9
+ * option: to be used in select components, bare minimum data
10
+ * full: to be used anywhere else, contains all the entity data
11
+ */
12
+ r?: "option" | "full";
13
+
14
+ /**
15
+ * Search query
16
+ */
17
+ t?: string;
18
+
19
+ /**
20
+ * Page number
21
+ */
22
+ page?: number | string;
23
+
24
+ /**
25
+ * Amount of items per page
26
+ */
27
+ perPage?: number | string;
28
+ };
@@ -0,0 +1,5 @@
1
+ export type KeysMatching<T, V> = {
2
+ [K in keyof T]-?: T[K] extends V ? K : never;
3
+ }[keyof T];
4
+
5
+ export type Maybe<T> = NonNullable<T> | undefined;
package/types/form.ts ADDED
@@ -0,0 +1,144 @@
1
+ import { Icon } from "@/enums/ui";
2
+ import { Website } from "@/types/website";
3
+ import { Pagination } from "@/types/ui";
4
+ import { APISearchFilters } from "@/types/api";
5
+ import { AddressModel, Country } from "@/types/address";
6
+ import { FormDataTypes, FormSubmissionFormat } from "@/enums/form";
7
+
8
+ export type SelectValuePrimitives = string | number;
9
+
10
+ export type SelectValue = SelectValuePrimitives | Array<SelectValuePrimitives>;
11
+
12
+ export type SelectOption = {
13
+ /** Optional icon, to be appended to the label */
14
+ icon?: `${Icon}`;
15
+
16
+ /** Option label, either a string or an object containing the props necessary to render the option */
17
+ label: any;
18
+
19
+ /** Optional type, used to diferentiate options from one another */
20
+ type?: string;
21
+
22
+ /** Optional renderer, containing the fully resolved path to the component that will be used
23
+ * to render the option
24
+ */
25
+ renderer?: string;
26
+ } & (
27
+ | {
28
+ /** If true, the option is a group label and can't be selected */
29
+ isGroupLabel: boolean;
30
+
31
+ value?: never;
32
+ action?: never;
33
+ }
34
+ | {
35
+ /** Option value */
36
+ value: SelectValue;
37
+
38
+ action?: never;
39
+ isGroupLabel?: never;
40
+ }
41
+ | {
42
+ /** Action to be executed once the option is selected */
43
+ action: (
44
+ filters?: APISearchFilters,
45
+ ) =>
46
+ | Promise<{ items: unknown[]; pagination: Pagination }>
47
+ | Promise<void>
48
+ | void;
49
+
50
+ value?: never;
51
+ isGroupLabel?: never;
52
+ }
53
+ );
54
+
55
+ export interface InputSocialModel {
56
+ profile: string;
57
+ network: number;
58
+ }
59
+
60
+ export interface InputPriceModel {
61
+ iso: string;
62
+ value: number;
63
+ }
64
+
65
+ export interface InputPasswordModel {
66
+ value: string;
67
+ strength?: number;
68
+ updatedAt?: Date;
69
+
70
+ /** If true, encrypts the password before posting to the API */
71
+ encrypt?: boolean;
72
+ }
73
+
74
+ export type FormStyle = { [key in "label" | "input"]?: string };
75
+
76
+ export type FormSchemaValueMap = {
77
+ [FormDataTypes.Address]: AddressModel;
78
+ [FormDataTypes.Boolean]: boolean;
79
+ [FormDataTypes.Country]: Country;
80
+ [FormDataTypes.Date]: Date;
81
+ [FormDataTypes.DateRange]: [Date, Date];
82
+ [FormDataTypes.Document]: File;
83
+ [FormDataTypes.Documents]: File[];
84
+ [FormDataTypes.Number]: number;
85
+ [FormDataTypes.Password]: InputPasswordModel;
86
+ [FormDataTypes.Price]: InputPriceModel;
87
+ [FormDataTypes.String]: string;
88
+ [FormDataTypes.StringArray]: string[];
89
+ [FormDataTypes.Website]: Website;
90
+ };
91
+
92
+ /**
93
+ * Form in the JSON format
94
+ */
95
+ export type JSONForm = { [prop: string]: string | number | boolean | string[] };
96
+
97
+ /**
98
+ * Form in the FormData format
99
+ */
100
+ export type FormDataForm = InstanceType<typeof FormData>;
101
+
102
+ export type FormSubmissionFormatMap = {
103
+ [FormSubmissionFormat.FormData]: FormDataForm;
104
+ [FormSubmissionFormat.JSON]: JSONForm;
105
+ };
106
+
107
+ /**
108
+ * Transformed form, the result of the form transformation from the high level form values
109
+ * to the desired submission format, either FormData or JSON
110
+ */
111
+ export type TransformedForm<T = FormSubmissionFormat.FormData> =
112
+ T extends FormSubmissionFormat.FormData
113
+ ? FormDataForm
114
+ : T extends FormSubmissionFormat.JSON
115
+ ? JSONForm
116
+ : never;
117
+
118
+ /**
119
+ * Validation result object, containing the validation status and the transformed form
120
+ */
121
+ export type ValidationResult<T = FormSubmissionFormat.FormData> = {
122
+ isValid: boolean;
123
+ form: TransformedForm<T>;
124
+ };
125
+
126
+ /**
127
+ * Form schema, defining the form fields and their corresponding FormDataTypes
128
+ */
129
+ export type FormSchema = {
130
+ [key: string]: FormDataTypes;
131
+ };
132
+
133
+ /**
134
+ * Object containing the form values, each value being of one of the types from
135
+ * FormDataTypes, defined by each corresponding input component
136
+ */
137
+ export type FormInstance<T extends Record<string, FormDataTypes>> = {
138
+ [K in keyof T]: FormSchemaValueMap[T[K]];
139
+ };
140
+
141
+ /**
142
+ * Type union of the accepted values by the FormData
143
+ */
144
+ export type AcceptedFormDataValues = string | Blob;
package/types/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./address";
2
+ export * from "./api";
3
+ export * from "./form";
4
+ export * from "./ui";
5
+ export * from "./website";
package/types/ui.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { ElementPosition, ElementVariant } from "@/enums/ui";
2
+
3
+ export interface Pagination {
4
+ /** Amount of items in current page */
5
+ items: number;
6
+
7
+ /** Current page */
8
+ page: number;
9
+
10
+ /** Amount of pages */
11
+ pages: number;
12
+
13
+ /** Amount of items per page */
14
+ perPage: number;
15
+
16
+ /** Amount of items being skipped */
17
+ skip: number;
18
+
19
+ /** Total number of items */
20
+ totalItems: number;
21
+ }
22
+
23
+ export type TableColumn = {
24
+ title?: string;
25
+ } & ({ slot: string } | { property: string });
26
+
27
+ export type TableEditorColumn = {
28
+ title?: string;
29
+
30
+ /** Property name, defaults to slot name */
31
+ property?: string;
32
+
33
+ /** Input type for editing column */
34
+ type?: "text" | "select" | "price";
35
+
36
+ /** Show/Hide column */
37
+ visible?: boolean;
38
+ } & ({ slot: string } | { property: string });
39
+
40
+ export type TableEditorRow = {
41
+ uuid: string;
42
+ [prop: string]: any;
43
+ };
44
+
45
+ export type Tab = {
46
+ title?: string;
47
+ slot?: string;
48
+ };
49
+
50
+ export type Message = {
51
+ id: number;
52
+ message: string;
53
+ variant: `${ElementVariant}`;
54
+ position: `${ElementPosition}`;
55
+ };
@@ -0,0 +1,16 @@
1
+ export type Website = {
2
+ url: string;
3
+ uri?: string;
4
+ www?: boolean;
5
+ secureHttp?: boolean;
6
+ title?: string;
7
+ updatedAt?: string;
8
+ favicon?: string;
9
+ faviconCache?: string;
10
+ faviconLink?: string;
11
+ };
12
+
13
+ export type WebsiteMinified = {
14
+ f: string;
15
+ u: string;
16
+ };