@claspo/common 7.3.1-dev.2 → 7.3.1-dev.3

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 (220) hide show
  1. package/package.json +1 -1
  2. package/coverage/lcov-report/block-navigation.js +0 -87
  3. package/coverage/lcov-report/prettify.js +0 -2
  4. package/coverage/lcov-report/sorter.js +0 -196
  5. package/jest.config.ts +0 -204
  6. package/src/DefaultEventEmitter.test.ts +0 -84
  7. package/src/DefaultEventEmitter.ts +0 -96
  8. package/src/HttpAbortableLoader.ts +0 -35
  9. package/src/InAppLayoutType.ts +0 -6
  10. package/src/LayoutType.ts +0 -18
  11. package/src/PrizePool.interface.ts +0 -32
  12. package/src/RenderMode.ts +0 -10
  13. package/src/UuidGenerator.ts +0 -16
  14. package/src/WidgetInitConfig.interface.ts +0 -163
  15. package/src/WidgetType.ts +0 -18
  16. package/src/action/type.ts +0 -7
  17. package/src/async/createAsyncIterator.ts +0 -33
  18. package/src/async/debounce.ts +0 -28
  19. package/src/async/timeout.ts +0 -3
  20. package/src/component-manifest/ComponentManifest.interface.ts +0 -160
  21. package/src/component-manifest/ContextMenuManifest.interface.ts +0 -52
  22. package/src/component-manifest/DisplayCondition.interface.ts +0 -65
  23. package/src/component-manifest/FloatingControlManifest.interface.ts +0 -89
  24. package/src/component-manifest/PropPathCondition.interface.ts +0 -4
  25. package/src/component-manifest/PropertyPaneManifest.interface.ts +0 -614
  26. package/src/converter/time/TimeConverter.spec.ts +0 -11
  27. package/src/converter/time/TimeUnit.spec.ts +0 -12
  28. package/src/converter/time/TimeUnit.ts +0 -34
  29. package/src/converter/time/TimerConverter.ts +0 -29
  30. package/src/document/ComponentInsertType.ts +0 -6
  31. package/src/document/Document.interface.ts +0 -625
  32. package/src/document/DocumentCssVarsReplace.test.ts +0 -2947
  33. package/src/document/DocumentCssVarsReplace.ts +0 -31
  34. package/src/document/DocumentUtils.test.ts +0 -595
  35. package/src/document/DocumentUtils.ts +0 -194
  36. package/src/document/hidden-fields.interface.ts +0 -54
  37. package/src/dom/ViewportSize.ts +0 -61
  38. package/src/dom/copyToClipboard.ts +0 -17
  39. package/src/dom/getMostNestedNode.ts +0 -9
  40. package/src/dom/insertHtmlIntoElement.ts +0 -36
  41. package/src/dom/sanitizeHTML.test.ts +0 -59
  42. package/src/dom/sanitizeHTML.ts +0 -78
  43. package/src/element/BaseElementInViewportHandler.ts +0 -41
  44. package/src/element/CssVarsOperations.ts +0 -37
  45. package/src/element/ThemeCssVars.ts +0 -28
  46. package/src/element/recursiveFindParentNodeByAttribute.test.ts +0 -63
  47. package/src/element/recursiveFindParentNodeByAttribute.ts +0 -25
  48. package/src/flat.ts +0 -16
  49. package/src/handler/HandlerTypes.ts +0 -4
  50. package/src/math/RandomDistributor.test.ts +0 -35
  51. package/src/math/RandomDistributor.ts +0 -58
  52. package/src/math/sum.ts +0 -3
  53. package/src/network/HttpClient.ts +0 -28
  54. package/src/network/HttpStatus.ts +0 -4
  55. package/src/object/isDictionary.test.ts +0 -24
  56. package/src/object/isDictionary.ts +0 -13
  57. package/src/object/omitKeys.test.ts +0 -19
  58. package/src/object/omitKeys.ts +0 -20
  59. package/src/storage/BaseCachingStorage.test.ts +0 -70
  60. package/src/storage/BaseCachingStorage.ts +0 -37
  61. package/src/storage/CachingCookieStorage.test.ts +0 -75
  62. package/src/storage/CachingCookieStorage.ts +0 -36
  63. package/src/storage/CachingLocalStorage.test.ts +0 -59
  64. package/src/storage/CachingLocalStorage.ts +0 -34
  65. package/src/storage/getCookie.test.ts +0 -53
  66. package/src/storage/getCookie.ts +0 -10
  67. package/src/storage/setCookie.test.ts +0 -97
  68. package/src/storage/setCookie.ts +0 -49
  69. package/src/theme/theme.utils.ts +0 -50
  70. package/src/url/sanitizeUrl.test.ts +0 -62
  71. package/src/url/sanitizeUrl.ts +0 -51
  72. package/src/utils/CaseTransformer.test.ts +0 -16
  73. package/src/utils/CaseTransformer.ts +0 -10
  74. package/src/utils/NullishCoalescingOperator.ts +0 -3
  75. package/src/utils/NumericDecline.ts +0 -25
  76. package/src/utils/addEventListener.ts +0 -23
  77. package/src/utils/allSettled.ts +0 -6
  78. package/src/utils/checkTimeZone.spec.ts +0 -18
  79. package/src/utils/checkTimeZone.ts +0 -6
  80. package/src/utils/deviceUtils.ts +0 -12
  81. package/src/utils/flatMap.test.ts +0 -21
  82. package/src/utils/flatMap.ts +0 -3
  83. package/src/utils/fromEntries.ts +0 -6
  84. package/src/utils/generateRandomNumber.test.ts +0 -23
  85. package/src/utils/generateRandomNumber.ts +0 -3
  86. package/src/utils/objectSort.ts +0 -41
  87. package/src/utils/orientationUtils.ts +0 -18
  88. package/src/velocity/SysVelocityContext.spec.ts +0 -88
  89. package/src/velocity/SysVelocityContext.ts +0 -129
  90. package/src/velocity/SysVelocityRenderer.spec.ts +0 -36
  91. package/src/velocity/SysVelocityRenderer.ts +0 -11
  92. package/test/__mocks/jestGlobalMocks.js +0 -1887
  93. /package/{out/DefaultEventEmitter.d.ts → DefaultEventEmitter.d.ts} +0 -0
  94. /package/{out/DefaultEventEmitter.js → DefaultEventEmitter.js} +0 -0
  95. /package/{out/HttpAbortableLoader.d.ts → HttpAbortableLoader.d.ts} +0 -0
  96. /package/{out/HttpAbortableLoader.js → HttpAbortableLoader.js} +0 -0
  97. /package/{out/InAppLayoutType.d.ts → InAppLayoutType.d.ts} +0 -0
  98. /package/{out/InAppLayoutType.js → InAppLayoutType.js} +0 -0
  99. /package/{out/LayoutType.d.ts → LayoutType.d.ts} +0 -0
  100. /package/{out/LayoutType.js → LayoutType.js} +0 -0
  101. /package/{out/PrizePool.interface.d.ts → PrizePool.interface.d.ts} +0 -0
  102. /package/{out/PrizePool.interface.js → PrizePool.interface.js} +0 -0
  103. /package/{out/RenderMode.d.ts → RenderMode.d.ts} +0 -0
  104. /package/{out/RenderMode.js → RenderMode.js} +0 -0
  105. /package/{out/UuidGenerator.d.ts → UuidGenerator.d.ts} +0 -0
  106. /package/{out/UuidGenerator.js → UuidGenerator.js} +0 -0
  107. /package/{out/WidgetInitConfig.interface.d.ts → WidgetInitConfig.interface.d.ts} +0 -0
  108. /package/{out/WidgetInitConfig.interface.js → WidgetInitConfig.interface.js} +0 -0
  109. /package/{out/WidgetType.d.ts → WidgetType.d.ts} +0 -0
  110. /package/{out/WidgetType.js → WidgetType.js} +0 -0
  111. /package/{out/action → action}/type.d.ts +0 -0
  112. /package/{out/action → action}/type.js +0 -0
  113. /package/{out/async → async}/createAsyncIterator.d.ts +0 -0
  114. /package/{out/async → async}/createAsyncIterator.js +0 -0
  115. /package/{out/async → async}/debounce.d.ts +0 -0
  116. /package/{out/async → async}/debounce.js +0 -0
  117. /package/{out/async → async}/timeout.d.ts +0 -0
  118. /package/{out/async → async}/timeout.js +0 -0
  119. /package/{out/component-manifest → component-manifest}/ComponentManifest.interface.d.ts +0 -0
  120. /package/{out/component-manifest → component-manifest}/ComponentManifest.interface.js +0 -0
  121. /package/{out/component-manifest → component-manifest}/ContextMenuManifest.interface.d.ts +0 -0
  122. /package/{out/component-manifest → component-manifest}/ContextMenuManifest.interface.js +0 -0
  123. /package/{out/component-manifest → component-manifest}/DisplayCondition.interface.d.ts +0 -0
  124. /package/{out/component-manifest → component-manifest}/DisplayCondition.interface.js +0 -0
  125. /package/{out/component-manifest → component-manifest}/FloatingControlManifest.interface.d.ts +0 -0
  126. /package/{out/component-manifest → component-manifest}/FloatingControlManifest.interface.js +0 -0
  127. /package/{out/component-manifest → component-manifest}/PropPathCondition.interface.d.ts +0 -0
  128. /package/{out/component-manifest → component-manifest}/PropPathCondition.interface.js +0 -0
  129. /package/{out/component-manifest → component-manifest}/PropertyPaneManifest.interface.d.ts +0 -0
  130. /package/{out/component-manifest → component-manifest}/PropertyPaneManifest.interface.js +0 -0
  131. /package/{out/converter → converter}/time/TimeUnit.d.ts +0 -0
  132. /package/{out/converter → converter}/time/TimeUnit.js +0 -0
  133. /package/{out/converter → converter}/time/TimerConverter.d.ts +0 -0
  134. /package/{out/converter → converter}/time/TimerConverter.js +0 -0
  135. /package/{out/document → document}/ComponentInsertType.d.ts +0 -0
  136. /package/{out/document → document}/ComponentInsertType.js +0 -0
  137. /package/{out/document → document}/Document.interface.d.ts +0 -0
  138. /package/{out/document → document}/Document.interface.js +0 -0
  139. /package/{out/document → document}/DocumentCssVarsReplace.d.ts +0 -0
  140. /package/{out/document → document}/DocumentCssVarsReplace.js +0 -0
  141. /package/{out/document → document}/DocumentUtils.d.ts +0 -0
  142. /package/{out/document → document}/DocumentUtils.js +0 -0
  143. /package/{out/document → document}/hidden-fields.interface.d.ts +0 -0
  144. /package/{out/document → document}/hidden-fields.interface.js +0 -0
  145. /package/{out/dom → dom}/ViewportSize.d.ts +0 -0
  146. /package/{out/dom → dom}/ViewportSize.js +0 -0
  147. /package/{out/dom → dom}/copyToClipboard.d.ts +0 -0
  148. /package/{out/dom → dom}/copyToClipboard.js +0 -0
  149. /package/{out/dom → dom}/getMostNestedNode.d.ts +0 -0
  150. /package/{out/dom → dom}/getMostNestedNode.js +0 -0
  151. /package/{out/dom → dom}/insertHtmlIntoElement.d.ts +0 -0
  152. /package/{out/dom → dom}/insertHtmlIntoElement.js +0 -0
  153. /package/{out/dom → dom}/sanitizeHTML.d.ts +0 -0
  154. /package/{out/dom → dom}/sanitizeHTML.js +0 -0
  155. /package/{out/element → element}/BaseElementInViewportHandler.d.ts +0 -0
  156. /package/{out/element → element}/BaseElementInViewportHandler.js +0 -0
  157. /package/{out/element → element}/CssVarsOperations.d.ts +0 -0
  158. /package/{out/element → element}/CssVarsOperations.js +0 -0
  159. /package/{out/element → element}/ThemeCssVars.d.ts +0 -0
  160. /package/{out/element → element}/ThemeCssVars.js +0 -0
  161. /package/{out/element → element}/recursiveFindParentNodeByAttribute.d.ts +0 -0
  162. /package/{out/element → element}/recursiveFindParentNodeByAttribute.js +0 -0
  163. /package/{out/flat.d.ts → flat.d.ts} +0 -0
  164. /package/{out/flat.js → flat.js} +0 -0
  165. /package/{out/handler → handler}/HandlerTypes.d.ts +0 -0
  166. /package/{out/handler → handler}/HandlerTypes.js +0 -0
  167. /package/{out/math → math}/RandomDistributor.d.ts +0 -0
  168. /package/{out/math → math}/RandomDistributor.js +0 -0
  169. /package/{out/math → math}/sum.d.ts +0 -0
  170. /package/{out/math → math}/sum.js +0 -0
  171. /package/{out/network → network}/HttpClient.d.ts +0 -0
  172. /package/{out/network → network}/HttpClient.js +0 -0
  173. /package/{out/network → network}/HttpStatus.d.ts +0 -0
  174. /package/{out/network → network}/HttpStatus.js +0 -0
  175. /package/{out/object → object}/isDictionary.d.ts +0 -0
  176. /package/{out/object → object}/isDictionary.js +0 -0
  177. /package/{out/object → object}/omitKeys.d.ts +0 -0
  178. /package/{out/object → object}/omitKeys.js +0 -0
  179. /package/{out/storage → storage}/BaseCachingStorage.d.ts +0 -0
  180. /package/{out/storage → storage}/BaseCachingStorage.js +0 -0
  181. /package/{out/storage → storage}/CachingCookieStorage.d.ts +0 -0
  182. /package/{out/storage → storage}/CachingCookieStorage.js +0 -0
  183. /package/{out/storage → storage}/CachingLocalStorage.d.ts +0 -0
  184. /package/{out/storage → storage}/CachingLocalStorage.js +0 -0
  185. /package/{out/storage → storage}/getCookie.d.ts +0 -0
  186. /package/{out/storage → storage}/getCookie.js +0 -0
  187. /package/{out/storage → storage}/setCookie.d.ts +0 -0
  188. /package/{out/storage → storage}/setCookie.js +0 -0
  189. /package/{out/theme → theme}/theme.utils.d.ts +0 -0
  190. /package/{out/theme → theme}/theme.utils.js +0 -0
  191. /package/{out/url → url}/sanitizeUrl.d.ts +0 -0
  192. /package/{out/url → url}/sanitizeUrl.js +0 -0
  193. /package/{out/utils → utils}/CaseTransformer.d.ts +0 -0
  194. /package/{out/utils → utils}/CaseTransformer.js +0 -0
  195. /package/{out/utils → utils}/NullishCoalescingOperator.d.ts +0 -0
  196. /package/{out/utils → utils}/NullishCoalescingOperator.js +0 -0
  197. /package/{out/utils → utils}/NumericDecline.d.ts +0 -0
  198. /package/{out/utils → utils}/NumericDecline.js +0 -0
  199. /package/{out/utils → utils}/addEventListener.d.ts +0 -0
  200. /package/{out/utils → utils}/addEventListener.js +0 -0
  201. /package/{out/utils → utils}/allSettled.d.ts +0 -0
  202. /package/{out/utils → utils}/allSettled.js +0 -0
  203. /package/{out/utils → utils}/checkTimeZone.d.ts +0 -0
  204. /package/{out/utils → utils}/checkTimeZone.js +0 -0
  205. /package/{out/utils → utils}/deviceUtils.d.ts +0 -0
  206. /package/{out/utils → utils}/deviceUtils.js +0 -0
  207. /package/{out/utils → utils}/flatMap.d.ts +0 -0
  208. /package/{out/utils → utils}/flatMap.js +0 -0
  209. /package/{out/utils → utils}/fromEntries.d.ts +0 -0
  210. /package/{out/utils → utils}/fromEntries.js +0 -0
  211. /package/{out/utils → utils}/generateRandomNumber.d.ts +0 -0
  212. /package/{out/utils → utils}/generateRandomNumber.js +0 -0
  213. /package/{out/utils → utils}/objectSort.d.ts +0 -0
  214. /package/{out/utils → utils}/objectSort.js +0 -0
  215. /package/{out/utils → utils}/orientationUtils.d.ts +0 -0
  216. /package/{out/utils → utils}/orientationUtils.js +0 -0
  217. /package/{out/velocity → velocity}/SysVelocityContext.d.ts +0 -0
  218. /package/{out/velocity → velocity}/SysVelocityContext.js +0 -0
  219. /package/{out/velocity → velocity}/SysVelocityRenderer.d.ts +0 -0
  220. /package/{out/velocity → velocity}/SysVelocityRenderer.js +0 -0
@@ -1,97 +0,0 @@
1
- import setCookie from './setCookie';
2
-
3
- describe('setCookie', () => {
4
- let originalDescriptor: PropertyDescriptor | undefined;
5
- let originalLocationHost: string | undefined;
6
- let originalLocationHostname: string | undefined;
7
-
8
- beforeEach(() => {
9
- originalDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
10
- originalLocationHost = window.location.host;
11
- originalLocationHostname = window.location.hostname;
12
- });
13
-
14
- afterEach(() => {
15
- if (originalDescriptor) {
16
- Object.defineProperty(document, 'cookie', originalDescriptor);
17
- }
18
- window.location.host = originalLocationHost as string;
19
- window.location.hostname = originalLocationHostname as string;
20
- });
21
-
22
- it('writes cookie once for a single-segment host', () => {
23
- const writes: string[] = [];
24
-
25
- window.location.host = 'localhost';
26
- window.location.hostname = 'localhost';
27
- Object.defineProperty(document, 'cookie', {
28
- get: () => '',
29
- set: (value: string) => {
30
- writes.push(value);
31
- },
32
- configurable: true,
33
- });
34
-
35
- setCookie('foo', 'bar');
36
-
37
- expect(writes).toHaveLength(1);
38
- expect(writes[0]).toContain('foo=bar');
39
- expect(writes[0]).toContain('path=/');
40
- expect(writes[0]).not.toContain('domain=');
41
- });
42
-
43
- it('falls back to a full host domain when parent domain write does not stick', () => {
44
- const writes: string[] = [];
45
-
46
- window.location.host = 'app.example.com';
47
- window.location.hostname = 'app.example.com';
48
- Object.defineProperty(document, 'cookie', {
49
- get: () => '',
50
- set: (value: string) => {
51
- writes.push(value);
52
- },
53
- configurable: true,
54
- });
55
-
56
- setCookie('foo', 'bar');
57
-
58
- expect(writes).toHaveLength(2);
59
- expect(writes[0]).toContain('domain=.example.com');
60
- expect(writes[1]).toContain('domain=.app.example.com');
61
- });
62
-
63
- it('does not write the fallback domain when parent domain write is readable', () => {
64
- const writes: string[] = [];
65
- let cookieValue = '';
66
-
67
- window.location.host = 'app.example.com';
68
- window.location.hostname = 'app.example.com';
69
- Object.defineProperty(document, 'cookie', {
70
- get: () => cookieValue,
71
- set: (value: string) => {
72
- writes.push(value);
73
- cookieValue = 'foo=bar';
74
- },
75
- configurable: true,
76
- });
77
-
78
- setCookie('foo', 'bar');
79
-
80
- expect(writes).toHaveLength(1);
81
- expect(writes[0]).toContain('domain=.example.com');
82
- });
83
-
84
- it('does not throw when cookie write fails', () => {
85
- window.location.host = 'app.example.com';
86
- window.location.hostname = 'app.example.com';
87
- Object.defineProperty(document, 'cookie', {
88
- get: () => '',
89
- set: () => {
90
- throw new Error('blocked');
91
- },
92
- configurable: true,
93
- });
94
-
95
- expect(() => setCookie('foo', 'bar')).not.toThrow();
96
- });
97
- });
@@ -1,49 +0,0 @@
1
- import getCookie from './getCookie';
2
-
3
- export interface CookieOptionsI {
4
- path?: string;
5
- expires?: Date | string;
6
- [key: string]: string | Date | boolean | undefined;
7
- }
8
-
9
- export default function setCookie(name: string, value: string | null, options: CookieOptionsI = {}): void {
10
- const normalizedOptions: CookieOptionsI = {
11
- path: '/',
12
- expires: new Date(new Date().getFullYear() + 5, 0),
13
- ...options,
14
- };
15
-
16
- if (normalizedOptions.expires instanceof Date) {
17
- normalizedOptions.expires = normalizedOptions.expires.toUTCString();
18
- }
19
-
20
- let updatedCookie = encodeURIComponent(name) + '=' + encodeURIComponent(String(value));
21
-
22
- for (const optionKey in normalizedOptions) {
23
- updatedCookie += '; ' + optionKey;
24
- const optionValue = normalizedOptions[optionKey];
25
- if (optionValue !== true) {
26
- updatedCookie += '=' + optionValue;
27
- }
28
- }
29
-
30
- try {
31
- const host = location.host ?? 'localhost';
32
-
33
- if (host.split('.').length === 1) {
34
- document.cookie = updatedCookie + '; path=/';
35
- return;
36
- }
37
-
38
- const domainParts = host.split('.');
39
- domainParts.shift();
40
- let domain = '.' + domainParts.join('.');
41
- document.cookie = updatedCookie + '; path=/; domain=' + domain;
42
-
43
- if (getCookie(name) == null || getCookie(name) !== String(value)) {
44
- domain = '.' + host;
45
- document.cookie = updatedCookie + '; path=/; domain=' + domain;
46
- }
47
- } catch (e) {
48
- }
49
- }
@@ -1,50 +0,0 @@
1
- import { ThemeI } from "../document/Document.interface";
2
-
3
- export const THEME_CSS_VAR_PREFIX = 'cl-schema-';
4
-
5
- export function toCssVarToken(token: string) {
6
- return `${THEME_CSS_VAR_PREFIX}${token}`;
7
- }
8
-
9
- export function fromCssVarToSchemaToken(cssVar: string = '') {
10
- return cssVar
11
- .replace(/var\(\s*(--[^,\s)]+).*\)/, '$1')
12
- .replace(`--${THEME_CSS_VAR_PREFIX}`, '');
13
- }
14
-
15
- export function extractRgbFromFallbackValue(value: string) {
16
- const rgbMatch = String(value).match(/var\([^,]+,\s*(rgb(?:a)?\([^)]+\))\)/);
17
- if (rgbMatch && rgbMatch[1]) {
18
- return rgbMatch[1];
19
- }
20
- return null;
21
- }
22
-
23
- export function extractColor(value: string, theme?: ThemeI | null) {
24
- const _value = String(value || '');
25
- if (_value.startsWith('var(')) {
26
- if (!theme) {
27
- return null;
28
- }
29
-
30
- const token = fromCssVarToSchemaToken(_value);
31
- const themeColor = theme.schema?.[token];
32
-
33
- if (themeColor) {
34
- return themeColor;
35
- }
36
-
37
- // Fallback to extract RGB from fallback value: var(--name, rgb(255, 0, 0))
38
- return extractRgbFromFallbackValue(_value) || null;
39
- }
40
-
41
- return _value;
42
- }
43
-
44
- export function createTheme(schema: Record<string, string> = {}): ThemeI {
45
- return {
46
- schema: {
47
- ...schema,
48
- }
49
- }
50
- }
@@ -1,62 +0,0 @@
1
- import sanitizeUrl from './sanitizeUrl';
2
-
3
- describe('sanitizeUrl', () => {
4
- it('should sanitize URLs correctly', () => {
5
- // Safe URLs - должны проходить без изменений
6
- expect(sanitizeUrl('http://example.com')).toBe('http://example.com');
7
- expect(sanitizeUrl('https://example.com')).toBe('https://example.com');
8
- expect(sanitizeUrl('mailto:user@example.com')).toBe('mailto:user@example.com');
9
- expect(sanitizeUrl('tel:+1234567890')).toBe('tel:+1234567890');
10
- expect(sanitizeUrl('sms:+1234567890')).toBe('sms:+1234567890');
11
- expect(sanitizeUrl('whatsapp://send?text=Hello')).toBe('whatsapp://send?text=Hello');
12
- expect(sanitizeUrl('tg://resolve?domain=username')).toBe('tg://resolve?domain=username');
13
- expect(sanitizeUrl('fb://profile/123456')).toBe('fb://profile/123456');
14
- expect(sanitizeUrl('twitter://user?screen_name=username')).toBe('twitter://user?screen_name=username');
15
- expect(sanitizeUrl('instagram://user?username=test')).toBe('instagram://user?username=test');
16
- expect(sanitizeUrl('myapp://action/123')).toBe('myapp://action/123');
17
- expect(sanitizeUrl('customscheme://open/page')).toBe('customscheme://open/page');
18
- expect(sanitizeUrl('app-name://deep/link/path')).toBe('app-name://deep/link/path');
19
- expect(sanitizeUrl('spotify:track:123456')).toBe('spotify:track:123456');
20
- expect(sanitizeUrl('maps://maps.google.com/maps?q=location')).toBe('maps://maps.google.com/maps?q=location');
21
- expect(sanitizeUrl('comgooglemaps://maps?q=location')).toBe('comgooglemaps://maps?q=location');
22
- expect(sanitizeUrl('zoommtg://zoom.us/join?confno=123456')).toBe('zoommtg://zoom.us/join?confno=123456');
23
- expect(sanitizeUrl('zoom://meeting/123456')).toBe('zoom://meeting/123456');
24
- expect(sanitizeUrl('slack://channel?team=T123&id=C456')).toBe('slack://channel?team=T123&id=C456');
25
- expect(sanitizeUrl('msteams://teams.microsoft.com/l/chat')).toBe('msteams://teams.microsoft.com/l/chat');
26
- expect(sanitizeUrl('itms-apps://itunes.apple.com/app/id123456')).toBe('itms-apps://itunes.apple.com/app/id123456');
27
- expect(sanitizeUrl('market://details?id=com.example.app')).toBe('market://details?id=com.example.app');
28
-
29
- // Опасные протоколы - должны блокироваться
30
- expect(sanitizeUrl('javascript:alert("XSS")')).toBe('about:blank');
31
- expect(sanitizeUrl('JavaScript:alert("XSS")')).toBe('about:blank');
32
- expect(sanitizeUrl('jAvAsCrIpT:alert("XSS")')).toBe('about:blank');
33
- expect(sanitizeUrl('data:text/html,<script>alert("XSS")</script>')).toBe('about:blank');
34
- expect(sanitizeUrl('data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik8L3NjcmlwdD4=')).toBe('about:blank');
35
- expect(sanitizeUrl('vbscript:alert("XSS")')).toBe('about:blank');
36
- expect(sanitizeUrl('chrome://settings')).toBe('about:blank');
37
- expect(sanitizeUrl('chrome-extension://abc/page.html')).toBe('about:blank');
38
- expect(sanitizeUrl('chrome-untrusted://abc')).toBe('about:blank');
39
- expect(sanitizeUrl('about:config')).toBe('about:blank');
40
- expect(sanitizeUrl('about:chrome')).toBe('about:blank');
41
-
42
- // XSS паттерны - должны блокироваться
43
- expect(sanitizeUrl('http://example.com/<script>alert("XSS")</script>')).toBe('about:blank');
44
- expect(sanitizeUrl('http://example.com/<iframe src="evil.com"></iframe>')).toBe('about:blank');
45
- expect(sanitizeUrl('http://example.com/<img onerror="alert(\'XSS\')">')).toBe('about:blank');
46
- expect(sanitizeUrl('data:image/svg+xml,<svg onload=alert("XSS")>')).toBe('about:blank');
47
- expect(sanitizeUrl('http://example.com/<embed src="evil.swf">')).toBe('about:blank');
48
- expect(sanitizeUrl('http://example.com/<object data="evil">')).toBe('about:blank');
49
- expect(sanitizeUrl('http://example.com/<applet code="Evil.class">')).toBe('about:blank');
50
- expect(sanitizeUrl('http://example.com/<meta http-equiv="refresh">')).toBe('about:blank');
51
- expect(sanitizeUrl('http://example.com/<link rel="import">')).toBe('about:blank');
52
- expect(sanitizeUrl('http://example.com/<style>body{background:url("javascript:alert()")}</style>')).toBe('about:blank');
53
-
54
- // Edge cases
55
- expect(sanitizeUrl('')).toBe('about:blank');
56
- expect(sanitizeUrl(null)).toBe('about:blank');
57
- expect(sanitizeUrl(undefined)).toBe('about:blank');
58
- expect(sanitizeUrl('about:blank')).toBe('about:blank');
59
- expect(sanitizeUrl(' https://example.com ')).toBe('https://example.com');
60
- expect(sanitizeUrl('\t\nhttps://example.com\n\t')).toBe('https://example.com');
61
- });
62
- });
@@ -1,51 +0,0 @@
1
- const DANGEROUS_PROTOCOLS: readonly string[] = [
2
- 'javascript:',
3
- 'data:',
4
- 'vbscript:',
5
- 'about:',
6
- 'chrome:',
7
- 'chrome-extension:',
8
- 'chrome-untrusted:',
9
- ];
10
-
11
- const DANGEROUS_PATTERNS: readonly RegExp[] = [
12
- /^data:[^,]*;base64,.*<script/i,
13
- /^data:image\/svg\+xml[^,]*,.*<script/i,
14
- /<script|<iframe|<embed|<object|<applet|<meta|<link|<style|<img.*on\w+=/i,
15
- ];
16
-
17
- export default function sanitizeUrl(url: string | null | undefined): string {
18
- if (!url) {
19
- return 'about:blank';
20
- }
21
-
22
- const cleanUrl = String(url).trim();
23
-
24
- if (!cleanUrl) {
25
- return 'about:blank';
26
- }
27
-
28
- if (cleanUrl === 'about:blank') {
29
- return 'about:blank';
30
- }
31
-
32
- const lowerUrl = cleanUrl.toLowerCase();
33
-
34
- const hasUnsafeProtocol = DANGEROUS_PROTOCOLS.some(protocol =>
35
- lowerUrl.startsWith(protocol)
36
- );
37
-
38
- if (hasUnsafeProtocol) {
39
- return 'about:blank';
40
- }
41
-
42
- const hasUnsafePattern = DANGEROUS_PATTERNS.some(pattern =>
43
- pattern.test(cleanUrl)
44
- );
45
-
46
- if (hasUnsafePattern) {
47
- return 'about:blank';
48
- }
49
-
50
- return cleanUrl;
51
- }
@@ -1,16 +0,0 @@
1
- import {CaseTransformer} from "./CaseTransformer";
2
-
3
- describe('CaseTransformer', () => {
4
- it('should modify camelCase to the dash-case', () => {
5
- expect(CaseTransformer.camelCaseToDashCase('someCamelCaseValue')).toEqual('some-camel-case-value');
6
- });
7
- it('should modify camelCase to the dash-case (case 2)', () => {
8
- expect(CaseTransformer.camelCaseToDashCase('testABC')).toEqual('test-a-b-c');
9
- });
10
- it('should modify camelCase to the UPPER_SNAKE_CASE', () => {
11
- expect(CaseTransformer.camelCaseToUpperSnakeCase('someCamelCaseValue')).toEqual('SOME_CAMEL_CASE_VALUE');
12
- });
13
- it('should modify camelCase to the UPPER_SNAKE_CASE (case 2)', () => {
14
- expect(CaseTransformer.camelCaseToUpperSnakeCase('testABC')).toEqual('TEST_A_B_C');
15
- });
16
- });
@@ -1,10 +0,0 @@
1
- export class CaseTransformer {
2
-
3
- static camelCaseToDashCase(string: string): string {
4
- return string.replace(/[A-Z]/g, match => "-" + match.toLowerCase());
5
- }
6
-
7
- static camelCaseToUpperSnakeCase(string: string): string {
8
- return string.replace(/[A-Z]/g, match => "_" + match).toUpperCase();
9
- }
10
- }
@@ -1,3 +0,0 @@
1
- export default function nullishCoalescingOperator<T>(a: T | null | undefined, b: T): T {
2
- return (a !== null && a !== undefined) ? a : b;
3
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Returns the correct grammatical form based on a numeric value.
3
- * Handles pluralization rules for different languages (English, Russian, etc.).
4
- * @param itemsCount - The number to determine the form for
5
- * @param translateKeys - Array of translation keys [singular, plural, genitive plural]
6
- * @param language - The language code (e.g., 'en', 'ru')
7
- * @returns The appropriate translation key for the given count
8
- * @example
9
- * getNumericDecline(1, ['item', 'items', 'items'], 'en'); // 'item'
10
- * getNumericDecline(5, ['item', 'items', 'items'], 'en'); // 'items'
11
- * getNumericDecline(21, ['товар', 'товара', 'товаров'], 'ru'); // 'товар'
12
- */
13
- export default function getNumericDecline(itemsCount: number, translateKeys: string[], language: string): string {
14
- if (language === 'en' && itemsCount > 1) {
15
- // for russian it's okay to use single item translation for 21, 31 and similar itemsCount
16
- // but for english it doesn't fit
17
- return translateKeys[1];
18
- }
19
-
20
- const number = Math.abs(itemsCount);
21
-
22
- const cases = [2, 0, 1, 1, 1, 2];
23
- return translateKeys[ (number % 100 > 4 &&
24
- number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5] ];
25
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * Adds an event listener to an element, with fallback to base implementation.
3
- * Handles cases where addEventListener may have been overridden.
4
- * @param element - The target element to attach the listener to
5
- * @param eventType - The event type to listen for (e.g., 'click', 'load')
6
- * @param callback - The callback function or object to invoke
7
- * @param options - Optional listener options (capture, passive, etc.)
8
- * @example
9
- * addEventListenerToElement(button, 'click', () => console.log('clicked'));
10
- */
11
- const addEventListenerToElement = (
12
- element: EventTarget,
13
- eventType: string,
14
- callback: EventListenerOrEventListenerObject,
15
- options?: boolean | AddEventListenerOptions
16
- ): void => {
17
- const prototype = EventTarget.prototype as any;
18
- const { addEventListenerBase, addEventListener } = prototype;
19
-
20
- (addEventListenerBase || addEventListener).call(element, eventType, callback, options);
21
- };
22
-
23
- export default addEventListenerToElement;
@@ -1,6 +0,0 @@
1
- export function allSettled<T>(promises: Promise<T>[] = []): Promise<PromiseSettledResult<T>[]> {
2
- return Promise.all(promises.map(p => Promise.resolve(p).then(
3
- value => ({status: 'fulfilled' as const, value}),
4
- reason => ({status: 'rejected' as const, reason}),
5
- )));
6
- }
@@ -1,18 +0,0 @@
1
- import {checkTimeZone} from "./checkTimeZone";
2
-
3
- describe('checkTimeZone', () => {
4
- test('should return Europe/Kiev when timeZone is Europe/Kyiv', () => {
5
- const result = checkTimeZone('Europe/Kyiv');
6
- expect(result).toBe('Europe/Kiev');
7
- });
8
-
9
- test('should return the same timeZone when it does not match Europe/Kyiv', () => {
10
- const result = checkTimeZone('America/New_York');
11
- expect(result).toBe('America/New_York');
12
- });
13
-
14
- test('should return undefined when timeZone is not provided', () => {
15
- const result = checkTimeZone(undefined);
16
- expect(result).toBeUndefined();
17
- });
18
- });
@@ -1,6 +0,0 @@
1
- export function checkTimeZone(timeZone: string | undefined): string | undefined {
2
- if (timeZone && timeZone === 'Europe/Kyiv') {
3
- return 'Europe/Kiev';
4
- }
5
- return timeZone;
6
- }
@@ -1,12 +0,0 @@
1
- export const isIPad = (): boolean => {
2
- return /iPad/.test(navigator.userAgent) ||
3
- (navigator.platform === 'MacIntel' && navigator['maxTouchPoints'] > 1);
4
- }
5
-
6
- export const isIPhone = (): boolean => {
7
- return /iPhone/i.test(navigator.userAgent);
8
- }
9
-
10
- export const isIOS = (): boolean => {
11
- return isIPhone() || isIPad();
12
- }
@@ -1,21 +0,0 @@
1
- import flatMap from './flatMap';
2
-
3
- describe('flatMap', () => {
4
- it('Should flatten an array of arrays', () => {
5
- const input = [[1, 2], [3, 4], [5]];
6
- const result = flatMap(input, x => x);
7
- expect(result).toEqual([1, 2, 3, 4, 5]);
8
- });
9
-
10
- it('Should apply a function to each item and flatten the result', () => {
11
- const input = [1, 2, 3];
12
- const result = flatMap(input, x => [x, x * 2]);
13
- expect(result).toEqual([1, 2, 2, 4, 3, 6]);
14
- });
15
-
16
- it('Should return an empty array when given an empty array', () => {
17
- const input = [];
18
- const result = flatMap(input, x => [x]);
19
- expect(result).toEqual([]);
20
- });
21
- });
@@ -1,3 +0,0 @@
1
- export default function flatMap<T, U>(arr: T[], func: (item: T) => U[]): U[] {
2
- return arr.reduce((acc: U[], item: T) => acc.concat(func(item)), []);
3
- }
@@ -1,6 +0,0 @@
1
- export function fromEntries<V>(iterable: Iterable<[string, V]>): Record<string, V> {
2
- return [...iterable].reduce((obj: Record<string, V>, [key, val]) => {
3
- obj[key] = val;
4
- return obj;
5
- }, {});
6
- }
@@ -1,23 +0,0 @@
1
- import generateRandomNumber from "./generateRandomNumber";
2
-
3
- describe('generateRandomNumber', () => {
4
- it('should calc', () => {
5
-
6
- let vars = {};
7
- let length = 1_000_000;
8
-
9
- for (let i = 0; i < length; i++) {
10
- let id = generateRandomNumber(1, 3);
11
- if (!vars[id]) {
12
- vars[id] = 1;
13
- } else {
14
- vars[id] += 1;
15
- }
16
-
17
- }
18
- expect(Object.keys(vars).length).toBe(3);
19
-
20
-
21
- });
22
-
23
- });
@@ -1,3 +0,0 @@
1
- export default function generateRandomNumber(min: number, max: number): number {
2
- return Math.floor(Math.random() * (max + 1- min)) + min;
3
- }
@@ -1,41 +0,0 @@
1
- import {fromEntries} from "./fromEntries";
2
-
3
- export function comparisonFunction(a: Record<string, any>, b: Record<string, any>, property: string, descending: boolean = false): number {
4
- let first = a[property];
5
- let second = b[property];
6
-
7
- if (isNaN(first) || isNaN(second)) {
8
- if (typeof first !== 'string' || typeof second !== 'string') {
9
- return 0;
10
-
11
- } else {
12
- first = first.toLowerCase();
13
- second = second.toLowerCase();
14
-
15
- if (descending) {
16
- return second.localeCompare(first);
17
-
18
- } else {
19
- return first.localeCompare(second);
20
- }
21
- }
22
- }
23
-
24
- if (first < second) {
25
- return descending ? 1 : -1;
26
- }
27
- if (first > second) {
28
- return descending ? -1 : 1;
29
- }
30
-
31
- return 0;
32
- }
33
-
34
- export function sort(object: Record<string, Record<string, any>>, property: string, descending: boolean = false): Record<string, Record<string, any>> {
35
- return fromEntries(
36
- Object.entries(object)
37
- .sort(([_ka, a], [_kb, b]) => {
38
- return comparisonFunction(a, b, property, descending);
39
- })
40
- );
41
- }
@@ -1,18 +0,0 @@
1
- export const detectOrientation = (): 'PORTRAIT' | 'LANDSCAPE' => {
2
- const screen = window.screen as any;
3
- const orientation =
4
- screen.orientation ||
5
- screen.mozOrientation ||
6
- screen.msOrientation;
7
-
8
- if (orientation) {
9
- return orientation.type.includes('portrait') ? 'PORTRAIT' : 'LANDSCAPE';
10
- } else if (typeof (window as any).orientation !== 'undefined') {
11
- if ((window as any).orientation === 0 || (window as any).orientation === 180) {
12
- return 'PORTRAIT';
13
- } else if ((window as any).orientation === 90 || (window as any).orientation === -90) {
14
- return 'LANDSCAPE';
15
- }
16
- }
17
- return 'PORTRAIT';
18
- };
@@ -1,88 +0,0 @@
1
- import SysVelocityContext from "./SysVelocityContext";
2
-
3
- describe('SysVelocityContext', function () {
4
-
5
- const velocityContext = new SysVelocityContext();
6
- const velocityObject = velocityContext.create();
7
- const dateTool = velocityObject.dateTool;
8
- const numberTool = velocityObject.numberTool;
9
- const mathTool = velocityObject.mathTool;
10
-
11
-
12
-
13
- it('should be able to add', function () {
14
- expect(mathTool.add(2, 2)).toEqual(4);
15
- expect(mathTool.add('2', 5)).toEqual(7);
16
- });
17
-
18
- it('should be able to subtract', function () {
19
- expect(mathTool.sub(5, 2)).toEqual(3);
20
- expect(mathTool.sub('15', '2')).toEqual(13);
21
- });
22
-
23
- it('should be able to multiply', function () {
24
- expect(mathTool.mul(5, 2)).toEqual(10);
25
- expect(mathTool.mul('15', '2')).toEqual(30);
26
- });
27
-
28
- it('should be able to divide', function () {
29
- expect(mathTool.div(6, 2)).toEqual(3);
30
- expect(mathTool.div('36', 3)).toEqual(12);
31
- });
32
-
33
- it('should be compare string ignore case', function () {
34
- expect(velocityObject.stringTool.equalsIgnoreCase('HEllO!', 'Hello!')).toBeTruthy();
35
- });
36
-
37
- it('should be displays an integer without rounding', function () {
38
- expect(numberTool.integer(25.36)).toEqual(25);
39
- expect(numberTool.integer(36)).toEqual(36);
40
- expect(numberTool.integer(3.0000000)).toEqual(3);
41
- expect(numberTool.integer('56.045000000')).toEqual(56);
42
- });
43
-
44
- it('should be formatting number by mask', function () {
45
- expect(numberTool.format('#.00', 56.026954)).toEqual('56.03');
46
- expect(numberTool.format('#.00', 56)).toBe('56.00');
47
- expect(numberTool.format('#.000', 56.026954)).toEqual('56.027');
48
- expect(numberTool.format('#.000', '56.026954')).toEqual('56.027');
49
- expect(numberTool.format('#.0', 56.026954)).toEqual('56.0');
50
- expect(numberTool.format('#.', 56.026954)).toEqual('56');
51
- expect(numberTool.format(null, 56.026954)).toEqual('56');
52
- });
53
-
54
- it('should be formatting number by ranks', function () {
55
- expect(numberTool.number(589362153.0025)).toEqual('589,362,153.003');
56
- expect(numberTool.number(589362153.00000000)).toEqual('589,362,153');
57
- expect(numberTool.number(589362153.0025, ' ')).toEqual('589 362 153.003');
58
- expect(numberTool.number(589362153.0025, ' ', 2)).toEqual('589 362 153');
59
- expect(numberTool.number(589362153.025, ' ', 2)).toEqual('589 362 153.02');
60
- expect(numberTool.number(589362153.026, ' ', 2)).toEqual('589 362 153.03');
61
- expect(numberTool.number(589362153.026, ' ', 5)).toEqual('589 362 153.02600');
62
- });
63
-
64
- it('should be formatting current date as timestamp', function () {
65
- const now = new Date();
66
- expect(dateTool.formatDate('ISO', now)).toEqual(now.toISOString());
67
- });
68
-
69
- it('should be formatting current date as ISO string', function () {
70
- const now = new Date();
71
- expect(dateTool.formatDate(null, now)).toEqual(now.getTime());
72
- });
73
-
74
- it('should be formatting date by mask', function () {
75
- const now = new Date(1495479520000);
76
- const month = now.getMonth() + 1 > 9 ? now.getMonth() + 1 : `0${now.getMonth() + 1}`;
77
- const day = now.getDate() > 9 ? now.getDate() : `0${now.getDate()}`;
78
- const hours = now.getHours() > 9 ? now.getHours() : `0${now.getHours()}`;
79
- const minutes = now.getMinutes() > 9 ? now.getMinutes() : `0${now.getMinutes()}`;
80
- const seconds = now.getSeconds() > 9 ? now.getSeconds() : `0${now.getSeconds()}`;
81
- expect(dateTool.formatDate('MM-DD', now)).toEqual(`${month}-${day}`);
82
- expect(dateTool.formatDate('YYYY-MM-DD', now))
83
- .toEqual(`${now.getFullYear()}-${month}-${day}`);
84
- expect(dateTool.formatDate('YYYY-MM-DD HH:MM:SS', now))
85
- .toEqual(`${now.getFullYear()}-${month}-${day} ${hours}:${minutes}:${seconds}`);
86
- });
87
-
88
- });