@kwiz/common 1.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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/dist/_dependencies.d.ts +1 -0
  3. package/dist/_dependencies.js +8 -0
  4. package/dist/_dependencies.js.map +1 -0
  5. package/dist/helpers/Guid.d.ts +119 -0
  6. package/dist/helpers/Guid.js +183 -0
  7. package/dist/helpers/Guid.js.map +1 -0
  8. package/dist/helpers/_dependencies.d.ts +2 -0
  9. package/dist/helpers/_dependencies.js +21 -0
  10. package/dist/helpers/_dependencies.js.map +1 -0
  11. package/dist/helpers/base64.d.ts +8 -0
  12. package/dist/helpers/base64.js +178 -0
  13. package/dist/helpers/base64.js.map +1 -0
  14. package/dist/helpers/browser.d.ts +144 -0
  15. package/dist/helpers/browser.js +1200 -0
  16. package/dist/helpers/browser.js.map +1 -0
  17. package/dist/helpers/browserinfo.d.ts +23 -0
  18. package/dist/helpers/browserinfo.js +215 -0
  19. package/dist/helpers/browserinfo.js.map +1 -0
  20. package/dist/helpers/collections.base.d.ts +128 -0
  21. package/dist/helpers/collections.base.js +430 -0
  22. package/dist/helpers/collections.base.js.map +1 -0
  23. package/dist/helpers/collections.d.ts +18 -0
  24. package/dist/helpers/collections.js +99 -0
  25. package/dist/helpers/collections.js.map +1 -0
  26. package/dist/helpers/color.d.ts +11 -0
  27. package/dist/helpers/color.js +57 -0
  28. package/dist/helpers/color.js.map +1 -0
  29. package/dist/helpers/cookies.d.ts +6 -0
  30. package/dist/helpers/cookies.js +56 -0
  31. package/dist/helpers/cookies.js.map +1 -0
  32. package/dist/helpers/date.d.ts +43 -0
  33. package/dist/helpers/date.js +158 -0
  34. package/dist/helpers/date.js.map +1 -0
  35. package/dist/helpers/debug.d.ts +33 -0
  36. package/dist/helpers/debug.js +177 -0
  37. package/dist/helpers/debug.js.map +1 -0
  38. package/dist/helpers/emails.d.ts +2 -0
  39. package/dist/helpers/emails.js +10 -0
  40. package/dist/helpers/emails.js.map +1 -0
  41. package/dist/helpers/eval.d.ts +1 -0
  42. package/dist/helpers/eval.js +10 -0
  43. package/dist/helpers/eval.js.map +1 -0
  44. package/dist/helpers/file.d.ts +11 -0
  45. package/dist/helpers/file.js +55 -0
  46. package/dist/helpers/file.js.map +1 -0
  47. package/dist/helpers/flatted.d.ts +20 -0
  48. package/dist/helpers/flatted.js +135 -0
  49. package/dist/helpers/flatted.js.map +1 -0
  50. package/dist/helpers/functions.d.ts +4 -0
  51. package/dist/helpers/functions.js +17 -0
  52. package/dist/helpers/functions.js.map +1 -0
  53. package/dist/helpers/graph/calendar.types.d.ts +3 -0
  54. package/dist/helpers/graph/calendar.types.js +15 -0
  55. package/dist/helpers/graph/calendar.types.js.map +1 -0
  56. package/dist/helpers/http.d.ts +25 -0
  57. package/dist/helpers/http.js +70 -0
  58. package/dist/helpers/http.js.map +1 -0
  59. package/dist/helpers/images.d.ts +16 -0
  60. package/dist/helpers/images.js +21 -0
  61. package/dist/helpers/images.js.map +1 -0
  62. package/dist/helpers/index.d.ts +29 -0
  63. package/dist/helpers/index.js +46 -0
  64. package/dist/helpers/index.js.map +1 -0
  65. package/dist/helpers/json.d.ts +3 -0
  66. package/dist/helpers/json.js +44 -0
  67. package/dist/helpers/json.js.map +1 -0
  68. package/dist/helpers/md5.d.ts +5 -0
  69. package/dist/helpers/md5.js +172 -0
  70. package/dist/helpers/md5.js.map +1 -0
  71. package/dist/helpers/objects.d.ts +49 -0
  72. package/dist/helpers/objects.js +271 -0
  73. package/dist/helpers/objects.js.map +1 -0
  74. package/dist/helpers/promises.d.ts +14 -0
  75. package/dist/helpers/promises.js +112 -0
  76. package/dist/helpers/promises.js.map +1 -0
  77. package/dist/helpers/random.d.ts +2 -0
  78. package/dist/helpers/random.js +32 -0
  79. package/dist/helpers/random.js.map +1 -0
  80. package/dist/helpers/scheduler/scheduler.d.ts +39 -0
  81. package/dist/helpers/scheduler/scheduler.js +109 -0
  82. package/dist/helpers/scheduler/scheduler.js.map +1 -0
  83. package/dist/helpers/sharepoint.d.ts +112 -0
  84. package/dist/helpers/sharepoint.js +629 -0
  85. package/dist/helpers/sharepoint.js.map +1 -0
  86. package/dist/helpers/strings.d.ts +56 -0
  87. package/dist/helpers/strings.js +282 -0
  88. package/dist/helpers/strings.js.map +1 -0
  89. package/dist/helpers/typecheckers.d.ts +56 -0
  90. package/dist/helpers/typecheckers.js +274 -0
  91. package/dist/helpers/typecheckers.js.map +1 -0
  92. package/dist/helpers/url.d.ts +46 -0
  93. package/dist/helpers/url.js +199 -0
  94. package/dist/helpers/url.js.map +1 -0
  95. package/dist/helpers/urlhelper.d.ts +16 -0
  96. package/dist/helpers/urlhelper.js +96 -0
  97. package/dist/helpers/urlhelper.js.map +1 -0
  98. package/dist/index.d.ts +15 -0
  99. package/dist/index.js +37 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/types/common.types.d.ts +19 -0
  102. package/dist/types/common.types.js +4 -0
  103. package/dist/types/common.types.js.map +1 -0
  104. package/dist/types/flatted.types.d.ts +49 -0
  105. package/dist/types/flatted.types.js +3 -0
  106. package/dist/types/flatted.types.js.map +1 -0
  107. package/dist/types/globals.types.d.ts +6 -0
  108. package/dist/types/globals.types.js +3 -0
  109. package/dist/types/globals.types.js.map +1 -0
  110. package/dist/types/graph/calendar.types.d.ts +79 -0
  111. package/dist/types/graph/calendar.types.js +3 -0
  112. package/dist/types/graph/calendar.types.js.map +1 -0
  113. package/dist/types/graph/index.d.ts +1 -0
  114. package/dist/types/graph/index.js +18 -0
  115. package/dist/types/graph/index.js.map +1 -0
  116. package/dist/types/index.d.ts +11 -0
  117. package/dist/types/index.js +28 -0
  118. package/dist/types/index.js.map +1 -0
  119. package/dist/types/knownscript.types.d.ts +22 -0
  120. package/dist/types/knownscript.types.js +3 -0
  121. package/dist/types/knownscript.types.js.map +1 -0
  122. package/dist/types/libs/datajs.types.d.ts +29 -0
  123. package/dist/types/libs/datajs.types.js +3 -0
  124. package/dist/types/libs/datajs.types.js.map +1 -0
  125. package/dist/types/libs/ics.types.d.ts +29 -0
  126. package/dist/types/libs/ics.types.js +3 -0
  127. package/dist/types/libs/ics.types.js.map +1 -0
  128. package/dist/types/libs/index.d.ts +3 -0
  129. package/dist/types/libs/index.js +20 -0
  130. package/dist/types/libs/index.js.map +1 -0
  131. package/dist/types/libs/msal.types.d.ts +33 -0
  132. package/dist/types/libs/msal.types.js +63 -0
  133. package/dist/types/libs/msal.types.js.map +1 -0
  134. package/dist/types/locales.d.ts +122 -0
  135. package/dist/types/locales.js +1 -0
  136. package/dist/types/locales.js.map +1 -0
  137. package/dist/types/localstoragecache.types.d.ts +8 -0
  138. package/dist/types/localstoragecache.types.js +3 -0
  139. package/dist/types/localstoragecache.types.js.map +1 -0
  140. package/dist/types/moment.d.ts +6 -0
  141. package/dist/types/moment.js +1 -0
  142. package/dist/types/moment.js.map +1 -0
  143. package/dist/types/regex.types.d.ts +14 -0
  144. package/dist/types/regex.types.js +3 -0
  145. package/dist/types/regex.types.js.map +1 -0
  146. package/dist/types/rest.types.d.ts +81 -0
  147. package/dist/types/rest.types.js +24 -0
  148. package/dist/types/rest.types.js.map +1 -0
  149. package/dist/types/sharepoint.types.d.ts +1432 -0
  150. package/dist/types/sharepoint.types.js +629 -0
  151. package/dist/types/sharepoint.types.js.map +1 -0
  152. package/dist/types/sharepoint.utils.types.d.ts +246 -0
  153. package/dist/types/sharepoint.utils.types.js +26 -0
  154. package/dist/types/sharepoint.utils.types.js.map +1 -0
  155. package/dist/utils/_dependencies.d.ts +3 -0
  156. package/dist/utils/_dependencies.js +24 -0
  157. package/dist/utils/_dependencies.js.map +1 -0
  158. package/dist/utils/base64.d.ts +2 -0
  159. package/dist/utils/base64.js +41 -0
  160. package/dist/utils/base64.js.map +1 -0
  161. package/dist/utils/consolelogger.d.ts +73 -0
  162. package/dist/utils/consolelogger.js +281 -0
  163. package/dist/utils/consolelogger.js.map +1 -0
  164. package/dist/utils/date.d.ts +10 -0
  165. package/dist/utils/date.js +30 -0
  166. package/dist/utils/date.js.map +1 -0
  167. package/dist/utils/emails.d.ts +2 -0
  168. package/dist/utils/emails.js +24 -0
  169. package/dist/utils/emails.js.map +1 -0
  170. package/dist/utils/index.d.ts +13 -0
  171. package/dist/utils/index.js +31 -0
  172. package/dist/utils/index.js.map +1 -0
  173. package/dist/utils/knownscript.d.ts +99 -0
  174. package/dist/utils/knownscript.js +261 -0
  175. package/dist/utils/knownscript.js.map +1 -0
  176. package/dist/utils/localstoragecache.d.ts +19 -0
  177. package/dist/utils/localstoragecache.js +372 -0
  178. package/dist/utils/localstoragecache.js.map +1 -0
  179. package/dist/utils/rest.d.ts +17 -0
  180. package/dist/utils/rest.js +402 -0
  181. package/dist/utils/rest.js.map +1 -0
  182. package/dist/utils/script.d.ts +33 -0
  183. package/dist/utils/script.js +169 -0
  184. package/dist/utils/script.js.map +1 -0
  185. package/dist/utils/sharepoint.rest/common.d.ts +32 -0
  186. package/dist/utils/sharepoint.rest/common.js +146 -0
  187. package/dist/utils/sharepoint.rest/common.js.map +1 -0
  188. package/dist/utils/sharepoint.rest/date.d.ts +2 -0
  189. package/dist/utils/sharepoint.rest/date.js +57 -0
  190. package/dist/utils/sharepoint.rest/date.js.map +1 -0
  191. package/dist/utils/sharepoint.rest/file.folder.d.ts +58 -0
  192. package/dist/utils/sharepoint.rest/file.folder.js +305 -0
  193. package/dist/utils/sharepoint.rest/file.folder.js.map +1 -0
  194. package/dist/utils/sharepoint.rest/index.d.ts +11 -0
  195. package/dist/utils/sharepoint.rest/index.js +28 -0
  196. package/dist/utils/sharepoint.rest/index.js.map +1 -0
  197. package/dist/utils/sharepoint.rest/item.d.ts +81 -0
  198. package/dist/utils/sharepoint.rest/item.js +444 -0
  199. package/dist/utils/sharepoint.rest/item.js.map +1 -0
  200. package/dist/utils/sharepoint.rest/list.d.ts +228 -0
  201. package/dist/utils/sharepoint.rest/list.js +868 -0
  202. package/dist/utils/sharepoint.rest/list.js.map +1 -0
  203. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.d.ts +19 -0
  204. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.js +629 -0
  205. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.js.map +1 -0
  206. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.d.ts +14 -0
  207. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.js +222 -0
  208. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.js.map +1 -0
  209. package/dist/utils/sharepoint.rest/listutils/common.d.ts +3 -0
  210. package/dist/utils/sharepoint.rest/listutils/common.js +198 -0
  211. package/dist/utils/sharepoint.rest/listutils/common.js.map +1 -0
  212. package/dist/utils/sharepoint.rest/user-search.d.ts +76 -0
  213. package/dist/utils/sharepoint.rest/user-search.js +239 -0
  214. package/dist/utils/sharepoint.rest/user-search.js.map +1 -0
  215. package/dist/utils/sharepoint.rest/user.d.ts +71 -0
  216. package/dist/utils/sharepoint.rest/user.js +404 -0
  217. package/dist/utils/sharepoint.rest/user.js.map +1 -0
  218. package/dist/utils/sharepoint.rest/web.d.ts +107 -0
  219. package/dist/utils/sharepoint.rest/web.js +929 -0
  220. package/dist/utils/sharepoint.rest/web.js.map +1 -0
  221. package/dist/utils/sod.d.ts +29 -0
  222. package/dist/utils/sod.js +177 -0
  223. package/dist/utils/sod.js.map +1 -0
  224. package/package.json +60 -0
  225. package/readme.md +13 -0
  226. package/src/_dependencies.ts +2 -0
  227. package/src/helpers/Guid.ts +182 -0
  228. package/src/helpers/_dependencies.ts +3 -0
  229. package/src/helpers/base64.ts +174 -0
  230. package/src/helpers/browser.test.js +9 -0
  231. package/src/helpers/browser.ts +1299 -0
  232. package/src/helpers/browserinfo.ts +293 -0
  233. package/src/helpers/collections.base.test.js +26 -0
  234. package/src/helpers/collections.base.ts +439 -0
  235. package/src/helpers/collections.ts +108 -0
  236. package/src/helpers/color.ts +55 -0
  237. package/src/helpers/cookies.ts +55 -0
  238. package/src/helpers/date.test.js +97 -0
  239. package/src/helpers/date.ts +163 -0
  240. package/src/helpers/debug.ts +187 -0
  241. package/src/helpers/emails.ts +7 -0
  242. package/src/helpers/eval.ts +5 -0
  243. package/src/helpers/file.test.js +51 -0
  244. package/src/helpers/file.ts +59 -0
  245. package/src/helpers/flatted.ts +150 -0
  246. package/src/helpers/functions.ts +17 -0
  247. package/src/helpers/graph/calendar.types.ts +11 -0
  248. package/src/helpers/http.ts +70 -0
  249. package/src/helpers/images.ts +23 -0
  250. package/src/helpers/index.ts +29 -0
  251. package/src/helpers/json.ts +39 -0
  252. package/src/helpers/md5.ts +190 -0
  253. package/src/helpers/objects.test.js +27 -0
  254. package/src/helpers/objects.ts +256 -0
  255. package/src/helpers/promises.test.js +18 -0
  256. package/src/helpers/promises.ts +102 -0
  257. package/src/helpers/random.ts +27 -0
  258. package/src/helpers/scheduler/scheduler.test.js +104 -0
  259. package/src/helpers/scheduler/scheduler.ts +132 -0
  260. package/src/helpers/sharepoint.ts +681 -0
  261. package/src/helpers/strings.test.js +43 -0
  262. package/src/helpers/strings.ts +288 -0
  263. package/src/helpers/typecheckers.test.js +35 -0
  264. package/src/helpers/typecheckers.ts +263 -0
  265. package/src/helpers/url.test.js +18 -0
  266. package/src/helpers/url.ts +202 -0
  267. package/src/helpers/urlhelper.ts +104 -0
  268. package/src/index.ts +24 -0
  269. package/src/types/common.types.ts +16 -0
  270. package/src/types/flatted.types.ts +60 -0
  271. package/src/types/globals.types.ts +7 -0
  272. package/src/types/graph/calendar.types.ts +81 -0
  273. package/src/types/graph/index.ts +1 -0
  274. package/src/types/index.ts +12 -0
  275. package/src/types/knownscript.types.ts +19 -0
  276. package/src/types/libs/datajs.types.ts +29 -0
  277. package/src/types/libs/ics.types.ts +31 -0
  278. package/src/types/libs/index.ts +4 -0
  279. package/src/types/libs/msal.types.ts +79 -0
  280. package/src/types/locales.ts +125 -0
  281. package/src/types/localstoragecache.types.ts +9 -0
  282. package/src/types/moment.ts +7 -0
  283. package/src/types/regex.types.ts +17 -0
  284. package/src/types/rest.types.ts +94 -0
  285. package/src/types/sharepoint.types.ts +1413 -0
  286. package/src/types/sharepoint.utils.types.ts +246 -0
  287. package/src/utils/_dependencies.ts +4 -0
  288. package/src/utils/base64.ts +27 -0
  289. package/src/utils/consolelogger.ts +315 -0
  290. package/src/utils/date.ts +36 -0
  291. package/src/utils/emails.ts +25 -0
  292. package/src/utils/index.ts +13 -0
  293. package/src/utils/knownscript.ts +280 -0
  294. package/src/utils/localstoragecache.ts +419 -0
  295. package/src/utils/rest.ts +465 -0
  296. package/src/utils/script.ts +168 -0
  297. package/src/utils/sharepoint.rest/common.ts +149 -0
  298. package/src/utils/sharepoint.rest/date.ts +61 -0
  299. package/src/utils/sharepoint.rest/file.folder.ts +368 -0
  300. package/src/utils/sharepoint.rest/index.ts +11 -0
  301. package/src/utils/sharepoint.rest/item.ts +456 -0
  302. package/src/utils/sharepoint.rest/list.ts +1144 -0
  303. package/src/utils/sharepoint.rest/listutils/GetListItemsByCaml.ts +750 -0
  304. package/src/utils/sharepoint.rest/listutils/GetListItemsById.ts +265 -0
  305. package/src/utils/sharepoint.rest/listutils/common.ts +202 -0
  306. package/src/utils/sharepoint.rest/user-search.ts +254 -0
  307. package/src/utils/sharepoint.rest/user.ts +447 -0
  308. package/src/utils/sharepoint.rest/web.ts +1031 -0
  309. package/src/utils/sod.ts +193 -0
  310. package/tsconfig.json +21 -0
@@ -0,0 +1,439 @@
1
+
2
+ /** this file will only use basic type checker and types, do not add functions that require
3
+ * a reference to tother helpers
4
+ */
5
+
6
+ import { IDictionary } from "./_dependencies";
7
+ import { getFromFullName, isBoolean, isDate, isFunction, isNotEmptyArray, isNullOrEmptyArray, isNullOrEmptyString, isNullOrUndefined, isNumber, isString, isTypeofFullNameFunction } from "./typecheckers";
8
+
9
+ /** this will support HtmlCollectionOf, Arrays, and any other types that have a length and indexer Issue 568 */
10
+ export interface IndexedCollection<ElementType> {
11
+ length: number;
12
+ [index: number]: ElementType;
13
+ }
14
+
15
+ /** Finds an object in array based on a filter and moves it to the start of the array */
16
+ export function moveToStart<T>(arr: T[], filter?: (item: T) => boolean) {
17
+ let index = firstIndexOf<T>(arr, filter);
18
+
19
+ if (index > 0) {
20
+ let obj = arr[index];
21
+ arr.splice(index, 1);
22
+ arr.unshift(obj);
23
+ }
24
+ }
25
+
26
+ /** Finds an object in array based on a filter and moves it to the end of the array */
27
+ export function moveToEnd<T>(arr: T[], filter?: (item: T) => boolean) {
28
+ let index = firstIndexOf<T>(arr, filter);
29
+
30
+ if (index !== -1 && index !== arr.length - 1) {
31
+ let obj = arr[index];
32
+ arr.splice(index, 1);
33
+ arr.push(obj);
34
+ }
35
+ }
36
+
37
+ /** Get the first index of an object of an array, or -1 if the array is empty / null */
38
+ // export function firstIndexOf<T extends Element>(arr: HTMLCollectionOf<T>, filter?: (item: T, index?: number) => boolean, startFrom?: number): number;
39
+ // export function firstIndexOf<T>(arr: T[], filter?: (item: T, index?: number) => boolean, startFrom?: number): number;
40
+ export function firstIndexOf<T>(arr: IndexedCollection<T>, filter?: (item: T, index?: number) => boolean, startFrom?: number): number {
41
+ if (!isNullOrUndefined(arr) && arr.length > 0) {
42
+ if (isFunction(filter)) {
43
+ //use for loop so we can stop when it is found
44
+ for (let i = startFrom > 0 ? startFrom : 0; i < arr.length; i++)
45
+ if (filter(arr[i], i) === true)
46
+ return i;
47
+ }
48
+ else return 0;
49
+ }
50
+
51
+ return -1;
52
+ }
53
+ /** Get the first object of an array, or null if the array is empty / null
54
+ * If you pass a filter, it will find the first element that matches the filter and return it, stopping the loop when it is found
55
+ * */
56
+ export function firstOrNull<T>(arr: IndexedCollection<T>, filter?: (item: T, index?: number) => boolean): T {
57
+ let index = firstIndexOf(arr, filter);
58
+ return index < 0 ? null : arr[index];
59
+ }
60
+
61
+
62
+ /** Get the last index of an object of an array, or -1 if the array is empty / null */
63
+ export function lastIndexOf<T>(arr: IndexedCollection<T>, filter?: (item: T) => boolean): number {
64
+ if (!isNullOrUndefined(arr) && arr.length > 0) {
65
+ if (isFunction(filter)) {
66
+ //use for loop so we can stop when it is found
67
+ for (let i = arr.length - 1; i >= 0; i--)
68
+ if (filter(arr[i]) === true)
69
+ return i;
70
+ }
71
+ else return arr.length - 1;
72
+ }
73
+
74
+ return -1;
75
+ }
76
+
77
+ /** get the last element or null */
78
+ export function lastOrNull<T>(arr: IndexedCollection<T>, filter?: (item: T) => boolean): T {
79
+ let index = lastIndexOf(arr as T[], filter);
80
+ return index < 0 ? null : arr[index];
81
+ }
82
+
83
+ /** Get the first index of an object of an array, or -1 if the array is empty / null */
84
+ export async function firstIndexOfAsync<T>(arr: IndexedCollection<T>, filter?: (item: T, index?: number) => Promise<boolean>, startFrom?: number): Promise<number> {
85
+ if (!isNullOrUndefined(arr) && arr.length > 0) {
86
+ if (isFunction(filter)) {
87
+ //use for loop so we can stop when it is found
88
+ for (let i = startFrom > 0 ? startFrom : 0; i < arr.length; i++)
89
+ if ((await filter(arr[i], i)) === true)
90
+ return i;
91
+ }
92
+ else return 0;
93
+ }
94
+
95
+ return -1;
96
+ }
97
+ /** Get the first object of an array, or null if the array is empty / null
98
+ * If you pass a filter, it will find the first element that matches the filter and return it, stopping the loop when it is found
99
+ * */
100
+ export async function firstOrNullAsync<T>(arr: IndexedCollection<T>, filter?: (item: T, index?: number) => Promise<boolean>): Promise<T> {
101
+ let index = await firstIndexOfAsync(arr, filter);
102
+ return index < 0 ? null : arr[index];
103
+ }
104
+
105
+
106
+ /** Get the last index of an object of an array, or -1 if the array is empty / null */
107
+ export async function lastIndexOfAsync<T>(arr: IndexedCollection<T>, filter?: (item: T) => Promise<boolean>): Promise<number> {
108
+ if (!isNullOrUndefined(arr) && arr.length > 0) {
109
+ if (isFunction(filter)) {
110
+ //use for loop so we can stop when it is found
111
+ for (let i = arr.length - 1; i >= 0; i--)
112
+ if ((await filter(arr[i])) === true)
113
+ return i;
114
+ }
115
+ else return arr.length - 1;
116
+ }
117
+
118
+ return -1;
119
+ }
120
+
121
+ /** get the last element or null */
122
+ export async function lastOrNullAsync<T>(arr: IndexedCollection<T>, filter?: (item: T) => Promise<boolean>): Promise<T> {
123
+ let index = await lastIndexOfAsync(arr, filter);
124
+ return index < 0 ? null : arr[index];
125
+ }
126
+
127
+ /** Sorts an array of complex objects, use defaultPrimitiveGetValue for default functionality */
128
+ export function sortArray<T>(arr: T[], getValue: (item: T) => number | string) {
129
+ if (!isNullOrEmptyArray(arr)) {
130
+ if (isTypeofFullNameFunction("Intl.Collator")) {
131
+ //todo: should probably use the SharePoint locale isntead of 'undefined'
132
+ let collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
133
+ arr.sort((a, b) => {
134
+ let va = getValue(a);
135
+ let vb = getValue(b);
136
+ return collator.compare(va as string, vb as string);
137
+ });
138
+ } else {
139
+ arr.sort((a, b) => {
140
+ let va = getValue(a);
141
+ if (isString(va)) va = va.toLowerCase();
142
+ let vb = getValue(b);
143
+ if (isString(vb)) vb = vb.toLowerCase();
144
+ return va === vb ? 0 : va > vb ? 1 : -1;
145
+ });
146
+ }
147
+ }
148
+ return arr;
149
+ }
150
+
151
+ /** removes null, undefined or "" elements from the array */
152
+ export function filterEmptyEntries<T>(arr: T[]) {
153
+ return arr.filter(val => !isNullOrEmptyString(val));
154
+ }
155
+
156
+
157
+ export function sortNumberArrayAsc(a: number, b: number): number {
158
+ return a - b;
159
+ }
160
+ export function sortNumberArray(a: number, b: number): number {
161
+ return b - a;
162
+ }
163
+ /** call a foreach on an object or an array, with an option to break when returning false */
164
+ export function forEach<T>(obj: IDictionary<T> | Array<T> | { [key: number]: T; length: number; }, func: (propertyName: string, propertyValue: T, _args?: any) => void | boolean, args?: any) {
165
+ if (obj && func && isFunction(func)) {
166
+ if (Array.isArray(obj) || obj.constructor && getFromFullName("constructor.name", obj) === "Array") {
167
+ for (let i = 0; i < (obj as Array<T>).length; i++) {
168
+ let property = i;
169
+ let value = obj[property];
170
+ let result = func(property.toString(10), value, args);
171
+ if (result === false) {
172
+ break;
173
+ }
174
+ }
175
+ }
176
+ else {
177
+ let keys = Object.keys(obj);
178
+ for (let i = 0; i < keys.length; i++) {
179
+ let property = keys[i];
180
+ let value = obj[property];
181
+ let result = func(property, value, args);
182
+ if (result === false) {
183
+ break;
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ export async function forEachAsync<ElmType, ResultType>(arr: Array<ElmType> | IDictionary<ElmType>, handler: (elm: ElmType, index: number) => Promise<ResultType>, options?: { parallel?: boolean; }) {
191
+ if (!isNullOrUndefined(arr) && Object.keys(arr).length > 0) {
192
+ let keys = Object.keys(arr);
193
+ if (options && options.parallel) {
194
+ let promises: Promise<ResultType>[] = [];
195
+ keys.forEach((key, i) => {
196
+ promises.push(handler(arr[key], i));
197
+ });
198
+ return Promise.all(promises);
199
+ }
200
+ else {
201
+ let results: ResultType[] = [];
202
+ for (let i = 0; i < keys.length; i++) {
203
+ results.push(await handler(arr[keys[i]], i));
204
+ }
205
+ return results;
206
+ }
207
+ }
208
+ else return []
209
+ }
210
+
211
+ export function sizeOf(obj: any) {
212
+ if (Array.isArray(obj))
213
+ return obj.length;
214
+ return Object.keys(obj).length;
215
+ }
216
+
217
+ export function chunkArray<T>(array: T[], chunkSize: number) {
218
+ var chunkedArray: T[][] = [];
219
+ for (var i = 0; i < array.length; i += chunkSize) {
220
+ chunkedArray.push(array.slice(i, i + chunkSize));
221
+ }
222
+ return chunkedArray;
223
+ }
224
+
225
+ /** Takes an array and transforms it into a hash. this will assign 1 item per key, assumig getKey will be unique per item. */
226
+ export function toHash<T, Y = T>(arr: T[], getKey: (element: T) => string | number, filter?: (element: T) => boolean, transformValue?: (element: T) => Y): IDictionary<Y> {
227
+ let hash: { [key: string | number]: Y; } = {};
228
+ if (!isFunction(transformValue)) transformValue = v => v as any as Y;
229
+ if (isNotEmptyArray(arr))
230
+ arr.forEach(i => {
231
+ if (!isFunction(filter) || filter(i))
232
+ hash[getKey(i)] = transformValue(i);
233
+ });
234
+ return hash;
235
+ }
236
+
237
+ /** Returns an array from the values of the dictionary. */
238
+ export function toArray<Source, Result = Source>(hash: { [key: string]: Source; }, filter?: (element: Source) => boolean, transform?: (key: string, element: Source) => Result): Result[] {
239
+ let arr: Result[] = [];
240
+ if (!isFunction(transform)) transform = (key, element) => element as any as Result;
241
+
242
+ if (!isNullOrUndefined(hash))
243
+ Object.keys(hash).forEach(key => {
244
+ if (!isFunction(filter) || filter(hash[key]))
245
+ arr.push(transform(key, hash[key]));
246
+ });
247
+ return arr;
248
+ }
249
+
250
+ /** returns a new dictionary, converting each entry in source using the transform function */
251
+ export function convertDictionary<S, R>(source: IDictionary<S>, transform: (sourceItem: S) => R): IDictionary<R> {
252
+ let result: IDictionary<R> = {};
253
+ forEach(source, (key, value) => { result[key] = transform(value); });
254
+ return result;
255
+ }
256
+
257
+ export function flattenArray<T>(array: (T | T[])[]) {
258
+ return array.reduce((acc, val) => (acc as T[]).concat(val), []) as T[];
259
+ }
260
+
261
+ /** careful, does not work for date/complex objects. Use GetUniqueArrayInfo if you suspect you might have Date/complex objects. */
262
+ export function makeUniqueArray<T>(arr: T[]) {
263
+ return arr.filter((v, i, a) => a.indexOf(v) === i);
264
+ }
265
+
266
+ /** return an array of unique values, and the first index they were found, use defaultPrimitiveGetValue for default functionality */
267
+ export function GetUniqueArrayInfo<T, V>(arr: T[], getValue: (item: T) => V) {
268
+ var uniqueValues: { item: T; value: V; firstIndex: number; }[] = [];
269
+ var uniqueArray: T[] = [];
270
+ var foundValues: V[] = [];
271
+ var hasDuplicates = false;
272
+ var duplicateIndexes: number[] = [];
273
+
274
+ if (isNotEmptyArray(arr)) {
275
+ arr.forEach((item, index) => {
276
+ let value = getValue(item);
277
+ if (foundValues.includes(value)) {
278
+ hasDuplicates = true;
279
+ duplicateIndexes.push(index);
280
+ }
281
+ else {
282
+ foundValues.push(value);
283
+ uniqueValues.push({ item: item, value: value, firstIndex: index });
284
+ uniqueArray.push(item);
285
+ }
286
+ });
287
+ }
288
+
289
+ return {
290
+ /** true if duplicate values found */
291
+ hasDuplicates: hasDuplicates,
292
+ /** all duplicate item indexes */
293
+ duplicateIndexes: duplicateIndexes,
294
+ /** unique values and their info */
295
+ uniqueValues: uniqueValues,
296
+ /** the unique version of this array */
297
+ uniqueArray: uniqueArray
298
+ };
299
+ }
300
+
301
+ export interface IMultiLevelGroupItem<ItemType> {
302
+ parentGroup: IMultiLevelGroup<ItemType>;
303
+ }
304
+ export interface IMultiLevelGroup<ItemType> {
305
+ groupItems: (ItemType & IMultiLevelGroupItem<ItemType>)[];
306
+ subGroups: IDictionary<IMultiLevelGroup<ItemType>>;
307
+ depth: number;
308
+ parentGroup: IMultiLevelGroup<ItemType>;
309
+ /** would contain the path to the group, such as: 0_1_3 for first group, second sub group, 4th sub-sub group */
310
+ key: string;
311
+ index: number;
312
+ title: string;
313
+ /** Optional, add a prefix to the group. For example: "Priority > " to fullTitle will be "Priority > High" */
314
+ groupPrefix?: string;
315
+ /** title with decorations, such as prefix */
316
+ fullTitle: string;
317
+ }
318
+ export type MultiLevelGroupItem<ItemType> = ItemType & IMultiLevelGroupItem<ItemType>;
319
+ export type MultiLevelGroupOrItem<ItemType> = MultiLevelGroupItem<ItemType> | IMultiLevelGroup<ItemType>;
320
+ /** returns true if the element is a group of items */
321
+ export function IsMultiLevelGroup<ItemType>(groupOrItem: MultiLevelGroupOrItem<ItemType>): groupOrItem is IMultiLevelGroup<ItemType> {
322
+ let asGroup = groupOrItem as IMultiLevelGroup<ItemType>;
323
+ return !isNullOrUndefined(asGroup.subGroups) && Array.isArray(asGroup.groupItems) && isNumber(asGroup.index) && isNumber(asGroup.depth);
324
+ }
325
+
326
+ /** returns a flat array of groups>items ordered by groups */
327
+ export function FlattenGroupItems<ItemType>(groups: IDictionary<IMultiLevelGroup<ItemType>>) {
328
+ let flatItems: MultiLevelGroupOrItem<ItemType>[] = [];
329
+ Object.keys(groups).forEach(groupName => {
330
+ let group = groups[groupName];
331
+ if (!isNullOrEmptyString(groupName))
332
+ flatItems.push(group);
333
+ let subGroups = Object.keys(group.subGroups);
334
+ if (isNotEmptyArray(subGroups)) {
335
+ flatItems.push(...FlattenGroupItems(group.subGroups));
336
+ }
337
+ else flatItems.push(...group.groupItems);
338
+ });
339
+
340
+ return flatItems;
341
+ }
342
+
343
+ /** split a collection by page size and return the info */
344
+ export function GetPagedCollectionInfo<T>(collection: Array<T>, pageSize: number, currentPage?: number) {
345
+ let pagedItems: (T[])[] = [];
346
+
347
+ if (pageSize < 1) {
348
+ pagedItems = [collection.slice()];
349
+ }
350
+ else {
351
+ let copy = collection.slice();
352
+ while (isNotEmptyArray(copy)) {
353
+ pagedItems.push(copy.splice(0, pageSize));
354
+ }
355
+ }
356
+
357
+ currentPage = isNumber(currentPage) && currentPage >= 0 && currentPage < pagedItems.length ? currentPage : 0;
358
+ return {
359
+ /** nubmer of pages */
360
+ pages: pagedItems.length,
361
+ /** page items, per page (Array of pages, each has an array of the page items) */
362
+ pagedItems: pagedItems,
363
+ /** the current page */
364
+ currentPage: currentPage,
365
+ /** the current page items */
366
+ currentPageItems: pagedItems[currentPage] || [],
367
+ /** has more than 1 page */
368
+ hasPages: pagedItems.length > 1,
369
+ allowPrev: currentPage > 0,
370
+ allowNext: currentPage < pagedItems.length - 1
371
+ };
372
+ }
373
+
374
+ /** use with sortArray or get unique array to handle premitive types or dates, with a JSON.stringify to all other values */
375
+ export function defaultPrimitiveGetValue<T>(item: T) {
376
+ return isNullOrUndefined(item)
377
+ ? ""
378
+ : isDate(item) ? item.getTime()
379
+ : isBoolean(item)
380
+ ? item === true ? 1 : 0
381
+ : isNumber(item) || isString(item)
382
+ ? item
383
+ : JSON.stringify(item);
384
+ }
385
+
386
+ export function RemoveItemFromArr<T>(arr: T[], item: T) {
387
+ let idx = arr.indexOf(item);
388
+ if (idx >= 0)
389
+ arr.splice(idx, 1);
390
+ }
391
+ export function PushNoDuplicate<T>(arr: T[], item: T) {
392
+ if (!arr.includes(item)) arr.push(item);
393
+ }
394
+ /** fills an array with a value. Array.fill isn't available on SPFx. */
395
+ export function ArrayFill<T>(arr: T[], value: T, onlyEmpty?: boolean) {
396
+ for (let i = 0; i < arr.length; i++) {
397
+ if (onlyEmpty !== true || isNullOrUndefined(arr[i]))
398
+ arr[i] = value;
399
+ }
400
+ return arr;
401
+ }
402
+
403
+ /** give a name and a collection, and it will return a unique name availalbe, suffixing a _# to the name
404
+ * example: file
405
+ * return file, file_2, file_9 etc... whichever is availalbe first.
406
+ */
407
+ export function FindNextAvailableName(name: string, usedNames: string[], options?: {
408
+ //check for specific letter case
409
+ caseSensitive?: boolean;
410
+ //append suffix when adding _# for example: file_1.docx, file_2.docx etc
411
+ suffix?: string;
412
+ }) {
413
+ let nameForTest = name;
414
+ if (options && options.caseSensitive !== true) {
415
+ usedNames = usedNames.map(n => n.toLowerCase());
416
+ nameForTest = name.toLowerCase();
417
+ }
418
+
419
+ let nameSuffix = options && options.suffix || "";
420
+
421
+ let suffixIdx = 0;
422
+ let suffixStr = "";
423
+ while (usedNames.indexOf(`${nameForTest}${suffixStr}${nameSuffix}`) >= 0) {
424
+ suffixIdx++;
425
+ suffixStr = "_" + suffixIdx;
426
+ }
427
+
428
+ return `${name}${suffixStr}${nameSuffix}`;
429
+ }
430
+
431
+ //** returns an array of numbers from 0,1,2... */
432
+ export function numbersArray<T extends number>(length: number, startFrom: number = 0) {
433
+ //dvp build will fail without any type
434
+ if (isNullOrUndefined(length) || length < 0) length = 0;
435
+ let arr: number[] = Array.from((Array(length) as any).keys());
436
+ return startFrom > 0
437
+ ? arr.map(i => i + startFrom) as T[]
438
+ : arr as T[];
439
+ }
@@ -0,0 +1,108 @@
1
+ import { IDictionary } from "./_dependencies";
2
+ import { IMultiLevelGroup, IMultiLevelGroupItem } from "./collections.base";
3
+ import { hasOwnProperty, objectsEqual } from "./objects";
4
+ import { isFunction, isNotEmptyArray, isNullOrEmptyArray, isNullOrEmptyString, isNullOrUndefined, isNumber, isString } from "./typecheckers";
5
+
6
+ /** check that every element in the arrays are the same value */
7
+ export function arraysEqual(arr1: any[], arr2: any[]): boolean {
8
+ if (isNullOrEmptyArray(arr1) && isNullOrEmptyArray(arr2)) return true;
9
+ return Array.isArray(arr1) && Array.isArray(arr2) && arr1.length === arr2.length && arr1.every((v1: any, i: number) => {
10
+ var v2 = arr2[i];
11
+ if (isString(v1) || isNumber(v1)) {
12
+ return v1 === v2;
13
+ } else if (Array.isArray(v1) && Array.isArray(v2)) {
14
+ return arraysEqual(v1, v2);
15
+ } else {
16
+ return objectsEqual(v1, v2);
17
+ }
18
+ });
19
+ }
20
+
21
+ /** Takes an array and transforms it into a dictionary. this will assign all items of the same key as an array. */
22
+ export function groupBy<T>(arr: T[], getKeys: (element: T) => string[], filter?: (element: T) => boolean): IDictionary<T[]> {
23
+ let dic: IDictionary<T[]> = {};
24
+
25
+ if (isNotEmptyArray(arr))
26
+ arr.forEach(i => {
27
+ if (!isFunction(filter) || filter(i)) {
28
+ let keys = getKeys(i);
29
+ keys.forEach(key => {
30
+ if (isNullOrEmptyString(key)) key = "";
31
+ if (!hasOwnProperty(dic, key)) dic[key] = [i];
32
+ else dic[key].push(i);
33
+ });
34
+ }
35
+ });
36
+ return dic;
37
+ }
38
+
39
+ var groupByMultipleCacheKey = "$groupByMultipleCache";
40
+ /** allows nested multi-level grouping */
41
+ export function GroupByMultiple<ItemType>(arr: ItemType[], groupDefinitions: {
42
+ /** return all groups this item belongs to */
43
+ getGroupsForThisElement: ((element: ItemType) => string[]);
44
+ /** Optional, add a prefix to the group. For example: "Priority > " to fullTitle will be "Priority > High" */
45
+ groupPrefix?: string;
46
+ }[], options?: {
47
+ filter?: (element: ItemType) => boolean;
48
+ /** if groups were calculated, they are returned from cache. send true to clear that cache. send true if you suspect getKeysCollection might change on your existing array. */
49
+ clearCache?: boolean;
50
+ parentGroup?: IMultiLevelGroup<ItemType>;
51
+ }): IDictionary<IMultiLevelGroup<ItemType>> {
52
+ options = options || {};
53
+ if (options.clearCache || isNullOrUndefined(arr[groupByMultipleCacheKey])) {
54
+ let dic: IDictionary<IMultiLevelGroup<ItemType>> = {};
55
+
56
+ let groupDefinition = groupDefinitions[0];//get first
57
+ let getKeys = groupDefinition.getGroupsForThisElement;
58
+
59
+ if (isNotEmptyArray(arr)) {
60
+ let groupIndex = 0;
61
+ arr.forEach(i => {
62
+ if (!isFunction(options.filter) || options.filter(i)) {
63
+ let keys = getKeys(i);
64
+ keys.forEach(key => {
65
+ if (isNullOrEmptyString(key)) key = "";
66
+ if (!hasOwnProperty(dic, key)) {
67
+ let groupKey = groupIndex.toString(10);
68
+ let groupKeyParent = options.parentGroup;
69
+ while (groupKeyParent) {
70
+ groupKey = groupKeyParent.index + "_" + groupKey;
71
+ groupKeyParent = groupKeyParent.parentGroup;
72
+ }
73
+ dic[key] = {
74
+ groupItems: [],
75
+ subGroups: {},
76
+ depth: options.parentGroup ? options.parentGroup.depth + 1 : 0,
77
+ parentGroup: options.parentGroup,
78
+ key: groupKey,
79
+ index: groupIndex,
80
+ title: key,
81
+ groupPrefix: groupDefinition.groupPrefix,
82
+ fullTitle: `${isNullOrEmptyString(groupDefinition.groupPrefix) ? "" : groupDefinition.groupPrefix}${key}`
83
+ };
84
+ groupIndex++;
85
+ }
86
+ let itemWithGroup = i as (ItemType & IMultiLevelGroupItem<ItemType>);
87
+ itemWithGroup.parentGroup = dic[key];
88
+ dic[key].groupItems.push(itemWithGroup);
89
+ });
90
+ }
91
+ });
92
+ }
93
+
94
+ if (isNotEmptyArray(groupDefinitions) && groupDefinitions.length > 1) {
95
+ //run for every group and call this again
96
+ Object.keys(dic).forEach(groupName => {
97
+ let currentGroup = dic[groupName];
98
+ currentGroup.subGroups = GroupByMultiple(currentGroup.groupItems, groupDefinitions.slice(1), {
99
+ ...options,
100
+ parentGroup: currentGroup
101
+ });
102
+ });
103
+ }
104
+
105
+ arr[groupByMultipleCacheKey] = dic;
106
+ }
107
+ return arr[groupByMultipleCacheKey];
108
+ }
@@ -0,0 +1,55 @@
1
+ import { isNullOrEmptyString } from "./typecheckers";
2
+
3
+ /** get the oposite color of a color, or the best contrasting black or white. This is useful to know which color text to show on a dynamic background color */
4
+ export function invertColor(color: string, blackOrWhite?: boolean, defaultIfEmpty?: string) {
5
+ if (isNullOrEmptyString(color) && !isNullOrEmptyString(defaultIfEmpty)) return defaultIfEmpty;
6
+ let rgba = colorToRGBA(color);
7
+
8
+ if (blackOrWhite) {
9
+ // http://stackoverflow.com/a/3943023/112731
10
+ return (rgba.r * 0.299 + rgba.g * 0.587 + rgba.b * 0.114) > 186
11
+ ? '#000000'
12
+ : '#FFFFFF';
13
+ }
14
+ // invert color components
15
+ let _r = (255 - rgba.r);
16
+ let _g = (255 - rgba.g);
17
+ let _b = (255 - rgba.b);
18
+ // pad each with zeros and return
19
+ return "#" + byteToHex(_r) + byteToHex(_g) + byteToHex(_b);
20
+ }
21
+
22
+
23
+ /** Returns the color as an array of [r, g, b, a] -- all range from 0 - 255 */
24
+ export function colorToRGBA(color: string) {
25
+ // Returns the color as an array of [r, g, b, a] -- all range from 0 - 255
26
+ // color must be a valid canvas fillStyle. This will cover most anything
27
+ // you'd want to use.
28
+ // Examples:
29
+ // colorToRGBA('red') # [255, 0, 0, 255]
30
+ // colorToRGBA('#f00') # [255, 0, 0, 255]
31
+ let cvs = document.createElement('canvas');
32
+ cvs.height = 1;
33
+ cvs.width = 1;
34
+ let ctx = cvs.getContext('2d');
35
+ ctx.fillStyle = color;
36
+ ctx.fillRect(0, 0, 1, 1);
37
+ let data = ctx.getImageData(0, 0, 1, 1).data;
38
+ return { r: data[0], g: data[1], b: data[2], a: data[3] };
39
+ }
40
+
41
+ function byteToHex(num: number) {
42
+ // Turns a number (0-255) into a 2-character hex number (00-ff)
43
+ return ('0' + num.toString(16)).slice(-2);
44
+ }
45
+
46
+ /** Convert any CSS color to a hex representation, returns #000000 */
47
+ export function colorToHex(color: string) {
48
+ //
49
+ // Examples:
50
+ // colorToHex('red') # '#ff0000'
51
+ // colorToHex('rgb(255, 0, 0)') # '#ff0000'
52
+ let rgba = colorToRGBA(color);
53
+ let hex = byteToHex(rgba.r) + byteToHex(rgba.g) + byteToHex(rgba.b);
54
+ return "#" + hex;
55
+ }
@@ -0,0 +1,55 @@
1
+ import { trim } from "./strings";
2
+ import { isNullOrEmptyString, isNumeric, isString } from "./typecheckers";
3
+
4
+ var _zeroDay = new Date(0);
5
+ var _today = new Date();
6
+
7
+ export function deleteCookie(cookieName: string, path?: string) {
8
+ var days = (_zeroDay.getTime() - _today.getTime()) / (24 * 60 * 60 * 1000);
9
+ setCookie(cookieName, "", Math.round(days), path);
10
+ }
11
+
12
+ export function getAllCookies(prefix?: string): string[] {
13
+ let cookies = document.cookie.split(';');
14
+ let names: string[] = [];
15
+ for (var k = 0; k < cookies.length; k++) {
16
+ let cookieSplit = cookies[k].split('=');
17
+ let cookieName = trim(cookieSplit[0]);
18
+ if (isNullOrEmptyString(prefix) || cookieName.indexOf(prefix) === 0)
19
+ names.push(cookieName);
20
+ }
21
+ return names;
22
+ }
23
+
24
+ /** get a cookie's value by that name, or null */
25
+ export function getCookie(cookieName: string) {
26
+ try {
27
+ let cookies = document.cookie.split(';');
28
+ for (var k = 0; k < cookies.length; k++) {
29
+ let cookieSplit = cookies[k].split('=');
30
+ if (trim(cookieSplit[0]) === cookieName) {
31
+ return decodeURIComponent(trim(cookieSplit[1]));
32
+ }
33
+ }
34
+ } catch (e) { }
35
+ return null;
36
+ }
37
+ /** set a cookie by that name and value. if you do not send expireDays, it will be a session cookie (in memory) */
38
+ export function setCookie(name: string, value: string, expireDays?: number, path?: string) {
39
+ var cookie: string[] = [];
40
+
41
+ var cookieValue = `${name}=${isString(value) ? value : ""}`;
42
+ cookie.push(cookieValue);
43
+
44
+ if (isNumeric(expireDays)) {
45
+ var d = new Date();
46
+ d.setTime(d.getTime() + (expireDays * 24 * 60 * 60 * 1000));
47
+ var cookieExpires = "expires=" + d.toUTCString();
48
+ cookie.push(cookieExpires);
49
+ }
50
+
51
+ var cookiePath = `${isString(path) ? `path=` + path : "path=/"}`;
52
+ cookie.push(cookiePath);
53
+
54
+ document.cookie = cookie.join(";");
55
+ }