@sparted/shared-library 1.9.4 → 1.9.5

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 (479) hide show
  1. package/.circleci/config.yml +40 -0
  2. package/.eslintignore +1 -0
  3. package/.eslintrc.json +25 -0
  4. package/.gitignore +37 -0
  5. package/.prettierrc.json +6 -0
  6. package/CHANGELOG.md +457 -0
  7. package/README.md +26 -0
  8. package/{business → dist/business}/types/multilingual.d.ts +1 -0
  9. package/{business → dist/business}/types/multilingual.js +1 -0
  10. package/dist/business/types/multilingual.js.map +1 -0
  11. package/dist/package.json +25 -0
  12. package/global.d.ts +2 -0
  13. package/package.json +51 -5
  14. package/rollup.config.ts +19 -0
  15. package/sparted-shared-library-v1.7.93.tgz +0 -0
  16. package/src/array/__tests__/array-to-map.test.ts +50 -0
  17. package/src/array/__tests__/get-values-from-keys.test.ts +14 -0
  18. package/src/array/__tests__/inner-join.test.ts +55 -0
  19. package/src/array/__tests__/left-outter-join.test.ts +55 -0
  20. package/src/array/array-to-map.ts +32 -0
  21. package/src/array/get-values-from-keys.ts +3 -0
  22. package/src/array/index.ts +4 -0
  23. package/src/array/inner-join.ts +10 -0
  24. package/src/array/left-outter-join.ts +10 -0
  25. package/src/business/campaign/__tests__/compute-current-session.test.ts +189 -0
  26. package/src/business/campaign/__tests__/compute-intense-calendar.test.ts +134 -0
  27. package/src/business/campaign/__tests__/find-next-available-date.test.ts +82 -0
  28. package/src/business/campaign/__tests__/get-calendar-dession-dates-from-campaign.test.ts +123 -0
  29. package/src/business/campaign/index.ts +1 -0
  30. package/src/business/campaign/live-campaign.ts +133 -0
  31. package/src/business/course/index.ts +1 -0
  32. package/src/business/course/microknowledge-max-lengths.ts +12 -0
  33. package/src/business/index.ts +4 -0
  34. package/src/business/picture-spot/index.ts +3 -0
  35. package/src/business/types/achievement.ts +41 -0
  36. package/src/business/types/activity.ts +64 -0
  37. package/src/business/types/audience.ts +23 -0
  38. package/src/business/types/battle.ts +17 -0
  39. package/src/business/types/breaking-news.ts +43 -0
  40. package/src/business/types/campaign.ts +163 -0
  41. package/src/business/types/content.ts +261 -0
  42. package/src/business/types/document.ts +17 -0
  43. package/src/business/types/index.ts +14 -0
  44. package/src/business/types/media.ts +18 -0
  45. package/src/business/types/multilingual.ts +47 -0
  46. package/src/business/types/player.ts +28 -0
  47. package/src/business/types/score.ts +61 -0
  48. package/src/business/types/thematic.ts +12 -0
  49. package/src/business/types/user-engagement.ts +11 -0
  50. package/src/cdn/__tests__/cdn.factory.test.ts +150 -0
  51. package/src/cdn/__tests__/utils.test.ts +528 -0
  52. package/src/cdn/cdn.factory.ts +70 -0
  53. package/src/cdn/index.ts +2 -0
  54. package/src/cdn/types/cdn-factory.type.ts +49 -0
  55. package/src/cdn/types/index.ts +1 -0
  56. package/src/cdn/utils/extract-info-from-url.util.ts +25 -0
  57. package/src/cdn/utils/get-cdn-from-s3-url.util.ts +20 -0
  58. package/src/cdn/utils/get-cdn-url.util.ts +31 -0
  59. package/src/cdn/utils/twicpics-transformations.util.ts +9 -0
  60. package/src/chrono/get-approximated-session-time.ts +27 -0
  61. package/src/chrono/index.ts +1 -0
  62. package/src/color/__tests__/get-contrast-color.test.ts +22 -0
  63. package/src/color/get-contrast-color.ts +18 -0
  64. package/src/color/index.ts +1 -0
  65. package/src/crypto/__tests__/aes256.test.ts +23 -0
  66. package/src/crypto/aes256.ts +22 -0
  67. package/src/crypto/index.ts +1 -0
  68. package/src/date/__tests__/get-iso-day-number.test.ts +34 -0
  69. package/src/date/__tests__/get-remaining-time.test.ts +78 -0
  70. package/src/date/__tests__/get-start-of-day.test.ts +92 -0
  71. package/src/date/__tests__/is-same-date.test.ts +50 -0
  72. package/src/date/__tests__/shift-date-by.test.ts +76 -0
  73. package/src/date/__tests__/to-utc-date-string.test.ts +28 -0
  74. package/src/date/add-days.ts +5 -0
  75. package/src/date/difference-in-days.ts +6 -0
  76. package/src/date/get-iso-day-number.ts +1 -0
  77. package/src/date/get-next-day.ts +6 -0
  78. package/src/date/get-remaining-time.ts +24 -0
  79. package/src/date/get-start-of-day.ts +11 -0
  80. package/src/date/index.ts +10 -0
  81. package/src/date/is-same-date.ts +7 -0
  82. package/src/date/shift-date-by.ts +17 -0
  83. package/src/date/to-plain-date-string.ts +1 -0
  84. package/src/date/to-utc-date-string.ts +3 -0
  85. package/src/formatting/__tests__/format-number.test.ts +11 -0
  86. package/src/formatting/format-number.ts +14 -0
  87. package/src/formatting/index.ts +1 -0
  88. package/src/fp/__tests__/run-while.test.ts +29 -0
  89. package/src/fp/index.ts +1 -0
  90. package/src/fp/run-while.ts +54 -0
  91. package/src/http/__tests__/build-search-params.test.ts +17 -0
  92. package/src/http/__tests__/encode-search-object.test.ts +34 -0
  93. package/src/http/__tests__/fetch-with-timeout.test.ts +50 -0
  94. package/src/http/build-search-params.ts +16 -0
  95. package/src/http/encode-search-object.ts +42 -0
  96. package/src/http/fetch-with-timeout.ts +27 -0
  97. package/src/http/index.ts +3 -0
  98. package/src/index.ts +19 -0
  99. package/src/linked-list/__tests__/apply-diff-linked-list.test.ts +103 -0
  100. package/src/linked-list/__tests__/create-linked-list.test.ts +204 -0
  101. package/src/linked-list/__tests__/find-linked-list.test.ts +40 -0
  102. package/src/linked-list/__tests__/get-linked-list.test.ts +28 -0
  103. package/src/linked-list/__tests__/insert-linked-list.test.ts +186 -0
  104. package/src/linked-list/__tests__/linked-list-utils.test.ts +252 -0
  105. package/src/linked-list/__tests__/reduce-linked-list.test.ts +31 -0
  106. package/src/linked-list/__tests__/remove-linked-list.test.ts +129 -0
  107. package/src/linked-list/__tests__/update-linked-list.test.ts +53 -0
  108. package/src/linked-list/__tests__/while-linked-list.test.ts +58 -0
  109. package/src/linked-list/apply-diff-linked-list.ts +35 -0
  110. package/src/linked-list/create-linked-list.ts +79 -0
  111. package/src/linked-list/find-linked-list.ts +26 -0
  112. package/src/linked-list/get-linked-list.ts +9 -0
  113. package/src/linked-list/index.ts +2 -0
  114. package/src/linked-list/insert-linked-list.ts +50 -0
  115. package/src/linked-list/linked-list-utils.ts +143 -0
  116. package/src/linked-list/reduce-linked-list.ts +18 -0
  117. package/src/linked-list/remove-linked-list.ts +36 -0
  118. package/src/linked-list/type.ts +38 -0
  119. package/src/linked-list/update-linked-list.ts +30 -0
  120. package/src/linked-list/while-linked-list.ts +33 -0
  121. package/src/math/__tests__/clamp-number.test.ts +30 -0
  122. package/src/math/__tests__/interpolate.test.ts +28 -0
  123. package/src/math/__tests__/median.test.ts +27 -0
  124. package/src/math/__tests__/number-range.test.ts +59 -0
  125. package/src/math/__tests__/random-number.test.ts +11 -0
  126. package/src/math/clamp-number.ts +8 -0
  127. package/src/math/index.ts +5 -0
  128. package/src/math/interpolate.ts +18 -0
  129. package/src/math/median.ts +21 -0
  130. package/src/math/number-range.ts +16 -0
  131. package/src/math/random-number.ts +10 -0
  132. package/src/object/__tests__/merge-deep.test.ts +56 -0
  133. package/src/object/__tests__/strip-properties-from-object.test.ts +65 -0
  134. package/src/object/index.ts +2 -0
  135. package/src/object/merge-deep.ts +26 -0
  136. package/src/object/strip-properties-from-object.ts +26 -0
  137. package/src/parsing/__tests__/parse-boolean.test.ts +15 -0
  138. package/src/parsing/__tests__/parse-enum.test.ts +19 -0
  139. package/src/parsing/__tests__/parse-number.test.ts +20 -0
  140. package/src/parsing/index.ts +3 -0
  141. package/src/parsing/parse-boolean.ts +10 -0
  142. package/src/parsing/parse-enum.ts +16 -0
  143. package/src/parsing/parse-number.ts +12 -0
  144. package/src/predicates/__tests__/is-function.test.ts +11 -0
  145. package/src/predicates/__tests__/is-null.test.ts +11 -0
  146. package/src/predicates/__tests__/is-object.test.ts +11 -0
  147. package/src/predicates/__tests__/is-primitive.test.ts +42 -0
  148. package/src/predicates/__tests__/is-undefined.test.ts +11 -0
  149. package/src/predicates/__tests__/is-uuid.test.ts +13 -0
  150. package/src/predicates/index.ts +5 -0
  151. package/src/predicates/is-function.ts +3 -0
  152. package/src/predicates/is-null.ts +1 -0
  153. package/src/predicates/is-object.ts +3 -0
  154. package/src/predicates/is-primitive.ts +19 -0
  155. package/src/predicates/is-undefined.ts +3 -0
  156. package/src/predicates/is-uuid.ts +3 -0
  157. package/src/promise/__tests__/delay.test.ts +13 -0
  158. package/src/promise/__tests__/execute-or-resolve-default.test.ts +25 -0
  159. package/src/promise/__tests__/execute-with-delay.test.ts +24 -0
  160. package/src/promise/delay.ts +3 -0
  161. package/src/promise/execute-or-resolve-default.ts +14 -0
  162. package/src/promise/execute-with-delay.ts +6 -0
  163. package/src/promise/index.ts +3 -0
  164. package/src/string/__tests__/is-string-length-within-range.test.ts +23 -0
  165. package/src/string/__tests__/replace-in-template.test.ts +52 -0
  166. package/src/string/index.ts +2 -0
  167. package/src/string/is-string-length-within-range.ts +10 -0
  168. package/src/string/replace-in-template.ts +45 -0
  169. package/src/time/__tests__/convert.test.ts +14 -0
  170. package/src/time/__tests__/format-minutes.test.ts +10 -0
  171. package/src/time/__tests__/get-time-diff-as-string.test.ts +128 -0
  172. package/src/time/constants.ts +4 -0
  173. package/src/time/convert.ts +5 -0
  174. package/src/time/format-minutes.ts +9 -0
  175. package/src/time/get-time-diff-as-string.ts +196 -0
  176. package/src/time/index.ts +4 -0
  177. package/src/types/function.ts +1 -0
  178. package/src/types/general.ts +15 -0
  179. package/src/types/index.ts +4 -0
  180. package/src/types/object.ts +33 -0
  181. package/src/types/search.ts +36 -0
  182. package/tmp-lib.tgz +0 -0
  183. package/tsconfig.json +25 -0
  184. package/yarn.lock +4280 -0
  185. package/business/types/multilingual.js.map +0 -1
  186. /package/{_virtual → dist/_virtual}/_tslib.js +0 -0
  187. /package/{_virtual → dist/_virtual}/_tslib.js.map +0 -0
  188. /package/{array → dist/array}/array-to-map.d.ts +0 -0
  189. /package/{array → dist/array}/array-to-map.js +0 -0
  190. /package/{array → dist/array}/array-to-map.js.map +0 -0
  191. /package/{array → dist/array}/get-values-from-keys.d.ts +0 -0
  192. /package/{array → dist/array}/get-values-from-keys.js +0 -0
  193. /package/{array → dist/array}/get-values-from-keys.js.map +0 -0
  194. /package/{array → dist/array}/index.d.ts +0 -0
  195. /package/{array → dist/array}/index.js +0 -0
  196. /package/{array → dist/array}/index.js.map +0 -0
  197. /package/{array → dist/array}/inner-join.d.ts +0 -0
  198. /package/{array → dist/array}/inner-join.js +0 -0
  199. /package/{array → dist/array}/inner-join.js.map +0 -0
  200. /package/{array → dist/array}/left-outter-join.d.ts +0 -0
  201. /package/{array → dist/array}/left-outter-join.js +0 -0
  202. /package/{array → dist/array}/left-outter-join.js.map +0 -0
  203. /package/{business → dist/business}/campaign/index.d.ts +0 -0
  204. /package/{business → dist/business}/campaign/index.js +0 -0
  205. /package/{business → dist/business}/campaign/index.js.map +0 -0
  206. /package/{business → dist/business}/campaign/live-campaign.d.ts +0 -0
  207. /package/{business → dist/business}/campaign/live-campaign.js +0 -0
  208. /package/{business → dist/business}/campaign/live-campaign.js.map +0 -0
  209. /package/{business → dist/business}/course/index.d.ts +0 -0
  210. /package/{business → dist/business}/course/index.js +0 -0
  211. /package/{business → dist/business}/course/index.js.map +0 -0
  212. /package/{business → dist/business}/course/microknowledge-max-lengths.d.ts +0 -0
  213. /package/{business → dist/business}/course/microknowledge-max-lengths.js +0 -0
  214. /package/{business → dist/business}/course/microknowledge-max-lengths.js.map +0 -0
  215. /package/{business → dist/business}/index.d.ts +0 -0
  216. /package/{business → dist/business}/index.js +0 -0
  217. /package/{business → dist/business}/index.js.map +0 -0
  218. /package/{business → dist/business}/picture-spot/index.d.ts +0 -0
  219. /package/{business → dist/business}/picture-spot/index.js +0 -0
  220. /package/{business → dist/business}/picture-spot/index.js.map +0 -0
  221. /package/{business → dist/business}/types/achievement.d.ts +0 -0
  222. /package/{business → dist/business}/types/activity.d.ts +0 -0
  223. /package/{business → dist/business}/types/activity.js +0 -0
  224. /package/{business → dist/business}/types/activity.js.map +0 -0
  225. /package/{business → dist/business}/types/audience.d.ts +0 -0
  226. /package/{business → dist/business}/types/battle.d.ts +0 -0
  227. /package/{business → dist/business}/types/breaking-news.d.ts +0 -0
  228. /package/{business → dist/business}/types/campaign.d.ts +0 -0
  229. /package/{business → dist/business}/types/campaign.js +0 -0
  230. /package/{business → dist/business}/types/campaign.js.map +0 -0
  231. /package/{business → dist/business}/types/content.d.ts +0 -0
  232. /package/{business → dist/business}/types/content.js +0 -0
  233. /package/{business → dist/business}/types/content.js.map +0 -0
  234. /package/{business → dist/business}/types/document.d.ts +0 -0
  235. /package/{business → dist/business}/types/index.d.ts +0 -0
  236. /package/{business → dist/business}/types/index.js +0 -0
  237. /package/{business → dist/business}/types/index.js.map +0 -0
  238. /package/{business → dist/business}/types/media.d.ts +0 -0
  239. /package/{business → dist/business}/types/player.d.ts +0 -0
  240. /package/{business → dist/business}/types/score.d.ts +0 -0
  241. /package/{business → dist/business}/types/score.js +0 -0
  242. /package/{business → dist/business}/types/score.js.map +0 -0
  243. /package/{business → dist/business}/types/thematic.d.ts +0 -0
  244. /package/{business → dist/business}/types/user-engagement.d.ts +0 -0
  245. /package/{cdn → dist/cdn}/cdn.factory.d.ts +0 -0
  246. /package/{cdn → dist/cdn}/cdn.factory.js +0 -0
  247. /package/{cdn → dist/cdn}/cdn.factory.js.map +0 -0
  248. /package/{cdn → dist/cdn}/index.d.ts +0 -0
  249. /package/{cdn → dist/cdn}/index.js +0 -0
  250. /package/{cdn → dist/cdn}/index.js.map +0 -0
  251. /package/{cdn → dist/cdn}/types/cdn-factory.type.d.ts +0 -0
  252. /package/{cdn → dist/cdn}/types/index.d.ts +0 -0
  253. /package/{cdn → dist/cdn}/types/index.js +0 -0
  254. /package/{cdn → dist/cdn}/types/index.js.map +0 -0
  255. /package/{cdn → dist/cdn}/utils/extract-info-from-url.util.d.ts +0 -0
  256. /package/{cdn → dist/cdn}/utils/extract-info-from-url.util.js +0 -0
  257. /package/{cdn → dist/cdn}/utils/extract-info-from-url.util.js.map +0 -0
  258. /package/{cdn → dist/cdn}/utils/get-cdn-from-s3-url.util.d.ts +0 -0
  259. /package/{cdn → dist/cdn}/utils/get-cdn-from-s3-url.util.js +0 -0
  260. /package/{cdn → dist/cdn}/utils/get-cdn-from-s3-url.util.js.map +0 -0
  261. /package/{cdn → dist/cdn}/utils/get-cdn-url.util.d.ts +0 -0
  262. /package/{cdn → dist/cdn}/utils/get-cdn-url.util.js +0 -0
  263. /package/{cdn → dist/cdn}/utils/get-cdn-url.util.js.map +0 -0
  264. /package/{cdn → dist/cdn}/utils/twicpics-transformations.util.d.ts +0 -0
  265. /package/{cdn → dist/cdn}/utils/twicpics-transformations.util.js +0 -0
  266. /package/{cdn → dist/cdn}/utils/twicpics-transformations.util.js.map +0 -0
  267. /package/{chrono → dist/chrono}/get-approximated-session-time.d.ts +0 -0
  268. /package/{chrono → dist/chrono}/get-approximated-session-time.js +0 -0
  269. /package/{chrono → dist/chrono}/get-approximated-session-time.js.map +0 -0
  270. /package/{chrono → dist/chrono}/index.d.ts +0 -0
  271. /package/{chrono → dist/chrono}/index.js +0 -0
  272. /package/{chrono → dist/chrono}/index.js.map +0 -0
  273. /package/{color → dist/color}/get-contrast-color.d.ts +0 -0
  274. /package/{color → dist/color}/get-contrast-color.js +0 -0
  275. /package/{color → dist/color}/get-contrast-color.js.map +0 -0
  276. /package/{color → dist/color}/index.d.ts +0 -0
  277. /package/{color → dist/color}/index.js +0 -0
  278. /package/{color → dist/color}/index.js.map +0 -0
  279. /package/{crypto → dist/crypto}/aes256.d.ts +0 -0
  280. /package/{crypto → dist/crypto}/aes256.js +0 -0
  281. /package/{crypto → dist/crypto}/aes256.js.map +0 -0
  282. /package/{crypto → dist/crypto}/index.d.ts +0 -0
  283. /package/{crypto → dist/crypto}/index.js +0 -0
  284. /package/{crypto → dist/crypto}/index.js.map +0 -0
  285. /package/{date → dist/date}/add-days.d.ts +0 -0
  286. /package/{date → dist/date}/add-days.js +0 -0
  287. /package/{date → dist/date}/add-days.js.map +0 -0
  288. /package/{date → dist/date}/difference-in-days.d.ts +0 -0
  289. /package/{date → dist/date}/difference-in-days.js +0 -0
  290. /package/{date → dist/date}/difference-in-days.js.map +0 -0
  291. /package/{date → dist/date}/get-iso-day-number.d.ts +0 -0
  292. /package/{date → dist/date}/get-iso-day-number.js +0 -0
  293. /package/{date → dist/date}/get-iso-day-number.js.map +0 -0
  294. /package/{date → dist/date}/get-next-day.d.ts +0 -0
  295. /package/{date → dist/date}/get-next-day.js +0 -0
  296. /package/{date → dist/date}/get-next-day.js.map +0 -0
  297. /package/{date → dist/date}/get-remaining-time.d.ts +0 -0
  298. /package/{date → dist/date}/get-remaining-time.js +0 -0
  299. /package/{date → dist/date}/get-remaining-time.js.map +0 -0
  300. /package/{date → dist/date}/get-start-of-day.d.ts +0 -0
  301. /package/{date → dist/date}/get-start-of-day.js +0 -0
  302. /package/{date → dist/date}/get-start-of-day.js.map +0 -0
  303. /package/{date → dist/date}/index.d.ts +0 -0
  304. /package/{date → dist/date}/index.js +0 -0
  305. /package/{date → dist/date}/index.js.map +0 -0
  306. /package/{date → dist/date}/is-same-date.d.ts +0 -0
  307. /package/{date → dist/date}/is-same-date.js +0 -0
  308. /package/{date → dist/date}/is-same-date.js.map +0 -0
  309. /package/{date → dist/date}/shift-date-by.d.ts +0 -0
  310. /package/{date → dist/date}/shift-date-by.js +0 -0
  311. /package/{date → dist/date}/shift-date-by.js.map +0 -0
  312. /package/{date → dist/date}/to-plain-date-string.d.ts +0 -0
  313. /package/{date → dist/date}/to-plain-date-string.js +0 -0
  314. /package/{date → dist/date}/to-plain-date-string.js.map +0 -0
  315. /package/{date → dist/date}/to-utc-date-string.d.ts +0 -0
  316. /package/{date → dist/date}/to-utc-date-string.js +0 -0
  317. /package/{date → dist/date}/to-utc-date-string.js.map +0 -0
  318. /package/{formatting → dist/formatting}/format-number.d.ts +0 -0
  319. /package/{formatting → dist/formatting}/format-number.js +0 -0
  320. /package/{formatting → dist/formatting}/format-number.js.map +0 -0
  321. /package/{formatting → dist/formatting}/index.d.ts +0 -0
  322. /package/{formatting → dist/formatting}/index.js +0 -0
  323. /package/{formatting → dist/formatting}/index.js.map +0 -0
  324. /package/{fp → dist/fp}/index.d.ts +0 -0
  325. /package/{fp → dist/fp}/index.js +0 -0
  326. /package/{fp → dist/fp}/index.js.map +0 -0
  327. /package/{fp → dist/fp}/run-while.d.ts +0 -0
  328. /package/{fp → dist/fp}/run-while.js +0 -0
  329. /package/{fp → dist/fp}/run-while.js.map +0 -0
  330. /package/{http → dist/http}/build-search-params.d.ts +0 -0
  331. /package/{http → dist/http}/build-search-params.js +0 -0
  332. /package/{http → dist/http}/build-search-params.js.map +0 -0
  333. /package/{http → dist/http}/encode-search-object.d.ts +0 -0
  334. /package/{http → dist/http}/encode-search-object.js +0 -0
  335. /package/{http → dist/http}/encode-search-object.js.map +0 -0
  336. /package/{http → dist/http}/fetch-with-timeout.d.ts +0 -0
  337. /package/{http → dist/http}/fetch-with-timeout.js +0 -0
  338. /package/{http → dist/http}/fetch-with-timeout.js.map +0 -0
  339. /package/{http → dist/http}/index.d.ts +0 -0
  340. /package/{http → dist/http}/index.js +0 -0
  341. /package/{http → dist/http}/index.js.map +0 -0
  342. /package/{index.d.ts → dist/index.d.ts} +0 -0
  343. /package/{index.js → dist/index.js} +0 -0
  344. /package/{index.js.map → dist/index.js.map} +0 -0
  345. /package/{linked-list → dist/linked-list}/apply-diff-linked-list.d.ts +0 -0
  346. /package/{linked-list → dist/linked-list}/apply-diff-linked-list.js +0 -0
  347. /package/{linked-list → dist/linked-list}/apply-diff-linked-list.js.map +0 -0
  348. /package/{linked-list → dist/linked-list}/create-linked-list.d.ts +0 -0
  349. /package/{linked-list → dist/linked-list}/create-linked-list.js +0 -0
  350. /package/{linked-list → dist/linked-list}/create-linked-list.js.map +0 -0
  351. /package/{linked-list → dist/linked-list}/find-linked-list.d.ts +0 -0
  352. /package/{linked-list → dist/linked-list}/find-linked-list.js +0 -0
  353. /package/{linked-list → dist/linked-list}/find-linked-list.js.map +0 -0
  354. /package/{linked-list → dist/linked-list}/get-linked-list.d.ts +0 -0
  355. /package/{linked-list → dist/linked-list}/get-linked-list.js +0 -0
  356. /package/{linked-list → dist/linked-list}/get-linked-list.js.map +0 -0
  357. /package/{linked-list → dist/linked-list}/index.d.ts +0 -0
  358. /package/{linked-list → dist/linked-list}/index.js +0 -0
  359. /package/{linked-list → dist/linked-list}/index.js.map +0 -0
  360. /package/{linked-list → dist/linked-list}/insert-linked-list.d.ts +0 -0
  361. /package/{linked-list → dist/linked-list}/insert-linked-list.js +0 -0
  362. /package/{linked-list → dist/linked-list}/insert-linked-list.js.map +0 -0
  363. /package/{linked-list → dist/linked-list}/linked-list-utils.d.ts +0 -0
  364. /package/{linked-list → dist/linked-list}/linked-list-utils.js +0 -0
  365. /package/{linked-list → dist/linked-list}/linked-list-utils.js.map +0 -0
  366. /package/{linked-list → dist/linked-list}/reduce-linked-list.d.ts +0 -0
  367. /package/{linked-list → dist/linked-list}/reduce-linked-list.js +0 -0
  368. /package/{linked-list → dist/linked-list}/reduce-linked-list.js.map +0 -0
  369. /package/{linked-list → dist/linked-list}/remove-linked-list.d.ts +0 -0
  370. /package/{linked-list → dist/linked-list}/remove-linked-list.js +0 -0
  371. /package/{linked-list → dist/linked-list}/remove-linked-list.js.map +0 -0
  372. /package/{linked-list → dist/linked-list}/type.d.ts +0 -0
  373. /package/{linked-list → dist/linked-list}/update-linked-list.d.ts +0 -0
  374. /package/{linked-list → dist/linked-list}/update-linked-list.js +0 -0
  375. /package/{linked-list → dist/linked-list}/update-linked-list.js.map +0 -0
  376. /package/{linked-list → dist/linked-list}/while-linked-list.d.ts +0 -0
  377. /package/{linked-list → dist/linked-list}/while-linked-list.js +0 -0
  378. /package/{linked-list → dist/linked-list}/while-linked-list.js.map +0 -0
  379. /package/{math → dist/math}/clamp-number.d.ts +0 -0
  380. /package/{math → dist/math}/clamp-number.js +0 -0
  381. /package/{math → dist/math}/clamp-number.js.map +0 -0
  382. /package/{math → dist/math}/index.d.ts +0 -0
  383. /package/{math → dist/math}/index.js +0 -0
  384. /package/{math → dist/math}/index.js.map +0 -0
  385. /package/{math → dist/math}/interpolate.d.ts +0 -0
  386. /package/{math → dist/math}/interpolate.js +0 -0
  387. /package/{math → dist/math}/interpolate.js.map +0 -0
  388. /package/{math → dist/math}/median.d.ts +0 -0
  389. /package/{math → dist/math}/median.js +0 -0
  390. /package/{math → dist/math}/median.js.map +0 -0
  391. /package/{math → dist/math}/number-range.d.ts +0 -0
  392. /package/{math → dist/math}/number-range.js +0 -0
  393. /package/{math → dist/math}/number-range.js.map +0 -0
  394. /package/{math → dist/math}/random-number.d.ts +0 -0
  395. /package/{math → dist/math}/random-number.js +0 -0
  396. /package/{math → dist/math}/random-number.js.map +0 -0
  397. /package/{object → dist/object}/index.d.ts +0 -0
  398. /package/{object → dist/object}/index.js +0 -0
  399. /package/{object → dist/object}/index.js.map +0 -0
  400. /package/{object → dist/object}/merge-deep.d.ts +0 -0
  401. /package/{object → dist/object}/merge-deep.js +0 -0
  402. /package/{object → dist/object}/merge-deep.js.map +0 -0
  403. /package/{object → dist/object}/strip-properties-from-object.d.ts +0 -0
  404. /package/{object → dist/object}/strip-properties-from-object.js +0 -0
  405. /package/{object → dist/object}/strip-properties-from-object.js.map +0 -0
  406. /package/{parsing → dist/parsing}/index.d.ts +0 -0
  407. /package/{parsing → dist/parsing}/index.js +0 -0
  408. /package/{parsing → dist/parsing}/index.js.map +0 -0
  409. /package/{parsing → dist/parsing}/parse-boolean.d.ts +0 -0
  410. /package/{parsing → dist/parsing}/parse-boolean.js +0 -0
  411. /package/{parsing → dist/parsing}/parse-boolean.js.map +0 -0
  412. /package/{parsing → dist/parsing}/parse-enum.d.ts +0 -0
  413. /package/{parsing → dist/parsing}/parse-enum.js +0 -0
  414. /package/{parsing → dist/parsing}/parse-enum.js.map +0 -0
  415. /package/{parsing → dist/parsing}/parse-number.d.ts +0 -0
  416. /package/{parsing → dist/parsing}/parse-number.js +0 -0
  417. /package/{parsing → dist/parsing}/parse-number.js.map +0 -0
  418. /package/{predicates → dist/predicates}/index.d.ts +0 -0
  419. /package/{predicates → dist/predicates}/index.js +0 -0
  420. /package/{predicates → dist/predicates}/index.js.map +0 -0
  421. /package/{predicates → dist/predicates}/is-function.d.ts +0 -0
  422. /package/{predicates → dist/predicates}/is-function.js +0 -0
  423. /package/{predicates → dist/predicates}/is-function.js.map +0 -0
  424. /package/{predicates → dist/predicates}/is-null.d.ts +0 -0
  425. /package/{predicates → dist/predicates}/is-null.js +0 -0
  426. /package/{predicates → dist/predicates}/is-null.js.map +0 -0
  427. /package/{predicates → dist/predicates}/is-object.d.ts +0 -0
  428. /package/{predicates → dist/predicates}/is-object.js +0 -0
  429. /package/{predicates → dist/predicates}/is-object.js.map +0 -0
  430. /package/{predicates → dist/predicates}/is-primitive.d.ts +0 -0
  431. /package/{predicates → dist/predicates}/is-primitive.js +0 -0
  432. /package/{predicates → dist/predicates}/is-primitive.js.map +0 -0
  433. /package/{predicates → dist/predicates}/is-undefined.d.ts +0 -0
  434. /package/{predicates → dist/predicates}/is-undefined.js +0 -0
  435. /package/{predicates → dist/predicates}/is-undefined.js.map +0 -0
  436. /package/{predicates → dist/predicates}/is-uuid.d.ts +0 -0
  437. /package/{promise → dist/promise}/delay.d.ts +0 -0
  438. /package/{promise → dist/promise}/delay.js +0 -0
  439. /package/{promise → dist/promise}/delay.js.map +0 -0
  440. /package/{promise → dist/promise}/execute-or-resolve-default.d.ts +0 -0
  441. /package/{promise → dist/promise}/execute-or-resolve-default.js +0 -0
  442. /package/{promise → dist/promise}/execute-or-resolve-default.js.map +0 -0
  443. /package/{promise → dist/promise}/execute-with-delay.d.ts +0 -0
  444. /package/{promise → dist/promise}/execute-with-delay.js +0 -0
  445. /package/{promise → dist/promise}/execute-with-delay.js.map +0 -0
  446. /package/{promise → dist/promise}/index.d.ts +0 -0
  447. /package/{promise → dist/promise}/index.js +0 -0
  448. /package/{promise → dist/promise}/index.js.map +0 -0
  449. /package/{string → dist/string}/index.d.ts +0 -0
  450. /package/{string → dist/string}/index.js +0 -0
  451. /package/{string → dist/string}/index.js.map +0 -0
  452. /package/{string → dist/string}/is-string-length-within-range.d.ts +0 -0
  453. /package/{string → dist/string}/is-string-length-within-range.js +0 -0
  454. /package/{string → dist/string}/is-string-length-within-range.js.map +0 -0
  455. /package/{string → dist/string}/replace-in-template.d.ts +0 -0
  456. /package/{string → dist/string}/replace-in-template.js +0 -0
  457. /package/{string → dist/string}/replace-in-template.js.map +0 -0
  458. /package/{time → dist/time}/constants.d.ts +0 -0
  459. /package/{time → dist/time}/constants.js +0 -0
  460. /package/{time → dist/time}/constants.js.map +0 -0
  461. /package/{time → dist/time}/convert.d.ts +0 -0
  462. /package/{time → dist/time}/convert.js +0 -0
  463. /package/{time → dist/time}/convert.js.map +0 -0
  464. /package/{time → dist/time}/format-minutes.d.ts +0 -0
  465. /package/{time → dist/time}/format-minutes.js +0 -0
  466. /package/{time → dist/time}/format-minutes.js.map +0 -0
  467. /package/{time → dist/time}/get-time-diff-as-string.d.ts +0 -0
  468. /package/{time → dist/time}/get-time-diff-as-string.js +0 -0
  469. /package/{time → dist/time}/get-time-diff-as-string.js.map +0 -0
  470. /package/{time → dist/time}/index.d.ts +0 -0
  471. /package/{time → dist/time}/index.js +0 -0
  472. /package/{time → dist/time}/index.js.map +0 -0
  473. /package/{types → dist/types}/function.d.ts +0 -0
  474. /package/{types → dist/types}/general.d.ts +0 -0
  475. /package/{types → dist/types}/index.d.ts +0 -0
  476. /package/{types → dist/types}/index.js +0 -0
  477. /package/{types → dist/types}/index.js.map +0 -0
  478. /package/{types → dist/types}/object.d.ts +0 -0
  479. /package/{types → dist/types}/search.d.ts +0 -0
@@ -0,0 +1,70 @@
1
+ import { buildSearchParams } from '../http/build-search-params';
2
+ import type { CdnConfig, CdnType, TransformationQueries, TwicpicsTransformationChain } from './types';
3
+ import { getCdnFromS3UrlFactory } from './utils/get-cdn-from-s3-url.util';
4
+ import { getCdnUrlFactory } from './utils/get-cdn-url.util';
5
+ import { twicpicsTransformationChainToString } from './utils/twicpics-transformations.util';
6
+
7
+ export const imgixTransformationQueries: TransformationQueries = ({
8
+ fit,
9
+ width,
10
+ height,
11
+ quality,
12
+ compress = true,
13
+ devicePixelRatio,
14
+ }) => {
15
+ const params = {
16
+ auto: compress ? 'compress,format' : undefined,
17
+ fit: fit === 'crop' ? 'crop' : undefined,
18
+ dpr: Number.isFinite(devicePixelRatio) ? devicePixelRatio : undefined,
19
+ h: Number.isFinite(height) ? height : undefined,
20
+ w: Number.isFinite(width) ? width : undefined,
21
+ q: quality !== undefined && quality >= 0 && quality <= 100 ? quality : undefined,
22
+ };
23
+ const searchParams = buildSearchParams(params).toString();
24
+
25
+ return searchParams ? `${searchParams}` : '';
26
+ };
27
+
28
+ export const twicpicsTransformationQueries: TransformationQueries = (params) => {
29
+ const quality = params.quality || 70;
30
+ const transformations: TwicpicsTransformationChain = [['quality', quality]];
31
+ const dpr = params.devicePixelRatio || 1;
32
+
33
+ const width = params.width ? Math.round(params.width * dpr) : '-';
34
+ const height = params.height ? Math.round(params.height * dpr) : '-';
35
+ const fit = params.fit || 'cover';
36
+
37
+ if (params.width !== undefined || params.height !== undefined) {
38
+ transformations.push([fit, `${width}x${height}`]);
39
+ }
40
+
41
+ if (params.output !== undefined) {
42
+ transformations.push(['output', params.output]);
43
+ }
44
+
45
+ return twicpicsTransformationChainToString(transformations);
46
+ };
47
+
48
+ /**
49
+ *
50
+ * @param type cdn provider: 'twicpics' | 'imgix'
51
+ * @param domain provider domain
52
+ * @param instanceMapper domain + the result of the instanceMapper will form the base path
53
+ * @param cacheVersion
54
+ * @returns \{ getCdnUrl, transformationQueries \}
55
+ */
56
+ export const createCdn = <T extends CdnType>({ type, domain, instanceMapper, cacheVersion }: CdnConfig<T>) => {
57
+ const getCdnUrl = getCdnUrlFactory({
58
+ domain,
59
+ instanceMapper,
60
+ transformationQueries: type === 'imgix' ? imgixTransformationQueries : twicpicsTransformationQueries,
61
+ cacheVersion,
62
+ });
63
+
64
+ return {
65
+ getCdnUrl,
66
+ getCdnFromS3Url: getCdnFromS3UrlFactory({
67
+ getCdnUrl,
68
+ }),
69
+ };
70
+ };
@@ -0,0 +1,2 @@
1
+ export { createCdn } from './cdn.factory';
2
+ export * from './types';
@@ -0,0 +1,49 @@
1
+ export type BaseUrlMapperFunc = (instanceId: string) => string;
2
+
3
+ export type Transformation = {
4
+ fit?: 'crop' | 'contain';
5
+ width?: number;
6
+ height?: number;
7
+ devicePixelRatio?: number;
8
+ quality?: number;
9
+ /**
10
+ * Only for imgix transformations. Default is true.
11
+ */
12
+ compress?: boolean;
13
+ output?: 'jpeg' | 'png' | 'webp' | 'image';
14
+ };
15
+
16
+ export type CdnParams = {
17
+ asThumbnail?: boolean;
18
+ transformation?: Transformation;
19
+ };
20
+
21
+ export type TransformationQueries = (params: Transformation) => string;
22
+
23
+ type TwicpicsOutputTransformation = ['output', Transformation['output']];
24
+
25
+ type TwicpicsFitTransformation = ['cover' | 'crop' | 'contain', string] | ['quality', number];
26
+
27
+ export type TwicpicsTransformation = TwicpicsOutputTransformation | TwicpicsFitTransformation;
28
+
29
+ export type TwicpicsTransformationChain = TwicpicsTransformation[];
30
+
31
+ export type GetCdnUrl = (instanceId: string, path: `/${string}`, params?: CdnParams) => string;
32
+
33
+ export type GetCdnFromS3Url = (url: string, params?: CdnParams) => string;
34
+
35
+ export type InstanceMapper = (instanceId: string) => string;
36
+
37
+ export type CdnType = 'twicpics' | 'imgix';
38
+
39
+ export type CdnConfig<T extends CdnType> = {
40
+ type: T;
41
+ domain: `https://${string}`;
42
+ instanceMapper: InstanceMapper;
43
+ cacheVersion?: T extends 'twicpics' ? number : undefined;
44
+ };
45
+
46
+ export type Cdn = {
47
+ getCdnUrl: GetCdnUrl;
48
+ getCdnFromS3Url: GetCdnFromS3Url;
49
+ };
@@ -0,0 +1 @@
1
+ export * from './cdn-factory.type';
@@ -0,0 +1,25 @@
1
+ type ExtractInfoFromUrl = (url: string) =>
2
+ | {
3
+ instanceId: string;
4
+ path: `/${string}`;
5
+ }
6
+ | undefined;
7
+
8
+ const S3_URL_RE = /https:\/\/sparted-prod-([^.]+)\.s3(\.eu-west-1)?(\.amazonaws\.com)?(\.fr-par\.scw\.cloud)?(\/[^?]+)/;
9
+
10
+ export const extractInfoFromUrl: ExtractInfoFromUrl = (url) => {
11
+ if (typeof url !== 'string') {
12
+ return undefined;
13
+ }
14
+
15
+ const matchS3Url = url.match(S3_URL_RE);
16
+
17
+ if (!matchS3Url) {
18
+ return undefined;
19
+ }
20
+
21
+ const instanceId = matchS3Url[1];
22
+ const path = matchS3Url[5] as `/${string}`;
23
+
24
+ return { instanceId, path };
25
+ };
@@ -0,0 +1,20 @@
1
+ import type { GetCdnFromS3Url, GetCdnUrl } from '../types';
2
+ import { extractInfoFromUrl } from './extract-info-from-url.util';
3
+
4
+ type FactoryConfig = {
5
+ getCdnUrl: GetCdnUrl;
6
+ };
7
+
8
+ export function getCdnFromS3UrlFactory(config: FactoryConfig): GetCdnFromS3Url {
9
+ return (url, params) => {
10
+ const { getCdnUrl } = config;
11
+
12
+ const info = extractInfoFromUrl(url);
13
+ if (info === undefined) {
14
+ return url;
15
+ }
16
+ const { instanceId, path } = info;
17
+
18
+ return getCdnUrl(instanceId, path, params);
19
+ };
20
+ }
@@ -0,0 +1,31 @@
1
+ import type { GetCdnUrl, InstanceMapper, Transformation, TransformationQueries } from '../types';
2
+
3
+ const DEFAULT_THUMBNAIL_CONFIG: Transformation = {
4
+ width: 300,
5
+ height: 300,
6
+ };
7
+
8
+ type FactoryConfig = {
9
+ domain: `https://${string}`;
10
+ instanceMapper: InstanceMapper;
11
+ transformationQueries: TransformationQueries;
12
+ cacheVersion?: number;
13
+ };
14
+
15
+ export const genCacheVersionQuery = (cacheVersion?: number) => (cacheVersion ? `v=${cacheVersion}` : '');
16
+
17
+ export const getCdnUrlFactory =
18
+ (config: FactoryConfig): GetCdnUrl =>
19
+ (instanceId, path, params = {}) => {
20
+ const { domain, instanceMapper, transformationQueries, cacheVersion } = config;
21
+
22
+ const { transformation = params.asThumbnail ? DEFAULT_THUMBNAIL_CONFIG : {} } = params;
23
+
24
+ const transformationQuery: string = transformationQueries(transformation);
25
+ const cacheVersionQuery = genCacheVersionQuery(cacheVersion);
26
+ const hasQueryParams = [transformationQuery, cacheVersionQuery].some((query) => query !== '');
27
+
28
+ return `${domain}${instanceMapper(instanceId)}${path}${hasQueryParams ? '?' : ''}${transformationQuery}${
29
+ cacheVersionQuery ? `&${cacheVersionQuery}` : ''
30
+ }`;
31
+ };
@@ -0,0 +1,9 @@
1
+ import { TwicpicsTransformationChain } from '../types';
2
+
3
+ export const twicpicsTransformationChainToString = (transformationChain: TwicpicsTransformationChain): string => {
4
+ if (transformationChain.length === 0) return '';
5
+
6
+ const transformations = transformationChain.map(([key, value]) => `${key}=${value}`).join('/');
7
+
8
+ return `twic=v1/${transformations}`;
9
+ };
@@ -0,0 +1,27 @@
1
+ import { type GameType } from '../business/types';
2
+
3
+ const DOLPHIN_CHRONO_GAMEPLAY = {
4
+ mcq: 27 * 1000,
5
+ 'error-text': 27 * 1000,
6
+ 'no-interaction': 20000,
7
+ 'picture-spot': 15 * 1000,
8
+ 'open-question': 73 * 1000,
9
+ 'swiping-cards': 15 * 1000,
10
+ 'ordering-cards': 20 * 1000 + 10000,
11
+ };
12
+
13
+ export const DOLPHIN_AVERAGE_CHRONO_GAMEPLAY =
14
+ Object.values(DOLPHIN_CHRONO_GAMEPLAY).reduce<number>((sum, time) => sum + time, 0) /
15
+ Object.keys(DOLPHIN_CHRONO_GAMEPLAY).length;
16
+
17
+ export const getApproximatedSessionTime = (gameTypes: GameType[]) => {
18
+ const time = gameTypes.reduce<number>((sessionTime, gameType) => {
19
+ const gameplayTime = DOLPHIN_CHRONO_GAMEPLAY[gameType];
20
+
21
+ return sessionTime + gameplayTime;
22
+ }, 0);
23
+
24
+ return time;
25
+ };
26
+
27
+ export const getAverageSessionTime = (gameCount: number) => gameCount * DOLPHIN_AVERAGE_CHRONO_GAMEPLAY;
@@ -0,0 +1 @@
1
+ export * from './get-approximated-session-time';
@@ -0,0 +1,22 @@
1
+ import { getContrastColor } from '../get-contrast-color';
2
+
3
+ describe('getContrastColor', () => {
4
+ const customLight = '#f18888';
5
+ const customDark = '#051831';
6
+
7
+ it('should return the default light color', () => {
8
+ expect(getContrastColor('#000000')).toBe('#FFFFFF');
9
+ });
10
+
11
+ it('should return the default dark color', () => {
12
+ expect(getContrastColor('#FFFFFF')).toBe('#000000');
13
+ });
14
+
15
+ it('should return a specified light color', () => {
16
+ expect(getContrastColor('#000000', customLight, customDark)).toBe(customLight);
17
+ });
18
+
19
+ it('should return a specified dark color', () => {
20
+ expect(getContrastColor('#FFFFFF', customLight, customDark)).toBe(customDark);
21
+ });
22
+ });
@@ -0,0 +1,18 @@
1
+ const DEFAULT_LIGHT_COLOR = '#FFFFFF';
2
+ const DEFAULT_DARK_COLOR = '#000000';
3
+
4
+ // Based on https://stackoverflow.com/questions/11867545/change-text-color-based-on-brightness-of-the-covered-background-area
5
+ export const getContrastColor = (bgColor: string, lightColor: string = DEFAULT_LIGHT_COLOR, darkColor: string = DEFAULT_DARK_COLOR): string => {
6
+ const color = bgColor.charAt(0) === '#' ? bgColor.substring(1, 7) : bgColor;
7
+
8
+ if (color.length !== 6) {
9
+ throw new Error(`Invalid HEX color "${bgColor}" in sparted mail manager.`);
10
+ }
11
+
12
+ const r = parseInt(color.substring(0, 2), 16); // hexToR
13
+ const g = parseInt(color.substring(2, 4), 16); // hexToG
14
+ const b = parseInt(color.substring(4, 6), 16); // hexToB
15
+
16
+ // Values from https://www.w3.org/TR/AERT/#color-contrast
17
+ return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? darkColor : lightColor;
18
+ };
@@ -0,0 +1 @@
1
+ export * from './get-contrast-color';
@@ -0,0 +1,23 @@
1
+ import { encrypt } from '../aes256';
2
+
3
+ const key = '6fa979f20126cb08aa645a8f495f6d856fa979f20126cb08aa645a8f495f6d85';
4
+ const iv = '49387a7941346c56684d43614a354b67';
5
+
6
+ const data = '111222333';
7
+
8
+ describe('aes-256-cbc', () => {
9
+ describe('encrypt', () => {
10
+ it('should match the expected cipher', () => {
11
+ const result = encrypt(data, key, iv);
12
+ expect(result).toBe('56457610927dc4923e2aa34cc2a79382');
13
+ });
14
+
15
+ it('should fail if the key is not 256 bits long', () => {
16
+ expect(() => encrypt(data, 'short-key', iv)).toThrow();
17
+ });
18
+
19
+ it('should fail if the iv is not 32 characters long', () => {
20
+ expect(() => encrypt(data, key, 'short-iv')).toThrow();
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,22 @@
1
+ import { encrypt as cryptoEncrypt } from 'crypto-js/aes';
2
+ import { enc, mode, pad } from 'crypto-js';
3
+
4
+ /**
5
+ * Encrypt data using AES-256-CBC
6
+ * @param data
7
+ * @param key Must be a 256 bits hex string
8
+ * @param iv Must be a 128 bits hex string
9
+ * @returns Encrypted data as a hex string
10
+ */
11
+ function encrypt(data: string, key: string, iv: string): string {
12
+ if (key.length !== 64) throw new Error('Key must be 256 bits long');
13
+ if (iv.length !== 32) throw new Error('IV must be 128 bits long');
14
+ const cipher = cryptoEncrypt(data, enc.Hex.parse(key), {
15
+ mode: mode.CBC,
16
+ padding: pad.Pkcs7,
17
+ iv: enc.Hex.parse(iv),
18
+ });
19
+ return enc.Hex.stringify(cipher.ciphertext);
20
+ }
21
+
22
+ export { encrypt };
@@ -0,0 +1 @@
1
+ export { encrypt } from './aes256';
@@ -0,0 +1,34 @@
1
+ import { getIsoDayNumber } from '../get-iso-day-number';
2
+
3
+ describe('getIsoDayNumber', () => {
4
+ it('returns 1..7 for Monday..Sunday', () => {
5
+ const cases: Array<[Date, number]> = [
6
+ [new Date(2023, 7, 7, 12, 0, 0), 1], // Monday 2023-08-07
7
+ [new Date(2023, 7, 8, 12, 0, 0), 2], // Tuesday
8
+ [new Date(2023, 7, 9, 12, 0, 0), 3], // Wednesday
9
+ [new Date(2023, 7, 10, 12, 0, 0), 4], // Thursday
10
+ [new Date(2023, 7, 11, 12, 0, 0), 5], // Friday
11
+ [new Date(2023, 7, 12, 12, 0, 0), 6], // Saturday
12
+ [new Date(2023, 7, 13, 12, 0, 0), 7], // Sunday
13
+ ];
14
+
15
+ for (const [date, expected] of cases) {
16
+ expect(getIsoDayNumber(date)).toBe(expected);
17
+ }
18
+ });
19
+
20
+ it('does not modify the original date', () => {
21
+ const date = new Date(2023, 7, 9, 12, 34, 56);
22
+ const originalTime = date.getTime();
23
+ getIsoDayNumber(date);
24
+ expect(date.getTime()).toBe(originalTime);
25
+ });
26
+
27
+ it('uses current date when no argument is provided', () => {
28
+ jest.useFakeTimers().setSystemTime(new Date(2023, 7, 7, 12, 0, 0)); // Monday
29
+ expect(getIsoDayNumber()).toBe(1);
30
+ jest.useRealTimers();
31
+ });
32
+ });
33
+
34
+
@@ -0,0 +1,78 @@
1
+ import { getRemainingTimeFromMs, getRemainingTimeInMsFromDate } from '../get-remaining-time';
2
+
3
+ describe('getRemainingTimeInMsFromDate', () => {
4
+ it('should return 0 if the argument passed is not an instance of Date', () => {
5
+ expect(getRemainingTimeInMsFromDate('2024-12-01' as any)).toBe(0);
6
+ expect(getRemainingTimeInMsFromDate(null as any)).toBe(0);
7
+ expect(getRemainingTimeInMsFromDate(undefined as any)).toBe(0);
8
+ expect(getRemainingTimeInMsFromDate(123 as any)).toBe(0);
9
+ expect(getRemainingTimeInMsFromDate({} as any)).toBe(0);
10
+ });
11
+
12
+ it('should return 0 if the date is in the past', () => {
13
+ const pastDate = new Date(Date.now() - 1000);
14
+ expect(getRemainingTimeInMsFromDate(pastDate)).toBe(0);
15
+ });
16
+
17
+ it('should return the remaining time in milliseconds if the date is in the future', () => {
18
+ const futureDate = new Date(Date.now() + 5000);
19
+ const remainingTime = getRemainingTimeInMsFromDate(futureDate);
20
+
21
+ expect(remainingTime).toBe(5000);
22
+ });
23
+
24
+ it('should return 0 if the date is exactly at the present moment', () => {
25
+ const currentTime = Date.now();
26
+ const presentDate = new Date(currentTime);
27
+
28
+ jest.spyOn(global.Date, 'now').mockReturnValue(currentTime);
29
+
30
+ const remainingTime = getRemainingTimeInMsFromDate(presentDate);
31
+ expect(remainingTime).toBe(0);
32
+
33
+ jest.restoreAllMocks();
34
+ });
35
+ });
36
+
37
+ describe('getRemainingTimeFromMs', () => {
38
+ it('should return correct time for a full day (86400000 ms)', () => {
39
+ const result = getRemainingTimeFromMs(86400000);
40
+ expect(result).toEqual({ daysLeft: 1, hoursLeft: 0, minutesLeft: 0, secondsLeft: 0 });
41
+ });
42
+
43
+ it('should return correct time for one hour (3600000 ms)', () => {
44
+ const result = getRemainingTimeFromMs(3600000);
45
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 1, minutesLeft: 0, secondsLeft: 0 });
46
+ });
47
+
48
+ it('should return correct time for one minute (60000 ms)', () => {
49
+ const result = getRemainingTimeFromMs(60000);
50
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 0, minutesLeft: 1, secondsLeft: 0 });
51
+ });
52
+
53
+ it('should return correct time for one second (1000 ms)', () => {
54
+ const result = getRemainingTimeFromMs(1000);
55
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 0, minutesLeft: 0, secondsLeft: 1 });
56
+ });
57
+
58
+ it('should return correct time for a combination of days, hours, minutes, and seconds', () => {
59
+ const ms = 90061000; // 1 day, 1 hour, 1 minute, 1 second
60
+ const result = getRemainingTimeFromMs(ms);
61
+ expect(result).toEqual({ daysLeft: 1, hoursLeft: 1, minutesLeft: 1, secondsLeft: 1 });
62
+ });
63
+
64
+ it('should return zero for all fields when ms is 0', () => {
65
+ const result = getRemainingTimeFromMs(0);
66
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 0, minutesLeft: 0, secondsLeft: 0 });
67
+ });
68
+
69
+ it('should handle non-integer values gracefully', () => {
70
+ const result = getRemainingTimeFromMs(1234567); // 0 days, 0 hours, 20 minutes, 34 seconds
71
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 0, minutesLeft: 20, secondsLeft: 34 });
72
+ });
73
+
74
+ it('should return zero for negative input', () => {
75
+ const result = getRemainingTimeFromMs(-1000);
76
+ expect(result).toEqual({ daysLeft: 0, hoursLeft: 0, minutesLeft: 0, secondsLeft: 0 });
77
+ });
78
+ });
@@ -0,0 +1,92 @@
1
+ import { startOfDay, startOfDayLocal } from '../get-start-of-day';
2
+
3
+ describe('startOfDay', () => {
4
+ it('should set the time of a date to 00:00:00 in local timezone', () => {
5
+ const date = new Date('2023-08-09T12:34:56');
6
+ const result = startOfDay(date);
7
+ const expected = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0));
8
+ expect(result.getTime()).toBe(expected.getTime());
9
+ });
10
+
11
+ it('should not modify the original date object', () => {
12
+ const date = new Date('2023-08-09T12:34:56');
13
+ const originalTime = date.getTime();
14
+ startOfDay(date);
15
+ expect(date.getTime()).toBe(originalTime);
16
+ });
17
+
18
+ it('should handle dates already at the start of the day', () => {
19
+ const date = new Date('2023-08-09T00:00:00');
20
+ const dateUTC = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
21
+ const result = startOfDay(dateUTC);
22
+ expect(result.getTime()).toBe(dateUTC.getTime());
23
+ });
24
+
25
+ it('should correctly handle leap year dates in local timezone', () => {
26
+ const date = new Date('2020-02-29T15:45:30');
27
+ const result = startOfDay(date);
28
+ const expected = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
29
+ expect(result.getTime()).toBe(expected.getTime());
30
+ });
31
+
32
+ it('should handle year boundaries correctly in local timezone', () => {
33
+ const date = new Date('2023-12-31T23:59:59');
34
+ const result = startOfDay(date);
35
+ const expected = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
36
+ expect(result.getTime()).toBe(expected.getTime());
37
+ });
38
+
39
+ it('should handle month boundaries correctly in local timezone', () => {
40
+ const date = new Date('2023-08-31T23:59:59');
41
+ const result = startOfDay(date);
42
+ const expected = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
43
+ expect(result.getTime()).toBe(expected.getTime());
44
+ });
45
+ });
46
+
47
+ describe('startOfDayLocal', () => {
48
+ it('should set the time of a date to 00:00:00 in local timezone', () => {
49
+ const date = new Date('2023-08-09T12:34:56');
50
+ const result = startOfDayLocal(date);
51
+ const expected = new Date(date);
52
+ expected.setHours(0, 0, 0, 0);
53
+ expect(result.getTime()).toBe(expected.getTime());
54
+ });
55
+
56
+ it('should not modify the original date object', () => {
57
+ const date = new Date('2023-08-09T12:34:56');
58
+ const originalTime = date.getTime();
59
+ startOfDayLocal(date);
60
+ expect(date.getTime()).toBe(originalTime);
61
+ });
62
+
63
+ it('should handle dates already at the start of the day', () => {
64
+ const date = new Date(2023, 7, 9, 0, 0, 0, 0);
65
+ const result = startOfDayLocal(date);
66
+ expect(result.getTime()).toBe(date.getTime());
67
+ });
68
+
69
+ it('should correctly handle leap year dates in local timezone', () => {
70
+ const date = new Date(2020, 1, 29, 15, 45, 30);
71
+ const result = startOfDayLocal(date);
72
+ const expected = new Date(date);
73
+ expected.setHours(0, 0, 0, 0);
74
+ expect(result.getTime()).toBe(expected.getTime());
75
+ });
76
+
77
+ it('should handle year boundaries correctly in local timezone', () => {
78
+ const date = new Date(2023, 11, 31, 23, 59, 59);
79
+ const result = startOfDayLocal(date);
80
+ const expected = new Date(date);
81
+ expected.setHours(0, 0, 0, 0);
82
+ expect(result.getTime()).toBe(expected.getTime());
83
+ });
84
+
85
+ it('should handle month boundaries correctly in local timezone', () => {
86
+ const date = new Date(2023, 7, 31, 23, 59, 59);
87
+ const result = startOfDayLocal(date);
88
+ const expected = new Date(date);
89
+ expected.setHours(0, 0, 0, 0);
90
+ expect(result.getTime()).toBe(expected.getTime());
91
+ });
92
+ });
@@ -0,0 +1,50 @@
1
+ import { isSameDate } from '../is-same-date';
2
+
3
+ describe('isSameDate', () => {
4
+ it('should return true for the same date with same time zones', () => {
5
+ const date1 = new Date('2023-08-09T12:00:00+02:00'); // 9 August 2023
6
+ const date2 = new Date('2023-08-09T12:00:00+02:00'); // 9 August 2023
7
+ expect(isSameDate(date1, date2)).toBe(true);
8
+ });
9
+
10
+ it('should return true for the same date across different time zones', () => {
11
+ const date1 = new Date('2023-08-09T23:00:00+00:00'); // 9 August 2023 UTC
12
+ const date2 = new Date('2023-08-10T01:00:00+02:00'); // 10 August 2023 UTC+2, but still 9 August in UTC
13
+ expect(isSameDate(date1, date2)).toBe(true);
14
+ });
15
+
16
+ it('should return true for the same plain date', () => {
17
+ const date1 = new Date(2023, 7, 9); // 9 August 2023
18
+ const date2 = new Date(2023, 7, 9); // 9 August 2023
19
+ expect(isSameDate(date1, date2)).toBe(true);
20
+ });
21
+
22
+ it('should return false for different dates across different time zones', () => {
23
+ const date1 = new Date('2023-08-09T23:00:00+00:00'); // 9 August 2023 UTC
24
+ const date2 = new Date('2023-08-10T02:00:00+02:00'); // 10 August 2023 UTC+2, also 10 August in UTC
25
+ expect(isSameDate(date1, date2)).toBe(false);
26
+ });
27
+
28
+ it('should return false for different dates in the same time zone', () => {
29
+ const date1 = new Date('2023-08-09T12:00:00+02:00'); // 9 August 2023 UTC+2
30
+ const date2 = new Date('2023-08-10T12:00:00+02:00'); // 10 August 2023 UTC+2
31
+ expect(isSameDate(date1, date2)).toBe(false);
32
+ });
33
+
34
+ it('should return false for different plain dates', () => {
35
+ const date1 = new Date(2023, 7, 9); // 9 August 2023
36
+ const date2 = new Date(2023, 7, 10); // 10 August 2023
37
+ expect(isSameDate(date1, date2)).toBe(false);
38
+ });
39
+
40
+ it('should return true when comparing the same date with itself', () => {
41
+ const date = new Date('2023-08-09T12:00:00+02:00'); // 9 August 2023
42
+ expect(isSameDate(date, date)).toBe(true);
43
+ });
44
+
45
+ it('should return false if one of the dates is invalid', () => {
46
+ const date1 = new Date('Invalid Date');
47
+ const date2 = new Date('2023-08-09T12:00:00+02:00'); // 9 August 2023
48
+ expect(isSameDate(date1, date2)).toBe(false);
49
+ });
50
+ });